Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 539 lines (453 sloc) 22.236 kb
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
1 //
2 // PreviewController.m
3 // Notation
4 //
5 // Created by Christian Tietze on 15.10.10.
6 // Copyright 2010
7
8 #import "PreviewController.h"
9 #import "AppController.h" // TODO for the defines only, can you get around that?
10 #import "AppController_Preview.h"
11 #import "NSString_MultiMarkdown.h"
12 #import "NSString_Markdown.h"
13 #import "NSString_Textile.h"
14
15 #define kDefaultMarkupPreviewVisible @"markupPreviewVisible"
16
17 @interface NSString (MIMEAdditions)
18 + (NSString*)MIMEBoundary;
19 + (NSString*)multipartMIMEStringWithDictionary:(NSDictionary*)dict;
20 @end
21
22 @implementation NSString (MIMEAdditions)
23 //this returns a unique boundary which is used in constructing the multipart MIME body of the POST request
24 + (NSString*)MIMEBoundary
25 {
26 static NSString* MIMEBoundary = nil;
27 if(!MIMEBoundary)
28 MIMEBoundary = [[NSString alloc] initWithFormat:@"----_=_nvALT_%@_=_----",[[NSProcessInfo processInfo] globallyUniqueString]];
29 return MIMEBoundary;
30 }
31 //this create a correctly structured multipart MIME body for the POST request from a dictionary
32 + (NSString*)multipartMIMEStringWithDictionary:(NSDictionary*)dict
33 {
34 NSMutableString* result = [NSMutableString string];
35 for (NSString* key in dict)
36 {
37 [result appendFormat:@"--%@\nContent-Disposition: form-data; name=\"%@\"\n\n%@\n",[NSString MIMEBoundary],key,[dict objectForKey:key]];
38 }
39 [result appendFormat:@"\n--%@--\n",[NSString MIMEBoundary]];
40 return result;
41 }
42 @end
43
44 @implementation PreviewController
45
46 @synthesize preview;
47 @synthesize isPreviewOutdated;
48
49 +(void)initialize
50 {
51 NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
52 forKey:kDefaultMarkupPreviewVisible];
53
54 [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
55 }
56
57 -(id)init
58 {
59 if ((self = [super initWithWindowNibName:@"MarkupPreview" owner:self])) {
60 self.isPreviewOutdated = YES;
61 [[self class] createCustomFiles];
62 BOOL showPreviewWindow = [[NSUserDefaults standardUserDefaults] boolForKey:kDefaultMarkupPreviewVisible];
63 if (showPreviewWindow) {
64 [[self window] orderFront:self];
65 }
66 [sourceView setTextContainerInset:NSMakeSize(20,20)];
67 [tabView selectTabViewItem:[tabView tabViewItemAtIndex:0]];
68 [tabSwitcher setTitle:@"View Source"];
69 // [preview setPolicyDelegate:self];
70 // [preview setUIDelegate:self];
71 }
72 return self;
73 }
74
75 -(void)awakeFromNib
76 {
77 AppController *app = [[NSApplication sharedApplication] delegate];;
78 cssString = [[[self class] css] retain];
79 htmlString = [[[self class] html] retain];
80 lastNote = [app selectedNoteObject];
81 }
82
618ccb9 @ttscoff Added the ability to use Cocoa.log from JavaScript in the Preview win…
ttscoff authored
83 //this returns a nice name for the method in the JavaScript environment
84 +(NSString*)webScriptNameForSelector:(SEL)sel
85 {
86 if(sel == @selector(logJavaScriptString:))
87 return @"log";
88 return nil;
89 }
90
91 //this allows JavaScript to call the -logJavaScriptString: method
92 + (BOOL)isSelectorExcludedFromWebScript:(SEL)sel
93 {
94 if(sel == @selector(logJavaScriptString:))
95 return NO;
96 return YES;
97 }
98
99 //this is a simple log command
100 - (void)logJavaScriptString:(NSString*) logText
101 {
102 NSLog(@"JavaScript: %@",logText);
103 }
104
105 //this is called as soon as the script environment is ready in the webview
106 - (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowScriptObject forFrame:(WebFrame *)frame
107 {
108 //add the controller to the script environment
109 //the "Cocoa" object will now be available to JavaScript
110 [windowScriptObject setValue:self forKey:@"Cocoa"];
111 }
112
113 // Above webView methods from <http://stackoverflow.com/questions/2288582/embedded-webkit-script-callbacks-how/2293305#2293305>
114
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
115 - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener {
116 NSString *targetURL = [[request URL] scheme];
117
118 if ([targetURL isEqual:@"http"]) {
119 [[NSWorkspace sharedWorkspace] openURL:[request URL]];
120 [listener ignore];
121 } else {
122 [listener use];
123 }
124 }
125
126 - (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id<WebPolicyDecisionListener>)listener {
127 NSLog(@"NEW WIN ACTION SENDER: %@",sender);
128 [[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]];
129 [listener ignore];
130 }
131
132 -(void)requestPreviewUpdate:(NSNotification *)notification
133 {
134 if (![[self window] isVisible]) {
135 self.isPreviewOutdated = YES;
136 return;
137 }
138
139 AppController *app = [notification object];
140 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(preview:) object:app];
141
142 [self performSelector:@selector(preview:) withObject:app afterDelay:0.5];
143 }
144
145 -(void)togglePreview:(id)sender
146 {
147 NSWindow *wnd = [self window];
148
149 if ([wnd isVisible]) {
150 if (attachedWindow) {
151 [[shareButton window] removeChildWindow:attachedWindow];
152 [attachedWindow orderOut:self];
153 [attachedWindow release];
154 attachedWindow = nil;
155 [shareURL release];
156 }
157 [wnd orderOut:self];
158 } else {
159 if (self.isPreviewOutdated) {
160 // TODO high coupling; too many assumptions on architecture:
161 [self performSelector:@selector(preview:) withObject:[[NSApplication sharedApplication] delegate] afterDelay:0.0];
162 }
163 [tabView selectTabViewItem:[tabView tabViewItemAtIndex:0]];
164 [tabSwitcher setTitle:@"View Source"];
165
166 [wnd orderFront:self];
dfe1eb2 @ttscoff Fullscreen refinements
ttscoff authored
167 [wnd setLevel:NSScreenSaverWindowLevel];
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
168 }
169
170 // save visibility to defaults
171 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:[wnd isVisible]]
172 forKey:kDefaultMarkupPreviewVisible];
173 }
174
175 -(void)windowWillClose:(NSNotification *)notification
176 {
177 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO]
178 forKey:kDefaultMarkupPreviewVisible];
179 }
180
181 +(NSString*)css {
182 NSFileManager *mgr = [NSFileManager defaultManager];
183
184 NSString *folder = @"~/Library/Application Support/Notational Velocity/";
185 folder = [folder stringByExpandingTildeInPath];
186 NSString *cssFileName = @"custom.css";
187 NSString *customCSSPath = [folder stringByAppendingPathComponent: cssFileName];
188
189 if (![mgr fileExistsAtPath:customCSSPath]) {
190 [[self class] createCustomFiles];
191 }
192 return [NSString stringWithContentsOfFile:customCSSPath
193 encoding:NSUTF8StringEncoding
194 error:NULL];
195
196 }
197
198 +(NSString*)html {
199 NSFileManager *mgr = [NSFileManager defaultManager];
200
201 NSString *folder = @"~/Library/Application Support/Notational Velocity/";
202 folder = [folder stringByExpandingTildeInPath];
203 NSString *htmlFileName = @"template.html";
204 NSString *customHTMLPath = [folder stringByAppendingPathComponent: htmlFileName];
205
206 if (![mgr fileExistsAtPath:customHTMLPath]) {
207 [[self class] createCustomFiles];
208 }
209 return [NSString stringWithContentsOfFile:customHTMLPath
210 encoding:NSUTF8StringEncoding
211 error:NULL];
212 }
213
214 -(void)preview:(id)object
215 {
216 NSString *lastScrollPosition = [[preview windowScriptObject] evaluateWebScript:@"document.getElementById('contentdiv').scrollTop"];
19e583c @ttscoff Big commit, sorry.
ttscoff authored
217 AppController *app = object;
218 NSString *rawString = [app noteContent];
219 SEL mode = [self markupProcessorSelector:[app currentPreviewMode]];
220 NSString *processedString = [NSString performSelector:mode withObject:rawString];
a0befe3 @ttscoff Switched bundle id and preference file out to avoid conflict during d…
ttscoff authored
221 NSString *previewString = processedString;
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
222 NSMutableString *outputString = [NSMutableString stringWithString:(NSString *)htmlString];
223 NSString *noteTitle = ([app selectedNoteObject]) ? [NSString stringWithFormat:@"%@",titleOfNote([app selectedNoteObject])] : @"";
224
225 if (lastNote == [app selectedNoteObject]) {
9925a38 @ttscoff Removed forgotten closing body tag in scroll position script inject.
ttscoff authored
226 NSString *restoreScrollPosition = [NSString stringWithFormat:@"\n<script>window.onload = function(){var div = document.getElementById('contentdiv'),oldscroll = %@;div.scrollTop = oldscroll;}</script>",lastScrollPosition];
a0befe3 @ttscoff Switched bundle id and preference file out to avoid conflict during d…
ttscoff authored
227 previewString = [processedString stringByAppendingString:restoreScrollPosition];
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
228 } else {
9925a38 @ttscoff Removed forgotten closing body tag in scroll position script inject.
ttscoff authored
229 [cssString release];
230 [htmlString release];
231 cssString = [[[self class] css] retain];
232 htmlString = [[[self class] html] retain];
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
233 lastNote = [app selectedNoteObject];
234 }
9925a38 @ttscoff Removed forgotten closing body tag in scroll position script inject.
ttscoff authored
235 NSString *nvSupportPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/Notational Velocity"];
236 [outputString replaceOccurrencesOfString:@"{%support%}" withString:nvSupportPath options:0 range:NSMakeRange(0, [outputString length])];
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
237 [outputString replaceOccurrencesOfString:@"{%title%}" withString:noteTitle options:0 range:NSMakeRange(0, [outputString length])];
a0befe3 @ttscoff Switched bundle id and preference file out to avoid conflict during d…
ttscoff authored
238 [outputString replaceOccurrencesOfString:@"{%content%}" withString:previewString options:0 range:NSMakeRange(0, [outputString length])];
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
239 [outputString replaceOccurrencesOfString:@"{%style%}" withString:cssString options:0 range:NSMakeRange(0, [outputString length])];
240
19e583c @ttscoff Big commit, sorry.
ttscoff authored
241 [[preview mainFrame] loadHTMLString:outputString baseURL:nil];
242 [sourceView replaceCharactersInRange:NSMakeRange(0, [[sourceView string] length]) withString:processedString];
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
243 self.isPreviewOutdated = NO;
244 }
245
246 -(SEL)markupProcessorSelector:(NSInteger)previewMode
247 {
248 if (previewMode == MarkdownPreview) {
a3ee667 @ttscoff Removed Markdown from Preview options. MultiMarkdown will render a Ma…
ttscoff authored
249 previewMode = MultiMarkdownPreview;
250 return @selector(stringWithProcessedMultiMarkdown:);
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
251 } else if (previewMode == MultiMarkdownPreview) {
252 return @selector(stringWithProcessedMultiMarkdown:);
253 } else if (previewMode == TextilePreview) {
254 return @selector(stringWithProcessedTextile:);
255 }
256
257 return nil;
258 }
259
260 + (void) createCustomFiles
261 {
262 NSFileManager *fileManager = [NSFileManager defaultManager];
263
264 NSString *folder = @"~/Library/Application Support/Notational Velocity/";
265 folder = [folder stringByExpandingTildeInPath];
266 NSString *cssFileName = @"custom.css";
267 NSString *cssFile = [folder stringByAppendingPathComponent: cssFileName];
268
269 if ([fileManager fileExistsAtPath: folder] == NO)
270 {
271 [fileManager createDirectoryAtPath: folder attributes: nil];
272
273 }
274 if ([fileManager fileExistsAtPath:cssFile] == NO)
275 {
276 NSString *cssString = @"body,p,td,div { font-family:Helvetica,Arial,sans-serif;line-height:1.4em;font-size:14px;color:#111; }\np { margin:0 0 1.7em 0; }\na { color:rgb(13,110,161);text-decoration:none;-webkit-transition:color .2s ease-in-out; }\na:hover { color:#3593d9; }\nh1.doctitle { background:#eee;font-size:14px;font-weight:bold;color:#333;line-height:25px;margin:0;padding:0 10px;border-bottom:solid 1px #aaa; }\nh1 { font-size:24px;color:#000;margin:12px 0 15px 0; }\nh2 { font-size:20px;color:#111;width:auto;margin:15px 0 10px 2px; }\nh2 em { line-height:1.6em;font-size:12px;color:#111;text-shadow:0 1px 0 #FFF;padding-left:10px; }\nh3 { font-size:20px;color:#111; }\nh4 { font-size:14px;color:#111;margin-bottom:1.3em; }\n.footnote { font-size:.8em;vertical-align:super;color:rgb(13,110,161); }\n#wrapper { background:#fff;position:fixed;top:0;left:0;right:0;bottom:0;-webkit-box-shadow:inset 0px 0px 4px #8F8D87; }\n#contentdiv { position:fixed;top:27px;left:5px;right:5px;bottom:5px;background:transparent;color:#303030;overflow:auto;text-indent:0px;padding:10px; }\n#contentdiv::-webkit-scrollbar { width:6px; }\n#contentdiv::-webkit-scrollbar:horizontal { height:6px;display:none; }\n#contentdiv::-webkit-scrollbar-track { background:transparent;-webkit-border-radius:0;right:10px; }\n#contentdiv::-webkit-scrollbar-track:disabled { display:none; }\n#contentdiv::-webkit-scrollbar-thumb { border-width:0;min-height:20px;background:#777;opacity:0.4;-webkit-border-radius:5px; }";
277
278 NSData *cssData = [NSData dataWithBytes:[cssString UTF8String] length:[cssString length]];
279 [fileManager createFileAtPath:cssFile contents:cssData attributes:nil];
280 }
281
282 NSString *htmlFileName = @"template.html";
283 NSString *htmlFile = [folder stringByAppendingPathComponent: htmlFileName];
284
285 if ([fileManager fileExistsAtPath:htmlFile] == NO)
286 {
287 NSString *htmlString = @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN\"\n \"http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd\">\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n <head>\n <meta name=\"Format\" content=\"complete\" />\n <meta name=\"format\" content=\"complete\" />\n <style type=\"text/css\">{%style%}</style>\n </head>\n<body>\n <div id=\"wrapper\">\n <h1 class=\"doctitle\">{%title%}</h1>\n <div id=\"contentdiv\">\n {%content%}\n </div>\n </div>\n</body>\n</html>";
288
289 NSData *htmlData = [NSData dataWithBytes:[htmlString UTF8String] length:[htmlString length]];
290 [fileManager createFileAtPath:htmlFile contents:htmlData attributes:nil];
291 }
292
293 }
294
295 - (NSString *)urlEncodeValue:(NSString *)str
296 {
297 NSString *result = (NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, NULL, CFSTR("?=&+"), kCFStringEncodingUTF8);
298 return [result autorelease];
299 }
300
301
302 -(IBAction)shareNote:(id)sender
303 {
304 AppController *app = [[NSApplication sharedApplication] delegate];
305 NSString *noteTitle = [NSString stringWithFormat:@"%@",titleOfNote([app selectedNoteObject])];
306 NSString *rawString = [app noteContent];
307 SEL mode = [self markupProcessorSelector:[app currentPreviewMode]];
308 NSString *processedString = [NSString performSelector:mode withObject:rawString];
309
310
311 NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
312 initWithURL:
313 [NSURL URLWithString:@"http://peg.gd/nvapi.php"]];
314 [request setHTTPMethod:@"POST"];
315 [request addValue:@"8bit" forHTTPHeaderField:@"Content-Transfer-Encoding"];
316 [request addValue: [NSString stringWithFormat:@"multipart/form-data; boundary=%@",[NSString MIMEBoundary]] forHTTPHeaderField: @"Content-Type"];
317 NSDictionary* postData = [NSDictionary dictionaryWithObjectsAndKeys:
318 @"8c4205ec33d8f6caeaaaa0c10a14138c", @"key",
319 noteTitle, @"title",
320 processedString, @"body",
321 nil];
322 [request setHTTPBody: [[NSString multipartMIMEStringWithDictionary: postData] dataUsingEncoding: NSUTF8StringEncoding]];
323 NSHTTPURLResponse * response = nil;
324 NSError * error = nil;
325 NSData * responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
326 NSString * responseString = [[[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding] autorelease];
327 NSLog(@"RESPONSE STRING: %@", responseString);
328 NSLog(@"%d",response.statusCode);
329 shareURL = [[NSString stringWithString:responseString] retain];
330 if (response.statusCode == 200) {
331 [self showShareURL:[NSString stringWithFormat:@"View %@",shareURL] isError:NO];
332 } else {
333 [self showShareURL:@"Error connecting" isError:YES];
334 }
335
336 [request release];
337
338 }
339
340 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
341 {
342 [receivedData setLength:0];
343 }
344
345
346 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
347 {
348 [receivedData appendData:data];
349 }
350
351 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
352 {
353 NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
354
355 NSString * responseString = [[[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding] autorelease];
356 NSLog(@"RESPONSE STRING: %@", responseString);
357 [receivedData release];
358 }
359
19e583c @ttscoff Big commit, sorry.
ttscoff authored
360 - (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
361 if (returnCode == NSFileHandlingPanelOKButton) {
362
363 AppController *app = [[NSApplication sharedApplication] delegate];
364 NSString *rawString = [app noteContent];
365 NSString *processedString = [[NSString alloc] init];
366
367 if ([app currentPreviewMode] == MarkdownPreview) {
368 processedString = [NSString stringWithProcessedMarkdown:rawString];
369 } else if ([app currentPreviewMode] == MultiMarkdownPreview) {
370 processedString = ( [includeTemplate state] == NSOnState ) ? [NSString documentWithProcessedMultiMarkdown:rawString] : [NSString xhtmlWithProcessedMultiMarkdown:rawString];
371 } else if ([app currentPreviewMode] == TextilePreview) {
372 processedString = ( [includeTemplate state] == NSOnState ) ? [NSString documentWithProcessedTextile:rawString] : [NSString xhtmlWithProcessedTextile:rawString];
373 }
374
375 NSURL *file = [sheet URL];
376 NSError *error;
377 [processedString writeToURL:file atomically:YES encoding:NSUTF8StringEncoding error:&error];
378 }
379 }
380
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
381 -(IBAction)saveHTML:(id)sender
382 {
19e583c @ttscoff Big commit, sorry.
ttscoff authored
383 if (!accessoryView) {
384 if (![NSBundle loadNibNamed:@"SaveHTMLPreview" owner:self]) {
385 NSLog(@"Failed to load SaveHTMLPreview.nib");
386 NSBeep();
387 return;
388 }
389 }
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
390 // TODO high coupling; too many assumptions on architecture:
391 AppController *app = [[NSApplication sharedApplication] delegate];
392
393 NSSavePanel *savePanel = [NSSavePanel savePanel];
19e583c @ttscoff Big commit, sorry.
ttscoff authored
394 [savePanel setAccessoryView:accessoryView];
395 [savePanel setCanCreateDirectories:YES];
396 [savePanel setCanSelectHiddenExtension:YES];
397
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
398 NSArray *fileTypes = [[NSArray alloc] initWithObjects:@"html",@"xhtml",@"htm",nil];
399 [savePanel setAllowedFileTypes:fileTypes];
19e583c @ttscoff Big commit, sorry.
ttscoff authored
400
401 NSString *noteTitle = ([app selectedNoteObject]) ? [NSString stringWithFormat:@"%@",titleOfNote([app selectedNoteObject])] : @"";
402 [savePanel beginSheetForDirectory:nil file:noteTitle modalForWindow:[self window] modalDelegate:self
403 didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
404
405 [fileTypes release];
406 }
407
408 -(IBAction)switchTabs:(id)sender
409 {
410 int tabSelection = [tabView indexOfTabViewItem:[tabView selectedTabViewItem]];
411
412 if (tabSelection == 0) {
413 [tabSwitcher setTitle:@"View Preview"];
414 [tabView selectTabViewItem:[tabView tabViewItemAtIndex:1]];
415 } else {
416 [tabSwitcher setTitle:@"View Source"];
417 [tabView selectTabViewItem:[tabView tabViewItemAtIndex:0]];
418 }
419 }
420
421 - (IBAction)shareAsk:(id)sender
422 {
423 if (!confirmWindow && !attachedWindow) {
424 int side = 3;
425 NSPoint buttonPoint = NSMakePoint(NSMidX([shareButton frame]),
426 NSMidY([shareButton frame]));
427 confirmWindow = [[MAAttachedWindow alloc] initWithView:shareConfirmation
428 attachedToPoint:buttonPoint
429 inWindow:[shareButton window]
430 onSide:side
431 atDistance:15.0f];
432 [confirmWindow setBorderColor:[NSColor colorWithCalibratedHue:0.278 saturation:0.000 brightness:0.871 alpha:0.950]];
433 [confirmWindow setBackgroundColor:[NSColor colorWithCalibratedRed:0.134 green:0.134 blue:0.134 alpha:0.950]];
434 [confirmWindow setViewMargin:3.0f];
435 [confirmWindow setBorderWidth:1.0f];
436 [confirmWindow setCornerRadius:10.0f];
437 [confirmWindow setHasArrow:YES];
438 [confirmWindow setDrawsRoundCornerBesideArrow:YES];
439 [confirmWindow setArrowBaseWidth:10.0f];
440 [confirmWindow setArrowHeight:6.0f];
441
442 [[shareButton window] addChildWindow:confirmWindow ordered:NSWindowAbove];
443
444 } else {
445 if (confirmWindow)
446 [self cancelShare:self];
447 else if (attachedWindow)
448 [self hideShareURL:self];
449 }
450 }
451
452 - (void)showShareURL:(NSString *)url isError:(BOOL)isError
453 {
454 if (confirmWindow) {
455 [[shareButton window] removeChildWindow:confirmWindow];
456 [confirmWindow orderOut:self];
457 [confirmWindow release];
458 confirmWindow = nil;
459 }
460 // Attach/detach window
461 if (!attachedWindow) {
462 int side = 3;
463 NSPoint buttonPoint = NSMakePoint(NSMidX([shareButton frame]),
464 NSMidY([shareButton frame]));
465 attachedWindow = [[MAAttachedWindow alloc] initWithView:shareNotification
466 attachedToPoint:buttonPoint
467 inWindow:[shareButton window]
468 onSide:side
469 atDistance:15.0f];
470 [attachedWindow setBorderColor:[NSColor colorWithCalibratedHue:0.278 saturation:0.000 brightness:0.871 alpha:0.950]];
471 [attachedWindow setBackgroundColor:[NSColor colorWithCalibratedRed:0.134 green:0.134 blue:0.134 alpha:0.950]];
472 [attachedWindow setViewMargin:3.0f];
473 [attachedWindow setBorderWidth:1.0f];
474 [attachedWindow setCornerRadius:10.0f];
475 [attachedWindow setHasArrow:YES];
476 [attachedWindow setDrawsRoundCornerBesideArrow:YES];
477 [attachedWindow setArrowBaseWidth:10.0f];
478 [attachedWindow setArrowHeight:6.0f];
479
480 [[shareButton window] addChildWindow:attachedWindow ordered:NSWindowAbove];
481
482 }
483
484 if (isError) {
485 [urlTextField setStringValue:url];
486 [viewOnWebButton setHidden:YES];
487 } else {
488 NSPasteboard *pb = [NSPasteboard generalPasteboard];
489 NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil];
490 [pb declareTypes:types owner:self];
491 [pb setString:shareURL forType:NSStringPboardType];
492 [urlTextField setHidden:NO];
493 [viewOnWebButton setTitle:url];
494 }
495
496
497 }
498
952125c @ttscoff Separating logic a little
ttscoff authored
499 -(void)closeShareURLView
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
500 {
501 [[shareButton window] removeChildWindow:attachedWindow];
502 [attachedWindow orderOut:self];
503 [attachedWindow release];
504 attachedWindow = nil;
505 [shareURL release];
506 }
507
952125c @ttscoff Separating logic a little
ttscoff authored
508 - (IBAction)hideShareURL:(id)sender
509 {
510 [self closeShareURLView];
511 }
512
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
513 - (IBAction)cancelShare:(id)sender
514 {
515 [[shareButton window] removeChildWindow:confirmWindow];
516 [confirmWindow orderOut:self];
517 [confirmWindow release];
518 confirmWindow = nil;
519 }
520
521 - (IBAction)openShareURL:(id)sender
522 {
523 [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:shareURL]];
524 [[shareButton window] removeChildWindow:attachedWindow];
525 [attachedWindow orderOut:self];
526 [attachedWindow release];
527 attachedWindow = nil;
528 [shareURL release];
529 }
530
531 - (void)dealloc {
532 [htmlString release];
533 [cssString release];
534 [lastNote release];
535 [super dealloc];
536 }
952125c @ttscoff Separating logic a little
ttscoff authored
537
c5cfe65 @ttscoff Slightly better way to handle adding scroll reset script.
ttscoff authored
538 @end
Something went wrong with that request. Please try again.