|
7 | 7 | //
|
8 | 8 |
|
9 | 9 | #import "AppDelegate.h"
|
10 |
| -#import "DragDropView.h" |
11 |
| -#import <QuartzCore/QuartzCore.h> |
12 |
| - |
13 |
| -@interface AppDelegate () |
14 |
| - |
15 |
| -// Jup, i know this all shoud be in neat UIWindows and stuff, i'm going to refractor the code soon. |
16 |
| - |
17 |
| -@property (nonatomic, retain) IBOutlet NSLayoutConstraint *topDragConstraint; |
18 |
| -@property (nonatomic, retain) IBOutlet NSLayoutConstraint *bottomDragConstraint; |
19 |
| -@property (nonatomic, retain) IBOutlet NSWindow *window; |
20 |
| -@property (nonatomic, retain) IBOutlet DragDropView *dropView; |
21 |
| - |
22 |
| -@property (nonatomic, retain) IBOutlet NSButton *settingsButton; |
23 |
| -@property (nonatomic, retain) IBOutlet NSTextField *jpegQualityField; |
24 |
| -@property (nonatomic, retain) IBOutlet NSStepper *jpegQualityStepper; |
25 |
| -@property (nonatomic, retain) IBOutlet NSButton *pngOutButton; |
26 |
| - |
27 |
| -@property (nonatomic, retain) IBOutlet NSProgressIndicator *loader; |
28 |
| - |
29 |
| -- (IBAction)checkForUpdates:(id)sender; |
30 |
| -- (IBAction)hitSettings:(id)sender; |
31 |
| -- (IBAction)stepperDidClick:(id)sender; |
32 |
| -- (IBAction)pngOutDidClick:(id)sender; |
33 |
| - |
34 |
| -@end |
35 | 10 |
|
36 | 11 | @implementation AppDelegate
|
37 | 12 |
|
38 |
| -@synthesize jpegQualityField, jpegQualityStepper, settingsButton, pngOutButton; |
39 |
| -@synthesize loader; |
| 13 | +@synthesize window; |
40 | 14 |
|
41 | 15 | - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
42 | 16 | {
|
43 |
| - return [self processFile:filename]; |
44 |
| -} |
45 |
| - |
46 |
| -- (BOOL)processFile:(NSString *)file |
47 |
| -{ |
48 |
| - [self.dropView checkFiles:@[file]]; |
49 |
| - |
50 |
| - return YES; // Return YES when file processed succesfull, else return NO. |
51 |
| -} |
52 |
| - |
53 |
| -- (IBAction)hitSettings:(id)sender |
54 |
| -{ |
55 |
| - if(self.bottomDragConstraint.animator.constant == 0){ |
56 |
| - [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { |
57 |
| - [context setDuration:0.2]; |
58 |
| - [context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; |
59 |
| - self.topDragConstraint.animator.constant = -105; |
60 |
| - self.bottomDragConstraint.animator.constant = 105; |
61 |
| - |
62 |
| - [settingsButton setTitle:@"Close"]; |
63 |
| - } completionHandler:^{ |
64 |
| - [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { |
65 |
| - [context setDuration:0.3]; |
66 |
| - [context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; |
67 |
| - self.topDragConstraint.animator.constant = -100; |
68 |
| - self.bottomDragConstraint.animator.constant = 100; |
69 |
| - } completionHandler:nil]; |
70 |
| - }]; |
71 |
| - } else{ |
72 |
| - [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { |
73 |
| - [context setDuration:0.15]; |
74 |
| - [context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]]; |
75 |
| - self.topDragConstraint.animator.constant = 5; |
76 |
| - self.bottomDragConstraint.animator.constant = -5; |
77 |
| - |
78 |
| - [settingsButton setTitle:@"Settings"]; |
79 |
| - } completionHandler:^{ |
80 |
| - [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { |
81 |
| - [context setDuration:0.2]; |
82 |
| - [context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]]; |
83 |
| - self.topDragConstraint.animator.constant = 0; |
84 |
| - self.bottomDragConstraint.animator.constant = 0; |
85 |
| - } completionHandler:nil]; |
86 |
| - }]; |
87 |
| - } |
88 |
| -} |
89 |
| - |
90 |
| -- (IBAction)stepperDidClick:(id)sender |
91 |
| -{ |
92 |
| - if([sender isKindOfClass:[NSStepper class]]){ |
93 |
| - NSStepper *stepper = (NSStepper *)sender; |
94 |
| - |
95 |
| - int stepperVal = MIN(MAX([stepper intValue], 1), 10); |
96 |
| - |
97 |
| - [jpegQualityField setStringValue:[NSString stringWithFormat:@"%i/10", stepperVal]]; |
98 |
| - |
99 |
| - [[NSUserDefaults standardUserDefaults] setInteger:stepperVal forKey:@"jpegQuality"]; |
100 |
| - [[NSUserDefaults standardUserDefaults] synchronize]; |
101 |
| - } |
102 |
| -} |
103 |
| - |
104 |
| -- (IBAction)pngOutDidClick:(id)sender |
105 |
| -{ |
106 |
| - [[NSUserDefaults standardUserDefaults] setInteger:[(NSButton *)sender state] forKey:@"pngOut"]; |
107 |
| - [[NSUserDefaults standardUserDefaults] synchronize]; |
108 |
| -} |
109 |
| - |
110 |
| -- (IBAction)checkForUpdates:(id)sender |
111 |
| -{ |
112 |
| - AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; |
113 |
| - manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //to bad github gives the raw content as plain text |
114 |
| - manager.requestSerializer = [AFHTTPRequestSerializer serializer]; //otherwise this would have been AFPlistResponse / requestserializers |
115 |
| - |
116 |
| - [manager GET:@"https://raw.githubusercontent.com/terwanerik/Retini/master/Retini/Info.plist" |
117 |
| - parameters:nil |
118 |
| - success:^(AFHTTPRequestOperation *operation, id responseObject) { |
119 |
| - [self checkPlist:responseObject andOrigin:sender]; |
120 |
| - } |
121 |
| - failure:^(AFHTTPRequestOperation *operation, NSError *error) { |
122 |
| - // just leave it be. |
123 |
| - }]; |
124 |
| -} |
125 |
| - |
126 |
| -- (void)checkPlist:(NSData *)plistData andOrigin:(id)sender |
127 |
| -{ |
128 |
| - NSString *error; |
129 |
| - NSPropertyListFormat format; |
130 |
| - NSDictionary *plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error]; |
131 |
| - |
132 |
| - // remove dots to get big number. Versioning will never go beyond 10 so should work fine atm. |
133 |
| - int onlineVersion = [[[plist objectForKey:@"CFBundleShortVersionString"] stringByReplacingOccurrencesOfString:@"." withString:@""] intValue]; |
134 |
| - int myVersion = [[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] stringByReplacingOccurrencesOfString:@"." withString:@""] intValue]; |
135 |
| - |
136 |
| - if(onlineVersion > myVersion){ |
137 |
| - NSAlert *newVersionAlert = [[NSAlert alloc] init]; |
138 |
| - [newVersionAlert setMessageText:@"A new version of Retini is found. Would you like to download the update?"]; |
139 |
| - [newVersionAlert addButtonWithTitle:@"Update"]; |
140 |
| - [newVersionAlert addButtonWithTitle:@"Cancel"]; |
141 |
| - [newVersionAlert setDelegate:self]; |
142 |
| - [newVersionAlert beginSheetModalForWindow:self.window |
143 |
| - modalDelegate:self |
144 |
| - didEndSelector:@selector(alertButtonClicked:returnCode:contextInfo:) |
145 |
| - contextInfo:nil]; |
146 |
| - } else if(sender != nil){ |
147 |
| - NSAlert *newVersionAlert = [[NSAlert alloc] init]; |
148 |
| - [newVersionAlert setMessageText:@"No new version is found.. Check GitHub to be sure?"]; |
149 |
| - [newVersionAlert addButtonWithTitle:@"GitHub? Letsgo!"]; |
150 |
| - [newVersionAlert addButtonWithTitle:@"I'm good."]; |
151 |
| - [newVersionAlert setDelegate:nil]; |
152 |
| - [newVersionAlert beginSheetModalForWindow:self.window |
153 |
| - modalDelegate:self |
154 |
| - didEndSelector:@selector(alertButtonClicked:returnCode:contextInfo:) |
155 |
| - contextInfo:nil]; |
156 |
| - } |
157 |
| -} |
158 |
| - |
159 |
| -- (void)alertButtonClicked:(NSAlert *)alert |
160 |
| - returnCode:(int)returnCode |
161 |
| - contextInfo:(void *)contextInfo |
162 |
| -{ |
163 |
| - if(returnCode == 1000){ |
164 |
| - if(alert.delegate == self){ |
165 |
| - //[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://github.com/terwanerik/Retini/raw/master/Retini.zip"]]; |
166 |
| - |
167 |
| - [self downloadNewZip]; |
168 |
| - } else{ |
169 |
| - [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://github.com/terwanerik/Retini"]]; |
170 |
| - } |
171 |
| - } |
172 |
| -} |
173 |
| - |
174 |
| -- (void)downloadNewZip |
175 |
| -{ |
176 |
| - [loader startAnimation:nil]; |
177 |
| - |
178 |
| - AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; |
179 |
| - manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //to bad github gives the raw content as plain text |
180 |
| - manager.requestSerializer = [AFHTTPRequestSerializer serializer]; //otherwise this would have been AFPlistResponse / requestserializers |
181 |
| - |
182 |
| - [manager GET:@"https://github.com/terwanerik/Retini/raw/master/Retini.zip" |
183 |
| - parameters:nil |
184 |
| - success:^(AFHTTPRequestOperation *operation, id responseObject) { |
185 |
| - [self installZip:responseObject]; |
186 |
| - } |
187 |
| - failure:^(AFHTTPRequestOperation *operation, NSError *error) { |
188 |
| - NSAlert *newVersionAlert = [[NSAlert alloc] init]; |
189 |
| - [newVersionAlert setMessageText:@"Couldn't download new version. Would you like to download it straight from GitHub?"]; |
190 |
| - [newVersionAlert addButtonWithTitle:@"GitHub? Letsgo!"]; |
191 |
| - [newVersionAlert addButtonWithTitle:@"I'm good."]; |
192 |
| - [newVersionAlert setDelegate:nil]; |
193 |
| - [newVersionAlert beginSheetModalForWindow:self.window |
194 |
| - modalDelegate:self |
195 |
| - didEndSelector:@selector(alertButtonClicked:returnCode:contextInfo:) |
196 |
| - contextInfo:nil]; |
197 |
| - }]; |
198 |
| -} |
199 |
| - |
200 |
| -- (void)installZip:(NSData *)zip |
201 |
| -{ |
202 |
| - NSString *filePath = [NSString stringWithFormat:@"%@/Retini.zip", NSTemporaryDirectory()]; |
203 |
| - |
204 |
| - if([[NSFileManager defaultManager] createFileAtPath:filePath |
205 |
| - contents:zip |
206 |
| - attributes:nil]){ |
207 |
| - |
208 |
| - NSTask *task = [[NSTask alloc] init]; |
209 |
| - [task setLaunchPath:@"/usr/bin/unzip"]; |
210 |
| - [task setCurrentDirectoryPath:NSTemporaryDirectory()]; |
211 |
| - [task setArguments:@[@"-o", @"Retini.zip"]]; |
212 |
| - [task launch]; |
213 |
| - [task waitUntilExit]; |
214 |
| - |
215 |
| - [loader stopAnimation:nil]; |
216 |
| - |
217 |
| - NSError *error; |
218 |
| - [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]; |
219 |
| - |
220 |
| - if(!error){ |
221 |
| - [[NSFileManager defaultManager] moveItemAtPath:[NSString stringWithFormat:@"%@/Retini.app", NSTemporaryDirectory()] |
222 |
| - toPath:@"/Applications/Retini_tmp.app" |
223 |
| - error:&error]; |
224 |
| - |
225 |
| - [self relaunchAfterDelay:1.0]; |
226 |
| - } |
227 |
| - } |
228 |
| -} |
229 |
| - |
230 |
| -- (void)relaunchAfterDelay:(float)seconds |
231 |
| -{ |
232 |
| - NSTask *task = [[NSTask alloc] init]; |
233 |
| - NSMutableArray *args = [NSMutableArray array]; |
234 |
| - [args addObject:@"-c"]; |
235 |
| - [args addObject:[NSString stringWithFormat:@"sleep %f; open \"%@\"", seconds, @"/Applications/Retini.app"]]; |
236 |
| - [task setLaunchPath:@"/bin/sh"]; |
237 |
| - [task setArguments:args]; |
238 |
| - [task launch]; |
239 |
| - |
240 |
| - NSError *error; |
241 |
| - |
242 |
| - if([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Retini.app"]){ |
243 |
| - [[NSFileManager defaultManager] removeItemAtPath:@"/Applications/Retini.app" error:&error]; |
244 |
| - } |
245 |
| - |
246 |
| - if(!error){ |
247 |
| - [[NSFileManager defaultManager] moveItemAtPath:@"/Applications/Retini_tmp.app" |
248 |
| - toPath:@"/Applications/Retini.app" |
249 |
| - error:&error]; |
250 |
| - |
251 |
| - [[NSApplication sharedApplication] terminate:nil]; |
252 |
| - } |
253 |
| -} |
254 |
| - |
255 |
| -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { |
256 |
| - [self checkForUpdates:nil]; |
257 |
| - |
258 |
| - if([[NSUserDefaults standardUserDefaults] integerForKey:@"jpegQuality"]){ |
259 |
| - [jpegQualityStepper setDoubleValue:[[NSUserDefaults standardUserDefaults] integerForKey:@"jpegQuality"]]; |
260 |
| - } |
261 |
| - |
262 |
| - if([[NSUserDefaults standardUserDefaults] integerForKey:@"pngOut"]){ |
263 |
| - [pngOutButton setState:[[NSUserDefaults standardUserDefaults] integerForKey:@"pngOut"]]; |
264 |
| - } |
265 |
| - |
266 |
| - int stepperVal = MIN(MAX([jpegQualityStepper intValue], 1), 10); |
267 |
| - |
268 |
| - [jpegQualityStepper setAlphaValue:0.7]; |
269 |
| - [jpegQualityField setStringValue:[NSString stringWithFormat:@"%i/10", stepperVal]]; |
270 |
| - |
271 |
| - [settingsButton setTarget:self]; |
272 |
| - [settingsButton setAction:@selector(hitSettings:)]; |
273 |
| - |
274 |
| - NSColor *color = [NSColor colorWithWhite:1.0 alpha:0.8]; |
275 |
| - NSMutableAttributedString *colorTitle = [[NSMutableAttributedString alloc] initWithAttributedString:[pngOutButton attributedTitle]]; |
276 |
| - NSRange titleRange = NSMakeRange(0, [colorTitle length]); |
277 |
| - [colorTitle addAttribute:NSForegroundColorAttributeName value:color range:titleRange]; |
278 |
| - [pngOutButton setAttributedTitle:colorTitle]; |
279 |
| - |
280 |
| - [self.window setBackgroundColor:[NSColor colorWithWhite:0.08 alpha:1.0]]; |
| 17 | + return [window processFile:filename]; |
281 | 18 | }
|
282 | 19 |
|
283 | 20 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
|
|
0 commit comments