Skip to content
This repository has been archived by the owner on Nov 11, 2024. It is now read-only.

Commit

Permalink
Adopting sandboxing allows version 2.1 to be submitted to the Mac App…
Browse files Browse the repository at this point in the history
… Store.

Adopting sandboxing allows version 2.1 to be submitted to the Mac App Store.
  • Loading branch information
LumingYin authored Apr 27, 2019
2 parents b44ba0a + 2f5f049 commit 18ce953
Show file tree
Hide file tree
Showing 118 changed files with 4,433 additions and 247 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.DS_Store
*/xcuserdata/*
Quick Caption.xcodeproj/xcuserdata
Quick Caption.xcodeproj/xcuserdata/*
/Quick Caption.xcodeproj/xcuserdata/*
Binary file modified Caption/.DS_Store
Binary file not shown.
Binary file not shown.
Binary file added Caption/Credits/QuickCaption_Acknowledgements.pdf
Binary file not shown.
4 changes: 2 additions & 2 deletions Caption/Model/Exporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ enum FileType {
srtString = srtString + "\(i+1)\n\(str)\n\n"
}
}
print(srtString)
// print(srtString)
return srtString
}

Expand Down Expand Up @@ -189,7 +189,7 @@ enum FileType {
}
}
}
print(txtString)
// print(txtString)
return txtString
}

Expand Down
39 changes: 28 additions & 11 deletions Caption/Model/Saver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ class Saver {
return
}

if type == .fcpXML {
if !Helper.fcpxTemplateAlreadyInstalled() {
Helper.displayInteractiveSheet(title: "Install Final Cut Pro X Caption Template", text: "For Final Cut Pro X to correctly import your FCPXML, Final Cut Pro X Caption Template must be installed first.", firstButtonText: "Continue", secondButtonText: "Cancel") { (confirm) in
if confirm {
Helper.installFCPXCaptionFiles(callback: {
Saver.writeFileToDisk(type: type, text: text, episode: episode)
})
}
}
return
}
}

guard let origonalVideoName = episode.videoURL?.lastPathComponent else {
return
}
Expand All @@ -57,22 +70,26 @@ class Saver {
newSubtitleName = "\(ogVN).fcpxml"
}

guard let newPath = episode.videoURL?.deletingLastPathComponent().appendingPathComponent(newSubtitleName) else {
guard let directoryPath = episode.videoURL?.deletingLastPathComponent() else {
return
}

do {
try text.write(to: newPath, atomically: true, encoding: String.Encoding.utf8)
Helper.displayInteractiveSheet(title: "Saved successfully!", text: "Subtitle saved as \(newSubtitleName) under \(newPath.deletingLastPathComponent()).", firstButtonText: "Show in Finder", secondButtonText: "Dismiss") { (firstButtonReturn) in
if firstButtonReturn == true {
NSWorkspace.shared.activateFileViewerSelecting([newPath])
let newPath = directoryPath.appendingPathComponent(newSubtitleName)

Helper.displaySaveFileDialog(newSubtitleName, directoryPath: directoryPath, callback: { (success, url, string) in
if success {
do {
try text.write(to: url!, atomically: true, encoding: String.Encoding.utf8)
Helper.displayInteractiveSheet(title: "Saved successfully!", text: "Subtitle saved as \(newSubtitleName) under \(newPath.deletingLastPathComponent()).", firstButtonText: "Show in Finder", secondButtonText: "Dismiss") { (firstButtonReturn) in
if firstButtonReturn == true {
NSWorkspace.shared.activateFileViewerSelecting([newPath])
}
}
} catch {
Helper.displayInformationalSheet(title: "Save failed!", text: "Save has failed. \(error)")
}
}
}
catch {
print("Error writing to file: \(error)")
Helper.displayInformationalSheet(title: "Saved failed!", text: "Save has failed. \(error)")
}
})
}

}
30 changes: 17 additions & 13 deletions Caption/Others/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,26 +96,19 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}

@IBAction func installFCPXExtras(_ sender: Any) {
Helper.installFCPXCaptionFiles(callback: nil)
}

func applicationDidFinishLaunching(_ aNotification: Notification) {
#if DEBUG
// UserDefaults.standard.set(true, forKey: "NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints")
#else
PFMoveToApplicationsFolderIfNecessary()
#endif
SUUpdater.shared()?.checkForUpdatesInBackground()
UserDefaults.standard.set(true, forKey: "SUAutomaticallyUpdate")
MSAppCenter.start("c5be1193-d482-4d0e-99a9-b5901f40d6f3", withServices:[
MSAnalytics.self,
MSCrashes.self,
])
Helper.installFCPXCaptionFiles()
// Helper.installFCPXCaptionFiles()
Timer.scheduledTimer(withTimeInterval: 30, repeats: true) { (_) in
self.saveEverything(self)
}
}

func applicationWillTerminate(_ aNotification: Notification) {
UserDefaults.standard.set(true, forKey: "SUAutomaticallyUpdate")
// UserDefaults.standard.set(true, forKey: "SUAutomaticallyUpdate")

do {
let fetchRequest: NSFetchRequest<EpisodeProject> = EpisodeProject.fetchRequest()
Expand Down Expand Up @@ -368,6 +361,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}

@IBAction func displayAcknowledgements(_ sender: Any) {
if let bundleURL = Bundle.main.url(forResource: "QuickCaption_Acknowledgements", withExtension: "pdf") {
NSWorkspace.shared.open(bundleURL)
}
}

@IBAction func projectNavigatorClicked(_ sender: Any) {
AppDelegate.mainWindow()?.toggleSidebarList(self)
}
Expand All @@ -386,6 +385,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {

@IBAction func replaceCaptionsWithSRT(_ sender: Any) {
}

@IBAction func checkForUpdates(_ sender: NSMenuItem) {
NSWorkspace.shared.open(URL(string: "macappstore://itunes.apple.com/us/app/quick-caption/id1363610340?mt=12")!)
}

}


195 changes: 195 additions & 0 deletions Caption/Others/AppSandboxFileAccess/AppSandboxFileAccess.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
//
// AppSandboxFileAccess.h
// AppSandboxFileAccess
//
// Created by Leigh McCulloch on 23/11/2013.
//
// Copyright (c) 2013, Leigh McCulloch
// All rights reserved.
//
// BSD-2-Clause License: http://opensource.org/licenses/BSD-2-Clause
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#import <Foundation/Foundation.h>
@import AppKit;

#pragma mark -
#pragma mark AppSandboxFileAccessProtocol

@protocol AppSandboxFileAccessProtocol<NSObject>

@required
- (NSData *)bookmarkDataForURL:(NSURL *)url;
- (void)setBookmarkData:(NSData *)data forURL:(NSURL *)url;
- (void)clearBookmarkDataForURL:(NSURL *)url;

@end

#pragma mark -
#pragma mark AppSandboxFileAccess

typedef void (^AppSandboxFileAccessBlock)(void);
typedef void (^AppSandboxFileSecurityScopeBlock)(NSURL *securityScopedFileURL, NSData *bookmarkData);

@interface AppSandboxFileAccess : NSObject

/*! @brief The title of the NSOpenPanel displayed when asking permission to access a file.
Default: "Allow Access"
*/
@property (readwrite, copy, nonatomic) NSString *title;
/*! @brief The message contained on the the NSOpenPanel displayed when asking permission to access a file.
Default: "[Application Name] needs to access this path to continue. Click Allow to continue."
*/
@property (readwrite, copy, nonatomic) NSString *message;
/*! @brief The prompt button on the the NSOpenPanel displayed when asking permission to access a file.
Default: "Allow"
*/
@property (readwrite, copy, nonatomic) NSString *prompt;

