PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/RMAppController.m

http://readomatic.googlecode.com/
Objective C | 166 lines | 110 code | 35 blank | 21 comment | 6 complexity | 40224852affb2eed7b29d7c202dd939c MD5 | raw file
  1. //
  2. // RMAppController.m
  3. // Readomatic
  4. //
  5. // Created by Gernot Poetsch 19.04.07.
  6. // Copyright 2007 Gernot Poetsch. Released under GLPv3. Have Fun!
  7. //
  8. #import "RMAppController.h"
  9. #import "RMDockController.h"
  10. @implementation RMAppController
  11. #pragma mark Class Methods
  12. + (void)initialize;
  13. {
  14. [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
  15. [NSNumber numberWithBool:NO], RMDefaultsOpenLinksInBackground,
  16. [NSNumber numberWithBool:YES], RMDefaultsShowUnreadCountInDock,
  17. [NSNumber numberWithBool:YES], RMDefaultsUseCustomStylesheet,
  18. nil]];
  19. }
  20. #pragma mark Init & Destroy
  21. - (void)awakeFromNib;
  22. {
  23. //Setup as URL-handler
  24. [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
  25. andSelector:@selector(handleOpenURLEvent:withReplyEvent:)
  26. forEventClass:kInternetEventClass
  27. andEventID:kAEGetURL];
  28. //We do menu handling manually for the main window
  29. [mainWindow setExcludedFromWindowsMenu:YES];
  30. //Load the Page
  31. NSURL *stylesheetUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"greader" ofType:@"css"]];
  32. [[webView preferences] bind:@"userStyleSheetEnabled" toObject:userDefaultsController withKeyPath:@"values.RMDefaultsUseCustomStylesheet" options:nil];
  33. [[webView preferences] setUserStyleSheetLocation:stylesheetUrl];
  34. NSURL *readerUrl = [NSURL URLWithString:RMGoogleReaderURLString];
  35. [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:readerUrl]];
  36. //Dock Icon
  37. dockController = [[RMDockController alloc] init];
  38. [dockController bind:@"unreadCountString" toObject:self withKeyPath:@"unreadCountString" options:nil];
  39. [dockController bind:@"showsUnreadCount" toObject:userDefaultsController withKeyPath:@"values.RMDefaultsShowUnreadCountInDock" options:nil];
  40. }
  41. - (void)dealloc;
  42. {
  43. [dockController release];
  44. [super dealloc];
  45. }
  46. #pragma mark Event Handling
  47. - (void)handleOpenURLEvent:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent;
  48. {
  49. NSString *feedString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
  50. if ([feedString hasPrefix:@"feed:"]) {
  51. feedString = [NSString stringWithFormat:@"http:%@", [feedString substringFromIndex:5]];
  52. }
  53. feedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)feedString, NULL, (CFStringRef)@":/?&", kCFStringEncodingUTF8);
  54. feedString = [NSString stringWithFormat:@"http://www.google.com/reader/view/feed/%@", feedString];
  55. //NSLog(@"Opening %@", feedString);
  56. NSURL *feedUrl = [NSURL URLWithString:feedString];
  57. [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:feedUrl]];
  58. }
  59. #pragma mark Application Delegate
  60. - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag;
  61. {
  62. if (!flag) {
  63. [mainWindow makeKeyAndOrderFront:self];
  64. }
  65. return YES;
  66. }
  67. #pragma mark WebKit Frame Loading Delegate
  68. - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
  69. {
  70. //Every time something in the DOM-tree changes, we trigger the KVO to look if the UnreadCount node changed
  71. [self willChangeValueForKey:@"unreadCountString"];
  72. [self didChangeValueForKey:@"unreadCountString"];
  73. }
  74. - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame;
  75. {
  76. //[mainWindow presentError:error];
  77. [frame loadHTMLString:[self HTMLStringForError:error] baseURL:nil];
  78. }
  79. #pragma mark WebKit Resource Loading Delegate
  80. -(void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource;
  81. {
  82. //see -webView:didFinishLoadForFrame:
  83. [self willChangeValueForKey:@"unreadCountString"];
  84. [self didChangeValueForKey:@"unreadCountString"];
  85. }
  86. #pragma mark WebKit Policy Delegate
  87. - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener;
  88. {
  89. //NSLog(@"Deciding Policy for %@", [actionInformation objectForKey:WebActionOriginalURLKey]);
  90. [listener use];
  91. }
  92. - (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id<WebPolicyDecisionListener>)listener;
  93. {
  94. //Everyting that normally opens in a new window (and that are all external links) open in the Browser instead.
  95. [listener ignore];
  96. BOOL opensLinksInBackground = [[[NSUserDefaults standardUserDefaults] objectForKey:RMDefaultsOpenLinksInBackground] boolValue];
  97. [[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:[actionInformation objectForKey:WebActionOriginalURLKey]]
  98. withAppBundleIdentifier:nil
  99. options:(opensLinksInBackground) ? NSWorkspaceLaunchWithoutActivation : nil
  100. additionalEventParamDescriptor:nil
  101. launchIdentifiers:nil];
  102. }
  103. #pragma mark Accessors
  104. - (NSString *)unreadCountString;
  105. {
  106. DOMDocument *document = [[webView mainFrame] DOMDocument];
  107. //Get the Node
  108. DOMHTMLElement *unreadCountElement = (DOMHTMLElement *)[document getElementById:@"reading-list-unread-count"];
  109. if (!unreadCountElement) return nil;
  110. //Is it hidden?
  111. if ([[unreadCountElement className] isEqualToString:@" hidden"]) return nil;
  112. //Get the Value
  113. NSString *nodeValue = [unreadCountElement innerText];
  114. if (!nodeValue) return nil;
  115. //Remove the brackets
  116. NSScanner *scanner = [[[NSScanner alloc] initWithString:nodeValue] autorelease];
  117. NSString *returnValue = nil;
  118. if ( [scanner scanString:@"(" intoString:NULL]
  119. &&[scanner scanUpToString:@")" intoString:&returnValue]) {
  120. return returnValue;
  121. }
  122. return nil;
  123. }
  124. #pragma mark Error Handling
  125. - (NSString *)HTMLStringForError:(NSError *)error;
  126. {
  127. NSString *loadButtonString = [NSString stringWithFormat:@"<form action=\"%@\"><input type=\"submit\" value=\"Reload\" /></form>", RMGoogleReaderURLString];
  128. NSString *body = [NSString stringWithFormat:@"<h1>An error has occurred</h1><p>%@</p><p>%@</p>", [error localizedDescription], loadButtonString];
  129. return [NSString stringWithFormat:@"<html><head></head><body><div id=\"error-message\">%@</div></body></html>", body];
  130. }
  131. @end