~ubuntu-branches/ubuntu/jaunty/viewpdf.app/jaunty

« back to all changes in this revision

Viewing changes to Controller.m

  • Committer: Bazaar Package Importer
  • Author(s): Gürkan Sengün
  • Date: 2006-09-16 18:13:34 UTC
  • mfrom: (2.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060916181334-10mrzvpblr2jpvu7
Tags: 1:0.2dfsg1-2
* Rebuild against latest libgnustep-gui-dev.
* Added co-maintainers.
* Updated build-depends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2005  Stefan Kleine Stegemann
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
17
 */
 
18
 
 
19
#import "Controller.h"
 
20
#import "Document.h"
 
21
#import "CenteringClipView.h"
 
22
 
 
23
/**
 
24
 * Non-Public methods.
 
25
 */
 
26
@interface Controller (Private)
 
27
- (Document*) _myDocument;
 
28
- (void) _updatePage: (NSNotification*)aNotification;
 
29
- (void) _zoomFactorUpdated: (NSNotification*)aNotification;
 
30
- (void) _toggleResizePolicy: (ResizePolicy)aPolicy;
 
31
- (void) _setResizePolicy: (ResizePolicy)aPolicy;
 
32
- (void) _setupScrollView;
 
33
- (void) _addDocumentTools;
 
34
- (void) _createSinglePageView;
 
35
- (void) _setInitialWindowSize;
 
36
- (NSRect) _calcPreferredFrameInFrame: (NSRect)maxFrame withPDFSize: (NSSize)aPDFSize;
 
37
- (NSSize) _calcPDFContentSize: (NSSize)aSize add: (BOOL)addToSize;
 
38
@end
 
39
 
 
40
 
 
41
@implementation Controller
 
42
 
 
43
- (id) initWithWindow: (NSWindow*)aWindow
 
44
{
 
45
   self = [super initWithWindow: aWindow];
 
46
   if (self)
 
47
   {
 
48
      singlePageView = nil;
 
49
      scrollView = nil;
 
50
      tools = nil;
 
51
      menuState = nil;
 
52
      windowIsVisible = NO;
 
53
   }
 
54
 
 
55
   return self;
 
56
}
 
57
 
 
58
- (void) dealloc
 
59
{
 
60
   NSLog(@"dealloc Controller");
 
61
 
 
62
   [[NSNotificationCenter defaultCenter] removeObserver: self];
 
63
   [menuState release];
 
64
   [singlePageView release];
 
65
   [super dealloc];
 
66
}
 
67
 
 
68
- (void) windowDidLoad
 
69
{
 
70
   [super windowDidLoad];
 
71
   
 
72
   [self _setupScrollView];
 
73
   [self _addDocumentTools];
 
74
   [self _createSinglePageView];
 
75
   [self goSinglePage: nil];
 
76
 
 
77
   // initialize the SinglePageView with the document's
 
78
   // PDFDocument.
 
79
   [singlePageView setDocument: [self _myDocument]];
 
80
   
 
81
   [[NSNotificationCenter defaultCenter]
 
82
         addObserver: self
 
83
            selector: @selector(_zoomFactorUpdated:)
 
84
                name: kZoomFactorChangedNotification
 
85
              object: singlePageView];
 
86
 
 
87
   [[NSNotificationCenter defaultCenter]
 
88
         addObserver: self
 
89
            selector: @selector(_updatePage:)
 
90
                name: kDocumentPageChangedNotification
 
91
              object: [self _myDocument]];
 
92
   
 
93
   // setup the multipageview
 
94
   //multipageview = [[MultiPageView alloc] initWithFrame: [pdfview frame]
 
95
   //                                            scaleFactor: 25];
 
96
   //[multipageview setDocument: [[self _myDocument] pdfDocument]];
 
97
   //[scrollview setDocumentView: multipageview];
 
98
   
 
99
   [self _setInitialWindowSize];
 
100
 
 
101
   // trigger initial setup
 
102
   [[self _myDocument] setPageByIndex: 1];
 
103
   
 
104
   // display initial zoom factor & page count
 
105
   [tools setZoom: [singlePageView zoom]];
 
106
   [tools setPageCount: [[self _myDocument] countPages]];
 
107
   
 
108
   // setup a delegate that keeps track of the menu's state
 
109
   menuState = [[MenuState alloc] initWithDocument: [self _myDocument]
 
110
                                       contentView: singlePageView];
 
111
}
 
112
 
 
113
- (void) windowDidBecomeMain: (NSNotification*)aNotification
 
114
{
 
115
   // We need to ensure, that the top of the content is visible
 
116
   // right after the window appears on the screen for the first
 
117
   // time. windowDidLoad here doesn"t work because the window manager
 
118
   // may decide to change the window size when it is put on the
 
119
   // screen (which takes place AFTER windowDidLoad)
 
120
   if (!windowIsVisible)
 
121
   {
 
122
      [singlePageView displayContentTop];
 
123
      windowIsVisible = YES;
 
124
   }
 
125
   
 
126
   [menuState stateChanged];
 
127
}
 
128
 
 
129
- (NSRect) windowWillUseStandardFrame: (NSWindow*)aWindow defaultFrame: (NSRect)aFrame
 
130
{
 
131
   return [self _calcPreferredFrameInFrame: aFrame
 
132
                               withPDFSize: [singlePageView preferredSize]];
 
133
}
 
134
 
 
135
- (IBAction) nextPage: (id)aSender
 
136
{
 
137
   [[self _myDocument] nextPage];
 
138
}
 
139
 
 
140
- (IBAction) previousPage: (id)aSender
 
141
{
 
142
   [[self _myDocument] previousPage];
 
143
}
 
144
 
 
145
- (IBAction) firstPage: (id)aSender
 
146
{
 
147
   [[self _myDocument] setPageByIndex: 1];
 
148
}
 
149
 
 
150
- (IBAction) lastPage: (id)aSender
 
151
{
 
152
   [[self _myDocument] setPageByIndex: [[self _myDocument] countPages]];
 
153
}
 
154
 
 
155
- (IBAction) takePageFrom: (id)aSender
 
156
{
 
157
   int page = [aSender intValue];
 
158
   if ((page > 0) && (page <= [[self _myDocument] countPages]))
 
159
   {
 
160
      [[self _myDocument] setPageByIndex: page];
 
161
   }
 
162
   else
 
163
   {
 
164
      // if the user entered "0", go to last page
 
165
      NSString* test = [[aSender stringValue] stringByTrimmingCharactersInSet:
 
166
                          [NSCharacterSet whitespaceCharacterSet]];
 
167
      if ([test hasPrefix: @"0"])
 
168
      {
 
169
         [self lastPage: nil];
 
170
      }
 
171
      else
 
172
      {
 
173
         [self _updatePage: nil];
 
174
      }
 
175
   }
 
176
}
 
177
 
 
178
- (IBAction) enterPageNumber: (id)aSender
 
179
{
 
180
   [tools focusPageField];
 
181
}
 
182
 
 
183
- (IBAction) takeZoomFrom: (id)aSender
 
184
{
 
185
   float zoom = [aSender floatValue];
 
186
   if (zoom > 0)
 
187
   {
 
188
      [singlePageView setZoom: zoom];
 
189
   }
 
190
   else
 
191
   {
 
192
      [self _zoomFactorUpdated: nil];
 
193
   }
 
194
}
 
195
 
 
196
- (IBAction) zoomIn: (id)aSender
 
197
{
 
198
   [self _setResizePolicy: ResizePolicyNone];
 
199
   [singlePageView zoomIn];
 
200
}
 
201
 
 
202
- (IBAction) zoomOut: (id)aSender
 
203
{
 
204
   [self _setResizePolicy: ResizePolicyNone];
 
205
   [singlePageView zoomOut];
 
206
}
 
207
 
 
208
- (IBAction) zoomActualSize: (id)aSender
 
209
{
 
210
   [self _setResizePolicy: ResizePolicyNone];
 
211
   [singlePageView setZoom: 100.0];
 
212
}
 
213
 
 
214
- (IBAction) zoomToFit: (id)aSender
 
215
{
 
216
   [self _setResizePolicy: ResizePolicyNone];
 
217
   [singlePageView zoomContentToFit: [scrollView contentSize]];
 
218
}
 
219
 
 
220
- (IBAction) toggleFitWidth: (id)aSender
 
221
{
 
222
   [self _toggleResizePolicy: ResizePolicyFitWidth];
 
223
}
 
224
 
 
225
- (IBAction) toggleFitHeight: (id)aSender
 
226
{
 
227
   [self _toggleResizePolicy: ResizePolicyFitHeight];
 
228
}
 
229
 
 
230
- (IBAction) toggleFitPage: (id)aSender
 
231
{
 
232
   [self _toggleResizePolicy: ResizePolicyFitPage];
 
233
}
 
234
 
 
235
- (IBAction) scrollPageUp: (id)aSender
 
236
{
 
237
   [singlePageView scrollUpOnePage];
 
238
}
 
239
 
 
240
- (IBAction) scrollPageDown: (id)aSender
 
241
{
 
242
   [singlePageView scrollDownOnePage];
 
243
}
 
244
 
 
245
- (IBAction) scrollLineUp: (id)aSender
 
246
{
 
247
   [singlePageView scrollUpOneLine];
 
248
}
 
249
 
 
250
- (IBAction) scrollLineDown: (id)aSender
 
251
{
 
252
   [singlePageView scrollDownOneLine];
 
253
}
 
254
 
 
255
- (IBAction) scrollToTop: (id)aSender
 
256
{
 
257
   [singlePageView displayContentTop];
 
258
}
 
259
 
 
260
- (IBAction) scrollToBottom: (id)aSender
 
261
{
 
262
   [singlePageView displayContentBottom];
 
263
}
 
264
 
 
265
- (IBAction) scrollLineLeft: (id)aSender
 
266
{
 
267
   [singlePageView scrollLeftOneLine];
 
268
}
 
269
 
 
270
- (IBAction) scrollLineRight: (id)aSender
 
271
{
 
272
   [singlePageView scrollRightOneLine];
 
273
}
 
274
 
 
275
- (IBAction) scrollToLeftEdge: (id)aSender
 
276
{
 
277
   [singlePageView displayContentLeft];
 
278
}
 
279
 
 
280
- (IBAction) scrollToRightEdge: (id)aSender;
 
281
{
 
282
   [singlePageView displayContentRight];
 
283
}
 
284
 
 
285
- (IBAction) goSinglePage: (id)aSender
 
286
{
 
287
   [scrollView setDocumentView: singlePageView];
 
288
   NSAssert([singlePageView paperColor], @"content view does not have a paper color");
 
289
   [scrollView setBackgroundColor: [singlePageView paperColor]];
 
290
}
 
291
 
 
292
- (IBAction) close: (id)aSender
 
293
{
 
294
   [self close];
 
295
}
 
296
 
 
297
@end
 
298
 
 
299
/* ----------------------------------------------------- */
 
300
/*  Category Private                                     */
 
301
/* ----------------------------------------------------- */
 
302
 
 
303
@implementation Controller (Private)
 
304
 
 
305
- (Document*) _myDocument
 
306
{
 
307
   return (Document*)[self document];
 
308
}
 
309
 
 
310
- (void) _updatePage: (NSNotification*)aNotification
 
311
{
 
312
   [tools setPage: [[self _myDocument] pageIndex]];
 
313
   [singlePageView update];
 
314
}
 
315
 
 
316
- (void) _zoomFactorUpdated: (NSNotification*)aNotification
 
317
{
 
318
   [tools setZoom: [singlePageView zoom]];
 
319
   [singlePageView update];
 
320
}
 
321
 
 
322
- (void) _toggleResizePolicy: (ResizePolicy)aPolicy
 
323
{
 
324
   ResizePolicy newPolicy;
 
325
 
 
326
   if ([singlePageView resizePolicy] == aPolicy)
 
327
   {
 
328
      newPolicy = ResizePolicyNone;
 
329
   }
 
330
   else
 
331
   {
 
332
      newPolicy = aPolicy;
 
333
   }
 
334
 
 
335
   [self _setResizePolicy: newPolicy];
 
336
}
 
337
 
 
338
- (void) _setResizePolicy: (ResizePolicy)aPolicy
 
339
{
 
340
   if ([singlePageView resizePolicy] == aPolicy)
 
341
   {
 
342
      return;
 
343
   }
 
344
 
 
345
   [singlePageView setResizePolicy: aPolicy];
 
346
   [tools setResizePolicy: [singlePageView resizePolicy]];
 
347
   [menuState stateChanged];
 
348
}
 
349
 
 
350
- (void) _setupScrollView
 
351
{
 
352
   NSAssert(scrollView, @"scrollview not set");
 
353
   
 
354
   // make the scrollview center it's document view
 
355
   id docView = [[scrollView documentView] retain];
 
356
   NSRect clipViewFrame = [[scrollView contentView] frame];
 
357
   NSClipView* newClipView = [[CenteringClipView alloc] initWithFrame: clipViewFrame];
 
358
   [newClipView  setBackgroundColor: [NSColor windowBackgroundColor]];
 
359
   [scrollView setContentView: newClipView];
 
360
   [scrollView setDocumentView: docView];
 
361
   [newClipView release];
 
362
   [docView release];
 
363
   
 
364
   [scrollView setHasVerticalScroller: YES];
 
365
   [scrollView setHasHorizontalScroller: YES];
 
366
   [scrollView setDrawsBackground: YES];
 
367
}
 
368
 
 
369
- (void) _addDocumentTools
 
370
{
 
371
   tools = [[DocumentTools alloc] initWithFrame: NSMakeRect(0, 0, 0, 0) target: self];
 
372
   
 
373
   // we need to re-frame the scrollview such that the tools view
 
374
   // fits underneath it
 
375
   NSRect scrollViewF = [scrollView frame];
 
376
   [scrollView setFrame: 
 
377
      NSMakeRect(NSMinX(scrollViewF), NSMinY(scrollViewF) + NSHeight([tools frame]),
 
378
                 NSWidth(scrollViewF), NSHeight(scrollViewF) - NSHeight([tools frame]))];
 
379
                 
 
380
   [[[self window] contentView] addSubview: tools];
 
381
   [tools release];
 
382
}
 
383
 
 
384
- (void) _createSinglePageView
 
385
{
 
386
   NSSize viewSize = [scrollView contentSize];
 
387
   NSRect frame = NSMakeRect(0, 0, viewSize.width, viewSize.height);
 
388
   singlePageView = [[SinglePageView alloc] initWithFrame: frame];
 
389
}
 
390
 
 
391
- (void) _setInitialWindowSize
 
392
{
 
393
   NSRect screenFrame = [[NSScreen mainScreen] frame];
 
394
 
 
395
#ifndef GNUSTEP
 
396
   // Reserve a little space at the top such that the window
 
397
   // does not appear "glued" to the menu bar
 
398
   screenFrame.size.height = NSHeight(screenFrame) - 30;
 
399
#endif
 
400
 
 
401
   NSRect winFrame = [self _calcPreferredFrameInFrame: screenFrame
 
402
                                          withPDFSize: [singlePageView preferredSize]];
 
403
 
 
404
   NSRect contentRect = [NSWindow contentRectForFrameRect: winFrame
 
405
                                                styleMask: [[self window] styleMask]];
 
406
 
 
407
   NSSize availableSize = [self _calcPDFContentSize: contentRect.size add: NO];
 
408
   NSSize usedSize = [singlePageView zoomContentToFit: availableSize];
 
409
   // recalc frame with actually used size
 
410
   winFrame = [self _calcPreferredFrameInFrame: screenFrame
 
411
                                   withPDFSize: usedSize];
 
412
 
 
413
   [[self window] setFrame: winFrame display: YES];
 
414
}
 
415
 
 
416
- (NSRect) _calcPreferredFrameInFrame: (NSRect)maxFrame withPDFSize: (NSSize)aPDFSize
 
417
{
 
418
#ifdef GNUSTEP
 
419
   // Reserve a little extra space at the top of the screen. This is necessary
 
420
   // if GNUstep does not draw the window decorations but the window manager.
 
421
   // Otherwise, the window might appear with the titlebar off-screen
 
422
   maxFrame.size.height = NSHeight(maxFrame) - 40;
 
423
#endif
 
424
 
 
425
   NSSize newContentSize = [self _calcPDFContentSize: aPDFSize add: YES];
 
426
 
 
427
   NSRect contentRect = [NSWindow contentRectForFrameRect: [[self window] frame]
 
428
                                                styleMask: [[self window] styleMask]];
 
429
   contentRect.size = newContentSize;
 
430
 
 
431
   NSRect newFrame = [NSWindow frameRectForContentRect: contentRect
 
432
                                             styleMask: [[self window] styleMask]];
 
433
 
 
434
   // constrain the computed frame inside the screen dimensions (aFrame)
 
435
   // (OSX works fine without, but I guess, with GNUstep, we're better of
 
436
   // taking care of this)
 
437
 
 
438
   //NSLog(@"NEW FRAME 1: %f @ %f - %f @ %f",
 
439
   //      NSMinX(newFrame), NSMinY(newFrame), NSMaxX(newFrame), NSMaxY(newFrame));
 
440
 
 
441
   // constrain height
 
442
   if (NSMinY(newFrame) < NSMinY(maxFrame))
 
443
   {
 
444
      newFrame.origin.x = NSMinY(maxFrame);
 
445
   }
 
446
   if (NSMaxY(newFrame) > NSHeight(maxFrame))
 
447
   {
 
448
      newFrame.origin.y = NSHeight(maxFrame) - NSHeight(newFrame);
 
449
      if (NSMinY(newFrame) < NSMinY(maxFrame))
 
450
      {
 
451
         newFrame.origin.y = NSMinY(maxFrame);
 
452
         newFrame.size.height = NSHeight(maxFrame);
 
453
      }
 
454
   }
 
455
 
 
456
   // constrain width
 
457
   if (NSMinX(newFrame) < NSMinX(maxFrame))
 
458
   {
 
459
      newFrame.origin.y = NSMinX(maxFrame);
 
460
   }
 
461
   if (NSMaxX(newFrame) > NSWidth(maxFrame))
 
462
   {
 
463
      newFrame.origin.x = NSWidth(maxFrame) - NSWidth(newFrame);
 
464
      if (NSMinX(newFrame) < NSMinX(maxFrame))
 
465
      {
 
466
         newFrame.origin.x = NSMinX(maxFrame);
 
467
         newFrame.size.width = NSWidth(maxFrame);
 
468
      }
 
469
   }
 
470
 
 
471
   // if the new frame has any anomalies, and return the maximum frame
 
472
   // (otherwise, the window may dissapear from the screen)
 
473
   if ((NSWidth(newFrame) <= 0) || (NSHeight(newFrame) <= 0))
 
474
   {
 
475
      return maxFrame;
 
476
   }
 
477
 
 
478
   //NSLog(@"NEW FRAME 2: %f @ %f - %f @ %f",
 
479
   //      NSMinX(newFrame), NSMinY(newFrame), NSMaxX(newFrame), NSMaxY(newFrame));
 
480
 
 
481
   return newFrame;
 
482
}
 
483
 
 
484
/** Add or subtract the size of additional components in the window (tools, scroller)
 
485
    to or from a rectangle.  */
 
486
- (NSSize) _calcPDFContentSize: (NSSize)aSize add: (BOOL)addToSize
 
487
{
 
488
   float factor = (addToSize ? 1 : -1);
 
489
   
 
490
   NSSize newSize = aSize;
 
491
   
 
492
   newSize.height += NSHeight([tools frame]) * factor;
 
493
   newSize.height += NSHeight([[scrollView horizontalScroller] frame]) * factor;
 
494
   newSize.width += NSWidth([[scrollView verticalScroller] frame]) * factor;
 
495
 
 
496
#ifdef GNUSTEP
 
497
   // add a little extra space, otherwise scrollbars appear
 
498
   // on GNUstep
 
499
   float additionalSpace = 2 * (addToSize ? 1 : -1);
 
500
   newSize.width += additionalSpace;
 
501
   newSize.height += additionalSpace;
 
502
#endif
 
503
 
 
504
   return newSize;
 
505
}
 
506
 
 
507
@end