[Path Suggester] Automatically pop where required
The Path Suggester will now automatically open when new files are added to the playlist and a given path is not in the sandbox settings. It will also pop for both the File Tree and MIDI SoundFont path configuration settings being changed. Signed-off-by: Christopher Snowhill <kode54@gmail.com>lastfm
parent
b6621da410
commit
ba33218ddf
|
@ -7,6 +7,7 @@
|
||||||
@class PlaylistController;
|
@class PlaylistController;
|
||||||
@class PlaylistView;
|
@class PlaylistView;
|
||||||
@class PlaylistLoader;
|
@class PlaylistLoader;
|
||||||
|
@class PreferencesController;
|
||||||
|
|
||||||
@interface AppController : NSObject {
|
@interface AppController : NSObject {
|
||||||
IBOutlet NSObjectController *currentEntryController;
|
IBOutlet NSObjectController *currentEntryController;
|
||||||
|
@ -47,6 +48,8 @@
|
||||||
|
|
||||||
IBOutlet FileTreeViewController *fileTreeViewController;
|
IBOutlet FileTreeViewController *fileTreeViewController;
|
||||||
|
|
||||||
|
IBOutlet PreferencesController *preferencesController;
|
||||||
|
|
||||||
NSOperationQueue *queue; // Since we are the app delegate, we take care of the op queue
|
NSOperationQueue *queue; // Since we are the app delegate, we take care of the op queue
|
||||||
|
|
||||||
NSMutableSet *expandedNodes;
|
NSMutableSet *expandedNodes;
|
||||||
|
@ -94,6 +97,9 @@
|
||||||
- (IBAction)toggleMiniMode:(id)sender;
|
- (IBAction)toggleMiniMode:(id)sender;
|
||||||
- (IBAction)toggleToolbarStyle:(id)sender;
|
- (IBAction)toggleToolbarStyle:(id)sender;
|
||||||
|
|
||||||
|
- (void)showPathSuggester;
|
||||||
|
+ (void)globalShowPathSuggester;
|
||||||
|
|
||||||
@property NSWindow *mainWindow;
|
@property NSWindow *mainWindow;
|
||||||
@property NSWindow *miniWindow;
|
@property NSWindow *miniWindow;
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,16 @@
|
||||||
#import "Shortcuts.h"
|
#import "Shortcuts.h"
|
||||||
#import <MASShortcut/Shortcut.h>
|
#import <MASShortcut/Shortcut.h>
|
||||||
|
|
||||||
|
#import "PreferencesController.h"
|
||||||
|
|
||||||
@import Firebase;
|
@import Firebase;
|
||||||
|
|
||||||
void *kAppControllerContext = &kAppControllerContext;
|
void *kAppControllerContext = &kAppControllerContext;
|
||||||
|
|
||||||
BOOL kAppControllerShuttingDown = NO;
|
BOOL kAppControllerShuttingDown = NO;
|
||||||
|
|
||||||
|
static AppController *kAppController = nil;
|
||||||
|
|
||||||
@implementation AppController {
|
@implementation AppController {
|
||||||
BOOL _isFullToolbarStyle;
|
BOOL _isFullToolbarStyle;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +74,8 @@ BOOL kAppControllerShuttingDown = NO;
|
||||||
[self initDefaults];
|
[self initDefaults];
|
||||||
|
|
||||||
queue = [[NSOperationQueue alloc] init];
|
queue = [[NSOperationQueue alloc] init];
|
||||||
|
|
||||||
|
kAppController = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -705,4 +711,12 @@ BOOL kAppControllerShuttingDown = NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)showPathSuggester {
|
||||||
|
[preferencesController showPathSuggester:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)globalShowPathSuggester {
|
||||||
|
[kAppController showPathSuggester];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -25,17 +25,17 @@
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<splitView dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2123">
|
<splitView dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2123">
|
||||||
<rect key="frame" x="0.0" y="353" width="1015" height="47"/>
|
<rect key="frame" x="0.0" y="371" width="1030" height="29"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="0.0" verticalLineScroll="24" verticalPageScroll="0.0" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="206" userLabel="Scroll View - Playlist View">
|
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="0.0" verticalLineScroll="24" verticalPageScroll="0.0" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="206" userLabel="Scroll View - Playlist View">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1015" height="46"/>
|
<rect key="frame" x="0.0" y="0.0" width="1030" height="29"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="KWC-Ti-8KY">
|
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="KWC-Ti-8KY">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1015" height="46"/>
|
<rect key="frame" x="0.0" y="0.0" width="1030" height="29"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" autosaveName="Playlist" rowHeight="18" headerView="1517" viewBased="YES" id="207" customClass="PlaylistView">
|
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" autosaveName="Playlist" rowHeight="18" headerView="1517" viewBased="YES" id="207" customClass="PlaylistView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1015" height="29"/>
|
<rect key="frame" x="0.0" y="0.0" width="1030" height="12"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<size key="intercellSpacing" width="3" height="6"/>
|
<size key="intercellSpacing" width="3" height="6"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -229,7 +229,7 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="gpC-Oe-Rog">
|
<tableCellView id="gpC-Oe-Rog">
|
||||||
<rect key="frame" x="234.5" y="3" width="149.5" height="18"/>
|
<rect key="frame" x="235" y="3" width="149" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="1WK-qN-Mgj">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="1WK-qN-Mgj">
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="hhB-nv-e78">
|
<tableCellView id="hhB-nv-e78">
|
||||||
<rect key="frame" x="540.5" y="3" width="95.5" height="18"/>
|
<rect key="frame" x="541" y="3" width="95" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="tHy-sM-HDB">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="tHy-sM-HDB">
|
||||||
|
@ -401,7 +401,7 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="rRl-p9-Awr">
|
<tableCellView id="rRl-p9-Awr">
|
||||||
<rect key="frame" x="735.5" y="3" width="144" height="18"/>
|
<rect key="frame" x="736" y="3" width="144" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yW6-2w-6mN">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yW6-2w-6mN">
|
||||||
|
@ -441,7 +441,7 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="hgh-VE-5kl">
|
<tableCellView id="hgh-VE-5kl">
|
||||||
<rect key="frame" x="882.5" y="3" width="38.5" height="18"/>
|
<rect key="frame" x="883" y="3" width="38" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yEY-MI-d3o">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yEY-MI-d3o">
|
||||||
|
@ -628,7 +628,7 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<tableHeaderView key="headerView" wantsLayer="YES" id="1517">
|
<tableHeaderView key="headerView" wantsLayer="YES" id="1517">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1015" height="17"/>
|
<rect key="frame" x="0.0" y="0.0" width="1030" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</tableHeaderView>
|
</tableHeaderView>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
|
@ -641,7 +641,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</splitView>
|
</splitView>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="778">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="778">
|
||||||
<rect key="frame" x="377" y="4" width="261" height="14"/>
|
<rect key="frame" x="385" y="4" width="261" height="14"/>
|
||||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="center" title="Total Duration: 00 hours 00 minutes 00 seconds" bezelStyle="round" id="1473">
|
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="center" title="Total Duration: 00 hours 00 minutes 00 seconds" bezelStyle="round" id="1473">
|
||||||
<font key="font" metaFont="controlContent" size="11"/>
|
<font key="font" metaFont="controlContent" size="11"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -1970,6 +1970,7 @@ Gw
|
||||||
</declaredKeys>
|
</declaredKeys>
|
||||||
<classReference key="objectClass" className="PlaylistEntry"/>
|
<classReference key="objectClass" className="PlaylistEntry"/>
|
||||||
<connections>
|
<connections>
|
||||||
|
<outlet property="appController" destination="226" id="lmS-HT-dqn"/>
|
||||||
<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"/>
|
||||||
<outlet property="spotlightWindowController" destination="1675" id="1709"/>
|
<outlet property="spotlightWindowController" destination="1675" id="1709"/>
|
||||||
|
@ -2004,6 +2005,7 @@ Gw
|
||||||
<outlet property="playlistController" destination="218" id="236"/>
|
<outlet property="playlistController" destination="218" id="236"/>
|
||||||
<outlet property="playlistLoader" destination="1319" id="1322"/>
|
<outlet property="playlistLoader" destination="1319" id="1322"/>
|
||||||
<outlet property="playlistView" destination="207" id="1257"/>
|
<outlet property="playlistView" destination="207" id="1257"/>
|
||||||
|
<outlet property="preferencesController" destination="1217" id="cps-Ql-RlL"/>
|
||||||
<outlet property="randomizeButton" destination="2467" id="swo-wn-Yr8"/>
|
<outlet property="randomizeButton" destination="2467" id="swo-wn-Yr8"/>
|
||||||
<outlet property="repeatButton" destination="1640" id="twI-AO-RJG"/>
|
<outlet property="repeatButton" destination="1640" id="twI-AO-RJG"/>
|
||||||
<outlet property="showAlbumColumn" destination="1340" id="1350"/>
|
<outlet property="showAlbumColumn" destination="1340" id="1350"/>
|
||||||
|
|
|
@ -1025,6 +1025,7 @@
|
||||||
8399D4E11805A55000B503B1 /* XmlContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XmlContainer.h; sourceTree = "<group>"; };
|
8399D4E11805A55000B503B1 /* XmlContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XmlContainer.h; sourceTree = "<group>"; };
|
||||||
839DA7CB274A2D4C001B18E5 /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Merge.h"; sourceTree = "<group>"; };
|
839DA7CB274A2D4C001B18E5 /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Merge.h"; sourceTree = "<group>"; };
|
||||||
839DA7CE274A2D4C001B18E5 /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Merge.m"; sourceTree = "<group>"; };
|
839DA7CE274A2D4C001B18E5 /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Merge.m"; sourceTree = "<group>"; };
|
||||||
|
839E3B53286595D700880EA2 /* GeneralPane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GeneralPane.h; path = Preferences/Preferences/GeneralPane.h; sourceTree = "<group>"; };
|
||||||
83A3B72F283AE6AA00CC6593 /* ColorToValueTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ColorToValueTransformer.m; path = Preferences/Preferences/ColorToValueTransformer.m; sourceTree = "<group>"; };
|
83A3B72F283AE6AA00CC6593 /* ColorToValueTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ColorToValueTransformer.m; path = Preferences/Preferences/ColorToValueTransformer.m; sourceTree = "<group>"; };
|
||||||
83A3B733283AE6AA00CC6593 /* ColorToValueTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ColorToValueTransformer.h; path = Preferences/Preferences/ColorToValueTransformer.h; sourceTree = "<group>"; };
|
83A3B733283AE6AA00CC6593 /* ColorToValueTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ColorToValueTransformer.h; path = Preferences/Preferences/ColorToValueTransformer.h; sourceTree = "<group>"; };
|
||||||
83AA7D00279EBC8200087AA4 /* libavcodec.59.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavcodec.59.dylib; path = ThirdParty/ffmpeg/lib/libavcodec.59.dylib; sourceTree = "<group>"; };
|
83AA7D00279EBC8200087AA4 /* libavcodec.59.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavcodec.59.dylib; path = ThirdParty/ffmpeg/lib/libavcodec.59.dylib; sourceTree = "<group>"; };
|
||||||
|
@ -1883,6 +1884,7 @@
|
||||||
8E07AAEA0AAC90DC00A4B32F /* Preferences */ = {
|
8E07AAEA0AAC90DC00A4B32F /* Preferences */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
839E3B53286595D700880EA2 /* GeneralPane.h */,
|
||||||
ED69CF0925BE74BB0090B90D /* Shortcuts.h */,
|
ED69CF0925BE74BB0090B90D /* Shortcuts.h */,
|
||||||
17D1B2610F633D2C00694C57 /* PreferencePanePlugin.h */,
|
17D1B2610F633D2C00694C57 /* PreferencePanePlugin.h */,
|
||||||
17D1B25B0F633A4F00694C57 /* PreferencePluginController.h */,
|
17D1B25B0F633A4F00694C57 /* PreferencePluginController.h */,
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#import "SandboxBroker.h"
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
|
#import "AppController.h"
|
||||||
|
|
||||||
static void *kFileTreeDataSourceContext = &kFileTreeDataSourceContext;
|
static void *kFileTreeDataSourceContext = &kFileTreeDataSourceContext;
|
||||||
|
|
||||||
static NSURL *defaultMusicDirectory(void) {
|
static NSURL *defaultMusicDirectory(void) {
|
||||||
|
@ -75,6 +77,10 @@ static NSURL *defaultMusicDirectory(void) {
|
||||||
if(url != nil) {
|
if(url != nil) {
|
||||||
[[[NSUserDefaultsController sharedUserDefaultsController] defaults] setObject:[url absoluteString]
|
[[[NSUserDefaultsController sharedUserDefaultsController] defaults] setObject:[url absoluteString]
|
||||||
forKey:@"fileTreeRootURL"];
|
forKey:@"fileTreeRootURL"];
|
||||||
|
|
||||||
|
if(![[SandboxBroker sharedSandboxBroker] areAllPathsSafe:@[url]]) {
|
||||||
|
[AppController globalShowPathSuggester];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
@class PlaylistEntry;
|
@class PlaylistEntry;
|
||||||
@class SpotlightWindowController;
|
@class SpotlightWindowController;
|
||||||
@class PlaybackController;
|
@class PlaybackController;
|
||||||
|
@class AppController;
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, RepeatMode) {
|
typedef NS_ENUM(NSInteger, RepeatMode) {
|
||||||
RepeatModeNoRepeat = 0,
|
RepeatModeNoRepeat = 0,
|
||||||
|
@ -43,6 +44,7 @@ typedef NS_ENUM(NSInteger, URLOrigin) {
|
||||||
IBOutlet PlaylistLoader *playlistLoader;
|
IBOutlet PlaylistLoader *playlistLoader;
|
||||||
IBOutlet SpotlightWindowController *spotlightWindowController;
|
IBOutlet SpotlightWindowController *spotlightWindowController;
|
||||||
IBOutlet PlaybackController *playbackController;
|
IBOutlet PlaybackController *playbackController;
|
||||||
|
IBOutlet AppController *appController;
|
||||||
|
|
||||||
NSValueTransformer *statusImageTransformer;
|
NSValueTransformer *statusImageTransformer;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
|
|
||||||
#import "Cog-Swift.h"
|
#import "Cog-Swift.h"
|
||||||
|
|
||||||
|
#import "AppController.h"
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
#define UNDO_STACK_LIMIT 0
|
#define UNDO_STACK_LIMIT 0
|
||||||
|
|
||||||
extern BOOL kAppControllerShuttingDown;
|
extern BOOL kAppControllerShuttingDown;
|
||||||
|
@ -1677,6 +1680,11 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
[self firstSawTrack:pe];
|
[self firstSawTrack:pe];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSArray *nsurls = [urls valueForKey:@"url"];
|
||||||
|
if(![[SandboxBroker sharedSandboxBroker] areAllPathsSafe:nsurls]) {
|
||||||
|
[appController showPathSuggester];
|
||||||
|
}
|
||||||
|
|
||||||
CGEventRef event = CGEventCreate(NULL);
|
CGEventRef event = CGEventCreate(NULL);
|
||||||
CGEventFlags mods = CGEventGetFlags(event);
|
CGEventFlags mods = CGEventGetFlags(event);
|
||||||
CFRelease(event);
|
CFRelease(event);
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
@property(readonly, copy) NSString *title;
|
@property(readonly, copy) NSString *title;
|
||||||
@property(readonly) NSImage *icon;
|
@property(readonly) NSImage *icon;
|
||||||
|
|
||||||
|
@optional
|
||||||
|
- (IBAction)showPathSuggester:(id)sender;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@protocol PreferencePanePlugin <NSObject>
|
@protocol PreferencePanePlugin <NSObject>
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
#import "MIDIPane.h"
|
#import "MIDIPane.h"
|
||||||
|
|
||||||
|
#import "SandboxBroker.h"
|
||||||
|
|
||||||
|
#import "AppController.h"
|
||||||
|
|
||||||
@implementation MIDIPane
|
@implementation MIDIPane
|
||||||
|
|
||||||
- (NSString *)title {
|
- (NSString *)title {
|
||||||
|
@ -34,6 +38,13 @@
|
||||||
NSInteger result = [panel runModal];
|
NSInteger result = [panel runModal];
|
||||||
if(result == NSModalResponseOK) {
|
if(result == NSModalResponseOK) {
|
||||||
[[NSUserDefaults standardUserDefaults] setValue:[[panel URL] path] forKey:@"soundFontPath"];
|
[[NSUserDefaults standardUserDefaults] setValue:[[panel URL] path] forKey:@"soundFontPath"];
|
||||||
|
|
||||||
|
id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");
|
||||||
|
NSURL *pathUrl = [panel URL];
|
||||||
|
if(![[sandboxBrokerClass sharedSandboxBroker] areAllPathsSafe:@[pathUrl]]) {
|
||||||
|
id appControllerClass = NSClassFromString(@"AppController");
|
||||||
|
[appControllerClass globalShowPathSuggester];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,8 +95,21 @@ static NSURL *defaultMoviesDirectory(void) {
|
||||||
NSMutableArray *items = [[NSMutableArray alloc] init];
|
NSMutableArray *items = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray *itemPaths = [[NSMutableArray alloc] init];
|
NSMutableArray *itemPaths = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
for(PlaylistEntry *pe in results) {
|
NSMutableArray *array = [[results valueForKey:@"url"] mutableCopy];
|
||||||
NSURL *url = [sandboxBrokerClass urlWithoutFragment:pe.url];
|
|
||||||
|
// Add other system paths to this setting
|
||||||
|
NSString *fileTreePath = [[NSUserDefaults standardUserDefaults] stringForKey:@"fileTreeRootURL"];
|
||||||
|
if(fileTreePath && [fileTreePath length]) {
|
||||||
|
[array addObject:[NSURL URLWithString:fileTreePath]];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *soundFontPath = [[NSUserDefaults standardUserDefaults] stringForKey:@"soundFontPath"];
|
||||||
|
if(soundFontPath && [soundFontPath length]) {
|
||||||
|
[array addObject:[NSURL fileURLWithPath:soundFontPath]];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(NSURL *fileUrl in array) {
|
||||||
|
NSURL *url = [sandboxBrokerClass urlWithoutFragment:fileUrl];
|
||||||
if([sandboxBrokerClass isPath:url aSubdirectoryOf:defaultMusic] ||
|
if([sandboxBrokerClass isPath:url aSubdirectoryOf:defaultMusic] ||
|
||||||
[sandboxBrokerClass isPath:url
|
[sandboxBrokerClass isPath:url
|
||||||
aSubdirectoryOf:defaultDownloads] ||
|
aSubdirectoryOf:defaultDownloads] ||
|
||||||
|
|
|
@ -116,6 +116,7 @@
|
||||||
837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIDIPluginBehaviorArrayController.m; sourceTree = "<group>"; };
|
837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIDIPluginBehaviorArrayController.m; sourceTree = "<group>"; };
|
||||||
8384913618081ECB00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
|
8384913618081ECB00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
|
||||||
8384917518084D9F00E7332D /* appearance.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = appearance.png; path = Icons/appearance.png; sourceTree = "<group>"; };
|
8384917518084D9F00E7332D /* appearance.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = appearance.png; path = Icons/appearance.png; sourceTree = "<group>"; };
|
||||||
|
839E3B5728659B2700880EA2 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppController.h; path = ../../Application/AppController.h; sourceTree = "<group>"; };
|
||||||
83A3B72A283AE04800CC6593 /* ColorToValueTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ColorToValueTransformer.h; sourceTree = "<group>"; };
|
83A3B72A283AE04800CC6593 /* ColorToValueTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ColorToValueTransformer.h; sourceTree = "<group>"; };
|
||||||
83A3B72B283AE04800CC6593 /* ColorToValueTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ColorToValueTransformer.m; sourceTree = "<group>"; };
|
83A3B72B283AE04800CC6593 /* ColorToValueTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ColorToValueTransformer.m; sourceTree = "<group>"; };
|
||||||
83AC57372861A54D009D6F50 /* PathSuggester.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PathSuggester.h; sourceTree = "<group>"; };
|
83AC57372861A54D009D6F50 /* PathSuggester.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PathSuggester.h; sourceTree = "<group>"; };
|
||||||
|
@ -202,6 +203,7 @@
|
||||||
08FB77AFFE84173DC02AAC07 /* Classes */ = {
|
08FB77AFFE84173DC02AAC07 /* Classes */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
839E3B5728659B2700880EA2 /* AppController.h */,
|
||||||
83AC573E2861B77E009D6F50 /* SandboxBroker.h */,
|
83AC573E2861B77E009D6F50 /* SandboxBroker.h */,
|
||||||
8307D30828604ECF000FF8EB /* PlaylistController.h */,
|
8307D30828604ECF000FF8EB /* PlaylistController.h */,
|
||||||
83F27E711810E41A00CEF538 /* Transformers */,
|
83F27E711810E41A00CEF538 /* Transformers */,
|
||||||
|
@ -287,7 +289,6 @@
|
||||||
32C88E010371C26100C91783 /* Other Sources */ = {
|
32C88E010371C26100C91783 /* Other Sources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
8363BABF284E450E00E5C9DD /* pffft.h */,
|
|
||||||
ED69CF0B25BE75330090B90D /* Shortcuts.h */,
|
ED69CF0B25BE75330090B90D /* Shortcuts.h */,
|
||||||
32DBCF630370AF2F00C91783 /* Preferences_Prefix.pch */,
|
32DBCF630370AF2F00C91783 /* Preferences_Prefix.pch */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,5 +14,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)showPreferences:(id)sender;
|
- (IBAction)showPreferences:(id)sender;
|
||||||
|
- (IBAction)showPathSuggester:(id)sender;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
@implementation PreferencesController
|
@implementation PreferencesController
|
||||||
|
|
||||||
- (IBAction)showPreferences:(id)sender {
|
- (void)initWindow {
|
||||||
if(nil == window) {
|
if(nil == window) {
|
||||||
// Determine path to the sample preference panes
|
// Determine path to the sample preference panes
|
||||||
NSString *pluginPath = [[NSBundle mainBundle] pathForResource:@"Preferences" ofType:@"preferencePane"];
|
NSString *pluginPath = [[NSBundle mainBundle] pathForResource:@"Preferences" ofType:@"preferencePane"];
|
||||||
|
@ -22,9 +22,20 @@
|
||||||
|
|
||||||
window = [[PreferencesWindow alloc] initWithPreferencePanes:[pluginController preferencePanes]];
|
window = [[PreferencesWindow alloc] initWithPreferencePanes:[pluginController preferencePanes]];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)showPreferences:(id)sender {
|
||||||
|
[self initWindow];
|
||||||
|
|
||||||
// Show the preferences window.
|
// Show the preferences window.
|
||||||
[window show];
|
[window show];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)showPathSuggester:(id)sender {
|
||||||
|
[self initWindow];
|
||||||
|
|
||||||
|
// Show the path suggester
|
||||||
|
[window showPathSuggester];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -22,5 +22,6 @@
|
||||||
defer:(BOOL)flag NS_UNAVAILABLE;
|
defer:(BOOL)flag NS_UNAVAILABLE;
|
||||||
|
|
||||||
- (void)show;
|
- (void)show;
|
||||||
|
- (void)showPathSuggester;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -151,6 +151,19 @@
|
||||||
[self makeKeyAndOrderFront:self];
|
[self makeKeyAndOrderFront:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)showPathSuggester {
|
||||||
|
NSString *name = NSLocalizedPrefString(@"General");
|
||||||
|
|
||||||
|
[self loadPaneNamed:name display:NO];
|
||||||
|
|
||||||
|
[self makeKeyAndOrderFront:self];
|
||||||
|
|
||||||
|
id<PreferencePane> pane = preferencePanes[name];
|
||||||
|
if(pane && [pane respondsToSelector:@selector(showPathSuggester:)]) {
|
||||||
|
[pane showPathSuggester:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Close on Esc pressed.
|
// Close on Esc pressed.
|
||||||
- (void)cancelOperation:(id)sender {
|
- (void)cancelOperation:(id)sender {
|
||||||
[self close];
|
[self close];
|
||||||
|
|
|
@ -24,6 +24,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
- (const void *)beginFolderAccess:(NSURL *)fileUrl;
|
- (const void *)beginFolderAccess:(NSURL *)fileUrl;
|
||||||
- (void)endFolderAccess:(const void *)handle;
|
- (void)endFolderAccess:(const void *)handle;
|
||||||
|
|
||||||
|
- (BOOL)areAllPathsSafe:(NSArray *)urls;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -151,13 +151,6 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
}
|
}
|
||||||
|
|
||||||
- (SandboxEntry *)recursivePathTest:(NSURL *)url {
|
- (SandboxEntry *)recursivePathTest:(NSURL *)url {
|
||||||
for(SandboxEntry *entry in storage) {
|
|
||||||
if(entry.path && [SandboxBroker isPath:url aSubdirectoryOf:[NSURL fileURLWithPath:entry.path]]) {
|
|
||||||
entry.refCount += 1;
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__block SandboxEntry *ret = nil;
|
__block SandboxEntry *ret = nil;
|
||||||
|
|
||||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||||
|
@ -194,10 +187,6 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
|
|
||||||
ret.secureUrl = secureUrl;
|
ret.secureUrl = secureUrl;
|
||||||
|
|
||||||
[storage addObject:ret];
|
|
||||||
|
|
||||||
[secureUrl startAccessingSecurityScopedResource];
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,14 +197,28 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
NSURL *folderUrl = [[SandboxBroker urlWithoutFragment:fileUrl] URLByDeletingLastPathComponent];
|
NSURL *folderUrl = [[SandboxBroker urlWithoutFragment:fileUrl] URLByDeletingLastPathComponent];
|
||||||
if(![folderUrl isFileURL]) return NULL;
|
if(![folderUrl isFileURL]) return NULL;
|
||||||
|
|
||||||
SandboxEntry *entry;
|
SandboxEntry *_entry = nil;
|
||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
entry = [self recursivePathTest:folderUrl];
|
for(SandboxEntry *entry in storage) {
|
||||||
|
if(entry.path && [SandboxBroker isPath:folderUrl aSubdirectoryOf:[NSURL fileURLWithPath:entry.path]]) {
|
||||||
|
entry.refCount += 1;
|
||||||
|
_entry = entry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entry) {
|
if(!_entry) {
|
||||||
return CFBridgingRetain(entry);
|
_entry = [self recursivePathTest:folderUrl];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_entry) {
|
||||||
|
[storage addObject:_entry];
|
||||||
|
|
||||||
|
[_entry.secureUrl startAccessingSecurityScopedResource];
|
||||||
|
|
||||||
|
return CFBridgingRetain(_entry);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -242,4 +245,13 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)areAllPathsSafe:(NSArray *)urls {
|
||||||
|
for(NSURL *url in urls) {
|
||||||
|
if(![self recursivePathTest:url]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in New Issue