OSDN Git Service

UIを調整
[kcd/KCD.git] / KCD / HMScreenshotWindowController.m
1 //
2 //  HMScreenshotWindowController.m
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2014/04/06.
6 //  Copyright (c) 2014年 Hori,Masaki. All rights reserved.
7 //
8
9 #import "HMScreenshotWindowController.h"
10 #import "HMUserDefaults.h"
11 #import "HMMaskSelectView.h"
12 #import "HMMaskInfomation.h"
13
14 #import "HMAppDelegate.h"
15
16 #import <Accounts/Accounts.h>
17 #import <Social/Social.h>
18
19
20 @interface NSFileManager (KCDExtension)
21 - (NSString *)_web_pathWithUniqueFilenameForPath:(NSString *)path;
22 @end
23
24 @interface HMScreenshotWindowController ()
25
26 @property (readonly) NSData *snapData;
27 @property (strong) NSImage *snap;
28
29
30 @property (strong) ACAccountStore *accountStore;
31 @property BOOL availableTwitter;
32 @property NSInteger shortURLLength;
33
34
35 - (void)postImage:(NSData *)jpeg withStatus:(NSString *)status;
36 @end
37
38 @implementation HMScreenshotWindowController
39 @synthesize snapImageRep = _snapImageRep;
40 @synthesize snap = _snap;
41 @synthesize appendKanColleTag = _appendKanColleTag;
42 @synthesize useMask = _useMask;
43
44 + (NSSet *)keyPathsForValuesAffectingLeaveLength
45 {
46         return [NSSet setWithObjects:@"tweetString", @"appendKanColleTag", nil];
47 }
48 + (NSSet *)keyPathsForValuesAffectingLeaveLengthColor
49 {
50         return [NSSet setWithObject:@"leaveLength"];
51 }
52 + (NSSet *)keyPathsForValuesAffectingSnap
53 {
54         return [NSSet setWithObject:@"snapData"];
55 }
56 + (NSSet *)keyPathsForValuesAffectingCanTweet
57 {
58         return [NSSet setWithObject:@"leaveLength"];
59 }
60
61 - (id)init
62 {
63         self = [super initWithWindowNibName:NSStringFromClass([self class])];
64         if(self) {
65                 _accountStore = [ACAccountStore new];
66                 
67                 [self checkShortURLLength];
68                 
69                 NSString *tag = NSLocalizedString(@"kancolle", @"kancolle twitter hash tag");
70                 if(tag) {
71                         _tagString = [NSString stringWithFormat:@" #%@", tag];
72                 } else {
73                         _tagString = @"";
74                 }
75                 _appendKanColleTag = HMStandardDefaults.appendKanColleTag;
76                 
77                 self.tweetString = @"";
78                 
79                 _useMask = HMStandardDefaults.useMask;
80         }
81         return self;
82 }
83
84 - (NSBitmapImageRep *)snapImageRep
85 {
86         return _snapImageRep;
87 }
88 - (void)setSnapImageRep:(NSBitmapImageRep *)snapImageRep
89 {
90         _snapImageRep = snapImageRep;
91         self.snap = nil;
92 }
93
94 - (NSData *)snapData
95 {
96         NSBitmapImageRep *rep = self.snapImageRep;
97         
98         if(self.useMask) {
99                 NSImage *image = [[NSImage alloc] initWithSize:[self.snapImageRep size]];
100                 [image addRepresentation:self.snapImageRep];
101                 
102                 [image lockFocus];
103                 for(HMMaskInfomation *info in self.maskSelectView.masks) {
104                         if(info.enable) {
105                                 NSBezierPath *path = [NSBezierPath bezierPathWithRect:info.maskRect];
106                                 [info.maskColor set];
107                                 [path fill];
108                         }
109                 }
110                 [image unlockFocus];
111                 
112                 NSData *tiffData = [image TIFFRepresentation];
113                 rep = [NSBitmapImageRep imageRepWithData:tiffData];
114         }
115         
116         return [rep representationUsingType:NSJPEGFileType properties:nil];
117 }
118 - (NSImage *)snap
119 {
120         if(_snap) return _snap;
121         
122         NSImage *image = [[NSImage alloc] initWithData:self.snapData];
123         _snap = image;
124         self.tweetString = @"";
125         
126         return _snap;
127 }
128 - (void)setSnap:(NSImage *)snap
129 {
130         _snap = snap;
131 }
132 - (BOOL)useMask
133 {
134         return _useMask;
135 }
136 - (void)setUseMask:(BOOL)useMask
137 {
138         HMStandardDefaults.useMask = useMask;
139         _useMask = useMask;
140 }
141 - (NSInteger)leaveLength
142 {
143         const NSUInteger maxTweetLength = 140;
144         if(self.appendKanColleTag) return maxTweetLength - self.tagString.length - self.shortURLLength - self.tweetString.length;
145         return maxTweetLength - self.shortURLLength - self.tweetString.length;
146 }
147 - (NSColor *)leaveLengthColor
148 {
149         if(self.leaveLength < 0) {
150                 return [NSColor colorWithCalibratedRed:159/255.0 green:14/255.0 blue:0 alpha:1];
151         }
152         return [NSColor controlTextColor];
153 }
154 - (BOOL)appendKanColleTag
155 {
156         return _appendKanColleTag;
157 }
158 - (void)setAppendKanColleTag:(BOOL)appendKanColleTag
159 {
160         HMStandardDefaults.appendKanColleTag = appendKanColleTag;
161         _appendKanColleTag = appendKanColleTag;
162 }
163 - (BOOL)canTweet
164 {
165         ACAccountType *twitterType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
166         if(![twitterType accessGranted]) {
167                 [self.accountStore requestAccessToAccountsWithType:twitterType
168                                                                                                    options:nil
169                                                                                                 completion:^(BOOL granted, NSError *error) {
170                                                                                                         if(!granted) {
171                                                                                                                 NSLog(@"No access granted");
172                                                                                                         } else {
173 //                                                                                                              NSLog(@"succsess");
174                                                                                                         }
175                                                                                                 }];
176         }
177         NSArray *accounts = [self.accountStore accountsWithAccountType:twitterType];
178         if([accounts count] == 0) {
179                 NSLog(@"twitter account not avail.");
180                 NSLog(@"Accounts -> %@", self.accountStore.accounts);
181                 return NO;
182         }
183         self.availableTwitter = YES;
184         
185         return self.availableTwitter && self.leaveLength >= 0;
186 }
187 - (BOOL)canSave
188 {
189         return self.snapData ? YES : NO;
190 }
191
192 - (NSURL *)saveDirectoryURL
193 {
194     HMAppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
195         return [NSURL fileURLWithPath:appDelegate.screenShotSaveDirectory];
196 }
197
198 - (IBAction)tweet:(id)sender
199 {
200         if(!self.snapData) {
201                 NSBeep();
202                 return;
203         }
204         
205         NSString *status = self.tweetString;
206         if(!status) status = @"";
207         if(self.appendKanColleTag) {
208                 status = [status stringByAppendingString:self.tagString];
209         }
210         
211         if(self.leaveLength >= 0) {
212                 [self postImage:self.snapData withStatus:status];
213                 [self.window.sheetParent endSheet:self.window returnCode:NSOKButton + 1];
214         } else {
215                 NSBeep();
216         }
217 }
218
219 - (IBAction)saveSnap:(id)sender
220 {
221         [self.window.sheetParent endSheet:self.window returnCode:NSOKButton + 0];
222         
223         if(!self.snapData) return;
224         
225         NSBundle *mainBundle = [NSBundle mainBundle];
226         NSDictionary *infoList = [mainBundle localizedInfoDictionary];
227         NSString *filename = [infoList objectForKey:@"CFBundleName"];
228         if([filename length] == 0) {
229                 filename = @"KCD";
230         }
231         filename = [filename stringByAppendingPathExtension:@"jpg"];
232         NSURL *path = [[self saveDirectoryURL] URLByAppendingPathComponent:filename];
233         
234         filename = [[NSFileManager defaultManager] _web_pathWithUniqueFilenameForPath:[path path]];
235         
236         [self.snapData writeToFile:filename atomically:YES];
237 }
238 - (IBAction)cancel:(id)sender
239 {
240         [self.window.sheetParent endSheet:self.window returnCode:NSCancelButton];
241 }
242 - (void)postImage:(NSData *)jpeg withStatus:(NSString *)status
243 {
244         ACAccountType *twitterType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
245         
246         SLRequestHandler requestHandler =
247         ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
248                 if (responseData) {
249                         NSInteger statusCode = urlResponse.statusCode;
250                         if (statusCode >= 200 && statusCode < 300) {
251 //                              NSDictionary *postResponseData =
252 //                              [NSJSONSerialization JSONObjectWithData:responseData
253 //                                                                                              options:NSJSONReadingMutableContainers
254 //                                                                                                error:NULL];
255 //                              NSLog(@"[SUCCESS!] Created Tweet with ID: %@", postResponseData[@"id_str"]);
256                         }
257                         else {
258                                 NSLog(@"[ERROR] Server responded: status code %ld %@", statusCode,
259                                           [NSHTTPURLResponse localizedStringForStatusCode:statusCode]);
260                         }
261                 }
262                 else {
263                         NSLog(@"[ERROR] An error occurred while posting: %@", [error localizedDescription]);
264                 }
265         };
266         
267         ACAccountStoreRequestAccessCompletionHandler accountStoreHandler =
268         ^(BOOL granted, NSError *error) {
269                 if (granted) {
270                         NSArray *accounts = [self.accountStore accountsWithAccountType:twitterType];
271                         NSURL *url = [NSURL URLWithString:@"https://api.twitter.com"
272                                                   @"/1.1/statuses/update_with_media.json"];
273                         NSDictionary *params = @{@"status" : status};
274                         SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
275                                                                                                         requestMethod:SLRequestMethodPOST
276                                                                                                                           URL:url
277                                                                                                            parameters:params];
278                         [request addMultipartData:jpeg
279                                                          withName:@"media[]"
280                                                                  type:@"image/jpeg"
281                                                          filename:@"image.jpg"];
282                         [request setAccount:[accounts lastObject]];
283                         [request performRequestWithHandler:requestHandler];
284                 }
285                 else {
286                         NSLog(@"[ERROR] An error occurred while asking for user authorization: %@",
287                                   [error localizedDescription]);
288                 }
289         };
290         
291         [self.accountStore requestAccessToAccountsWithType:twitterType
292                                                                                            options:NULL
293                                                                                         completion:accountStoreHandler];
294 }
295
296 - (void)checkShortURLLength
297 {
298         ACAccountType *twitterType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
299         
300         SLRequestHandler requestHandler =
301         ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
302                 if (responseData) {
303                         NSInteger statusCode = urlResponse.statusCode;
304                         if (statusCode >= 200 && statusCode < 300) {
305                                 NSDictionary *postResponseData =
306                                 [NSJSONSerialization JSONObjectWithData:responseData
307                                                                                                 options:NSJSONReadingMutableContainers
308                                                                                                   error:NULL];
309 //                              NSLog(@"[SUCCESS!] characters_reserved_per_media is %@", postResponseData[@"characters_reserved_per_media"]);
310                                 
311                                 self.shortURLLength = [postResponseData[@"characters_reserved_per_media"] integerValue];
312                         }
313                         else {
314                                 NSLog(@"[ERROR] Server responded: status code %ld %@", statusCode,
315                                           [NSHTTPURLResponse localizedStringForStatusCode:statusCode]);
316                         }
317                 }
318                 else {
319                         NSLog(@"[ERROR] An error occurred while posting: %@", [error localizedDescription]);
320                 }
321         };
322         
323         ACAccountStoreRequestAccessCompletionHandler accountStoreHandler =
324         ^(BOOL granted, NSError *error) {
325                 if (granted) {
326                         NSArray *accounts = [self.accountStore accountsWithAccountType:twitterType];
327                         NSURL *url = [NSURL URLWithString:@"https://api.twitter.com"
328                                                   @"/1.1/help/configuration.json"];
329                         SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
330                                                                                                         requestMethod:SLRequestMethodGET
331                                                                                                                           URL:url
332                                                                                                            parameters:nil];
333                         [request setAccount:[accounts lastObject]];
334                         [request performRequestWithHandler:requestHandler];
335                 }
336                 else {
337                         NSLog(@"[ERROR] An error occurred while asking for user authorization: %@",
338                                   [error localizedDescription]);
339                 }
340         };
341         
342         [self.accountStore requestAccessToAccountsWithType:twitterType
343                                                                                            options:NULL
344                                                                                         completion:accountStoreHandler];
345         
346 }
347
348
349 /**
350  NSControl delegate
351  */
352 - (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector
353 {
354     BOOL result = NO;
355     if (commandSelector == @selector(insertNewline:))
356     {
357         [textView insertNewlineIgnoringFieldEditor:self];
358         result = YES;
359     }
360     return result;
361 }
362
363 /**
364  *  NSWindow delegate
365  */
366 - (void)windowWillClose:(NSNotification *)notification
367 {
368         [self.maskSelectView disableAllMasks:self];
369 }
370
371 @end