PageRenderTime 82ms CodeModel.GetById 40ms app.highlight 3ms RepoModel.GetById 37ms app.codeStats 0ms

/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
 24
 25@interface SelectionControllerLeopard : SelectionController
 26{
 27  NSInvocation* setCurrentSelection;
 28  NSInvocation* setColor;
 29  NSInvocation* setHighlightedSelections;
 30}
 31@end
 32
 33@interface SelectionControllerTiger : SelectionController
 34{
 35  NSColor* selectColor;
 36  NSArray* currentSelection;
 37  NSMutableArray* highlightedSelections;
 38}
 39@end
 40
 41@implementation SelectionController
 42
 43- (id)initWithView:(PDFView*)view {
 44  if (self = [super init]) {
 45    _view = view;
 46  }
 47  return self;
 48}
 49
 50+ (SelectionController*)forPDFView:(PDFView*)view
 51{
 52  SEL sel = @selector(setCurrentSelection:animate:);
 53  if ([view respondsToSelector:sel]) {
 54    return [[[SelectionControllerLeopard alloc] initWithView:view] autorelease];
 55  } else {
 56    return [[[SelectionControllerTiger alloc] initWithView:view] autorelease];
 57  }
 58}
 59
 60// "abstract"
 61- (void)setCurrentSelection:(PDFSelection*)selection {}
 62- (void)setHighlightedSelections:(NSArray*)selections {}
 63
 64@end
 65
 66NSInvocation* invocationForSelector(SEL sel, Class clazz) {
 67  NSMethodSignature* sig = [clazz instanceMethodSignatureForSelector:sel];
 68  NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sig];
 69  [invocation setSelector:sel];
 70  return invocation;
 71}
 72
 73// From PDFViewEdit.m
 74static NSRect RectPlusScale (NSRect aRect, float scale);
 75
 76@implementation SelectionControllerLeopard
 77
 78- (void)dealloc
 79{
 80  [setCurrentSelection release];
 81  [setColor release];
 82  [setHighlightedSelections release];
 83  [super dealloc];
 84}
 85
 86- (id)initWithView:(PDFView*)view {
 87  if (self = [super initWithView:view]) {
 88    setCurrentSelection = [invocationForSelector(@selector(setCurrentSelection:animate:), [PDFView class]) retain];
 89    BOOL yes = YES;
 90    [setCurrentSelection setArgument:&yes atIndex:3];
 91    
 92    NSColor* yellow = [NSColor yellowColor];
 93    setColor = [invocationForSelector(@selector(setColor:), [PDFSelection class]) retain];
 94    [setColor setArgument:&yellow atIndex:2];
 95    [setColor retainArguments];
 96    
 97    setHighlightedSelections = [invocationForSelector(@selector(setHighlightedSelections:), [PDFView class]) retain];
 98  }
 99  return self;
100}
101
102
103- (void)setCurrentSelection:(PDFSelection*)selection
104{
105  
106  [_view setCurrentSelection:selection];
107  [_view scrollSelectionToVisible:nil];
108  [setCurrentSelection setArgument:&selection atIndex:2];
109  [setCurrentSelection invokeWithTarget:_view];
110}
111
112- (void)setHighlightedSelections:(NSArray*)selections
113{
114  int count = [selections count];
115  for (int i = 0; i < count; i++) {
116    PDFSelection* selection = [selections objectAtIndex:i];
117    [setColor invokeWithTarget:selection];
118  }
119  [setHighlightedSelections setArgument:&selections atIndex:2];
120  [setHighlightedSelections invokeWithTarget:_view];
121}
122
123@end
124
125@implementation SelectionControllerTiger
126
127- (id)initWithView:(PDFView*)view {
128  if (self = [super initWithView:view]) {
129    selectColor = [[NSColor colorWithDeviceRed:0.22 green:0.85 blue:0.47 alpha:1.0] retain];
130    highlightedSelections = [[NSMutableArray arrayWithCapacity:10] retain];
131    [[NSNotificationCenter defaultCenter] addObserver:self 
132        selector:@selector(mouseDown) name:@"mouseDown" object:_view];
133  }
134  return self;
135}
136
137- (void)dealloc
138{
139  [selectColor release];
140  [currentSelection release];
141  [highlightedSelections release];
142  [super dealloc];
143}
144
145// PDFView doesn't automatically determine annotations need to be 'redisplayed'
146- (void)setNeedsDisplay:(PDFAnnotation*)annotation
147{
148  // From PDFViewEdit.m
149  [_view setNeedsDisplayInRect: RectPlusScale([_view convertRect: [annotation bounds]
150				fromPage: [annotation page]], [_view scaleFactor])];
151}
152
153- (void)removeAnnotations:(NSArray*)array
154{
155  int count = [array count];
156  for (int i = 0; i < count; i++) {
157    PDFAnnotation* annotation = [array objectAtIndex:i];
158    [[annotation page] removeAnnotation:annotation];
159    [self setNeedsDisplay:annotation];
160  }
161}
162
163- (NSArray*)addAnnotationForSelection:(PDFSelection*)selection color:(NSColor*)color
164{
165  NSMutableArray* annotations = [NSMutableArray arrayWithCapacity:10];
166  NSArray* pages = [selection pages];
167  int count = [pages count];
168  for (int i = 0; i < count; i++) {
169    PDFPage* page = [pages objectAtIndex:i];
170    NSRect bounds = [selection boundsForPage:page];
171    PDFAnnotation* annotation = [[PDFAnnotationMarkup alloc] initWithBounds:bounds]; 
172    [annotation setColor:color];
173    [page addAnnotation:annotation];
174    [annotations addObject:annotation];
175    [self setNeedsDisplay:annotation];
176  }
177  return annotations;
178}
179
180- (void)setCurrentSelection:(PDFSelection*)selection
181{
182  if (currentSelection) {
183    [self removeAnnotations:currentSelection];
184    [currentSelection release];
185    currentSelection = nil;
186  }
187  if (selection) {
188    currentSelection = [[self addAnnotationForSelection:selection color:selectColor] retain];
189  }
190  [_view setCurrentSelection:selection];
191  [_view scrollSelectionToVisible:nil];
192}
193
194- (void)setHighlightedSelections:(NSArray*)selections
195{
196  [self removeAnnotations:highlightedSelections];
197  [highlightedSelections removeAllObjects];
198  
199  if (selections) {
200    int count = [selections count];
201    for (int i = 0; i < count; i++) {
202      PDFSelection* selection = [selections objectAtIndex:i];
203      NSArray* annotations = [self addAnnotationForSelection:selection color:[NSColor yellowColor]];
204      [highlightedSelections addObjectsFromArray:annotations];
205    }
206  }
207}
208
209- (void)mouseDown
210{
211  if (currentSelection) {
212    [self removeAnnotations:currentSelection];
213    [currentSelection release];
214    currentSelection = nil;
215  }
216}
217
218@end
219
220// From PDFViewEdit.m in Apple's PDF Annotation Editor example
221static NSRect RectPlusScale (NSRect aRect, float scale)
222{
223	float		maxX;
224	float		maxY;
225	NSPoint		origin;
226	
227	// Determine edges.
228	maxX = ceilf(aRect.origin.x + aRect.size.width) + scale;
229	maxY = ceilf(aRect.origin.y + aRect.size.height) + scale;
230	origin.x = floorf(aRect.origin.x) - scale;
231	origin.y = floorf(aRect.origin.y) - scale;
232	
233	return NSMakeRect(origin.x, origin.y, maxX - origin.x, maxY - origin.y);
234}