/[gnustep]/gnustep/usr-apps/gworkspace/Viewers/BrowserViewer/BrowserViewer.m
ViewVC logotype

Contents of /gnustep/usr-apps/gworkspace/Viewers/BrowserViewer/BrowserViewer.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations) (download)
Fri Sep 26 10:25:38 2003 UTC (20 years, 7 months ago) by esersale
Branch: MAIN
Changes since 1.2: +1 -1 lines
*** empty log message ***

1 /* BrowserViewer.m
2 *
3 * Copyright (C) 2003 Free Software Foundation, Inc.
4 *
5 * Author: Enrico Sersale <enrico@imago.ro>
6 * Date: August 2001
7 *
8 * This file is part of the GNUstep GWorkspace application
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25
26 #include <Foundation/Foundation.h>
27 #include <AppKit/AppKit.h>
28 #ifdef GNUSTEP
29 #include "GWFunctions.h"
30 #include "GWNotifications.h"
31 #include "GWProtocol.h"
32 #include "Browser2.h"
33 #else
34 #include <GWorkspace/GWFunctions.h>
35 #include <GWorkspace/GWNotifications.h>
36 #include <GWorkspace/GWProtocol.h>
37 #include <GWorkspace/Browser2.h>
38 #endif
39 #include "GNUstep.h"
40 #include "BrowserViewer.h"
41 #include "BrowserViewerPref.h"
42
43 #define CHECKRECT(rct) \
44 if (rct.size.width < 0) rct.size.width = 0; \
45 if (rct.size.height < 0) rct.size.height = 0
46
47 @implementation BrowserViewer
48
49 - (void)dealloc
50 {
51 [[NSNotificationCenter defaultCenter] removeObserver: self];
52 TEST_RELEASE (rootPath);
53 TEST_RELEASE (lastPath);
54 TEST_RELEASE (selectedPaths);
55 TEST_RELEASE (watchedPaths);
56 TEST_RELEASE (browser);
57 TEST_RELEASE (prefs);
58 [super dealloc];
59 }
60
61 - (id)init
62 {
63 self = [super initWithFrame: NSZeroRect];
64
65 if (self) {
66 #ifdef GNUSTEP
67 Class gwclass = [[NSBundle mainBundle] principalClass];
68 #else
69 Class gwclass = [[NSBundle mainBundle] classNamed: @"GWorkspace"];
70 #endif
71
72 gworkspace = (id<GWProtocol>)[gwclass gworkspace];
73 usesShelf = YES;
74 cellsIcons = NO;
75 browser = nil;
76 rootPath = nil;
77 lastPath = nil;
78 selectedPaths = nil;
79 watchedPaths = nil;
80 prefs = nil;
81 fm = [NSFileManager defaultManager];
82 }
83
84 return self;
85 }
86
87 //
88 // NSCopying
89 //
90 - (id)copyWithZone:(NSZone *)zone
91 {
92 BrowserViewer *vwr = [[BrowserViewer alloc] init];
93 return vwr;
94 }
95
96 //
97 // ViewersProtocol
98 //
99 - (void)setRootPath:(NSString *)rpath
100 viewedPath:(NSString *)vpath
101 selection:(NSArray *)selection
102 delegate:(id)adelegate
103 viewApps:(BOOL)canview
104 {
105 int colswidth, winwidth;
106 unsigned int style = 0;
107
108 [self checkUsesShelf];
109 [self checkUsesCellsIcons];
110
111 [self setDelegate: adelegate];
112 ASSIGN (rootPath, rpath);
113 TEST_RELEASE (selectedPaths);
114 selectedPaths = [[NSArray alloc] initWithObjects: rootPath, nil];
115 viewsapps = canview;
116 autoSynchronize = YES;
117
118 colswidth = [delegate browserColumnsWidth];
119 resizeIncrement = colswidth;
120 winwidth = [delegate getWindowFrameWidth];
121 columns = (int)winwidth / resizeIncrement;
122 columnsWidth = (winwidth - 16) / columns;
123
124 [self setAutoresizingMask: (NSViewWidthSizable | NSViewHeightSizable)];
125
126 if (browser != nil) {
127 [browser removeFromSuperview];
128 RELEASE (browser);
129 }
130
131 style = GWColumnIconMask;
132 if (viewsapps) {
133 style |= GWViewsPaksgesMask;
134 }
135 if (cellsIcons) {
136 style |= GWIconCellsMask;
137 }
138
139 browser = [[Browser2 alloc] initWithBasePath: rootPath
140 visibleColumns: columns
141 styleMask: style
142 delegate: self
143 remoteHost: nil];
144
145 [browser setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
146 [self addSubview: browser];
147
148 [[NSNotificationCenter defaultCenter] removeObserver: self];
149
150 [[NSNotificationCenter defaultCenter] addObserver: self
151 selector: @selector(fileSystemWillChange:)
152 name: GWFileSystemWillChangeNotification
153 object: nil];
154
155 [[NSNotificationCenter defaultCenter] addObserver: self
156 selector: @selector(fileSystemDidChange:)
157 name: GWFileSystemDidChangeNotification
158 object: nil];
159
160 [[NSNotificationCenter defaultCenter] addObserver: self
161 selector: @selector(sortTypeDidChange:)
162 name: GWSortTypeDidChangeNotification
163 object: nil];
164
165 if (watchedPaths != nil) {
166 [self unsetWatchers];
167 RELEASE (watchedPaths);
168 watchedPaths = nil;
169 }
170
171 if (selection) {
172 [self setCurrentSelection: selection];
173 [delegate addPathToHistory: selection];
174 } else {
175 [self setCurrentSelection: [NSArray arrayWithObject: rootPath]];
176 [delegate addPathToHistory: [NSArray arrayWithObject: rootPath]];
177 }
178 }
179
180 - (NSString *)menuName
181 {
182 return @"Browser";
183 }
184
185 - (NSString *)shortCut
186 {
187 return @"b";
188 }
189
190 - (BOOL)usesShelf
191 {
192 return usesShelf;
193 }
194
195 - (NSSize)resizeIncrements
196 {
197 return NSZeroSize;
198 }
199
200 - (NSImage *)miniicon
201 {
202 NSBundle *bundle = [NSBundle bundleForClass: [self class]];
203 NSString *imgpath = [bundle pathForResource: @"miniwindow" ofType: @"tiff"];
204 NSImage *img = [[NSImage alloc] initWithContentsOfFile: imgpath];
205 return AUTORELEASE (img);
206 }
207
208 - (BOOL)hasPreferences
209 {
210 return YES;
211 }
212
213 - (id)prefController
214 {
215 if (prefs == nil) {
216 prefs = [[BrowserViewerPref alloc] init];
217 }
218
219 return prefs;
220 }
221
222 - (void)setSelectedPaths:(NSArray *)paths
223 {
224 NSString *newPath;
225 NSArray *components;
226 NSMutableArray *wpaths;
227 NSString *s;
228 BOOL isDir;
229 int i, j;
230
231 if ((paths == nil) || ([paths count] == 0)
232 || ([paths isEqualToArray: selectedPaths])) {
233 return;
234 }
235
236 ASSIGN (selectedPaths, paths);
237 [delegate setTheSelectedPaths: paths];
238
239 newPath = [paths objectAtIndex: 0];
240 [fm fileExistsAtPath: newPath isDirectory: &isDir];
241 if ((isDir == NO) || ([paths count] > 1)) {
242 newPath = [newPath stringByDeletingLastPathComponent];
243 } else {
244 if (([gworkspace isPakageAtPath: newPath]) && (viewsapps == NO)) {
245 newPath = [newPath stringByDeletingLastPathComponent];
246 }
247 }
248
249 if (lastPath && [lastPath isEqual: newPath]) {
250 return;
251 } else {
252 ASSIGN (lastPath, newPath);
253 }
254
255 components = [newPath pathComponents];
256 wpaths = [NSMutableArray arrayWithCapacity: 1];
257 s = [NSString string];
258
259 for (i = 0; i < [components count]; i++) {
260 s = [s stringByAppendingPathComponent: [components objectAtIndex: i]];
261 [wpaths addObject: s];
262 }
263
264 if (watchedPaths == nil) {
265 watchedPaths = [wpaths mutableCopy];
266 [self setWatchers];
267
268 } else {
269 int count = [wpaths count];
270
271 for (i = 0; i < [watchedPaths count]; i++) {
272 NSString *s1, *s2;
273
274 s1 = [watchedPaths objectAtIndex: i];
275
276 if (count > i) {
277 s2 = [wpaths objectAtIndex: i];
278 } else {
279 i = count;
280 break;
281 }
282
283 if ([s1 isEqualToString: s2] == NO) {
284 break;
285 }
286 }
287
288 for (j = i; j < [watchedPaths count]; j++) {
289 [self unsetWatcherForPath: [watchedPaths objectAtIndex: j]];
290 }
291
292 for (j = i; j < [wpaths count]; j++) {
293 [self setWatcherForPath: [wpaths objectAtIndex: j]];
294 }
295
296 TEST_RELEASE (watchedPaths);
297 watchedPaths = [wpaths mutableCopy];
298 }
299 }
300
301 - (void)setCurrentSelection:(NSArray *)paths
302 {
303 [browser setPathAndSelection: paths];
304 [self setSelectedPaths: paths];
305 [delegate updateTheInfoString];
306 }
307
308 - (NSPoint)positionForSlidedImage
309 {
310 NSPoint p = [browser positionForSlidedImage];
311
312 if (NSEqualPoints(p, NSZeroPoint) == NO) {
313 return [[self window] convertBaseToScreen: p];
314 }
315
316 return NSZeroPoint;
317 }
318
319 - (void)selectAll
320 {
321 [browser selectAllInLastColumn];
322 }
323
324 - (NSArray *)selectedPaths
325 {
326 return selectedPaths;
327 }
328
329 - (NSString *)currentViewedPath
330 {
331 return [browser pathToLastColumn];
332 }
333
334 - (NSPoint)locationOfIconForPath:(NSString *)path
335 {
336 if ([selectedPaths containsObject: path]) {
337 NSPoint p = [browser positionOfLastIcon];
338
339 if (NSEqualPoints(p, NSZeroPoint) == NO) {
340 return [self convertPoint: p toView: nil];
341 }
342
343 return NSZeroPoint;
344 }
345
346 return NSZeroPoint;
347 }
348
349 - (void)unsetWatchers
350 {
351 int i;
352
353 [[NSNotificationCenter defaultCenter] removeObserver: self
354 name: GWFileWatcherFileDidChangeNotification object: nil];
355
356 for (i = 0; i < [watchedPaths count]; i++) {
357 [self unsetWatcherForPath: [watchedPaths objectAtIndex: i]];
358 }
359 }
360
361 - (void)setResizeIncrement:(int)increment
362 {
363 resizeIncrement = increment;
364 }
365
366 - (void)setAutoSynchronize:(BOOL)value
367 {
368 autoSynchronize = value;
369 }
370
371 - (void)thumbnailsDidChangeInPaths:(NSArray *)paths
372 {
373 if (paths == nil) {
374 [self renewAll];
375 return;
376 } else {
377 int i;
378
379 for (i = 0; i < [paths count]; i++) {
380 NSString *dir = [paths objectAtIndex: i];
381
382 if ([browser isShowingPath: dir]) {
383 [browser reloadColumnWithPath: dir];
384 [browser renewLastIcon];
385 }
386 }
387 }
388 }
389
390 - (id)viewerView
391 {
392 return browser;
393 }
394
395 - (BOOL)viewsApps
396 {
397 return viewsapps;
398 }
399
400 - (id)delegate
401 {
402 return delegate;
403 }
404
405 - (void)setDelegate:(id)anObject
406 {
407 delegate = anObject;
408 }
409
410 //
411 // End of ViewersProtocol
412 //
413
414 - (void)checkUsesShelf
415 {
416 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
417 usesShelf = ![defaults boolForKey: @"viewersDontUsesShelf"];
418 }
419
420 - (void)checkUsesCellsIcons
421 {
422 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
423 cellsIcons = [defaults boolForKey: @"browserCellsIcons"];
424 }
425
426 - (void)renewAll
427 {
428 NSArray *spats = RETAIN (selectedPaths);
429
430 [self setRootPath: rootPath
431 viewedPath: nil
432 selection: spats
433 delegate: delegate
434 viewApps: viewsapps];
435
436 [self setCurrentSelection: [NSArray arrayWithObject: rootPath]];
437 [self resizeWithOldSuperviewSize: [self frame].size];
438 [self setCurrentSelection: spats];
439 [self resizeWithOldSuperviewSize: [self frame].size];
440 RELEASE (spats);
441 }
442
443 - (void)validateRootPathAfterOperation:(NSDictionary *)opdict
444 {
445 if ([rootPath isEqualToString: fixPath(@"/", 0)] == YES) {
446 return;
447
448 } else {
449 NSString *operation = [opdict objectForKey: @"operation"];
450 NSString *source = [opdict objectForKey: @"source"];
451 NSArray *files = [opdict objectForKey: @"files"];
452 int i;
453
454 if (operation == NSWorkspaceMoveOperation
455 || operation == NSWorkspaceDestroyOperation
456 || operation == GWorkspaceRenameOperation
457 || operation == NSWorkspaceRecycleOperation
458 || operation == GWorkspaceRecycleOutOperation
459 || operation == GWorkspaceEmptyRecyclerOperation) {
460
461 if (operation == GWorkspaceRenameOperation) {
462 files = [NSArray arrayWithObject: [source lastPathComponent]];
463 source = [source stringByDeletingLastPathComponent];
464 }
465
466 for (i = 0; i < [files count]; i++) {
467 NSString *fpath = [source stringByAppendingPathComponent: [files objectAtIndex: i]];
468
469 if (subPathOfPath(fpath, rootPath)
470 || [fpath isEqualToString: rootPath]) {
471 [self closeNicely];
472 break;
473 }
474 }
475
476 }
477 }
478 }
479
480 - (void)fileSystemWillChange:(NSNotification *)notification
481 {
482 NSDictionary *dict = (NSDictionary *)[notification object];
483 NSString *operation = [dict objectForKey: @"operation"];
484 NSString *source = [dict objectForKey: @"source"];
485 NSString *destination = [dict objectForKey: @"destination"];
486 NSArray *files = [dict objectForKey: @"files"];
487
488 [self validateRootPathAfterOperation: dict];
489
490 [delegate startIndicatorForOperation: operation];
491
492 if (operation == NSWorkspaceMoveOperation
493 || operation == NSWorkspaceCopyOperation
494 || operation == NSWorkspaceLinkOperation
495 || operation == NSWorkspaceDuplicateOperation
496 || operation == NSWorkspaceRecycleOperation
497 || operation == GWorkspaceRecycleOutOperation) {
498
499 if ([browser isShowingPath: destination]) {
500 [browser addDimmedCellsWithNames: files
501 inColumnWithPath: destination];
502
503 [self unsetWatchersFromPath: destination];
504
505 [browser extendSelectionWithDimmedFiles: files
506 fromColumnWithPath: destination];
507 }
508 }
509
510 if (operation == GWorkspaceRenameOperation) {
511 NSString *dest = [destination stringByDeletingLastPathComponent];
512
513 if ([browser isShowingPath: dest]) {
514 [self unsetWatchersFromPath: dest];
515 }
516 }
517
518 if (operation == GWorkspaceCreateFileOperation
519 || operation == GWorkspaceCreateDirOperation) {
520 if ([browser isShowingPath: destination]) {
521 [self unsetWatchersFromPath: destination];
522 }
523 }
524
525 if (operation == NSWorkspaceMoveOperation
526 || operation == NSWorkspaceDestroyOperation
527 || operation == NSWorkspaceRecycleOperation
528 || operation == GWorkspaceRecycleOutOperation
529 || operation == GWorkspaceEmptyRecyclerOperation) {
530
531 if ([browser isShowingPath: source]) {
532 [self unsetWatchersFromPath: source];
533
534 [browser lockCellsWithNames: files
535 inColumnWithPath: source];
536
537 [browser extendSelectionWithDimmedFiles: files
538 fromColumnWithPath: source];
539 }
540 }
541 }
542
543 - (void)fileSystemDidChange:(NSNotification *)notification
544 {
545 NSDictionary *dict = (NSDictionary *)[notification object];
546 NSString *operation = [dict objectForKey: @"operation"];
547 NSString *source = [dict objectForKey: @"source"];
548 NSString *destination = [dict objectForKey: @"destination"];
549 NSArray *files = [dict objectForKey: @"files"];
550
551 [delegate stopIndicatorForOperation: operation];
552
553 if (operation == NSWorkspaceMoveOperation
554 || operation == NSWorkspaceCopyOperation
555 || operation == NSWorkspaceLinkOperation
556 || operation == NSWorkspaceDuplicateOperation
557 || operation == NSWorkspaceRecycleOperation
558 || operation == GWorkspaceRecycleOutOperation) {
559
560 if ([browser isShowingPath: destination]) {
561 [browser reloadFromColumnWithPath: destination];
562 [self reSetWatchersFromPath: destination];
563 }
564 }
565
566 if (operation == NSWorkspaceMoveOperation
567 || operation == NSWorkspaceDestroyOperation
568 || operation == NSWorkspaceRecycleOperation
569 || operation == GWorkspaceRecycleOutOperation
570 || operation == GWorkspaceEmptyRecyclerOperation) {
571
572 if ([browser isShowingPath: source]) {
573 [browser reloadFromColumnWithPath: source];
574 [self reSetWatchersFromPath: source];
575 }
576 }
577
578 if (operation == GWorkspaceRenameOperation) {
579 NSString *dest = [destination stringByDeletingLastPathComponent];
580
581 if ([browser isShowingPath: dest]) {
582 [browser reloadFromColumnWithPath: dest];
583
584 if ([[self window] isKeyWindow]) {
585 NSString *newname = [destination lastPathComponent];
586
587 [browser selectCellsWithNames: [NSArray arrayWithObject: newname]
588 inColumnWithPath: dest
589 sendAction: YES];
590 }
591
592 [self reSetWatchersFromPath: dest];
593 }
594 }
595
596 if (operation == GWorkspaceCreateFileOperation
597 || operation == GWorkspaceCreateDirOperation) {
598
599 if ([browser isShowingPath: destination]) {
600 [browser reloadFromColumnWithPath: destination];
601
602 if ([[self window] isKeyWindow]) {
603 [browser selectCellsWithNames: files
604 inColumnWithPath: destination
605 sendAction: YES];
606
607 [browser selectForEditingInLastColumn];
608 }
609
610 [self reSetWatchersFromPath: destination];
611 }
612 }
613
614 [delegate updateTheInfoString];
615 }
616
617 - (void)sortTypeDidChange:(NSNotification *)notification
618 {
619 NSString *notifPath = [notification object];
620
621 if (notifPath != nil) {
622 [browser reloadColumnWithPath: notifPath];
623 } else {
624 [self renewAll];
625 }
626 }
627
628 - (void)watcherNotification:(NSNotification *)notification
629 {
630 NSDictionary *notifdict = (NSDictionary *)[notification object];
631 NSString *path = [notifdict objectForKey: @"path"];
632
633 if ([watchedPaths containsObject: path] == NO) {
634 return;
635
636 } else {
637 NSString *event = [notifdict objectForKey: @"event"];
638
639 if (event == GWWatchedDirectoryDeleted) {
640 if ((subPathOfPath(path, rootPath) == YES)
641 || ([path isEqualToString: rootPath] == YES)) {
642 [self closeNicely];
643 return;
644 } else {
645 NSString *s = [path stringByDeletingLastPathComponent];
646
647 [self unsetWatcherForPath: path];
648
649 if ([browser isShowingPath: s]) {
650 [browser reloadFromColumnWithPath: s];
651 }
652
653 return;
654 }
655 }
656
657 if (event == GWFileDeletedInWatchedDirectory) {
658 if (subPathOfPath(path, rootPath) == NO) {
659 [browser removeCellsWithNames: [notifdict objectForKey: @"files"]
660 inColumnWithPath: path];
661 return;
662 }
663 }
664
665 if (event == GWFileCreatedInWatchedDirectory) {
666 if (subPathOfPath(path, rootPath) == NO) {
667 [browser addCellsWithNames: [notifdict objectForKey: @"files"]
668 inColumnWithPath: path];
669 }
670 }
671 }
672 }
673
674 - (void)setWatchers
675 {
676 int i;
677
678 for (i = 0; i < [watchedPaths count]; i++) {
679 [self setWatcherForPath: [watchedPaths objectAtIndex: i]];
680 }
681
682 [[NSNotificationCenter defaultCenter] addObserver: self
683 selector: @selector(watcherNotification:)
684 name: GWFileWatcherFileDidChangeNotification
685 object: nil];
686 }
687
688 - (void)setWatcherForPath:(NSString *)path
689 {
690 [gworkspace addWatcherForPath: path];
691 }
692
693 - (void)unsetWatcherForPath:(NSString *)path
694 {
695 [gworkspace removeWatcherForPath: path];
696 }
697
698 - (void)unsetWatchersFromPath:(NSString *)path
699 {
700 unsigned index = [watchedPaths indexOfObject: path];
701
702 if (index != NSNotFound) {
703 int i;
704
705 for (i = index; i < [watchedPaths count]; i++) {
706 [self unsetWatcherForPath: [watchedPaths objectAtIndex: i]];
707 }
708 }
709 }
710
711 - (void)reSetWatchersFromPath:(NSString *)path
712 {
713 unsigned index = [watchedPaths indexOfObject: path];
714
715 if (index != NSNotFound) {
716 int i, count;
717 BOOL isdir;
718
719 count = [watchedPaths count];
720
721 for (i = index; i < count; i++) {
722 NSString *wpath = [watchedPaths objectAtIndex: i];
723
724 if ([fm fileExistsAtPath: wpath isDirectory: &isdir] && isdir) {
725 [self setWatcherForPath: wpath];
726 } else {
727 [watchedPaths removeObjectAtIndex: i];
728 count--;
729 i--;
730 }
731 }
732 }
733 }
734
735 - (void)closeNicely
736 {
737 NSTimer *t;
738
739 [self unsetWatchers];
740 [[NSNotificationCenter defaultCenter] removeObserver: self];
741
742 t = [NSTimer timerWithTimeInterval: 0.5 target: self
743 selector: @selector(close:) userInfo: nil repeats: NO];
744 [[NSRunLoop currentRunLoop] addTimer: t forMode: NSDefaultRunLoopMode];
745 }
746
747 - (void)close:(id)sender
748 {
749 [[self window] performClose: nil];
750 }
751
752 - (void)resizeWithOldSuperviewSize:(NSSize)oldFrameSize
753 {
754 NSRect r = [self frame];
755 float w = r.size.width;
756 float h = r.size.height;
757 NSRect brect = NSMakeRect(0, 0, w, h - 2);
758 int col = columns;
759
760 CHECKRECT (brect);
761 [browser setFrame: brect];
762
763 if (autoSynchronize == YES) {
764 columns = (int)[[self window] frame].size.width / resizeIncrement;
765
766 if (col != columns) {
767 [self renewAll];
768 }
769 }
770 }
771
772 @end
773
774 //
775 // Browser2 Delegate Methods
776 //
777 @implementation BrowserViewer (Browser2DelegateMethods)
778
779 - (void)currentSelectedPaths:(NSArray *)paths
780 {
781 if (autoSynchronize == YES) {
782 [self setSelectedPaths: paths];
783 [delegate addPathToHistory: paths];
784 [delegate updateTheInfoString];
785 }
786 }
787
788 - (void)openSelectedPaths:(NSArray *)paths newViewer:(BOOL)isnew
789 {
790 [self setSelectedPaths: paths];
791 [gworkspace openSelectedPaths: paths newViewer: isnew];
792 }
793
794 @end

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26