Finalize sandbox file access persistence. Add another cover art filename.
This commit is contained in:
parent
79fcd4e20a
commit
49d91d5f5f
16 changed files with 452 additions and 16 deletions
|
@ -15,6 +15,8 @@
|
||||||
#import "PathNode.h"
|
#import "PathNode.h"
|
||||||
#import <CogAudio/Status.h>
|
#import <CogAudio/Status.h>
|
||||||
|
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
#import "MiniModeMenuTitleTransformer.h"
|
#import "MiniModeMenuTitleTransformer.h"
|
||||||
#import "DualWindow.h"
|
#import "DualWindow.h"
|
||||||
|
@ -72,13 +74,15 @@ void* kAppControllerContext = &kAppControllerContext;
|
||||||
[p setResolvesAliases:YES];
|
[p setResolvesAliases:YES];
|
||||||
|
|
||||||
[p beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger result) {
|
[p beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger result) {
|
||||||
|
[p close];
|
||||||
|
[NSApp stopModal];
|
||||||
if ( result == NSModalResponseOK ) {
|
if ( result == NSModalResponseOK ) {
|
||||||
[self->playlistLoader willInsertURLs:[p URLs] origin:URLOriginInternal];
|
[self->playlistLoader willInsertURLs:[p URLs] origin:URLOriginInternal];
|
||||||
[self->playlistLoader didInsertURLs:[self->playlistLoader addURLs:[p URLs] sort:YES] origin:URLOriginInternal];
|
[self->playlistLoader didInsertURLs:[self->playlistLoader addURLs:[p URLs] sort:YES] origin:URLOriginInternal];
|
||||||
} else {
|
|
||||||
[p close];
|
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
[NSApp runModalForWindow:[NSApp mainWindow]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)savePlaylist:(id)sender
|
- (IBAction)savePlaylist:(id)sender
|
||||||
|
@ -143,6 +147,12 @@ void* kAppControllerContext = &kAppControllerContext;
|
||||||
[self registerHotKeys];
|
[self registerHotKeys];
|
||||||
|
|
||||||
(void) [spotlightWindowController init];
|
(void) [spotlightWindowController init];
|
||||||
|
|
||||||
|
SandboxBroker * sandboxBroker = [SandboxBroker sharedSandboxBroker];
|
||||||
|
if (!sandboxBroker)
|
||||||
|
{
|
||||||
|
ALog("sandbox init failed");
|
||||||
|
}
|
||||||
|
|
||||||
[[playlistController undoManager] disableUndoRegistration];
|
[[playlistController undoManager] disableUndoRegistration];
|
||||||
NSString *basePath = [@"~/Library/Application Support/Cog/" stringByExpandingTildeInPath];
|
NSString *basePath = [@"~/Library/Application Support/Cog/" stringByExpandingTildeInPath];
|
||||||
|
@ -355,6 +365,9 @@ void* kAppControllerContext = &kAppControllerContext;
|
||||||
|
|
||||||
NSError *error;
|
NSError *error;
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:[folder stringByAppendingPathComponent:fileName] error:&error];
|
[[NSFileManager defaultManager] removeItemAtPath:[folder stringByAppendingPathComponent:fileName] error:&error];
|
||||||
|
|
||||||
|
DLog(@"Saving bookmarks for sandbox access");
|
||||||
|
[[SandboxBroker sharedSandboxBroker] shutdown];
|
||||||
|
|
||||||
DLog(@"Saving expanded nodes: %@", [expandedNodes description]);
|
DLog(@"Saving expanded nodes: %@", [expandedNodes description]);
|
||||||
|
|
||||||
|
@ -387,10 +400,11 @@ void* kAppControllerContext = &kAppControllerContext;
|
||||||
{
|
{
|
||||||
//Need to convert to urls
|
//Need to convert to urls
|
||||||
NSMutableArray *urls = [NSMutableArray array];
|
NSMutableArray *urls = [NSMutableArray array];
|
||||||
|
|
||||||
for (NSString *filename in filenames)
|
for (NSString *filename in filenames)
|
||||||
{
|
{
|
||||||
[urls addObject:[NSURL fileURLWithPath:filename]];
|
NSURL * fileUrl = [NSURL fileURLWithPath:filename];
|
||||||
|
[urls addObject:fileUrl];
|
||||||
}
|
}
|
||||||
[playlistLoader willInsertURLs:urls origin:URLOriginExternal];
|
[playlistLoader willInsertURLs:urls origin:URLOriginExternal];
|
||||||
[playlistLoader didInsertURLs:[playlistLoader addURLs:urls sort:YES] origin:URLOriginExternal];
|
[playlistLoader didInsertURLs:[playlistLoader addURLs:urls sort:YES] origin:URLOriginExternal];
|
||||||
|
|
|
@ -366,6 +366,7 @@
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8DC2EF4F0486A6940098B216 = {
|
8DC2EF4F0486A6940098B216 = {
|
||||||
DevelopmentTeam = "";
|
DevelopmentTeam = "";
|
||||||
|
LastSwiftMigration = 1240;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -431,10 +432,12 @@
|
||||||
1DEB91AE08733DA50010E9CD /* Debug */ = {
|
1DEB91AE08733DA50010E9CD /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
|
@ -448,12 +451,15 @@
|
||||||
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
||||||
PRODUCT_NAME = CogAudio;
|
PRODUCT_NAME = CogAudio;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
WARNING_LDFLAGS = "";
|
WARNING_LDFLAGS = "";
|
||||||
WRAPPER_EXTENSION = framework;
|
WRAPPER_EXTENSION = framework;
|
||||||
ZERO_LINK = YES;
|
ZERO_LINK = YES;
|
||||||
|
@ -463,9 +469,11 @@
|
||||||
1DEB91AF08733DA50010E9CD /* Release */ = {
|
1DEB91AF08733DA50010E9CD /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
|
@ -477,12 +485,14 @@
|
||||||
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
||||||
PRODUCT_NAME = CogAudio;
|
PRODUCT_NAME = CogAudio;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
WARNING_LDFLAGS = "";
|
WARNING_LDFLAGS = "";
|
||||||
WRAPPER_EXTENSION = framework;
|
WRAPPER_EXTENSION = framework;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18121" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18121"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||||
<rect key="contentRect" x="331" y="367" width="1000" height="400"/>
|
<rect key="contentRect" x="331" y="367" width="1000" height="400"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||||
<value key="minSize" type="size" width="750" height="200"/>
|
<value key="minSize" type="size" width="750" height="200"/>
|
||||||
<stackView key="contentView" distribution="equalSpacing" orientation="vertical" alignment="centerX" spacing="0.0" detachesHiddenViews="YES" id="2">
|
<stackView key="contentView" distribution="equalSpacing" orientation="vertical" alignment="centerX" spacing="0.0" detachesHiddenViews="YES" id="2">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1000" height="400"/>
|
<rect key="frame" x="0.0" y="0.0" width="1000" height="400"/>
|
||||||
|
@ -565,7 +565,7 @@
|
||||||
<window title="Cog" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Mini Window" animationBehavior="default" toolbarStyle="unified" id="2234" userLabel="Mini Window (Window)" customClass="MiniWindow">
|
<window title="Cog" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Mini Window" animationBehavior="default" toolbarStyle="unified" id="2234" userLabel="Mini Window (Window)" customClass="MiniWindow">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<rect key="contentRect" x="192" y="547" width="640" height="0.0"/>
|
<rect key="contentRect" x="192" y="547" width="640" height="0.0"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||||
<view key="contentView" hidden="YES" wantsLayer="YES" id="2235">
|
<view key="contentView" hidden="YES" wantsLayer="YES" id="2235">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="640" height="0.0"/>
|
<rect key="frame" x="0.0" y="0.0" width="640" height="0.0"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
@ -1435,7 +1435,6 @@ Gw
|
||||||
<string>status</string>
|
<string>status</string>
|
||||||
<mutableString>queued</mutableString>
|
<mutableString>queued</mutableString>
|
||||||
</declaredKeys>
|
</declaredKeys>
|
||||||
<classReference key="objectClass" className="PlaylistEntry"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="playbackController" destination="705" id="2121"/>
|
<outlet property="playbackController" destination="705" id="2121"/>
|
||||||
<outlet property="playlistLoader" destination="1319" id="1321"/>
|
<outlet property="playlistLoader" destination="1319" id="1321"/>
|
||||||
|
@ -1755,7 +1754,6 @@ Gw
|
||||||
<mutableString>title</mutableString>
|
<mutableString>title</mutableString>
|
||||||
<mutableString>artist</mutableString>
|
<mutableString>artist</mutableString>
|
||||||
</declaredKeys>
|
</declaredKeys>
|
||||||
<classReference key="objectClass" className="PlaylistEntry"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<binding destination="218" name="contentObject" keyPath="currentEntry" id="1902"/>
|
<binding destination="218" name="contentObject" keyPath="currentEntry" id="1902"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
@ -1767,7 +1765,6 @@ Gw
|
||||||
<string>artist</string>
|
<string>artist</string>
|
||||||
<string>album</string>
|
<string>album</string>
|
||||||
</declaredKeys>
|
</declaredKeys>
|
||||||
<classReference key="objectClass" className="PlaylistEntry"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<binding destination="218" name="contentArray" keyPath="arrangedObjects" id="2039"/>
|
<binding destination="218" name="contentArray" keyPath="arrangedObjects" id="2039"/>
|
||||||
<binding destination="218" name="selectionIndexes" keyPath="selectionIndexes" id="2041"/>
|
<binding destination="218" name="selectionIndexes" keyPath="selectionIndexes" id="2041"/>
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.cs.disable-library-validation</key>
|
<key>com.apple.security.cs.disable-library-validation</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>com.apple.security.files.bookmarks.app-scope</key>
|
||||||
|
<true/>
|
||||||
<key>com.apple.security.files.user-selected.read-only</key>
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.network.client</key>
|
<key>com.apple.security.network.client</key>
|
||||||
|
|
|
@ -153,6 +153,7 @@
|
||||||
83BC5AC320E4CE8D00631CD4 /* SpotlightPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 178456C00F6320B5007E8021 /* SpotlightPanel.xib */; };
|
83BC5AC320E4CE8D00631CD4 /* SpotlightPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 178456C00F6320B5007E8021 /* SpotlightPanel.xib */; };
|
||||||
83BC5AC420E4CE9000631CD4 /* Feedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B1DA0F6330D400694C57 /* Feedback.xib */; };
|
83BC5AC420E4CE9000631CD4 /* Feedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B1DA0F6330D400694C57 /* Feedback.xib */; };
|
||||||
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
|
83CAEB9125EB3EE100D6ACCC /* SandboxBroker.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CAEB9025EB3EE100D6ACCC /* SandboxBroker.m */; };
|
||||||
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; };
|
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; };
|
||||||
83E5E54C18087CA5001F3284 /* miniModeOffTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83E5E54A18087CA5001F3284 /* miniModeOffTemplate.pdf */; };
|
83E5E54C18087CA5001F3284 /* miniModeOffTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83E5E54A18087CA5001F3284 /* miniModeOffTemplate.pdf */; };
|
||||||
83E5E54D18087CA5001F3284 /* miniModeOnTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83E5E54B18087CA5001F3284 /* miniModeOnTemplate.pdf */; };
|
83E5E54D18087CA5001F3284 /* miniModeOnTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83E5E54B18087CA5001F3284 /* miniModeOnTemplate.pdf */; };
|
||||||
|
@ -899,6 +900,8 @@
|
||||||
83BC5AD820E4D0D900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SpotlightPanel.strings; sourceTree = "<group>"; };
|
83BC5AD820E4D0D900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SpotlightPanel.strings; sourceTree = "<group>"; };
|
||||||
83BC5ADA20E4D0E900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Feedback.strings; sourceTree = "<group>"; };
|
83BC5ADA20E4D0E900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Feedback.strings; sourceTree = "<group>"; };
|
||||||
83BC5ADC20E4D0EC00631CD4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Feedback.strings; sourceTree = "<group>"; };
|
83BC5ADC20E4D0EC00631CD4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Feedback.strings; sourceTree = "<group>"; };
|
||||||
|
83CAEB8D25EB3E8B00D6ACCC /* SandboxBroker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SandboxBroker.h; sourceTree = "<group>"; };
|
||||||
|
83CAEB9025EB3EE100D6ACCC /* SandboxBroker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SandboxBroker.m; sourceTree = "<group>"; };
|
||||||
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; };
|
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; };
|
||||||
83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; };
|
83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; };
|
||||||
83E5E54A18087CA5001F3284 /* miniModeOffTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = miniModeOffTemplate.pdf; path = Images/miniModeOffTemplate.pdf; sourceTree = "<group>"; };
|
83E5E54A18087CA5001F3284 /* miniModeOffTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = miniModeOffTemplate.pdf; path = Images/miniModeOffTemplate.pdf; sourceTree = "<group>"; };
|
||||||
|
@ -1078,6 +1081,8 @@
|
||||||
17FAEBAB0F662985007C8707 /* ToolTipTextField.m */,
|
17FAEBAB0F662985007C8707 /* ToolTipTextField.m */,
|
||||||
8355D6B4180612F300D05687 /* NSData+MD5.h */,
|
8355D6B4180612F300D05687 /* NSData+MD5.h */,
|
||||||
8355D6B5180612F300D05687 /* NSData+MD5.m */,
|
8355D6B5180612F300D05687 /* NSData+MD5.m */,
|
||||||
|
83CAEB8D25EB3E8B00D6ACCC /* SandboxBroker.h */,
|
||||||
|
83CAEB9025EB3EE100D6ACCC /* SandboxBroker.m */,
|
||||||
);
|
);
|
||||||
path = Utils;
|
path = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1735,7 +1740,7 @@
|
||||||
LastUpgradeCheck = 1100;
|
LastUpgradeCheck = 1100;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8D1107260486CEB800E47090 = {
|
8D1107260486CEB800E47090 = {
|
||||||
DevelopmentTeam = RXH4D9SUXM;
|
DevelopmentTeam = 4S876G9VCD;
|
||||||
LastSwiftMigration = 1220;
|
LastSwiftMigration = 1220;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
|
@ -2242,6 +2247,7 @@
|
||||||
17E0D5EA0F520F02005B6FED /* MainWindow.m in Sources */,
|
17E0D5EA0F520F02005B6FED /* MainWindow.m in Sources */,
|
||||||
836D28A818086386005B7299 /* MiniModeMenuTitleTransformer.m in Sources */,
|
836D28A818086386005B7299 /* MiniModeMenuTitleTransformer.m in Sources */,
|
||||||
17E0D5EB0F520F02005B6FED /* MiniWindow.m in Sources */,
|
17E0D5EB0F520F02005B6FED /* MiniWindow.m in Sources */,
|
||||||
|
83CAEB9125EB3EE100D6ACCC /* SandboxBroker.m in Sources */,
|
||||||
17E0D5EC0F520F02005B6FED /* PositionSlider.m in Sources */,
|
17E0D5EC0F520F02005B6FED /* PositionSlider.m in Sources */,
|
||||||
17E0D5ED0F520F02005B6FED /* TimeField.m in Sources */,
|
17E0D5ED0F520F02005B6FED /* TimeField.m in Sources */,
|
||||||
17E0D6160F520F87005B6FED /* FontSizetoLineHeightTransformer.m in Sources */,
|
17E0D6160F520F87005B6FED /* FontSizetoLineHeightTransformer.m in Sources */,
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#import "StatusImageTransformer.h"
|
#import "StatusImageTransformer.h"
|
||||||
#import "ToggleQueueTitleTransformer.h"
|
#import "ToggleQueueTitleTransformer.h"
|
||||||
|
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
|
|
||||||
#define UNDO_STACK_LIMIT 0
|
#define UNDO_STACK_LIMIT 0
|
||||||
|
@ -264,7 +266,7 @@
|
||||||
NSArray *entries = [playlistLoader insertURLs:acceptedURLs atIndex:row sort:YES];
|
NSArray *entries = [playlistLoader insertURLs:acceptedURLs atIndex:row sort:YES];
|
||||||
[self didInsertURLs:entries origin:URLOriginInternal];
|
[self didInsertURLs:entries origin:URLOriginInternal];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([self shuffle] != ShuffleOff) [self resetShuffleList];
|
if ([self shuffle] != ShuffleOff) [self resetShuffleList];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
|
@ -347,9 +349,12 @@
|
||||||
DLog(@"Removing indexes: %@", indexes);
|
DLog(@"Removing indexes: %@", indexes);
|
||||||
DLog(@"Current index: %i", currentEntry.index);
|
DLog(@"Current index: %i", currentEntry.index);
|
||||||
|
|
||||||
|
SandboxBroker * sandboxBroker = [SandboxBroker sharedSandboxBroker];
|
||||||
|
|
||||||
NSMutableIndexSet *unarrangedIndexes = [[NSMutableIndexSet alloc] init];
|
NSMutableIndexSet *unarrangedIndexes = [[NSMutableIndexSet alloc] init];
|
||||||
for (PlaylistEntry *pe in objects) {
|
for (PlaylistEntry *pe in objects) {
|
||||||
[unarrangedIndexes addIndex:[pe index]];
|
[unarrangedIndexes addIndex:[pe index]];
|
||||||
|
[sandboxBroker removeBookmarkForURL:[pe URL]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentEntry.index >= 0 && [unarrangedIndexes containsIndex:currentEntry.index]) {
|
if (currentEntry.index >= 0 && [unarrangedIndexes containsIndex:currentEntry.index]) {
|
||||||
|
@ -964,6 +969,12 @@
|
||||||
if (shouldClear) {
|
if (shouldClear) {
|
||||||
[self clear:self];
|
[self clear:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SandboxBroker * sandboxBroker = [SandboxBroker sharedSandboxBroker];
|
||||||
|
|
||||||
|
for (NSURL * url in urls) {
|
||||||
|
[sandboxBroker addBookmarkToDictionary:url];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didInsertURLs:(NSArray *)urls origin:(URLOrigin)origin {
|
- (void)didInsertURLs:(NSArray *)urls origin:(URLOrigin)origin {
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
8359FF2617FEF35C0060F3ED /* ArchiveSource-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ArchiveSource-Prefix.pch"; sourceTree = "<group>"; };
|
8359FF2617FEF35C0060F3ED /* ArchiveSource-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ArchiveSource-Prefix.pch"; sourceTree = "<group>"; };
|
||||||
8359FF6A17FEF39F0060F3ED /* File_Extractor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = File_Extractor.xcodeproj; path = ../../Frameworks/File_Extractor/File_Extractor.xcodeproj; sourceTree = "<group>"; };
|
8359FF6A17FEF39F0060F3ED /* File_Extractor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = File_Extractor.xcodeproj; path = ../../Frameworks/File_Extractor/File_Extractor.xcodeproj; sourceTree = "<group>"; };
|
||||||
8384913518081BA000E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../../Utils/Logging.h; sourceTree = "<group>"; };
|
8384913518081BA000E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../../Utils/Logging.h; sourceTree = "<group>"; };
|
||||||
|
83CAEB9225EB3F7A00D6ACCC /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../../Utils/SandboxBroker.h; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -116,6 +117,7 @@
|
||||||
8359FF2017FEF35C0060F3ED /* ArchiveSource */ = {
|
8359FF2017FEF35C0060F3ED /* ArchiveSource */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
83CAEB9225EB3F7A00D6ACCC /* SandboxBroker.h */,
|
||||||
8384913518081BA000E7332D /* Logging.h */,
|
8384913518081BA000E7332D /* Logging.h */,
|
||||||
835900A017FF079C0060F3ED /* Plugin.h */,
|
835900A017FF079C0060F3ED /* Plugin.h */,
|
||||||
8359009A17FEFDA80060F3ED /* ArchiveContainer.h */,
|
8359009A17FEFDA80060F3ED /* ArchiveContainer.h */,
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#import <File_Extractor/fex.h>
|
#import <File_Extractor/fex.h>
|
||||||
|
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
|
|
||||||
static NSString * path_pack_string(NSString * src)
|
static NSString * path_pack_string(NSString * src)
|
||||||
|
@ -49,6 +51,11 @@ static NSString * g_make_unpack_path(NSString * archive, NSString * file, NSStri
|
||||||
if (![url isFileURL]) {
|
if (![url isFileURL]) {
|
||||||
return [NSArray array];
|
return [NSArray array];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");
|
||||||
|
id sandboxBroker = [sandboxBrokerClass sharedSandboxBroker];
|
||||||
|
|
||||||
|
[sandboxBroker beginFolderAccess:url];
|
||||||
|
|
||||||
fex_t * fex;
|
fex_t * fex;
|
||||||
fex_err_t error = fex_open( &fex, [[url path] UTF8String] );
|
fex_err_t error = fex_open( &fex, [[url path] UTF8String] );
|
||||||
|
@ -67,6 +74,8 @@ static NSString * g_make_unpack_path(NSString * archive, NSString * file, NSStri
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_close( fex );
|
fex_close( fex );
|
||||||
|
|
||||||
|
[sandboxBroker endFolderAccess:url];
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
NSUInteger size;
|
NSUInteger size;
|
||||||
|
|
||||||
NSURL *_url;
|
NSURL *_url;
|
||||||
|
NSURL *fileURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#import "ArchiveSource.h"
|
#import "ArchiveSource.h"
|
||||||
|
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
|
|
||||||
static NSString * path_unpack_string(NSString * src, NSRange * remainder)
|
static NSString * path_unpack_string(NSString * src, NSRange * remainder)
|
||||||
|
@ -87,6 +89,13 @@ static BOOL g_parse_unpack_path(NSString * src, NSString ** archive, NSString **
|
||||||
if (![type isEqualToString:@"fex"])
|
if (![type isEqualToString:@"fex"])
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
|
fileURL = [NSURL fileURLWithPath:archive];
|
||||||
|
|
||||||
|
id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");
|
||||||
|
id sandboxBroker = [sandboxBrokerClass sharedSandboxBroker];
|
||||||
|
|
||||||
|
[sandboxBroker beginFolderAccess:fileURL];
|
||||||
|
|
||||||
fex_err_t error;
|
fex_err_t error;
|
||||||
|
|
||||||
error = fex_open( &fex, [archive UTF8String] );
|
error = fex_open( &fex, [archive UTF8String] );
|
||||||
|
@ -161,6 +170,13 @@ static BOOL g_parse_unpack_path(NSString * src, NSString ** archive, NSString **
|
||||||
fex_close( fex );
|
fex_close( fex );
|
||||||
fex = NULL;
|
fex = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( fileURL ) {
|
||||||
|
id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");
|
||||||
|
id sandboxBroker = [sandboxBrokerClass sharedSandboxBroker];
|
||||||
|
|
||||||
|
[sandboxBroker endFolderAccess:fileURL];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURL *)url
|
- (NSURL *)url
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#import "FileSource.h"
|
#import "FileSource.h"
|
||||||
|
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
@implementation FileSource
|
@implementation FileSource
|
||||||
|
|
||||||
|
@ -30,6 +31,11 @@
|
||||||
{
|
{
|
||||||
[self setURL:url];
|
[self setURL:url];
|
||||||
|
|
||||||
|
id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");
|
||||||
|
id sandboxBroker = [sandboxBrokerClass sharedSandboxBroker];
|
||||||
|
|
||||||
|
[sandboxBroker beginFolderAccess:url];
|
||||||
|
|
||||||
NSString * path = [url path];
|
NSString * path = [url path];
|
||||||
|
|
||||||
fex_type_t type;
|
fex_type_t type;
|
||||||
|
@ -132,6 +138,11 @@
|
||||||
fex_close( fex );
|
fex_close( fex );
|
||||||
fex = NULL;
|
fex = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");
|
||||||
|
id sandboxBroker = [sandboxBrokerClass sharedSandboxBroker];
|
||||||
|
|
||||||
|
[sandboxBroker endFolderAccess:_url];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURL *)url
|
- (NSURL *)url
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
17ADB4190B979AEB00257CA2 /* FileSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileSource.m; sourceTree = "<group>"; };
|
17ADB4190B979AEB00257CA2 /* FileSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileSource.m; sourceTree = "<group>"; };
|
||||||
32DBCF630370AF2F00C91783 /* FileSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSource_Prefix.pch; sourceTree = "<group>"; };
|
32DBCF630370AF2F00C91783 /* FileSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSource_Prefix.pch; sourceTree = "<group>"; };
|
||||||
8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = File_Extractor.xcodeproj; path = ../../Frameworks/File_Extractor/File_Extractor.xcodeproj; sourceTree = "<group>"; };
|
8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = File_Extractor.xcodeproj; path = ../../Frameworks/File_Extractor/File_Extractor.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
83CAEB9325EB402B00D6ACCC /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../Utils/SandboxBroker.h; sourceTree = "<group>"; };
|
||||||
8D5B49B6048680CD000E48DA /* FileSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FileSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
8D5B49B6048680CD000E48DA /* FileSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FileSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||||
|
@ -102,6 +103,7 @@
|
||||||
08FB77AFFE84173DC02AAC07 /* Classes */ = {
|
08FB77AFFE84173DC02AAC07 /* Classes */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
83CAEB9325EB402B00D6ACCC /* SandboxBroker.h */,
|
||||||
17ADB4080B979A8A00257CA2 /* Plugin.h */,
|
17ADB4080B979A8A00257CA2 /* Plugin.h */,
|
||||||
17ADB4180B979AEB00257CA2 /* FileSource.h */,
|
17ADB4180B979AEB00257CA2 /* FileSource.h */,
|
||||||
17ADB4190B979AEB00257CA2 /* FileSource.m */,
|
17ADB4190B979AEB00257CA2 /* FileSource.m */,
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
17F563B40C3BDBB30019975C /* TagLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17F563A60C3BDB8F0019975C /* TagLib.framework */; };
|
17F563B40C3BDBB30019975C /* TagLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17F563A60C3BDB8F0019975C /* TagLib.framework */; };
|
||||||
17F563B60C3BDBB50019975C /* TagLib.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F563A60C3BDB8F0019975C /* TagLib.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
17F563B60C3BDBB50019975C /* TagLib.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F563A60C3BDB8F0019975C /* TagLib.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
8384913A18081FFC00E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384913918081FFC00E7332D /* Logging.h */; };
|
8384913A18081FFC00E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384913918081FFC00E7332D /* Logging.h */; };
|
||||||
|
83B5CB9825EB9688000B0F8B /* SandboxBroker.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B5CB9725EB9688000B0F8B /* SandboxBroker.h */; };
|
||||||
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
|
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
17F563A00C3BDB8F0019975C /* TagLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = TagLib.xcodeproj; path = ../../Frameworks/TagLib/TagLib.xcodeproj; sourceTree = SOURCE_ROOT; };
|
17F563A00C3BDB8F0019975C /* TagLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = TagLib.xcodeproj; path = ../../Frameworks/TagLib/TagLib.xcodeproj; sourceTree = SOURCE_ROOT; };
|
||||||
32DBCF630370AF2F00C91783 /* TagLib_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagLib_Prefix.pch; sourceTree = "<group>"; };
|
32DBCF630370AF2F00C91783 /* TagLib_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagLib_Prefix.pch; sourceTree = "<group>"; };
|
||||||
8384913918081FFC00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
|
8384913918081FFC00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
|
||||||
|
83B5CB9725EB9688000B0F8B /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../Utils/SandboxBroker.h; sourceTree = "<group>"; };
|
||||||
8D5B49B6048680CD000E48DA /* TagLib.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TagLib.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
8D5B49B6048680CD000E48DA /* TagLib.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TagLib.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||||
|
@ -107,6 +109,7 @@
|
||||||
08FB77AFFE84173DC02AAC07 /* Classes */ = {
|
08FB77AFFE84173DC02AAC07 /* Classes */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
83B5CB9725EB9688000B0F8B /* SandboxBroker.h */,
|
||||||
8384913918081FFC00E7332D /* Logging.h */,
|
8384913918081FFC00E7332D /* Logging.h */,
|
||||||
07CACE890ED1AD1000C0F1E8 /* TagLibMetadataWriter.h */,
|
07CACE890ED1AD1000C0F1E8 /* TagLibMetadataWriter.h */,
|
||||||
07CACE8A0ED1AD1000C0F1E8 /* TagLibMetadataWriter.m */,
|
07CACE8A0ED1AD1000C0F1E8 /* TagLibMetadataWriter.m */,
|
||||||
|
@ -168,6 +171,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
8384913A18081FFC00E7332D /* Logging.h in Headers */,
|
8384913A18081FFC00E7332D /* Logging.h in Headers */,
|
||||||
|
83B5CB9825EB9688000B0F8B /* SandboxBroker.h in Headers */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#import <taglib/mpeg/id3v2/id3v2tag.h>
|
#import <taglib/mpeg/id3v2/id3v2tag.h>
|
||||||
#import <taglib/mpeg/id3v2/frames/attachedpictureframe.h>
|
#import <taglib/mpeg/id3v2/frames/attachedpictureframe.h>
|
||||||
|
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
@implementation TagLibMetadataReader
|
@implementation TagLibMetadataReader
|
||||||
|
|
||||||
+ (NSDictionary *)metadataForURL:(NSURL *)url
|
+ (NSDictionary *)metadataForURL:(NSURL *)url
|
||||||
|
@ -27,7 +29,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
|
// Open sandbox access, may already be granted
|
||||||
|
id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");
|
||||||
|
id sandboxBroker = [sandboxBrokerClass sharedSandboxBroker];
|
||||||
|
|
||||||
|
[sandboxBroker beginFolderAccess:url];
|
||||||
|
|
||||||
// if ( !*TagLib::ascii_encoding ) {
|
// if ( !*TagLib::ascii_encoding ) {
|
||||||
// NSStringEncoding enc = [NSString defaultCStringEncoding];
|
// NSStringEncoding enc = [NSString defaultCStringEncoding];
|
||||||
// CFStringEncoding cfenc = CFStringConvertNSStringEncodingToEncoding(enc);
|
// CFStringEncoding cfenc = CFStringConvertNSStringEncodingToEncoding(enc);
|
||||||
|
@ -164,7 +172,6 @@
|
||||||
|
|
||||||
if (nil == image) {
|
if (nil == image) {
|
||||||
// Try to load image from external file
|
// Try to load image from external file
|
||||||
|
|
||||||
NSString *path = [[url path] stringByDeletingLastPathComponent];
|
NSString *path = [[url path] stringByDeletingLastPathComponent];
|
||||||
|
|
||||||
// Gather list of candidate image files
|
// Gather list of candidate image files
|
||||||
|
@ -185,6 +192,8 @@
|
||||||
[dict setObject:image forKey:@"albumArt"];
|
[dict setObject:image forKey:@"albumArt"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[sandboxBroker endFolderAccess:url];
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +211,7 @@
|
||||||
|
|
||||||
+ (NSArray *)coverNames
|
+ (NSArray *)coverNames
|
||||||
{
|
{
|
||||||
return [NSArray arrayWithObjects:@"cover", @"folder", @"album", @"front", nil];
|
return [NSArray arrayWithObjects:@"cover", @"folder", @"album", @"albumart", @"front", nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)fileTypes
|
+ (NSArray *)fileTypes
|
||||||
|
|
28
Utils/SandboxBroker.h
Normal file
28
Utils/SandboxBroker.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
//
|
||||||
|
// SandboxBroker.h
|
||||||
|
// Cog
|
||||||
|
//
|
||||||
|
// Created by Christopher Snowhill on 2/27/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SandboxBroker_h
|
||||||
|
#define SandboxBroker_h
|
||||||
|
|
||||||
|
@interface SandboxBroker : NSObject {
|
||||||
|
NSMutableDictionary *storage;
|
||||||
|
NSError *errorState;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (id) sharedSandboxBroker;
|
||||||
|
|
||||||
|
- (id) init;
|
||||||
|
- (void) shutdown;
|
||||||
|
|
||||||
|
- (void) addBookmarkToDictionary:(NSURL *)fileUrl;
|
||||||
|
- (void) removeBookmarkForURL:(NSURL *)fileUrl;
|
||||||
|
|
||||||
|
- (void) beginFolderAccess:(NSURL *)fileUrl;
|
||||||
|
- (void) endFolderAccess:(NSURL *)fileUrl;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif /* SandboxBroker_h */
|
314
Utils/SandboxBroker.m
Normal file
314
Utils/SandboxBroker.m
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
//
|
||||||
|
// SandboxBroker.m
|
||||||
|
// CogAudio Framework
|
||||||
|
//
|
||||||
|
// Created by Christopher Snowhill on 2/27/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
#import "Logging.h"
|
||||||
|
|
||||||
|
static NSURL * urlWithoutFragment(NSURL * u) {
|
||||||
|
NSString * s = [u path];
|
||||||
|
|
||||||
|
NSString* lastComponent = [u lastPathComponent];
|
||||||
|
|
||||||
|
// Find that last component in the string from the end to make sure
|
||||||
|
// to get the last one
|
||||||
|
NSRange fragmentRange = [s rangeOfString:lastComponent
|
||||||
|
options:NSBackwardsSearch];
|
||||||
|
|
||||||
|
// Chop the fragment.
|
||||||
|
NSString* newURLString = [s substringToIndex:fragmentRange.location + fragmentRange.length];
|
||||||
|
|
||||||
|
return [NSURL fileURLWithPath:newURLString];
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface SandboxEntry : NSObject <NSSecureCoding> {
|
||||||
|
NSInteger _pathRefCount;
|
||||||
|
NSInteger _secRefCount;
|
||||||
|
NSData *_bookmark;
|
||||||
|
NSURL *_secureUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
@property(class, readonly) BOOL supportsSecureCoding;
|
||||||
|
|
||||||
|
@property(readonly) NSData * bookmark;
|
||||||
|
|
||||||
|
@property NSURL * secureUrl;
|
||||||
|
|
||||||
|
@property NSInteger pathRefCount;
|
||||||
|
@property NSInteger secRefCount;
|
||||||
|
|
||||||
|
- (id) initWithCoder:(NSCoder *)coder;
|
||||||
|
- (void) encodeWithCoder:(NSCoder *)coder;
|
||||||
|
|
||||||
|
- (id) initWithBookmark:(NSData *)bookmark;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation SandboxEntry
|
||||||
|
- (id) initWithCoder:(NSCoder *)coder {
|
||||||
|
SandboxEntry * obj = [super init];
|
||||||
|
if (obj) {
|
||||||
|
obj->_pathRefCount = [coder decodeIntegerForKey:@"refCount"];
|
||||||
|
obj->_bookmark = [coder decodeObjectForKey:@"bookmark"];
|
||||||
|
obj->_secRefCount = 0;
|
||||||
|
obj->_secureUrl = nil;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) encodeWithCoder:(NSCoder *)coder {
|
||||||
|
[coder encodeInteger:_pathRefCount forKey:@"refCount"];
|
||||||
|
[coder encodeObject:_bookmark forKey:@"bookmark"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithBookmark:(NSData *)bookmark {
|
||||||
|
SandboxEntry * obj = [super init];
|
||||||
|
if (obj) {
|
||||||
|
obj->_pathRefCount = 1;
|
||||||
|
obj->_secRefCount = 0;
|
||||||
|
obj->_secureUrl = nil;
|
||||||
|
obj->_bookmark = bookmark;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (BOOL) supportsSecureCoding {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger) pathRefCount {
|
||||||
|
return _pathRefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setPathRefCount:(NSInteger)pathRefCount {
|
||||||
|
_pathRefCount = pathRefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger) secRefCount {
|
||||||
|
return _secRefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setSecRefCount:(NSInteger)secRefCount {
|
||||||
|
_secRefCount = secRefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSURL *) secureUrl {
|
||||||
|
return _secureUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setSecureUrl:(NSURL *)url {
|
||||||
|
_secureUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSData *) bookmark {
|
||||||
|
return _bookmark;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation SandboxBroker
|
||||||
|
|
||||||
|
+ (id) sharedSandboxBroker {
|
||||||
|
static SandboxBroker *theSharedSandboxBroker = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
theSharedSandboxBroker = [[self alloc] init];
|
||||||
|
});
|
||||||
|
return theSharedSandboxBroker;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) init {
|
||||||
|
id _self = [super init];
|
||||||
|
if (_self) {
|
||||||
|
NSData *archiveData = [[NSUserDefaults standardUserDefaults] valueForKey:@"fileBookmarks"];
|
||||||
|
|
||||||
|
if (archiveData) {
|
||||||
|
NSError * err = nil;
|
||||||
|
|
||||||
|
// It's an NSDictionary, containing SandboxEntry objects, referenced by NSURL keys
|
||||||
|
NSSet * classes = [NSSet setWithObjects:[NSDictionary class], [SandboxEntry class], [NSURL class], nil];
|
||||||
|
|
||||||
|
NSDictionary * _storage = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:archiveData error:&err];
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ALog("bookmark archive error - %@", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_storage) {
|
||||||
|
storage = [_storage mutableCopy];
|
||||||
|
return _self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storage = [[NSMutableDictionary alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
return _self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) shutdown {
|
||||||
|
NSError * err = nil;
|
||||||
|
|
||||||
|
NSArray * allKeys = [[storage allKeys] copy];
|
||||||
|
|
||||||
|
for (NSURL * folderUrl in allKeys) {
|
||||||
|
SandboxEntry * obj = [storage objectForKey:folderUrl];
|
||||||
|
if ([obj secureUrl]) {
|
||||||
|
[[obj secureUrl] stopAccessingSecurityScopedResource];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSData * archiveData = [NSKeyedArchiver archivedDataWithRootObject:storage requiringSecureCoding:YES error:&err];
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ALog("error archiving bookmarks - %@", err);
|
||||||
|
} else {
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:archiveData forKey:@"fileBookmarks"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) addBookmarkToDictionary:(NSURL *)fileUrl {
|
||||||
|
__block NSURL * folderUrl = [urlWithoutFragment(fileUrl) URLByDeletingLastPathComponent];
|
||||||
|
|
||||||
|
@synchronized(self) {
|
||||||
|
__block SandboxEntry * obj = [storage objectForKey:folderUrl];
|
||||||
|
if (!obj) {
|
||||||
|
NSOpenPanel *p;
|
||||||
|
|
||||||
|
p = [NSOpenPanel openPanel];
|
||||||
|
|
||||||
|
[p setCanChooseFiles:NO];
|
||||||
|
[p setCanChooseDirectories:YES];
|
||||||
|
[p setAllowsMultipleSelection:YES];
|
||||||
|
[p setResolvesAliases:YES];
|
||||||
|
|
||||||
|
[p setDirectoryURL:folderUrl];
|
||||||
|
[p setTitle:@"Press OK to grant access to this folder"];
|
||||||
|
|
||||||
|
errorState = nil;
|
||||||
|
|
||||||
|
[p beginSheetModalForWindow:[NSApp mainWindow] completionHandler:^(NSInteger result) {
|
||||||
|
if ( result == NSModalResponseOK ) {
|
||||||
|
folderUrl = [[p URLs] objectAtIndex:0];
|
||||||
|
|
||||||
|
NSError * err = nil;
|
||||||
|
NSData * bookmark = [folderUrl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&err];
|
||||||
|
if (!bookmark && err) {
|
||||||
|
ALog("failed to bookmark path %@ with error %@", folderUrl, err);
|
||||||
|
self->errorState = err;
|
||||||
|
[NSApp stopModal];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = [[SandboxEntry alloc] initWithBookmark:bookmark];
|
||||||
|
[self->storage setObject:obj forKey:folderUrl];
|
||||||
|
[NSApp stopModal];
|
||||||
|
} else {
|
||||||
|
ALog("user rejected file access prompt");
|
||||||
|
self->errorState = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadNoPermissionError userInfo:nil];
|
||||||
|
[NSApp stopModal];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
[NSApp runModalForWindow:[NSApp mainWindow]];
|
||||||
|
} else {
|
||||||
|
[obj setPathRefCount:[obj pathRefCount] + 1];
|
||||||
|
[storage setObject:obj forKey:folderUrl];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) removeBookmarkForURL:(NSURL *)fileUrl {
|
||||||
|
NSURL * folderUrl = [urlWithoutFragment(fileUrl) URLByDeletingLastPathComponent];
|
||||||
|
|
||||||
|
@synchronized (self) {
|
||||||
|
SandboxEntry * obj = [storage objectForKey:folderUrl];
|
||||||
|
if (obj) {
|
||||||
|
NSInteger refCount = [obj pathRefCount];
|
||||||
|
if (refCount > 1) {
|
||||||
|
[obj setPathRefCount:refCount - 1];
|
||||||
|
[storage setObject:obj forKey:folderUrl];
|
||||||
|
} else {
|
||||||
|
if ([obj secureUrl]) {
|
||||||
|
[[obj secureUrl] stopAccessingSecurityScopedResource];
|
||||||
|
}
|
||||||
|
[storage removeObjectForKey:folderUrl];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) beginFolderAccess:(NSURL *)fileUrl {
|
||||||
|
NSURL * folderUrl = [urlWithoutFragment(fileUrl) URLByDeletingLastPathComponent];
|
||||||
|
|
||||||
|
@synchronized (self) {
|
||||||
|
SandboxEntry * obj = [storage objectForKey:folderUrl];
|
||||||
|
if (!obj) {
|
||||||
|
errorState = nil;
|
||||||
|
|
||||||
|
[self addBookmarkToDictionary:fileUrl];
|
||||||
|
|
||||||
|
obj = [storage objectForKey:folderUrl];
|
||||||
|
|
||||||
|
if (errorState) {
|
||||||
|
ALog(@"error granting permission to folder - %@", errorState);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj) {
|
||||||
|
NSInteger refCount = [obj secRefCount];
|
||||||
|
if (refCount > 0) {
|
||||||
|
[obj setSecRefCount:refCount + 1];
|
||||||
|
[storage setObject:obj forKey:folderUrl];
|
||||||
|
} else {
|
||||||
|
NSError * err = nil;
|
||||||
|
BOOL isStale = NO;
|
||||||
|
NSURL * secureUrl = [NSURL URLByResolvingBookmarkData:[obj bookmark] options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:&isStale error:&err];
|
||||||
|
if (!secureUrl && err)
|
||||||
|
{
|
||||||
|
ALog("failed to access bookmark for %@ with error %@", folderUrl, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[secureUrl startAccessingSecurityScopedResource];
|
||||||
|
|
||||||
|
[obj setSecureUrl:secureUrl];
|
||||||
|
[obj setSecRefCount:1];
|
||||||
|
[storage setObject:obj forKey:folderUrl];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) endFolderAccess:(NSURL *)fileUrl {
|
||||||
|
NSURL * folderUrl = [urlWithoutFragment(fileUrl) URLByDeletingLastPathComponent];
|
||||||
|
|
||||||
|
@synchronized (self) {
|
||||||
|
SandboxEntry * obj = [storage objectForKey:folderUrl];
|
||||||
|
if (obj) {
|
||||||
|
NSInteger refCount = [obj secRefCount];
|
||||||
|
if (refCount > 1) {
|
||||||
|
[obj setSecRefCount:refCount - 1];
|
||||||
|
[storage setObject:obj forKey:folderUrl];
|
||||||
|
} else {
|
||||||
|
if ([obj secureUrl]) {
|
||||||
|
[[obj secureUrl] stopAccessingSecurityScopedResource];
|
||||||
|
[obj setSecureUrl:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
[obj setSecRefCount:0];
|
||||||
|
|
||||||
|
[storage setObject:obj forKey:folderUrl];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in a new issue