/*! @brief This is an optional delegate object that can be provided to customize the persistance of bookmark data (e.g. in a Core Data database).
Default: nil (Default uses the AppSandboxFileAccessPersist class.)
*/
@property (nonatomic, weak) id <AppSandboxFileAccessProtocol> bookmarkPersistanceDelegate;

/*! @brief Create the object with the default values. */
+ (AppSandboxFileAccess *)fileAccess;

/*! @brief Initialise the object with the default values. */
- (instancetype)init;

/*! @brief Access a file path to read or write, automatically gaining permission from the user with NSOpenPanel if required
and using persisted permissions if possible.
@see accessFile:persistPermission:withBlock:
@see securityScopedURLForFilePath:persistPermission:bookmark:
@param path A file path, either a file or folder, that the caller needs access to.
@param persist If YES will save the permission for future calls.
@param block The block that will be given access to the file or folder.
@return YES if permission was granted or already available, NO otherwise.
*/
- (BOOL)accessFilePath:(NSString *)path persistPermission:(BOOL)persist withBlock:(AppSandboxFileAccessBlock)block;

/*!
@warning Deprecated.
@see accessFilePath:persistPermission:withBlock:
@param path A file path, either a file or folder, that the caller needs access to.
@param block The block that will be given access to the file or folder.
@param persist If YES will save the permission for future calls.
@return YES if permission was granted or already available, NO otherwise.
*/
- (BOOL)accessFilePath:(NSString *)path withBlock:(AppSandboxFileAccessBlock)block persistPermission:(BOOL)persist __attribute__((deprecated("Use 'accessFilePath:persistPermission:withBlock:' instead.")));

