PageRenderTime 36ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/src/SelectionController.mm

http://firefox-mac-pdf.googlecode.com/
Objective C++ | 234 lines | 173 code | 34 blank | 27 comment | 13 complexity | 3b917ca126e0d49f4496bedb87f91fb7 MD5 | raw file
  1. /*
  2. * Copyright (c) 2008 Samuel Gross.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. * THE SOFTWARE.
  21. */
  22. #import "SelectionController.h"
  23. @interface SelectionControllerLeopard : SelectionController
  24. {
  25. NSInvocation* setCurrentSelection;
  26. NSInvocation* setColor;
  27. NSInvocation* setHighlightedSelections;
  28. }
  29. @end
  30. @interface SelectionControllerTiger : SelectionController
  31. {
  32. NSColor* selectColor;
  33. NSArray* currentSelection;
  34. NSMutableArray* highlightedSelections;
  35. }
  36. @end
  37. @implementation SelectionController
  38. - (id)initWithView:(PDFView*)view {
  39. if (self = [super init]) {
  40. _view = view;
  41. }
  42. return self;
  43. }
  44. + (SelectionController*)forPDFView:(PDFView*)view
  45. {
  46. SEL sel = @selector(setCurrentSelection:animate:);
  47. if ([view respondsToSelector:sel]) {
  48. return [[[SelectionControllerLeopard alloc] initWithView:view] autorelease];
  49. } else {
  50. return [[[SelectionControllerTiger alloc] initWithView:view] autorelease];
  51. }
  52. }
  53. // "abstract"
  54. - (void)setCurrentSelection:(PDFSelection*)selection {}
  55. - (void)setHighlightedSelections:(NSArray*)selections {}
  56. @end
  57. NSInvocation* invocationForSelector(SEL sel, Class clazz) {
  58. NSMethodSignature* sig = [clazz instanceMethodSignatureForSelector:sel];
  59. NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sig];
  60. [invocation setSelector:sel];
  61. return invocation;
  62. }
  63. // From PDFViewEdit.m
  64. static NSRect RectPlusScale (NSRect aRect, float scale);
  65. @implementation SelectionControllerLeopard
  66. - (void)dealloc
  67. {
  68. [setCurrentSelection release];
  69. [setColor release];
  70. [setHighlightedSelections release];
  71. [super dealloc];
  72. }
  73. - (id)initWithView:(PDFView*)view {
  74. if (self = [super initWithView:view]) {
  75. setCurrentSelection = [invocationForSelector(@selector(setCurrentSelection:animate:), [PDFView class]) retain];
  76. BOOL yes = YES;
  77. [setCurrentSelection setArgument:&yes atIndex:3];
  78. NSColor* yellow = [NSColor yellowColor];
  79. setColor = [invocationForSelector(@selector(setColor:), [PDFSelection class]) retain];
  80. [setColor setArgument:&yellow atIndex:2];
  81. [setColor retainArguments];
  82. setHighlightedSelections = [invocationForSelector(@selector(setHighlightedSelections:), [PDFView class]) retain];
  83. }
  84. return self;
  85. }
  86. - (void)setCurrentSelection:(PDFSelection*)selection
  87. {
  88. [_view setCurrentSelection:selection];
  89. [_view scrollSelectionToVisible:nil];
  90. [setCurrentSelection setArgument:&selection atIndex:2];
  91. [setCurrentSelection invokeWithTarget:_view];
  92. }
  93. - (void)setHighlightedSelections:(NSArray*)selections
  94. {
  95. int count = [selections count];
  96. for (int i = 0; i < count; i++) {
  97. PDFSelection* selection = [selections objectAtIndex:i];
  98. [setColor invokeWithTarget:selection];
  99. }
  100. [setHighlightedSelections setArgument:&selections atIndex:2];
  101. [setHighlightedSelections invokeWithTarget:_view];
  102. }
  103. @end
  104. @implementation SelectionControllerTiger
  105. - (id)initWithView:(PDFView*)view {
  106. if (self = [super initWithView:view]) {
  107. selectColor = [[NSColor colorWithDeviceRed:0.22 green:0.85 blue:0.47 alpha:1.0] retain];
  108. highlightedSelections = [[NSMutableArray arrayWithCapacity:10] retain];
  109. [[NSNotificationCenter defaultCenter] addObserver:self
  110. selector:@selector(mouseDown) name:@"mouseDown" object:_view];
  111. }
  112. return self;
  113. }
  114. - (void)dealloc
  115. {
  116. [selectColor release];
  117. [currentSelection release];
  118. [highlightedSelections release];
  119. [super dealloc];
  120. }
  121. // PDFView doesn't automatically determine annotations need to be 'redisplayed'
  122. - (void)setNeedsDisplay:(PDFAnnotation*)annotation
  123. {
  124. // From PDFViewEdit.m
  125. [_view setNeedsDisplayInRect: RectPlusScale([_view convertRect: [annotation bounds]
  126. fromPage: [annotation page]], [_view scaleFactor])];
  127. }
  128. - (void)removeAnnotations:(NSArray*)array
  129. {
  130. int count = [array count];
  131. for (int i = 0; i < count; i++) {
  132. PDFAnnotation* annotation = [array objectAtIndex:i];
  133. [[annotation page] removeAnnotation:annotation];
  134. [self setNeedsDisplay:annotation];
  135. }
  136. }
  137. - (NSArray*)addAnnotationForSelection:(PDFSelection*)selection color:(NSColor*)color
  138. {
  139. NSMutableArray* annotations = [NSMutableArray arrayWithCapacity:10];
  140. NSArray* pages = [selection pages];
  141. int count = [pages count];
  142. for (int i = 0; i < count; i++) {
  143. PDFPage* page = [pages objectAtIndex:i];
  144. NSRect bounds = [selection boundsForPage:page];
  145. PDFAnnotation* annotation = [[PDFAnnotationMarkup alloc] initWithBounds:bounds];
  146. [annotation setColor:color];
  147. [page addAnnotation:annotation];
  148. [annotations addObject:annotation];
  149. [self setNeedsDisplay:annotation];
  150. }
  151. return annotations;
  152. }
  153. - (void)setCurrentSelection:(PDFSelection*)selection
  154. {
  155. if (currentSelection) {
  156. [self removeAnnotations:currentSelection];
  157. [currentSelection release];
  158. currentSelection = nil;
  159. }
  160. if (selection) {
  161. currentSelection = [[self addAnnotationForSelection:selection color:selectColor] retain];
  162. }
  163. [_view setCurrentSelection:selection];
  164. [_view scrollSelectionToVisible:nil];
  165. }
  166. - (void)setHighlightedSelections:(NSArray*)selections
  167. {
  168. [self removeAnnotations:highlightedSelections];
  169. [highlightedSelections removeAllObjects];
  170. if (selections) {
  171. int count = [selections count];
  172. for (int i = 0; i < count; i++) {
  173. PDFSelection* selection = [selections objectAtIndex:i];
  174. NSArray* annotations = [self addAnnotationForSelection:selection color:[NSColor yellowColor]];
  175. [highlightedSelections addObjectsFromArray:annotations];
  176. }
  177. }
  178. }
  179. - (void)mouseDown
  180. {
  181. if (currentSelection) {
  182. [self removeAnnotations:currentSelection];
  183. [currentSelection release];
  184. currentSelection = nil;
  185. }
  186. }
  187. @end
  188. // From PDFViewEdit.m in Apple's PDF Annotation Editor example
  189. static NSRect RectPlusScale (NSRect aRect, float scale)
  190. {
  191. float maxX;
  192. float maxY;
  193. NSPoint origin;
  194. // Determine edges.
  195. maxX = ceilf(aRect.origin.x + aRect.size.width) + scale;
  196. maxY = ceilf(aRect.origin.y + aRect.size.height) + scale;
  197. origin.x = floorf(aRect.origin.x) - scale;
  198. origin.y = floorf(aRect.origin.y) - scale;
  199. return NSMakeRect(origin.x, origin.y, maxX - origin.x, maxY - origin.y);
  200. }