1// 2// PXAppDelegate.m 3// Pixen-XCode 4// 5// Copyright (c) 2003,2004 Open Sword Group 6 7// Permission is hereby granted, free of charge, to any person obtaining a copy 8// of this software and associated documentation files (the "Software"), to deal 9// in the Software without restriction, including without limitation the rights 10// to use,copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11// of the Software, and to permit persons to whom the Software is furnished to 12// do so, subject to the following conditions: 13 14// The above copyright notice and this permission notice shall be included in all copies 15// or substantial portions of the Software. 16 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 18// BUT NOT LIMITED TO THE WARRANTIES 19// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 20// OR COPYRIGHT HOLDERS 21// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24// Author : Andy Matuschak 25// Created on Tue Dec 09 2003. 26 27 28 29 30//This class is the application delegate. 31//it respond as delegate for applicationShouldOpenUntitledFile: applicationDidFinishLaunching: applicationWillTerminate: 32//methods (see NSApplication documentation) 33// it also responds to message from menu (only menu ??) 34// TODO : finish that 35 36#import "PXAppDelegate.h" 37 38#import "PXAboutController.h" 39#import "PXWelcomeController.h" 40#import "PXPreferencesController.h" 41#import "PXUserWarmer.h" 42 43#import <Foundation/NSFileManager.h> 44#import <AppKit/NSAlert.h> 45 46extern BOOL isTiling; 47 48/***********************************/ 49/******** Private method ***********/ 50/***********************************/ 51 52@interface PXAppDelegate (Private) 53//Call from applicationDidFinishLaunching: 54- (void) _checkForUncleanCrash; 55- (void) _createApplicationSupportSubdirectories; 56@end 57 58@implementation PXAppDelegate (Private) 59 60- (void) _checkForUncleanCrash 61{ 62 NSArray *dirtyFiles = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"PXDirtyFiles"] copy] autorelease]; 63 64 if ( (! dirtyFiles ) || [dirtyFiles count] < 1) 65 return; 66 else 67 { 68 [[NSUserDefaults standardUserDefaults] setObject:[NSArray array] forKey:@"PXDirtyFiles"]; 69 NSEnumerator *dirtyFileEnumerator = [dirtyFiles objectEnumerator]; 70 NSString *dirtyFile; 71 72 while ( ( dirtyFile = [dirtyFileEnumerator nextObject] ) ) { 73 if ([[NSFileManager defaultManager] fileExistsAtPath:dirtyFile]) { 74 id document = [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfFile:dirtyFile 75 display:YES]; 76 [document setFileName:nil]; 77 [[NSFileManager defaultManager] removeFileAtPath:dirtyFile handler:nil]; 78 } 79 } 80 81 [[NSAlert alertWithMessageText:NSLocalizedString(@"CRASH_RECOVERY", @"Crash Recover") 82 defaultButton:@"OK" 83 alternateButton:nil 84 otherButton:nil 85 informativeTextWithFormat:NSLocalizedString(@"CRASH_TEXT", @"Crash Text")] runModal]; 86 } 87} 88 89//TODO Create Subdirectories for colors too 90 91- (void) _createApplicationSupportSubdirectory:(NSString *)sub inDirectory:(NSString *)root 92{ 93 NSFileManager *fileManager = [NSFileManager defaultManager]; 94 BOOL isDir; 95 NSString *path = [root stringByAppendingPathComponent:sub]; 96 if ( ! [fileManager fileExistsAtPath:path isDirectory:&isDir] ) 97 { 98 if ( ! [fileManager createDirectoryAtPath:path attributes:nil] ) 99 { 100 [PXUserWarmer warmTheUser:@"I couldn't create a directory in your library or application support directory! That's kind of... not good. Please adjust permissions or something."]; // localize? 101 return; 102 } 103 } 104 else 105 { 106 if ( ! isDir ) 107 { 108 [PXUserWarmer warmTheUser:[NSString stringWithFormat:@"Um, there's a file named %@ in %@... were you trying to make me crash, or what?", sub, root]]; // localize? 109 return; 110 } 111 } 112} 113 114- (void) _createApplicationSupportSubdirectories 115{ 116 //Check the Library user path 117 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); 118 NSFileManager *fileManager = [NSFileManager defaultManager]; 119 BOOL isDir; 120 NSString *path; 121 122 if ( [paths count] == 0 ) 123 { 124 [PXUserWarmer warmTheUser:@"The Library directory does not exist. This is highly irregular. Get thee to your nearest Apple retailer and demand a refund!"]; // localize? 125 return; 126 } 127 path = [paths objectAtIndex:0]; 128 //Application Support 129#ifdef __COCOA__ 130 path = [path stringByAppendingPathComponent: @"Application Support"]; 131 132 if ( ( ! [fileManager fileExistsAtPath:path isDirectory:&isDir] ) 133 || ( ! isDir ) ) 134 { 135 [PXUserWarmer warmTheUser:@"There's no Application Support directory! That blows and sucks, at the same time!"]; // localize? 136 return; 137 } 138#endif 139 [self _createApplicationSupportSubdirectory:@"Pixen" inDirectory:path]; // ./Pixen 140 path = [path stringByAppendingPathComponent:@"Pixen"]; 141 [self _createApplicationSupportSubdirectory:@"Backgrounds" inDirectory:path]; // ./Pixen/Backgrounds 142 [self _createApplicationSupportSubdirectory:@"Presets" 143 inDirectory:[path stringByAppendingPathComponent:@"Backgrounds"]]; // ./Pixen/Backgrounds/Presets 144 [self _createApplicationSupportSubdirectory:@"Palettes" inDirectory:path]; // ./Pixen/Palettes 145 [self _createApplicationSupportSubdirectory:@"Presets" 146 inDirectory:[path stringByAppendingPathComponent:@"Palettes"]]; // ./Pixen/Palettes/Presets 147} 148@end 149 150 151@implementation PXAppDelegate 152 153// 154// Delegate methods 155// 156- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 157{ 158 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 159 160 //Create some directories needs to store backgrounds and Colors 161 [self _createApplicationSupportSubdirectories]; 162 163 164 //init all palettes 165 toolPaletteController = [PXToolPaletteController sharedToolPaletteController]; 166 colorPaletteController = [PXColorPaletteController sharedPaletteController]; 167 leftToolPropertiesController = [PXToolPropertiesController leftToolPropertiesController]; 168 rightToolPropertiesController = [PXToolPropertiesController rightToolPropertiesController]; 169 infoPanelController = [PXInfoPanelController sharedInfoPanelController]; 170 171 // Open some panels if the user have let them open the last time 172 if ( [defaults boolForKey:@"PXLeftToolPropertiesIsOpen"] ) { 173 [[leftToolPropertiesController propertiesPanel] makeKeyAndOrderFront:self]; 174 } 175 if ( [defaults boolForKey:@"PXRightToolPropertiesIsOpen"] ) { 176 [[rightToolPropertiesController propertiesPanel] makeKeyAndOrderFront:self]; 177 } 178 179 if ( [defaults boolForKey:@"PXInfoPanelIsOpen"] ) 180 [[infoPanelController infoPanel] makeKeyAndOrderFront:self]; 181 182 if ( [defaults boolForKey:@"PXColorPaletteIsOpen"] ) 183 [[colorPaletteController palettePanel] makeKeyAndOrderFront:self]; 184 185 //Always display toolPanel 186 [[toolPaletteController toolPanel] display]; 187 // Please keep this line AFTER the tool properties' creation, so everything will update properly. 188 189 [self _checkForUncleanCrash]; 190 191 //If it is the first time Pixen run launch the welcome Panel 192 //TODO (could be cleaner) : Fabien 193 if (! [defaults boolForKey:@"PXHasRunBefore"] ) 194 { 195 id welcome = [[PXWelcomeController alloc] init]; 196 197 isTiling = NO; 198 [defaults setBool:NO forKey:@"PXShouldTile"]; 199 [defaults setBool:YES forKey:@"UKUpdateCheckerCheckAtStartup"]; 200 [defaults setInteger:120 forKey:@"PXAutosaveInterval"]; 201 [defaults setBool:YES forKey:@"PXInfoPanelIsOpen"]; 202 [defaults setBool:YES forKey:@"PXHasRunBefore"]; 203 [welcome showWindow:self]; 204 } 205 206 207} 208 209- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender 210{ 211 return NO; 212} 213 214- (void)applicationWillTerminate:(NSNotification *)aNotification 215{ 216 if ( [[leftToolPropertiesController propertiesPanel] isVisible] ) 217 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PXLeftToolPropertiesIsOpen"]; 218 else 219 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"PXLeftToolPropertiesIsOpen"]; 220 221 if ( [[rightToolPropertiesController propertiesPanel] isVisible] ) 222 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PXRightToolPropertiesIsOpen"]; 223 else 224 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"PXRightToolPropertiesIsOpen"]; 225 226 if ( [[infoPanelController infoPanel] isVisible] ) 227 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PXInfoPanelIsOpen"]; 228 else 229 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"PXInfoPanelIsOpen"]; 230 231 if ( [[colorPaletteController palettePanel] isVisible] ) 232 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PXColorPaletteIsOpen"]; 233 else 234 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"PXColorPaletteIsOpen"]; 235 236 [[NSUserDefaults standardUserDefaults] synchronize]; 237} 238 239 240// 241// Actions methods 242// 243- (void)showAboutPanel:(id) sender 244{ 245 [[PXAboutController sharedAboutController] showPanel:self]; 246} 247 248- (IBAction)donate:(id) sender 249{ 250 [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.opensword.org/donate.php"]]; 251} 252 253- (IBAction)showLeftToolProperties:(id) sender; 254{ 255 [[leftToolPropertiesController propertiesPanel] makeKeyAndOrderFront:self]; 256} 257 258- (IBAction)showRightToolProperties:(id) sender; 259{ 260 [[rightToolPropertiesController propertiesPanel] makeKeyAndOrderFront:self]; 261} 262 263- (IBAction)showColorPalette:(id) sender 264{ 265 [[colorPaletteController palettePanel] makeKeyAndOrderFront:self]; 266} 267 268- (IBAction)showPreferences:(id) sender 269{ 270 [[PXPreferencesController sharedPreferencesController] showWindow:self]; 271} 272 273- (IBAction)showInfoPanel:(id) sender 274{ 275 [[[PXInfoPanelController sharedInfoPanelController] infoPanel] makeKeyAndOrderFront:self]; 276} 277 278//BUG : Could be call twice ! Should be a singleton (Fabien) 279- (IBAction)discoverPixen:(id) sender 280{ 281 id welcome = [[PXWelcomeController alloc] init]; 282 [welcome showWindow:self]; 283} 284 285@end 286 287