/*! @brief Access a file URL to read or write, automatically gaining permission from the user with NSOpenPanel if required
and using persisted permissions if possible.
@see requestAccessPermissionsForFileURL:persistPermission:withBlock:
@discussion Internally calls `requestAccessPermissionsForFileURL:persistPermission:withBlock:` and accesses the returned scoped URL if successful.
@discussion See `requestAccessPermissionsForFileURL:persistPermission:withBlock:` for detailed behaviour.
@param fileURL A file URL, either a file or folder, that the caller needs access to.
@param persist If YES will save the permission for future calls.
@param block The block that will be given access to the file or folder.
@return YES if permission was granted or already available, NO otherwise.
*/
- (BOOL)accessFileURL:(NSURL *)fileURL persistPermission:(BOOL)persist withBlock:(AppSandboxFileAccessBlock)block;

/*!
@warning Deprecated.
@see accessFileURL:persistPermission:withBlock:
@param fileURL A file URL, either a file or folder, that the caller needs access to.
@param persist If YES will save the permission for future calls.
@param block The block that will be given access to the file or folder.
@return YES if permission was granted or already available, NO otherwise.
*/
- (BOOL)accessFileURL:(NSURL *)fileURL withBlock:(AppSandboxFileAccessBlock)block persistPermission:(BOOL)persist __attribute__((deprecated("Use 'accessFileURL:persistPermission:withBlock:' instead.")));

/*! @brief Request access permission for a file path to read or write, automatically with NSOpenPanel if required
and using persisted permissions if possible.
@see securityScopedURLForFilePath:persistPermission:bookmark:
@param filePath A file path, either a file or folder, that the caller needs access to.
@param persist If YES will save the permission for future calls.
@return YES if permission was granted or already available, NO otherwise.
*/
- (BOOL)requestAccessPermissionsForFilePath:(NSString *)filePath persistPermission:(BOOL)persist withBlock:(AppSandboxFileSecurityScopeBlock)block;

/*! @brief Request access permission for a file path to read or write, automatically with NSOpenPanel if required
and using persisted permissions if possible.
@discussion Use this function to access a file URL to either read or write in an application restricted by the App Sandbox.
This function will ask the user for permission if necessary using a well formed NSOpenPanel. The user will
have the option of approving access to the URL you specify, or a parent path for that URL. If persist is YES
the permission will be stored as a bookmark in NSUserDefaults and further calls to this function will
load the saved permission and not ask for permission again.
@discussion If the file URL does not exist, it's parent directory will be asked for permission instead, since permission
to the directory will be required to write the file. If the parent directory doesn't exist, it will ask for
permission of whatever part of the parent path exists.
@discussion Note: If the caller has permission to access a file because it was dropped onto the application or introduced
to the application in some other way, this function will not be aware of that permission and still prompt
the user. To prevent this, use the persistPermission function to persist a permission you've been given
whenever a user introduces a file to the application. E.g. when dropping a file onto the application window
or dock or when using an NSOpenPanel.
@param fileURL A file URL, either a file or folder, that the caller needs access to.
@param persist If YES will save the permission for future calls.
@param block The block that will be given access to the file or folder.
@return YES if permission was granted or already available, NO otherwise.
*/
- (BOOL)requestAccessPermissionsForFileURL:(NSURL *)fileURL persistPermission:(BOOL)persist withBlock:(AppSandboxFileSecurityScopeBlock)block;

/*! @brief Persist a security bookmark for the given path. The calling application must already have permission.
@see persistPermissionURL:
@param path The path with permission that will be persisted.
@return Bookmark data if permission was granted or already available, nil otherwise.
*/
- (NSData *)persistPermissionPath:(NSString *)path;

/*! @brief Persist a security bookmark for the given URL. The calling application must already have permission.
@discussion Use this function to persist permission of a URL that has already been granted when a user introduced
a file to the calling application. E.g. by dropping the file onto the application window, or dock icon,
or when using an NSOpenPanel.
Note: If the calling application does not have access to this file, this call will do nothing.
@param url The URL with permission that will be persisted.
@return Bookmark data if permission was granted or already available, nil otherwise.
*/
- (NSData *)persistPermissionURL:(NSURL *)url;

@end
Loading

0 comments on commit 18ce953

Please sign in to comment.