1/* 2 3 Preferences.m 4 Zipper 5 6 Copyright (C) 2012 Free Software Foundation, Inc 7 8 Authors: Dirk Olmes <dirk@xanthippe.ping.de> 9 Riccardo Mottola <rm@gnu.org> 10 11 This application is free software; you can redistribute it and/or modify it 12 under the terms of the GNU General Public License as published by the Free 13 Software Foundation; either version 2 of the License, or (at your option) 14 any later version. 15 16 This program is distributed in the hope that it will be useful, but 17 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 or FITNESS FOR A PARTICULAR PURPOSE. 19 See the GNU General Public License for more details 20 21 */ 22 23#import <Foundation/Foundation.h> 24#import "Preferences.h" 25#import "NSFileManager+Custom.h" 26 27#define X_MISSING_PREF @"MissingPreferenceException" 28#define X_WRONG_PREF @"WrongPreferenceException" 29 30@interface Preferences (PrivateAPI) 31+ (NSString *)stringForKey:(NSString *)key; 32+ (BOOL)boolForKey:(NSString *)key; 33+ (void)checkExecutable:(NSString *)executable withName:(NSString *)name; 34@end 35 36/** 37 * This class encapsulates the access to the app's preferences. It faciliates providing a 38 * Dictionary that will be used instead of NSUserDefaults and searching the PATH environment 39 * variable. 40 */ 41@implementation Preferences : NSObject 42 43/** 44 * To faciliate unit testing it's possible to provide the Preferences class with an NSDictionary 45 * that makes up the preferences. 46 */ 47static NSDictionary *_replacementPrefs = nil; 48 49/** 50 * Additional Preferences loaded from PropertyList file 51 */ 52static NSDictionary *_plistPrefs; 53 54/** 55 * This is the mapping between file extensions and tar's extract option. This option differs 56 * from platform to platform. In order to encapsulate this, Preferences manages this mapping 57 * and clients can ask for a compression argument with <code>compressionArgumentForFile:</code> 58 */ 59static NSMutableDictionary *_extensionMapping = nil; 60 61+ (void)initialize 62{ 63 NSString *path; 64 65 if (_extensionMapping == nil) 66 { 67 _extensionMapping = [[NSMutableDictionary dictionaryWithObjectsAndKeys: 68 @"", @"tar", 69 @"-z", @"gz", 70 @"-z", @"tgz", 71 @"-j", @"bz2", 72 nil] retain]; 73 } 74 75 // see if there's a property list containing preferences to use 76 path = [[NSBundle bundleForClass:self] pathForResource:@"DefaultPreferences" ofType:@"plist"]; 77 if (path != nil) 78 { 79 _plistPrefs = [[NSDictionary dictionaryWithContentsOfFile:path] retain]; 80 } 81} 82 83+ (void)usePreferences:(NSDictionary *)newPrefs; 84{ 85 [_replacementPrefs release]; 86 _replacementPrefs = newPrefs; 87 [_replacementPrefs retain]; 88} 89 90+ (NSString *)tarExecutable; 91{ 92 NSString *tar = [self stringForKey:PREF_KEY_TAR]; 93 if (tar == nil) 94 { 95 // search the PATH 96 tar = [[NSFileManager defaultManager] locateExecutable:@"tar"]; 97 } 98 return tar; 99} 100 101+ (void)setTarExecutable:(NSString *)newTar 102{ 103 if (newTar != nil) 104 { 105 [[NSUserDefaults standardUserDefaults] setObject:newTar forKey:PREF_KEY_TAR]; 106 } 107} 108 109+ (BOOL)isBsdTar; 110{ 111 return [self boolForKey:PREF_KEY_BSD_TAR]; 112} 113 114+ (void)setIsBsdTar:(BOOL)flag 115{ 116 [[NSUserDefaults standardUserDefaults] setBool:flag forKey:PREF_KEY_BSD_TAR]; 117 if (flag == YES) 118 { 119 // on BSD tar also uses -z for extracting .bz archives 120 [_extensionMapping setObject:@"-z" forKey:@"bz2"]; 121 } 122 else 123 { 124 [_extensionMapping setObject:@"-j" forKey:@"bz2"]; 125 } 126} 127 128+ (NSString *)zipExecutable; 129{ 130 NSString *zip = [self stringForKey:PREF_KEY_ZIP]; 131 if (zip == nil) 132 { 133 zip = [[NSFileManager defaultManager] locateExecutable:@"zip"]; 134 } 135 return zip; 136} 137+ (void)setZipExecutable:(NSString *)newZip 138{ 139 if (newZip != nil) 140 { 141 [[NSUserDefaults standardUserDefaults] setObject:newZip forKey:PREF_KEY_ZIP]; 142 } 143} 144 145+ (NSString *)unzipExecutable; 146{ 147 NSString *unzip = [self stringForKey:PREF_KEY_UNZIP]; 148 if (unzip == nil) 149 { 150 unzip = [[NSFileManager defaultManager] locateExecutable:@"unzip"]; 151 } 152 return unzip; 153} 154 155+ (void)setUnzipExecutable:(NSString *)newUnzip 156{ 157 if (newUnzip != nil) 158 { 159 [[NSUserDefaults standardUserDefaults] setObject:newUnzip forKey:PREF_KEY_UNZIP]; 160 } 161} 162 163+ (NSString *)sevenZipExecutable; 164{ 165 NSString *zip = [self stringForKey:PREF_KEY_SEVEN_ZIP]; 166 if (zip == nil) 167 { 168 zip = [[NSFileManager defaultManager] locateExecutable:@"7z"]; 169 170 // corner case: only 7za may be available on the system 171 if (zip == nil) 172 { 173 zip = [[NSFileManager defaultManager] locateExecutable:@"7za"]; 174 } 175 } 176 return zip; 177} 178 179+ (void)setSevenZipExecutable:(NSString *)new7zip 180{ 181 if (new7zip != nil) 182 { 183 [[NSUserDefaults standardUserDefaults] setObject:new7zip forKey:PREF_KEY_SEVEN_ZIP]; 184 } 185} 186 187+ (NSString *)rarExecutable; 188{ 189 NSString *rar = [self stringForKey:PREF_KEY_RAR]; 190 if (rar == nil) 191 { 192 rar = [[NSFileManager defaultManager] locateExecutable:@"unrar"]; 193 } 194 return rar; 195} 196 197+ (void)setRarExecutable:(NSString *)newRar; 198{ 199 if (newRar != nil) 200 { 201 [[NSUserDefaults standardUserDefaults] setObject:newRar forKey:PREF_KEY_RAR]; 202 } 203} 204 205+ (NSString *)lhaExecutable 206{ 207 NSString *lha = [self stringForKey:PREF_KEY_LHA]; 208 if (lha == nil) 209 { 210 lha = [[NSFileManager defaultManager] locateExecutable:@"lha"]; 211 } 212 return lha; 213} 214 215+ (void)setLhaExecutable:(NSString *)newLha; 216{ 217 if (newLha != nil) 218 { 219 [[NSUserDefaults standardUserDefaults] setObject:newLha forKey:PREF_KEY_LHA]; 220 } 221} 222 223+ (NSString *)lzxExecutable 224{ 225 NSString *lzx = [self stringForKey:PREF_KEY_LZX]; 226 if (lzx == nil) 227 { 228 lzx = [[NSFileManager defaultManager] locateExecutable:@"unlzx"]; 229 } 230 return lzx; 231} 232 233+ (void)setLzxExecutable:(NSString *)newLzx; 234{ 235 if (newLzx != nil) 236 { 237 [[NSUserDefaults standardUserDefaults] setObject:newLzx forKey:PREF_KEY_LZX]; 238 } 239} 240 241+ (NSString *)gzipExecutable 242{ 243 NSString *gzip = [self stringForKey:PREF_KEY_GZIP]; 244 if (gzip == nil) 245 { 246 gzip = [[NSFileManager defaultManager] locateExecutable:@"gzip"]; 247 } 248 return gzip; 249} 250 251+ (void)setGzipExecutable:(NSString *)newGzip 252{ 253 if (newGzip != nil) 254 { 255 [[NSUserDefaults standardUserDefaults] setObject:newGzip forKey:PREF_KEY_GZIP]; 256 } 257} 258 259+ (NSString *)gunzipExecutable 260{ 261 NSString *gunzip = [self stringForKey:PREF_KEY_GUNZIP]; 262 if (gunzip == nil) 263 { 264 gunzip = [[NSFileManager defaultManager] locateExecutable:@"gunzip"]; 265 } 266 return gunzip; 267} 268 269+ (void)setGunzipExecutable:(NSString *)newGunzip 270{ 271 if (newGunzip != nil) 272 { 273 [[NSUserDefaults standardUserDefaults] setObject:newGunzip forKey:PREF_KEY_GUNZIP]; 274 } 275} 276 277+ (NSString *)bzip2Executable 278{ 279 NSString *bzip2 = [self stringForKey:PREF_KEY_BZIP2]; 280 if (bzip2 == nil) 281 { 282 bzip2 = [[NSFileManager defaultManager] locateExecutable:@"bzip2"]; 283 } 284 return bzip2; 285} 286 287+ (void)setBzip2Executable:(NSString *)newBzip2 288{ 289 if (newBzip2 != nil) 290 { 291 [[NSUserDefaults standardUserDefaults] setObject:newBzip2 forKey:PREF_KEY_BZIP2]; 292 } 293} 294 295+ (NSString *)bunzip2Executable 296{ 297 NSString *bunzip2 = [self stringForKey:PREF_KEY_BUNZIP2]; 298 if (bunzip2 == nil) 299 { 300 bunzip2 = [[NSFileManager defaultManager] locateExecutable:@"bunzip2"]; 301 } 302 return bunzip2; 303} 304 305+ (void)setBunzip2Executable:(NSString *)newBunzip2 306{ 307 if (newBunzip2 != nil) 308 { 309 [[NSUserDefaults standardUserDefaults] setObject:newBunzip2 forKey:PREF_KEY_BUNZIP2]; 310 } 311} 312 313+ (NSString *)unarjExecutable 314{ 315 NSString *unarj = [self stringForKey:PREF_KEY_UNARJ]; 316 if (unarj == nil) 317 { 318 unarj = [[NSFileManager defaultManager] locateExecutable:@"unarj"]; 319 } 320 return unarj; 321} 322 323+ (void)setUnarjExecutable:(NSString *)newUnarj 324{ 325 if (newUnarj != nil) 326 { 327 [[NSUserDefaults standardUserDefaults] setObject:newUnarj forKey:PREF_KEY_UNARJ]; 328 } 329} 330 331+ (NSString *)unaceExecutable 332{ 333 NSString *unace = [self stringForKey:PREF_KEY_UNACE]; 334 if (unace == nil) 335 { 336 unace = [[NSFileManager defaultManager] locateExecutable:@"unace"]; 337 } 338 return unace; 339} 340 341+ (void)setUnaceExecutable:(NSString *)newUnace 342{ 343 if (newUnace != nil) 344 { 345 [[NSUserDefaults standardUserDefaults] setObject:newUnace forKey:PREF_KEY_UNACE]; 346 } 347} 348 349+ (NSString *)zooExecutable 350{ 351 NSString *zoo = [self stringForKey:PREF_KEY_ZOO]; 352 if (zoo == nil) 353 { 354 zoo = [[NSFileManager defaultManager] locateExecutable:@"zoo"]; 355 } 356 return zoo; 357} 358 359+ (void)setZooExecutable:(NSString *)newZoo 360{ 361 if (newZoo != nil) 362 { 363 [[NSUserDefaults standardUserDefaults] setObject:newZoo forKey:PREF_KEY_ZOO]; 364 } 365} 366 367+ (NSString *)xzExecutable 368{ 369 NSString *xz = [self stringForKey:PREF_KEY_XZ]; 370 if (xz == nil) 371 { 372 xz = [[NSFileManager defaultManager] locateExecutable:@"xz"]; 373 } 374 return xz; 375} 376 377+ (void)setXzExecutable:(NSString *)newXz 378{ 379 if (newXz != nil) 380 { 381 [[NSUserDefaults standardUserDefaults] setObject:newXz forKey:PREF_KEY_XZ]; 382 } 383} 384 385+ (NSString *)lastOpenDirectory 386{ 387 return [self stringForKey:PREF_KEY_OPEN_DIR]; 388} 389 390+ (void)setLastOpenDirectory:(NSString *)path; 391{ 392 [[NSUserDefaults standardUserDefaults] setObject:path forKey:PREF_KEY_OPEN_DIR]; 393} 394 395+ (NSString *)lastExtractDirectory; 396{ 397 return [self stringForKey:PREF_KEY_EXTRACT_DIR]; 398} 399 400+ (void)setLastExtractDirectory:(NSString *)path; 401{ 402 [[NSUserDefaults standardUserDefaults] setObject:path forKey:PREF_KEY_EXTRACT_DIR]; 403} 404 405+ (NSString *)compressionArgumentForFile:(NSString *)fileName 406{ 407 if (fileName != nil) 408 { 409 return [_extensionMapping objectForKey:[fileName pathExtension]]; 410 } 411 return nil; 412} 413 414/** 415 * Returns the name of the app that will be used to open files that don't have a 416 * pathExtension. 417 */ 418+ (NSString *)defaultOpenApp; 419{ 420 return [self stringForKey:PREF_KEY_DEFAULT_OPEN_APP]; 421} 422 423+ (void)setDefaultOpenApp:(NSString *)path; 424{ 425 [[NSUserDefaults standardUserDefaults] setObject:path forKey:PREF_KEY_DEFAULT_OPEN_APP]; 426} 427 428+ (void)save 429{ 430 [[NSUserDefaults standardUserDefaults] synchronize]; 431} 432 433//------------------------------------------------------------------------------ 434// private API 435//------------------------------------------------------------------------------ 436+ (NSString *)stringForKey:(NSString *)key; 437{ 438 NSString *value; 439 440 if (_replacementPrefs != nil) 441 { 442 return [_replacementPrefs objectForKey:key]; 443 } 444 445 value = [[NSUserDefaults standardUserDefaults] stringForKey:key]; 446 if ((value == nil) && (_plistPrefs != nil)) 447 { 448 value = [_plistPrefs objectForKey:key]; 449 } 450 return value; 451} 452 453+ (BOOL)boolForKey:(NSString *)key 454{ 455 if (_replacementPrefs != nil) 456 { 457 NSString *value = [_replacementPrefs objectForKey:key]; 458 return [value isEqual:@"YES"]; 459 } 460 return [[NSUserDefaults standardUserDefaults] boolForKey:key]; 461} 462 463@end 464