allow selection of config/data file when init failed

pull/400/head
Li Linfeng 2019-09-09 22:17:40 +08:00
parent 2a2ec1b45f
commit 9c9a80526f
9 changed files with 197 additions and 204 deletions

View File

@ -4,9 +4,9 @@
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>

View File

@ -343,7 +343,7 @@ CelestiaCore *appCore;
{
BOOL result = NO;
appCore = new CelestiaCore();
std::string confFile = [configPath UTF8String];
std::string confFile = configPath ? [configPath UTF8String] : "";
std::vector<std::string> extrasDirs;
MacOSXSplashProgressNotifier progressNotifier;
@ -352,15 +352,16 @@ CelestiaCore *appCore;
extrasDirs.push_back([extraPath UTF8String]);
}
appCore->setAlerter(new MacOSXAlerter());
appCore->setCursorHandler(new MacOSXCursorHandler());
result = appCore->initSimulation(&confFile,
result = appCore->initSimulation(confFile.empty() ? NULL : &confFile,
&extrasDirs,
&progressNotifier);
if (result)
{
CelestiaSettings *settings = [CelestiaSettings shared];
new MacSettingsWatcher(self, settings); // adds itself to the appCore
appCore->setAlerter(new MacOSXAlerter());
}
return result;

View File

@ -25,11 +25,11 @@
{
CelestiaSettings* settings;
CelestiaAppCore* appCore;
BOOL threaded;
BOOL ready;
BOOL isDirty;
BOOL isFullScreen;
BOOL needsRelaunch;
BOOL forceQuit;
IBOutlet SplashWindowController *splashWindowController;
IBOutlet NSTextView *glInfo;
IBOutlet NSPanel *glInfoPanel;
@ -65,7 +65,7 @@
-(void)setDirty;
-(void)forceDisplay;
-(void)resize;
-(void)startInitialization;
-(BOOL)startInitialization;
-(void)finishInitialization;
-(void)display;
-(void)awakeFromNib;

View File

@ -52,45 +52,55 @@ NSString* fatalErrorMessage;
// read config file/data dir from saved
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSData *configFileData = [prefs objectForKey:configFilePathPrefKey];
NSData *dataDirData = [prefs objectForKey:configFilePathPrefKey];
NSData *dataDirData = [prefs objectForKey:dataDirPathPrefKey];
if (configFileData != nil && dataDirData != nil) {
// read saved sandbox bookmark
NSError *error = nil;
configFilePath = [NSURL URLByResolvingBookmarkData:configFileData options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:nil error:&error];
dataDirPath = [NSURL URLByResolvingBookmarkData:dataDirData options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:nil error:&error];
}
if (configFilePath == nil || dataDirPath == nil)
// access saved bookmarks
if (configFileData != nil)
{
// use the default location
configFilePath = [[[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"%@/celestia.cfg", CELESTIA_RESOURCES_FOLDER] withExtension:nil] retain];
dataDirPath = [[[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"%@", CELESTIA_RESOURCES_FOLDER] withExtension:nil] retain];
NSError *error = nil;
NSURL *tempPath = [NSURL URLByResolvingBookmarkData:configFileData options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:nil error:&error];
if ([tempPath startAccessingSecurityScopedResource])
{
configFilePath = [tempPath retain];
}
}
if (dataDirData != nil)
{
NSError *error = nil;
NSURL *tempPath = [NSURL URLByResolvingBookmarkData:dataDirData options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:nil error:&error];
if ([tempPath startAccessingSecurityScopedResource])
{
dataDirPath = [tempPath retain];
}
}
// use the default location for nil ones
if (configFilePath == nil)
configFilePath = [[ConfigSelectionWindowController applicationConfig] retain];
if (dataDirPath == nil)
dataDirPath = [[ConfigSelectionWindowController applicationDataDirectory] retain];
// add the edit configuration menu item
NSMenu *appMenu = [[[[NSApp mainMenu] itemArray] objectAtIndex:0] submenu];
[appMenu insertItem:[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Change Configuration File", "") action:@selector(changeConfigFileLocation) keyEquivalent:@""] atIndex:[[appMenu itemArray] count] - 1];
[appMenu insertItem:[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Change Configuration File", "") action:@selector(changeConfigFileLocationFromMenu) keyEquivalent:@""] atIndex:[[appMenu itemArray] count] - 1];
int cpuCount = 0;
size_t cpuCountSize = sizeof cpuCount;
if (0 == sysctlbyname("hw.ncpu", &cpuCount, &cpuCountSize, NULL, 0))
{
threaded = (cpuCount > 1);
}
ready = NO;
isDirty = YES;
isFullScreen = NO;
needsRelaunch = NO;
forceQuit = NO;
appCore = nil;
fatalErrorMessage = nil;
lastScript = nil;
[self setupResourceDirectory];
[scriptsController buildScriptMenuWithScriptDir:extraDataDirPath.path];
[scriptsController buildScriptMenuWithScriptDir:[extraDataDirPath path]];
// hide main window until ready
[[glView window] setAlphaValue: 0.0f]; // not [[glView window] orderOut: nil];
[[glView window] setIgnoresMouseEvents:YES];
// create appCore
appCore = [CelestiaAppCore sharedAppCore];
@ -109,30 +119,38 @@ NSString* fatalErrorMessage;
{
[splashWindowController showWindow];
}
if (threaded)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// start initialization thread
[NSThread detachNewThreadSelector: @selector(startInitialization) toTarget: self
withObject: nil];
// wait for completion
[self performSelectorOnMainThread: @selector(waitWhileLoading:) withObject: nil waitUntilDone: NO ];
}
else
{
[self performSelector:@selector(startInitialization) withObject:nil afterDelay:0];
}
BOOL result = [self startInitialization];
dispatch_async(dispatch_get_main_queue(), ^{
[splashWindowController close];
if (result)
[self finishInitialization];
else
[self initializationError];
});
});
}
- (void)setNeedsRelaunch:(BOOL)newValue {
- (void)setNeedsRelaunch:(BOOL)newValue
{
needsRelaunch = newValue;
}
- (void)changeConfigFileLocation {
- (void)changeConfigFileLocationFromMenu
{
[self changeConfigFileLocation:YES];
}
- (void)changeConfigFileLocation:(BOOL)cancelAllowed
{
if (configSelectionWindowController == nil) {
configSelectionWindowController = [[ConfigSelectionWindowController alloc] initWithWindowNibName:@"ConfigSelectionWindow"];
configSelectionWindowController->dataDirPath = [dataDirPath retain];
configSelectionWindowController->configFilePath = [configFilePath retain];
}
[configSelectionWindowController setMandatory:!cancelAllowed];
[configSelectionWindowController showWindow:self];
}
@ -168,7 +186,7 @@ NSString* fatalErrorMessage;
}
}
- (void)startInitialization
- (BOOL)startInitialization
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@ -176,37 +194,43 @@ NSString* fatalErrorMessage;
#ifdef DEBUG
NSDate *t = [NSDate date];
#endif
if (![appCore initSimulationWithConfigPath:configFilePath.path extraPath:extraDataDirPath.path])
BOOL result = [appCore initSimulationWithConfigPath:[configFilePath path] extraPath:[extraDataDirPath path]];
if (!result)
{
[startupCondition lock];
[startupCondition unlockWithCondition: 99];
#ifdef DEBUG
[pool release];
#endif
[self fatalError: NSLocalizedString(@"Error loading data files. Celestia will now quit.",@"")];
if (!threaded)
[self fatalError: nil];
else
[NSThread exit];
return;
[startupCondition unlockWithCondition:99];
}
#ifdef DEBUG
NSLog(@"Init took %lf seconds\n", -[t timeIntervalSinceNow]);
#endif
[startupCondition lock];
[startupCondition unlockWithCondition: 1];
if (!threaded)
else
{
[splashWindowController close];
// complete startup
[self fatalError: nil];
[self finishInitialization];
#ifdef DEBUG
NSLog(@"Init took %lf seconds\n", -[t timeIntervalSinceNow]);
#endif
[startupCondition lock];
[startupCondition unlockWithCondition:1];
}
[pool release];
return result;
}
- (void) initializationError
{
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:NSLocalizedString(@"Celestia failed to load data files.", @"")];
[alert addButtonWithTitle:NSLocalizedString(@"Choose Configuration File", @"")];
[alert addButtonWithTitle:NSLocalizedString(@"Quit", @"")];
forceQuit = YES;
if ([alert runModal] == NSAlertFirstButtonReturn)
{
// choose new configuration file
[self changeConfigFileLocation:NO];
return;
}
// quit
[NSApp terminate:self];
}
- (void) fatalError: (NSString *) msg
{
@ -223,37 +247,6 @@ NSString* fatalErrorMessage;
fatalErrorMessage = [msg retain];
}
- (void) waitWhileLoading: (id) obj
{
// display loading indicator window while loading
static NSModalSession session = nil;
if ( [startupCondition condition] == 0 )
{
if ( session != nil )
return;
// beginModalSession also displays the window, but the centering
// is wrong so do the display and centering beforehand
session = [NSApp beginModalSessionForWindow: [splashWindowController window]];
for (;;)
{
if ( fatalErrorMessage != nil )
break;
if ([NSApp runModalSession:session] != NSRunContinuesResponse)
break;
if ( [startupCondition condition] != 0 )
break;
}
[NSApp endModalSession:session];
}
[splashWindowController close];
// check for fatal error in loading thread
[self fatalError: nil];
// complete startup
[self finishInitialization];
}
-(void) setupFavorites
{
NSInvocation *menuCallback;
@ -267,6 +260,7 @@ NSString* fatalErrorMessage;
-(void) startGLView
{
[[glView window] setIgnoresMouseEvents:NO];
[[glView window] setAutodisplay:YES];
[[glView window] setHidesOnDeactivate: NO];
[[glView window] setFrameUsingName: @"Celestia"];
@ -300,72 +294,6 @@ NSString* fatalErrorMessage;
- (void)finishInitialization
{
#ifndef NO_VP_WORKAROUND
NSString *VP_PROBLEM_EXT = @"GL_ARB_vertex_program";
NSString *VP_PATCH_SCRIPT = @"vp_patch.sh";
NSString *VP_PATCH_SHELL = @"/bin/zsh";
NSString *CELESTIA_CFG = @"~/.celestia.cfg";
const char *VP_PROBLEM_RENDERERS[] = { "ATI Radeon 9200" };
const char *glRenderer = (const char *) glGetString(GL_RENDERER);
BOOL shouldWorkaround = NO;
size_t i = 0;
if (glRenderer)
{
for (; i < (sizeof VP_PROBLEM_RENDERERS)/sizeof(char *); ++i)
{
if (strstr(glRenderer, VP_PROBLEM_RENDERERS[i]))
{
shouldWorkaround = YES;
break;
}
}
}
if (shouldWorkaround && ![appCore glExtensionIgnored: VP_PROBLEM_EXT])
{
if (NSRunAlertPanel([NSString stringWithFormat: NSLocalizedString(@"It appears you are running Celestia on %s hardware. Do you wish to install a workaround?",nil), VP_PROBLEM_RENDERERS[i]],
[NSString stringWithFormat: NSLocalizedString(@"A shell script will be run to modify your %@, adding an IgnoreGLExtensions directive. This can prevent freezing issues.",nil), CELESTIA_CFG],
NSLocalizedString(@"Yes",nil),
NSLocalizedString(@"No",nil),
nil) == NSAlertDefaultReturn)
{
// Install it
NSString *cfgPath = [CELESTIA_CFG stringByStandardizingPath];
NSString *toolPath = [[NSBundle mainBundle] pathForResource: VP_PATCH_SCRIPT ofType: @""];
BOOL patchInstalled = NO;
if (toolPath)
{
NSArray *taskArgs = [NSArray arrayWithObjects:
toolPath, cfgPath, nil];
NSTask *theTask = [NSTask launchedTaskWithLaunchPath: VP_PATCH_SHELL
arguments: taskArgs];
if (theTask)
{
[theTask waitUntilExit];
patchInstalled = ([theTask terminationStatus] == 0);
}
}
if (patchInstalled)
{
// Have to apply same patch to config already loaded in memory
[appCore setGLExtensionIgnored: VP_PROBLEM_EXT];
NSRunAlertPanel(NSLocalizedString(@"Workaround successfully installed.",nil),
[NSString stringWithFormat: NSLocalizedString(@"Your original %@ has been backed up.",nil), CELESTIA_CFG],
nil, nil, nil);
}
else
{
[[CelestiaController shared] fatalError: NSLocalizedString(@"There was a problem installing the workaround. You can attempt to perform the workaround manually by following the instructions in the README.",nil)];
[[CelestiaController shared] fatalError: nil];
}
}
}
#endif NO_VP_WORKAROUND
[glView setAASamples: [appCore aaSamples]];
[appCore initRenderer];
@ -469,7 +397,7 @@ NSString* fatalErrorMessage;
-(BOOL)applicationShouldTerminate:(id)sender
{
if (needsRelaunch)
if (forceQuit || needsRelaunch)
return YES;
if ( NSRunAlertPanel(NSLocalizedString(@"Quit Celestia?",@""),
@ -494,6 +422,11 @@ NSString* fatalErrorMessage;
{
[settings storeUserDefaults];
[configFilePath stopAccessingSecurityScopedResource];
[dataDirPath stopAccessingSecurityScopedResource];
[configFilePath release];
[dataDirPath release];
[lastScript release];
[eclipseFinderController release];
[browserWindowController release];
@ -504,10 +437,11 @@ NSString* fatalErrorMessage;
appCore = nil;
}
if (needsRelaunch)
{
[[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:[[NSBundle mainBundle] bundleIdentifier] options:NSWorkspaceLaunchAsync additionalEventParamDescriptor:nil launchIdentifier:nil];
}
// TODO: relaunch app in sandbox
// if (needsRelaunch)
// {
// [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:[[NSBundle mainBundle] bundleIdentifier] options:NSWorkspaceLaunchAsync additionalEventParamDescriptor:nil launchIdentifier:nil];
// }
}

View File

@ -8,6 +8,7 @@
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ConfigSelectionWindowController">
<connections>
<outlet property="cancelButton" destination="ff6-C3-vKK" id="kLt-ZT-Tum"/>
<outlet property="configFilePathControl" destination="Rsa-NG-CKd" id="zuh-8R-j4m"/>
<outlet property="dataDirPathControl" destination="28L-dp-ArL" id="vJR-Xg-VZd"/>
<outlet property="window" destination="RKC-D9-XqT" id="wIx-7S-quQ"/>
@ -16,7 +17,7 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Configuration File Selection" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" frameAutosaveName="" animationBehavior="default" id="RKC-D9-XqT">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="131" y="158" width="393" height="111"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
@ -30,7 +31,7 @@
<rect key="frame" x="133" y="73" width="204" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<pathCell key="cell" controlSize="small" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="e39-KY-FwS">
<font key="font" metaFont="controlContent" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<url key="url" string="file://localhost/Applications/"/>
<allowedTypes>
<string>cfg</string>
@ -41,7 +42,7 @@
<rect key="frame" x="18" y="77" width="97" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Configuration File" id="mm9-vf-wMR">
<font key="font" metaFont="controlContent" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -50,7 +51,7 @@
<rect key="frame" x="18" y="55" width="80" height="14"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Data Directory" id="UVE-HK-9If">
<font key="font" metaFont="controlContent" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -59,33 +60,19 @@
<rect key="frame" x="133" y="51" width="204" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<pathCell key="cell" controlSize="small" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="mzg-f0-1Fg">
<font key="font" metaFont="controlContent" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<url key="url" string="file://localhost/Applications/"/>
<allowedTypes>
<string>public.folder</string>
</allowedTypes>
</pathCell>
</pathControl>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ff6-C3-vKK">
<rect key="frame" x="148" y="14" width="79" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nal-G6-jSo">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="controlContent" size="11"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="performClose:" target="RKC-D9-XqT" id="rhQ-aJ-hns"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="niS-ko-H04">
<rect key="frame" x="236" y="14" width="142" height="27"/>
<rect key="frame" x="262" y="14" width="116" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Confirm and Relaunch" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bzF-c1-7D5">
<buttonCell key="cell" type="push" title="Confirm and Quit" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bzF-c1-7D5">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="controlContent" size="11"/>
<font key="font" metaFont="menu" size="11"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
@ -94,6 +81,31 @@ DQ
<action selector="confirmSelection:" target="-2" id="fHd-Fv-LIW"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5kO-L1-5fQ">
<rect key="frame" x="185" y="14" width="79" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Reset" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0Be-hl-H3l">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu" size="11"/>
</buttonCell>
<connections>
<action selector="reset:" target="-2" id="wjO-34-KGh"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ff6-C3-vKK">
<rect key="frame" x="108" y="14" width="79" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nal-G6-jSo">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu" size="11"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancelButtonClicked:" target="-2" id="wAn-rF-JTn"/>
</connections>
</button>
</subviews>
</view>
<point key="canvasLocation" x="31.5" y="90.5"/>

View File

@ -15,8 +15,14 @@ extern NSString *const dataDirPathPrefKey;
NSURL *configFilePath;
NSURL *dataDirPath;
@private
BOOL mandatory;
IBOutlet NSPathControl *configFilePathControl;
IBOutlet NSPathControl *dataDirPathControl;
IBOutlet NSButton *cancelButton;
}
+ (NSURL *)applicationConfig;
+ (NSURL *)applicationDataDirectory;
- (void)setMandatory:(BOOL)isMandatory;
@end

View File

@ -13,25 +13,49 @@ NSString *const dataDirPathPrefKey = @"dataDirPath";
@implementation ConfigSelectionWindowController
- (void)awakeFromNib {
- (void)awakeFromNib
{
[super awakeFromNib];
[configFilePathControl setURL:configFilePath];
[dataDirPathControl setURL:dataDirPath];
[cancelButton setTitle:mandatory ? NSLocalizedString(@"Quit", @"") : NSLocalizedString(@"Cancel", @"")];
[[[self window] standardWindowButton:NSWindowCloseButton] setEnabled:!mandatory];
}
- (void)dealloc {
- (void)dealloc
{
[configFilePath release];
[dataDirPath release];
[super dealloc];
}
- (IBAction)confirmSelection:(id)sender {
- (IBAction)reset:(id)sender
{
[configFilePathControl setURL:[ConfigSelectionWindowController applicationConfig]];
[dataDirPathControl setURL:[ConfigSelectionWindowController applicationDataDirectory]];
}
- (IBAction)confirmSelection:(id)sender
{
// save the selection, since we are running in a sandboxed environment, save bookmark
NSError *error = nil;
NSData *configFilePathData = [[configFilePathControl URL] bookmarkDataWithOptions:NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess includingResourceValuesForKeys:nil relativeToURL:nil error:&error];
NSData *dataDirPathData = [[dataDirPathControl URL] bookmarkDataWithOptions:NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess includingResourceValuesForKeys:nil relativeToURL:nil error:&error];
if (error != nil) {
NSData *configFilePathData = nil;
NSData *dataDirPathData = nil; [[dataDirPathControl URL] bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&error];
// if reset to default, don't change and save nil
if (![[configFilePathControl URL] isEqual:[ConfigSelectionWindowController applicationConfig]])
{
configFilePathData = [[configFilePathControl URL] bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&error];
}
if (![[dataDirPathControl URL] isEqual:[ConfigSelectionWindowController applicationDataDirectory]])
{
dataDirPathData = [[dataDirPathControl URL] bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&error];
}
if (error != nil)
{
// failed
[[NSAlert alertWithError:error] runModal];
return;
@ -46,4 +70,31 @@ NSString *const dataDirPathPrefKey = @"dataDirPath";
[NSApp terminate:nil];
}
- (void)setMandatory:(BOOL)isMandatory {
mandatory = isMandatory;
if ([self window] != nil)
{
[cancelButton setTitle:mandatory ? NSLocalizedString(@"Quit", @"") : NSLocalizedString(@"Cancel", @"")];
[[[self window] standardWindowButton:NSWindowCloseButton] setEnabled:!mandatory];
}
}
- (IBAction)cancelButtonClicked:(id)sender
{
if (mandatory)
[NSApp terminate:nil];
else
[[self window] performClose:nil];
}
+ (NSURL *)applicationConfig
{
return [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"%@/celestia.cfg", CELESTIA_RESOURCES_FOLDER] withExtension:nil];
}
+ (NSURL *)applicationDataDirectory
{
return [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"%@", CELESTIA_RESOURCES_FOLDER] withExtension:nil];
}
@end

View File

@ -247,7 +247,6 @@
E5CAABA70D3D7A08001926FC /* POSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CAABA60D3D7A08001926FC /* POSupport.cpp */; };
E5CC203709AA836E00CFFF2C /* POConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = E5CC203209AA834B00CFFF2C /* POConverter.m */; };
E5CC204709AA843300CFFF2C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5CC204509AA843300CFFF2C /* Localizable.strings */; };
E5D3196B096C91A6007FA87F /* vp_patch.sh in Resources */ = {isa = PBXBuildFile; fileRef = E5D3196A096C91A6007FA87F /* vp_patch.sh */; };
E5D3E6550D1EA18A00214838 /* axisarrow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5D3E6530D1EA18A00214838 /* axisarrow.cpp */; };
E5D446660777291700A1577D /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5D446640777291700A1577D /* utf8.cpp */; };
E5D4467607772B6C00A1577D /* CelestiaSettings.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5D4467407772B6C00A1577D /* CelestiaSettings.mm */; };
@ -711,7 +710,6 @@
E5CC203309AA834B00CFFF2C /* POSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = POSupport.h; sourceTree = "<group>"; };
E5CC204609AA843300CFFF2C /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = "<group>"; };
E5CC204809AA846600CFFF2C /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
E5D3196A096C91A6007FA87F /* vp_patch.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = vp_patch.sh; sourceTree = "<group>"; };
E5D3E6530D1EA18A00214838 /* axisarrow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = axisarrow.cpp; path = ../src/celengine/axisarrow.cpp; sourceTree = SOURCE_ROOT; };
E5D3E6540D1EA18A00214838 /* axisarrow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = axisarrow.h; path = ../src/celengine/axisarrow.h; sourceTree = SOURCE_ROOT; };
E5D446640777291700A1577D /* utf8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = utf8.cpp; path = ../src/celutil/utf8.cpp; sourceTree = SOURCE_ROOT; };
@ -1181,7 +1179,6 @@
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
E5D3196A096C91A6007FA87F /* vp_patch.sh */,
E54742CF09631D3600E89E09 /* defaults.plist */,
E599A78C097CAB390079C254 /* Credits.rtf */,
E5C9B46B084909B90071B1EE /* README for Mac OS X.rtf */,
@ -1936,7 +1933,6 @@
E56A5AD10848F24D00A21D7E /* caution.tiff in Resources */,
E5E365AF095C123E00B14224 /* splash.png in Resources */,
E54742D009631D3600E89E09 /* defaults.plist in Resources */,
E5D3196B096C91A6007FA87F /* vp_patch.sh in Resources */,
E599A78E097CAB390079C254 /* Credits.rtf in Resources */,
E5D766140982B1860099DBBD /* HelpWindow.nib in Resources */,
E5CC204709AA843300CFFF2C /* Localizable.strings in Resources */,

View File

@ -1,7 +0,0 @@
#!/bin/zsh
if [[ -e $1 ]]; then
[[ -w $1 ]] && sed -e 's/[[:blank:]]*#[[:blank:]]*IgnoreGLExtensions/ IgnoreGLExtensions/' -i .bak $1;
else
echo 'Configuration {\nIgnoreGLExtensions [ "GL_ARB_vertex_program" ]\n}' > $1;
fi