|
1 /***************************************************************** |
|
2 M3InstallController.m |
|
3 |
|
4 Created by Martin Pilkington on 02/06/2007. |
|
5 |
|
6 Copyright (c) 2006-2009 M Cubed Software |
|
7 |
|
8 Permission is hereby granted, free of charge, to any person |
|
9 obtaining a copy of this software and associated documentation |
|
10 files (the "Software"), to deal in the Software without |
|
11 restriction, including without limitation the rights to use, |
|
12 copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
13 copies of the Software, and to permit persons to whom the |
|
14 Software is furnished to do so, subject to the following |
|
15 conditions: |
|
16 |
|
17 The above copyright notice and this permission notice shall be |
|
18 included in all copies or substantial portions of the Software. |
|
19 |
|
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
|
22 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
23 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
24 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
|
25 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
26 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
|
27 OTHER DEALINGS IN THE SOFTWARE. |
|
28 |
|
29 *****************************************************************/ |
|
30 |
|
31 #import "M3InstallController.h" |
|
32 #import "NSWorkspace_RBAdditions.h" |
|
33 |
|
34 #import <Foundation/Foundation.h> |
|
35 |
|
36 @implementation M3InstallController |
|
37 |
|
38 -(id) init { |
|
39 if ((self = [super init])) { |
|
40 NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; |
|
41 NSString *title = [NSString stringWithFormat:NSLocalizedString(@"%@ is currently running from a disk image", @"AppName is currently running from a disk image"), appName]; |
|
42 NSString *body = [NSString stringWithFormat:NSLocalizedString(@"Would you like to install %@ in your applications folder before quitting?", @"Would you like to install App Name in your applications folder before quitting?"), appName]; |
|
43 alert = [[NSAlert alertWithMessageText:title |
|
44 defaultButton:NSLocalizedString(@"Install", @"Install") |
|
45 alternateButton:NSLocalizedString(@"Don't Install", @"Don't Install") |
|
46 otherButton:nil |
|
47 informativeTextWithFormat:body] retain]; |
|
48 //[alert setShowsSuppressionButton:YES]; |
|
49 } |
|
50 return self; |
|
51 } |
|
52 |
|
53 -(void) displayInstaller { |
|
54 NSString *imageFilePath = [[[NSWorkspace sharedWorkspace] propertiesForPath:[[NSBundle mainBundle] bundlePath]] objectForKey:NSWorkspace_RBimagefilepath]; |
|
55 if (imageFilePath && ![imageFilePath isEqualToString:[NSString stringWithFormat:@"/Users/.%@/%@.sparseimage", NSUserName(), NSUserName()]] && ![[NSUserDefaults standardUserDefaults] boolForKey:@"M3DontAskInstallAgain"]) { |
|
56 NSInteger returnValue = [alert runModal]; |
|
57 if (returnValue == NSAlertDefaultReturn) { |
|
58 [self installApp]; |
|
59 } |
|
60 if ([NSAlert instancesRespondToSelector:@selector(suppressionButton)]) |
|
61 if ([[alert performSelector:@selector(suppressionButton)] state] == NSOnState) |
|
62 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"M3DontAskInstallAgain"]; |
|
63 } |
|
64 } |
|
65 |
|
66 -(void) installApp { |
|
67 NSString *appsPath = [[NSString stringWithString:@"/Applications"] stringByAppendingPathComponent:[[[NSBundle mainBundle] bundlePath] lastPathComponent]]; |
|
68 NSString *userAppsPath = [[[NSString stringWithString:@"~/Applications"] stringByAppendingPathComponent:[[[NSBundle mainBundle] bundlePath] lastPathComponent]] stringByExpandingTildeInPath]; |
|
69 NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; |
|
70 NSString *currentPath = [[NSBundle mainBundle] bundlePath]; |
|
71 NSString *finalPath; |
|
72 NSError *error = nil; |
|
73 BOOL success; |
|
74 |
|
75 // Prepare the remove invocation |
|
76 SEL removeSelector; |
|
77 if ([NSFileManager instancesRespondToSelector:@selector(removeItemAtPath:error:)]) |
|
78 removeSelector = @selector(removeItemAtPath:error:); |
|
79 else |
|
80 removeSelector = @selector(removeFileAtPath:handler:); |
|
81 |
|
82 NSMethodSignature *removeSignature = [NSFileManager instanceMethodSignatureForSelector:removeSelector]; |
|
83 NSInvocation *removeInvocation = [NSInvocation invocationWithMethodSignature:removeSignature]; |
|
84 [removeInvocation setTarget:[NSFileManager defaultManager]]; |
|
85 [removeInvocation setSelector:removeSelector]; |
|
86 |
|
87 // Delete the app if already installed |
|
88 if ([[NSFileManager defaultManager] fileExistsAtPath:appsPath]) { |
|
89 [removeInvocation setArgument:&appsPath atIndex:2]; |
|
90 [removeInvocation setArgument:&error atIndex:3]; |
|
91 [removeInvocation invoke]; |
|
92 } |
|
93 |
|
94 // Prepare the copy invocation |
|
95 SEL copySelector; |
|
96 if ([NSFileManager instancesRespondToSelector:@selector(copyItemAtPath:toPath:error:)]) |
|
97 copySelector = @selector(copyItemAtPath:toPath:error:); |
|
98 else |
|
99 copySelector = @selector(copyPath:toPath:handler:); |
|
100 |
|
101 NSMethodSignature *copySignature = [NSFileManager instanceMethodSignatureForSelector:copySelector]; |
|
102 NSInvocation *copyInvocation = [NSInvocation invocationWithMethodSignature:copySignature]; |
|
103 |
|
104 [copyInvocation setTarget:[NSFileManager defaultManager]]; |
|
105 [copyInvocation setSelector:copySelector]; |
|
106 |
|
107 // Copy the app in /Applications |
|
108 [copyInvocation setArgument:¤tPath atIndex:2]; |
|
109 [copyInvocation setArgument:&appsPath atIndex:3]; |
|
110 [copyInvocation setArgument:&error atIndex:4]; |
|
111 [copyInvocation invoke]; |
|
112 [copyInvocation getReturnValue:&success]; |
|
113 finalPath = @"/Applications"; |
|
114 |
|
115 // In case something went wrong, let's try again somewhere else |
|
116 if (success == NO) { |
|
117 // Delete the app if already installed |
|
118 if ([[NSFileManager defaultManager] fileExistsAtPath:userAppsPath]) { |
|
119 [removeInvocation setArgument:&userAppsPath atIndex:2]; |
|
120 [removeInvocation invoke]; |
|
121 } |
|
122 |
|
123 // Copy the app in ~/Applications |
|
124 [copyInvocation setArgument:&userAppsPath atIndex:3]; |
|
125 [copyInvocation invoke]; |
|
126 [copyInvocation getReturnValue:&success]; |
|
127 finalPath = [[NSString stringWithString:@"~/Applications"] stringByExpandingTildeInPath]; |
|
128 } |
|
129 |
|
130 if (success) |
|
131 NSRunAlertPanel([NSString stringWithFormat:NSLocalizedString(@"%@ installed successfully", @"successful installation title"), appName], |
|
132 [NSString stringWithFormat:NSLocalizedString(@"%@ was installed in %@", @"successfull installation text"), appName, finalPath], |
|
133 NSLocalizedString(@"Ok", @"ok message"), nil, nil); |
|
134 else |
|
135 NSRunAlertPanel([NSString stringWithFormat:NSLocalizedString(@"Could not install %@", @"installation failure title"), appName], |
|
136 NSLocalizedString(@"An error occurred when installing", @"installation failure text"), |
|
137 NSLocalizedString(@"Quit", @"exit message"), nil, nil); |
|
138 } |
|
139 |
|
140 @end |