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

Contents of /gnustep/usr-apps/gworkspace/GWorkspace/GWorkspace.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (show annotations) (download)
Sat Oct 4 14:45:18 2003 UTC (20 years, 6 months ago) by esersale
Branch: MAIN
Changes since 1.16: +10 -7 lines

2003-10-03 Enrico Sersale  <enrico@imago.ro>

  * GWorkspace/FileOperations/FileOperation.m
    -calculateNumFiles doesn't block anymore.
    the stop button now works.

  * Viewers/SmallIconsViewer/SmallIconsPanel.m
    in -selectIconWithPath: now the view scroll to show the icon.
-

1 /* GWorkspace.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 #include <Foundation/Foundation.h>
26 #include <AppKit/AppKit.h>
27 #include <math.h>
28 #ifdef GNUSTEP
29 #include "GWLib.h"
30 #include "GWFunctions.h"
31 #include "GWNotifications.h"
32 #include "ViewersProtocol.h"
33 #else
34 #include <GWorkspace/GWLib.h>
35 #include <GWorkspace/GWFunctions.h>
36 #include <GWorkspace/GWNotifications.h>
37 #include <GWorkspace/ViewersProtocol.h>
38 #endif
39 #include "GWorkspace.h"
40 #include "FileOperations/FileOperation.h"
41 #include "Dialogs/Dialogs.h"
42 #include "Dialogs/OpenWithController.h"
43 #include "Dialogs/RunExternalController.h"
44 #include "Inspectors/InspectorsController.h"
45 #include "Apps/Apps.h"
46 #include "Finder/FinderController.h"
47 #include "Preferences/PrefController.h"
48 #include "Fiend/Fiend.h"
49 #include "ViewersWindow.h"
50 #include "Desktop/DesktopWindow.h"
51 #include "Desktop/DesktopView.h"
52 #include "TShelf/TShelfWin.h"
53 #include "Recycler/Recycler.h"
54 #include "History/History.h"
55 #include "GNUstep.h"
56
57 NSString *defaulteditor = @"nedit.app";
58 NSString *defaultxterm = @"xterm";
59
60 static GWorkspace *gworkspace = nil;
61
62 @implementation GWorkspace
63
64 #ifndef byname
65 #define byname 0
66 #define bykind 1
67 #define bydate 2
68 #define bysize 3
69 #define byowner 4
70 #endif
71
72 #ifndef CACHED_MAX
73 #define CACHED_MAX 20
74 #endif
75
76 //
77 // GWProtocol
78 //
79 + (GWorkspace *)gworkspace
80 {
81 if (gworkspace == nil) {
82 gworkspace = [[GWorkspace alloc] init];
83 }
84 return gworkspace;
85 }
86
87 - (BOOL)performFileOperation:(NSString *)operation
88 source:(NSString *)source
89 destination:(NSString *)destination
90 files:(NSArray *)files
91 tag:(int *)tag
92 {
93 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
94 NSString *confirmString = [operation stringByAppendingString: @"Confirm"];
95 BOOL confirm = !([defaults boolForKey: confirmString]);
96 NSRect scr = [[NSScreen mainScreen] visibleFrame];
97 NSRect wrect = NSZeroRect;
98 FileOperation *op;
99 NSRect wr;
100 int i;
101
102 #define WMARGIN 50
103 #define WSHIFT 10
104
105 scr.origin.x += WMARGIN;
106 scr.origin.y += WMARGIN;
107 scr.size.width -= (WMARGIN * 2);
108 scr.size.height -= (WMARGIN * 2);
109
110 for (i = 0; i < [operations count]; i++) {
111 op = [operations objectAtIndex: i];
112 wr = [op winRect];
113
114 if (NSEqualRects(wr, NSZeroRect) == NO) {
115 wrect = NSMakeRect(wr.origin.x + WSHIFT,
116 wr.origin.y - wr.size.height - WSHIFT,
117 wr.size.width,
118 wr.size.height);
119
120 if (NSContainsRect(scr, wrect) == NO) {
121 wrect = NSMakeRect(scr.origin.x,
122 scr.size.height - wr.size.height,
123 wr.size.width,
124 wr.size.height);
125 break;
126 }
127 }
128 }
129
130 op = [[FileOperation alloc] initWithOperation: operation
131 source: source
132 destination: destination
133 files: files
134 useConfirmation: confirm
135 showWindow: showFileOpStatus
136 windowRect: wrect];
137 [operations addObject: op];
138 RELEASE (op);
139
140 return YES;
141 }
142
143 - (void)performFileOperationWithDictionary:(id)opdict
144 {
145 NSString *operation = [opdict objectForKey: @"operation"];
146 NSString *source = [opdict objectForKey: @"source"];
147 NSString *destination = [opdict objectForKey: @"destination"];
148 NSArray *files = [opdict objectForKey: @"files"];
149 int tag;
150
151 [self performFileOperation: operation source: source
152 destination: destination files: files tag: &tag];
153 }
154
155 - (BOOL)application:(NSApplication *)theApplication
156 openFile:(NSString *)filename
157 {
158 BOOL isDir;
159
160 if ([filename isAbsolutePath]
161 && [fm fileExistsAtPath: filename isDirectory: &isDir]) {
162 if (isDir) {
163 id viewer = [self newViewerAtPath: filename
164 canViewApps: [GWLib isPakageAtPath: filename]];
165 [viewer orderFrontRegardless];
166 return YES;
167 } else {
168 [self selectFile: filename
169 inFileViewerRootedAtPath: [filename stringByDeletingLastPathComponent]];
170 [self openFile: filename];
171 return YES;
172 }
173 }
174
175 return NO;
176 }
177
178 - (BOOL)openFile:(NSString *)fullPath
179 {
180 NSPoint p = [currentViewer locationOfIconForPath: fullPath];
181 NSView *aview = [currentViewer viewer];
182 NSImage *image;
183 NSString *defApp;
184 NSString *type;
185
186 [ws getInfoForFile: fullPath application: &defApp type: &type];
187 image = [GWLib iconForFile: fullPath ofType: type];
188
189 return [self openFile: fullPath fromImage: image at: p inView: aview];
190 }
191
192 - (BOOL)openFile:(NSString *)fullPath
193 fromImage:(NSImage *)anImage
194 at:(NSPoint)point
195 inView:(NSView *)aView
196 {
197 NSString *appName;
198 NSString *type;
199 id fiendLeaf;
200 id app;
201 NSPoint toPoint;
202 BOOL dissolved;
203
204 #define RETURN_OPEN \
205 return [ws openFile: fullPath withApplication: appName]
206
207 [ws getInfoForFile: fullPath application: &appName type: &type];
208
209 if (appName == nil) {
210 appName = defEditor;
211 }
212
213 if (animateLaunck == NO) RETURN_OPEN;
214
215 if ((fiend == nil) || ([[fiend myWin] isVisible] == NO)) RETURN_OPEN;
216
217 fiendLeaf = [fiend fiendLeafOfType: NSApplicationFileType withName: appName];
218 if (fiendLeaf == nil) RETURN_OPEN;
219
220 app = [self connectApplication: appName];
221 if (app == nil) {
222 dissolved = [fiend dissolveLeaf: fiendLeaf];
223 }
224
225 if (point.x <= 0 || point.y <= 0) RETURN_OPEN;
226
227 toPoint = [fiend positionOfLeaf: fiendLeaf];
228 if (toPoint.x <= 0 || toPoint.y <= 0) RETURN_OPEN;
229
230 point = [[aView window] convertBaseToScreen: point];
231 [self slideImage: anImage from: point to: toPoint];
232
233 RETURN_OPEN;
234 }
235
236 - (BOOL)selectFile:(NSString *)fullPath
237 inFileViewerRootedAtPath:(NSString *)rootFullpath
238 {
239 NSArray *paths;
240 int l1, l2;
241 BOOL isdirRoot, isdirFpath;
242 BOOL newViewer = YES;
243
244 if ([fm fileExistsAtPath: fullPath isDirectory: &isdirFpath] == NO) {
245 return NO;
246 }
247
248 if ((rootFullpath == nil) || ([rootFullpath length] == 0)) {
249 newViewer = NO;
250 } else if (([fm fileExistsAtPath: rootFullpath isDirectory: &isdirRoot] && isdirRoot) == NO) {
251 return NO;
252 }
253
254 l1 = [rootFullpath length];
255 l2 = [fullPath length];
256
257 if ((l1 > l2) || ((l1 == l2) && (isdirFpath == NO))) {
258 return NO;
259 }
260
261 if (newViewer) {
262 if ([[fullPath substringToIndex: l1] isEqualToString: rootFullpath] == NO) {
263 return NO;
264 }
265 }
266
267 paths = [NSArray arrayWithObject: fullPath];
268
269 if (newViewer) {
270 ViewersWindow *viewer = [self viewerRootedAtPath: rootFullpath];
271
272 if ((viewer == nil) || ([rootFullpath isEqual: fixPath(@"/", 0)])) {
273 NSString *app, *type;
274 [ws getInfoForFile: rootFullpath application: &app type: &type];
275 viewer = [self newViewerAtPath: rootFullpath canViewApps: (type == NSApplicationFileType)];
276 }
277
278 [viewer setViewerSelection: paths];
279 [viewer orderFrontRegardless];
280 } else {
281 [self setSelectedPaths: paths];
282 [rootViewer setViewerSelection: paths];
283 }
284
285 return YES;
286 }
287
288 - (void)rootViewerSelectFiles:(NSArray *)paths
289 {
290 [rootViewer makeKeyAndOrderFront: nil];
291 [self setSelectedPaths: paths];
292 [rootViewer setViewerSelection: paths];
293 }
294
295 - (void)slideImage:(NSImage *)image
296 from:(NSPoint)fromPoint
297 to:(NSPoint)toPoint
298 {
299 [[NSWorkspace sharedWorkspace] slideImage: image from: fromPoint to: toPoint];
300 }
301
302 - (void)openSelectedPaths:(NSArray *)paths newViewer:(BOOL)newv
303 {
304 NSString *apath;
305 NSString *defApp, *type;
306 int i;
307
308 [self setSelectedPaths: paths];
309
310 for (i = 0; i < [paths count]; i++) {
311 apath = [paths objectAtIndex: i];
312
313 [ws getInfoForFile: apath application: &defApp type: &type];
314
315 if ((type == NSDirectoryFileType) || (type == NSFilesystemFileType)) {
316 if (newv) {
317 [self newViewerAtPath: apath canViewApps: NO];
318 }
319 } else if ((type == NSPlainFileType)
320 || ([type isEqual: NSShellCommandFileType])) {
321 if ([GWLib isPakageAtPath: apath]) {
322 if (newv) {
323 [self newViewerAtPath: apath canViewApps: YES];
324 } else {
325 [self openFile: apath];
326 }
327 } else {
328 [self openFile: apath];
329 }
330 } else if (type == NSApplicationFileType) {
331 if (newv) {
332 [self newViewerAtPath: apath canViewApps: YES];
333 } else {
334 [ws launchApplication: apath];
335 }
336 }
337 }
338 }
339
340 - (void)openSelectedPathsWith
341 {
342 BOOL found = NO;
343 int i;
344
345 for (i = 0; i < [selectedPaths count]; i++) {
346 NSString *spath = [selectedPaths objectAtIndex: i];
347 NSDictionary *attributes = [fm fileAttributesAtPath: spath traverseLink: YES];
348
349 if ([attributes objectForKey: NSFileType] != NSFileTypeDirectory) {
350 NSString *defApp, *fileType;
351
352 [ws getInfoForFile: spath application: &defApp type: &fileType];
353
354 if((fileType != NSPlainFileType) && (fileType != NSShellCommandFileType)) {
355 found = YES;
356 }
357
358 } else {
359 found = YES;
360 }
361
362 if (found) {
363 break;
364 }
365 }
366
367 if (found == NO) {
368 [openWithController activate];
369 }
370 }
371
372 - (ViewersWindow *)newViewerAtPath:(NSString *)path canViewApps:(BOOL)viewapps
373 {
374 ViewersWindow *viewer = [[ViewersWindow alloc] initWithViewerTemplates: viewersTemplates
375 forPath: path viewPakages: viewapps
376 isRootViewer: NO onStart: starting];
377 [viewer activate];
378 [viewers addObject: viewer];
379 RELEASE (viewer);
380
381 return [viewers objectAtIndex: [viewers count] -1];
382 }
383
384 - (NSArray *)getSelectedPaths
385 {
386 return selectedPaths;
387 }
388
389 - (NSString *)trashPath
390 {
391 return trashPath;
392 }
393
394 - (NSArray *)viewersSearchPaths
395 {
396 return viewersSearchPaths;
397 }
398
399 - (BOOL)animateChdir
400 {
401 return animateChdir;
402 }
403
404 - (BOOL)animateLaunck
405 {
406 return animateLaunck;
407 }
408
409 - (BOOL)animateSlideBack
410 {
411 return animateSlideBack;
412 }
413
414 - (BOOL)usesContestualMenu
415 {
416 return contestualMenu;
417 }
418 //
419 // end of GWProtocol
420 //
421
422 + (void)initialize
423 {
424 static BOOL initialized = NO;
425
426 if (initialized == YES) {
427 return;
428 }
429
430 initialized = YES;
431 }
432
433 + (void)registerForServices
434 {
435 NSArray *sendTypes = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
436 NSArray *returnTypes = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
437 [NSApp registerServicesMenuSendTypes: sendTypes returnTypes: returnTypes];
438 }
439
440 - (void)dealloc
441 {
442 [[NSDistributedNotificationCenter defaultCenter] removeObserver: self];
443 [[NSNotificationCenter defaultCenter] removeObserver: self];
444 RELEASE (defEditor);
445 RELEASE (defXterm);
446 RELEASE (defXtermArgs);
447 RELEASE (selectedPaths);
448 TEST_RELEASE (rootViewer);
449 RELEASE (viewers);
450 TEST_RELEASE (viewersTemplates);
451 TEST_RELEASE (viewersSearchPaths);
452 TEST_RELEASE (inspController);
453 TEST_RELEASE (appsViewer);
454 TEST_RELEASE (finder);
455 TEST_RELEASE (fiend);
456 TEST_RELEASE (history);
457 TEST_RELEASE (recycler);
458 TEST_RELEASE (trashPath);
459 RELEASE (openWithController);
460 RELEASE (runExtController);
461 RELEASE (operations);
462 TEST_RELEASE (desktopWindow);
463 TEST_RELEASE (tshelfWin);
464 TEST_RELEASE (tshelfBackground);
465 [super dealloc];
466 }
467
468 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
469 {
470 NSUserDefaults *defaults;
471 NSString *processName;
472 NSMutableArray *viewersPaths;
473 NSString *path;
474 id result;
475 NSArray *keys;
476 NSMutableDictionary *viewersPrefs;
477 BOOL hideSysFiles;
478 int i, count;
479
480 [isa registerForServices];
481
482 fm = [NSFileManager defaultManager];
483 ws = [NSWorkspace sharedWorkspace];
484
485 defaults = [NSUserDefaults standardUserDefaults];
486 processName = [[NSProcessInfo processInfo] processName];
487 [defaults setObject: processName forKey: @"GSWorkspaceApplication"];
488
489 result = [defaults stringForKey: @"defaulteditor"];
490 if (result == nil) {
491 defEditor = [[NSString alloc] initWithString: defaulteditor];
492 } else {
493 ASSIGN (defEditor, result);
494 }
495
496 result = [defaults stringForKey: @"defxterm"];
497 if (result == nil) {
498 defXterm = [[NSString alloc] initWithString: defaultxterm];
499 } else {
500 ASSIGN (defXterm, result);
501 }
502
503 result = [defaults stringForKey: @"defaultxtermargs"];
504 if (result == nil) {
505 defXtermArgs = nil;
506 } else {
507 ASSIGN (defXtermArgs, result);
508 }
509
510 result = [defaults objectForKey: @"shelfcellswidth"];
511 if (result == nil) {
512 shelfCellsWidth = 90;
513 } else {
514 shelfCellsWidth = [result intValue];
515 }
516
517 result = [defaults objectForKey: @"defaultsorttype"];
518 if (result == nil) {
519 [defaults setObject: @"0" forKey: @"defaultsorttype"];
520 [GWLib setDefSortType: byname];
521 } else {
522 [GWLib setDefSortType: [result intValue]];
523 }
524
525 showFileOpStatus = [defaults boolForKey: @"showfopstatus"];
526
527 result = [defaults objectForKey: @"GSFileBrowserHideDotFiles"];
528 if (result) {
529 hideSysFiles = [result boolValue];
530 } else {
531 NSDictionary *domain = [defaults persistentDomainForName: NSGlobalDomain];
532
533 result = [domain objectForKey: @"GSFileBrowserHideDotFiles"];
534 if (result) {
535 hideSysFiles = [result boolValue];
536 } else {
537 hideSysFiles = NO;
538 }
539 }
540 [GWLib setHideSysFiles: hideSysFiles];
541
542 animateChdir = ![defaults boolForKey: @"nochdiranim"];
543 animateLaunck = ![defaults boolForKey: @"nolaunchanim"];
544 animateSlideBack = ![defaults boolForKey: @"noslidebackanim"];
545
546 contestualMenu = [defaults boolForKey: @"UsesContestualMenu"];
547
548 usesThumbnails = [defaults boolForKey: @"usesthumbnails"];
549 [GWLib setUseThumbnails: usesThumbnails];
550
551 result = [defaults dictionaryForKey: @"viewersprefs"];
552 if (result) {
553 viewersPrefs = [result mutableCopy];
554 } else {
555 viewersPrefs = [[NSMutableDictionary alloc] initWithCapacity: 1];
556 }
557 keys = [viewersPrefs allKeys];
558 for (i = 0; i < [keys count]; i++) {
559 BOOL exists, isdir;
560 NSString *key = [keys objectAtIndex: i];
561
562 if ([key isEqual: @"rootViewer"] == NO) {
563 exists = [fm fileExistsAtPath: key isDirectory: &isdir];
564 if((exists == NO) || (isdir == NO)) {
565 [viewersPrefs removeObjectForKey: key];
566 }
567 }
568 }
569 [defaults setObject: viewersPrefs forKey: @"viewersprefs"];
570 RELEASE (viewersPrefs);
571
572 result = [defaults objectForKey: @"viewerspaths"];
573 if (result == nil) {
574 viewersPaths = [NSMutableArray new];
575 } else {
576 viewersPaths = [result mutableCopy];
577 }
578 count = [viewersPaths count];
579 for (i = 0; i < count; i++) {
580 BOOL exists, isdir;
581 NSString *path = [viewersPaths objectAtIndex: i];
582 exists = [fm fileExistsAtPath: path isDirectory: &isdir];
583 if((exists == NO) || (isdir == NO)) {
584 [viewersPaths removeObjectAtIndex: i];
585 i--;
586 count--;
587 }
588 }
589 [defaults setObject: viewersPaths forKey: @"viewerspaths"];
590 RELEASE (viewersPaths);
591
592 selectedPaths = [[NSArray alloc] initWithObjects: NSHomeDirectory(), nil];
593
594 operations = [NSMutableArray new];
595 oprefnum = 0;
596
597 appsViewer = [[AppsViewer alloc] init];
598 history = [[History alloc] init];
599 prefController = [[PrefController alloc] init];
600 inspController = nil;
601 finder = nil;
602 fiend = nil;
603
604 tshelfBackground = nil;
605 [self showHideDesktop: [defaults boolForKey: @"desktop"]];
606
607 if ([defaults boolForKey: @"usefiend"]) {
608 [self showFiend: nil];
609 } else {
610 [self hideFiend: nil];
611 }
612
613 if ([defaults boolForKey: @"tshelf"]) {
614 [self showTShelf: nil];
615 } else {
616 [self hideTShelf: nil];
617 }
618
619 [self createRecycler];
620
621 openWithController = [[OpenWithController alloc] init];
622 runExtController = [[RunExternalController alloc] init];
623
624 starting = YES;
625 viewers = [[NSMutableArray alloc] initWithCapacity: 1];
626 viewersSearchPaths = [[NSMutableArray alloc] initWithCapacity: 1];
627 [self makeViewersTemplates];
628
629 rootViewer = nil;
630 [self showViewer: nil];
631
632 viewersPaths = [defaults objectForKey: @"viewerspaths"];
633 for (i = 0; i < [viewersPaths count]; i++) {
634 path = [viewersPaths objectAtIndex: i];
635 [self newViewerAtPath: path
636 canViewApps: ([GWLib isPakageAtPath: path] ? YES : NO)];
637 }
638
639 result = [defaults objectForKey: @"cachedmax"];
640 if (result) {
641 [GWLib setCachedMax: [result intValue]];
642 } else {
643 [GWLib setCachedMax: CACHED_MAX];
644 [defaults setObject: [NSNumber numberWithInt: CACHED_MAX] forKey: @"cachedmax"];
645 }
646
647 starting = NO;
648
649 [defaults synchronize];
650
651 [[NSDistributedNotificationCenter defaultCenter] addObserver: self
652 selector: @selector(fileSystemWillChange:)
653 name: GWFileSystemWillChangeNotification
654 object: nil];
655
656 [[NSDistributedNotificationCenter defaultCenter] addObserver: self
657 selector: @selector(fileSystemDidChange:)
658 name: GWFileSystemDidChangeNotification
659 object: nil];
660
661 [[NSNotificationCenter defaultCenter] addObserver: self
662 selector: @selector(iconAnimationChanged:)
663 name: GWIconAnimationChangedNotification
664 object: nil];
665
666 [[NSDistributedNotificationCenter defaultCenter] addObserver: self
667 selector: @selector(thumbnailsDidChange:)
668 name: GWThumbnailsDidChangeNotification
669 object: nil];
670 }
671
672 - (BOOL)applicationShouldTerminate:(NSApplication *)app
673 {
674 int i;
675
676 #define TEST_CLOSE(o, w) if ((o) && ([w isVisible])) [w close]
677
678 [self updateDefaults];
679
680 TEST_CLOSE (rootViewer, rootViewer);
681 for (i = 0; i < [viewers count]; i++) {
682 id vwr = [viewers objectAtIndex: i];
683 TEST_CLOSE (vwr, vwr);
684 }
685 TEST_CLOSE (appsViewer, [appsViewer myWin]);
686 TEST_CLOSE (inspController, [inspController myWin]);
687 TEST_CLOSE (finder, [finder myWin]);
688 TEST_CLOSE (prefController, [prefController myWin]);
689 TEST_CLOSE (fiend, [fiend myWin]);
690 TEST_CLOSE (recycler, [recycler myWin]);
691 TEST_CLOSE (recycler, [recycler recyclerWin]);
692 TEST_CLOSE (history, [history myWin]);
693 TEST_CLOSE (desktopWindow, desktopWindow);
694 TEST_CLOSE (tshelfWin, tshelfWin);
695
696 return YES;
697 }
698
699 - (NSString *)defEditor
700 {
701 return defEditor;
702 }
703
704 - (NSString *)defXterm
705 {
706 return defXterm;
707 }
708
709 - (NSString *)defXtermArgs
710 {
711 return defXtermArgs;
712 }
713
714 - (History *)historyWindow
715 {
716 return history;
717 }
718
719 - (id)rootViewer
720 {
721 return rootViewer;
722 }
723
724 - (ViewersWindow *)viewerRootedAtPath:(NSString *)vpath
725 {
726 int i;
727
728 for (i = 0; i < [viewers count]; i++) {
729 ViewersWindow *viewer = [viewers objectAtIndex: i];
730
731 if ([[viewer rootPath] isEqual: vpath]) {
732 return viewer;
733 }
734 }
735
736 return nil;
737 }
738
739 - (id)desktopView
740 {
741 if (desktopWindow != nil) {
742 return [desktopWindow desktopView];
743 }
744 return nil;
745 }
746
747 - (void)showHideDesktop:(BOOL)active
748 {
749 if (active) {
750 if (desktopWindow == nil) {
751 desktopWindow = [[DesktopWindow alloc] init];
752 [desktopWindow activate];
753 } else if ([desktopWindow isVisible] == NO) {
754 [desktopWindow activate];
755 }
756 [self makeTshelfBackground];
757 } else {
758 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
759 [[desktopWindow desktopView] saveDefaults];
760 [desktopWindow deactivate];
761 }
762 }
763 }
764
765 - (NSImage *)tshelfBackground
766 {
767 return tshelfBackground;
768 }
769
770 - (void)makeTshelfBackground
771 {
772 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
773 ASSIGN (tshelfBackground, [[desktopWindow desktopView] shelfBackground]);
774 }
775 }
776
777 - (NSColor *)tshelfBackColor
778 {
779 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
780 return [[desktopWindow desktopView] backColor];
781 }
782 return nil;
783 }
784
785 - (void)changeDefaultEditor:(NSString *)editor
786 {
787 ASSIGN (defEditor, editor);
788 }
789
790 - (void)changeDefaultXTerm:(NSString *)xterm arguments:(NSString *)args
791 {
792 ASSIGN (defXterm, xterm);
793 ASSIGN (defXtermArgs, args);
794 }
795
796 - (void)updateDefaults
797 {
798 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
799 NSMutableArray *viewersPaths;
800 int i;
801
802 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
803 [[desktopWindow desktopView] saveDefaults];
804 [defaults setBool: YES forKey: @"desktop"];
805 } else {
806 [defaults setBool: NO forKey: @"desktop"];
807 }
808
809 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
810 [tshelfWin saveDefaults];
811 [defaults setBool: YES forKey: @"tshelf"];
812 } else {
813 [defaults setBool: NO forKey: @"tshelf"];
814 }
815
816 if ((inspController != nil) && ([[inspController myWin] isVisible])) {
817 [inspController updateDefaults];
818 }
819
820 if ([[appsViewer myWin] isVisible]) {
821 [appsViewer updateDefaults];
822 }
823
824 if (finder != nil) {
825 [finder updateDefaults];
826 }
827
828 if ([[prefController myWin] isVisible]) {
829 [prefController updateDefaults];
830 }
831
832 if ((fiend != nil) && ([[fiend myWin] isVisible])) {
833 [fiend updateDefaults];
834 [defaults setBool: YES forKey: @"usefiend"];
835 } else {
836 [defaults setBool: NO forKey: @"usefiend"];
837 }
838
839 [recycler updateDefaults];
840 [history updateDefaults];
841 [rootViewer updateDefaults];
842
843 viewersPaths = [NSMutableArray arrayWithCapacity: 1];
844 for (i = 0; i < [viewers count]; i++) {
845 ViewersWindow *viewer = [viewers objectAtIndex: i];
846 [viewer updateDefaults];
847 [viewersPaths addObject: [viewer rootPath]];
848 }
849
850 [defaults setObject: viewersPaths forKey: @"viewerspaths"];
851
852 [defaults setObject: defEditor forKey: @"defaulteditor"];
853 [defaults setObject: defXterm forKey: @"defxterm"];
854 if (defXtermArgs != nil) {
855 [defaults setObject: defXtermArgs forKey: @"defaultxtermargs"];
856 }
857
858 [defaults setObject: [NSString stringWithFormat: @"%i", shelfCellsWidth]
859 forKey: @"shelfcellswidth"];
860
861 [defaults setBool: !animateChdir forKey: @"nochdiranim"];
862 [defaults setBool: !animateLaunck forKey: @"nolaunchanim"];
863 [defaults setBool: !animateSlideBack forKey: @"noslidebackanim"];
864
865 [defaults setBool: usesThumbnails forKey: @"usesthumbnails"];
866
867 [defaults synchronize];
868 }
869
870 - (void)startXTermOnDirectory:(NSString *)dirPath
871 {
872 NSTask *task = [NSTask new];
873 AUTORELEASE (task);
874 [task setCurrentDirectoryPath: dirPath];
875 [task setLaunchPath: defXterm];
876 if (defXtermArgs != nil) {
877 NSArray *args = [defXtermArgs componentsSeparatedByString:@" "];
878 [task setArguments: args];
879 }
880 [task launch];
881 }
882
883 - (int)defaultSortType
884 {
885 return [GWLib defSortType];
886 }
887
888 - (void)setDefaultSortType:(int)type
889 {
890 [GWLib setDefSortType: type];
891 }
892
893 - (int)shelfCellsWidth
894 {
895 return shelfCellsWidth;
896 }
897
898 - (int)defaultShelfCellsWidth
899 {
900 [self setShelfCellsWidth: 90];
901 return 90;
902 }
903
904 - (void)setShelfCellsWidth:(int)w
905 {
906 shelfCellsWidth = w;
907
908 [[NSNotificationCenter defaultCenter]
909 postNotificationName: GWShelfCellsWidthChangedNotification
910 object: nil];
911 }
912
913 - (void)createRecycler
914 {
915 NSDictionary *env;
916 NSString *basePath, *tpath;
917 BOOL isdir;
918
919 env = [[NSProcessInfo processInfo] environment];
920 basePath = [env objectForKey: @"GNUSTEP_USER_ROOT"];
921 if (basePath == nil) {
922 basePath = [NSHomeDirectory() stringByAppendingPathComponent: @"GNUstep"];
923 NSLog (@"Warning - GNUSTEP_USER_ROOT is not set - using %@", basePath);
924 }
925
926 tpath = [basePath stringByAppendingPathComponent: @".GWTrash"];
927
928 if ([fm fileExistsAtPath: tpath isDirectory: &isdir] == NO) {
929 [fm createDirectoryAtPath: tpath attributes: nil];
930
931 } else {
932 if (isdir == NO) {
933 NSLog (@"Warning - %@ is not a directory - quitting now!", tpath);
934 [[NSApplication sharedApplication] terminate: self];
935 }
936 }
937
938 ASSIGN (trashPath, tpath);
939 recycler = [[Recycler alloc] initWithTrashPath: trashPath];
940 [recycler activate];
941 }
942
943 - (BOOL)validateMenuItem:(NSMenuItem *)anItem
944 {
945 NSString *title = [anItem title];
946
947 if ([title isEqual: NSLocalizedString(@"Empty Recycler", @"")]) {
948 return [recycler isFull];
949 } else if ([title isEqual: NSLocalizedString(@"Put Away", @"")]) {
950 if ([recycler isFull] && [recycler isFull]) {
951 if ([recycler selectedPath] != nil) {
952 return YES;
953 }
954 }
955 return NO;
956 }
957
958 if ([title isEqual: NSLocalizedString(@"File Operations...", @"")]) {
959 return [operations count];
960 }
961
962 if ([title isEqual: NSLocalizedString(@"Open With...", @"")]) {
963 BOOL found = NO;
964 int i;
965
966 for (i = 0; i < [selectedPaths count]; i++) {
967 NSString *spath = [selectedPaths objectAtIndex: i];
968 NSDictionary *attributes = [fm fileAttributesAtPath: spath traverseLink: YES];
969
970 if ([attributes objectForKey: NSFileType] != NSFileTypeDirectory) {
971 NSString *defApp, *fileType;
972
973 [ws getInfoForFile: spath application: &defApp type: &fileType];
974
975 if((fileType != NSPlainFileType) && (fileType != NSShellCommandFileType)) {
976 found = YES;
977 }
978
979 } else {
980 found = YES;
981 }
982
983 if (found) {
984 break;
985 }
986 }
987
988 return !found;
989 }
990
991 return YES;
992 }
993
994 - (void)makeViewersTemplates
995 {
996 NSMutableArray *bundlesPaths;
997 NSArray *bPaths;
998 NSString *home;
999 int i;
1000
1001 #define VERIFY_VIEWERS( x ) \
1002 if (!x) { \
1003 NSRunAlertPanel(NSLocalizedString(@"error", @""), \
1004 NSLocalizedString(@"No Viewer found! Quitting now.", @""), \
1005 NSLocalizedString(@"OK", @""), nil, nil); \
1006 [[NSApplication sharedApplication] terminate: nil]; \
1007 }
1008
1009 TEST_RELEASE (viewersTemplates);
1010 viewersTemplates = [[NSMutableArray alloc] initWithCapacity: 1];
1011
1012 bundlesPaths = [NSMutableArray array];
1013
1014 //load all default Viewers
1015 bPaths = [self bundlesWithExtension: @"viewer"
1016 inDirectory: [[NSBundle mainBundle] resourcePath]];
1017 [bundlesPaths addObjectsFromArray: bPaths];
1018
1019 VERIFY_VIEWERS (bundlesPaths && [bundlesPaths count]);
1020
1021 //load user Viewers
1022 home = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
1023 [bundlesPaths addObjectsFromArray: [self bundlesWithExtension: @"viewer"
1024 inDirectory: [home stringByAppendingPathComponent: @"GWorkspace"]]];
1025
1026 for (i = 0; i < [bundlesPaths count]; i++) {
1027 NSString *bpath = [bundlesPaths objectAtIndex: i];
1028 NSBundle *bundle = [NSBundle bundleWithPath: bpath];
1029
1030 if (bundle) {
1031 Class principalClass = [bundle principalClass];
1032
1033 if (principalClass) {
1034 if ([principalClass conformsToProtocol: @protocol(ViewersProtocol)]) {
1035 id<ViewersProtocol> vwr = AUTORELEASE ([[principalClass alloc] init]);
1036
1037 [self addViewer: vwr withBundlePath: bpath];
1038 }
1039 }
1040 }
1041 }
1042
1043 VERIFY_VIEWERS([viewersTemplates count]);
1044
1045 [[NSNotificationCenter defaultCenter] addObserver: self
1046 selector: @selector(watcherNotification:)
1047 name: GWFileWatcherFileDidChangeNotification
1048 object: nil];
1049
1050 [viewersSearchPaths addObject: [[NSBundle mainBundle] resourcePath]];
1051 [viewersSearchPaths addObject: [home stringByAppendingPathComponent: @"GWorkspace"]];
1052
1053 for (i = 0; i < [viewersSearchPaths count]; i++) {
1054 NSString *spath = [viewersSearchPaths objectAtIndex: i];
1055 [GWLib addWatcherForPath: spath];
1056 }
1057 }
1058
1059 - (void)addViewer:(id)vwr withBundlePath:(NSString *)bpath
1060 {
1061 NSString *name = [vwr menuName];
1062 BOOL found = NO;
1063 int i = 0;
1064
1065 for (i = 0; i < [viewersTemplates count]; i++) {
1066 NSDictionary *vdict = [viewersTemplates objectAtIndex: i];
1067 NSString *vname = [vdict objectForKey: @"name"];
1068
1069 if ([vname isEqual: name]) {
1070 found = YES;
1071 break;
1072 }
1073 }
1074
1075 if (found == NO) {
1076 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity: 1];
1077
1078 [dict setObject: vwr forKey: @"viewer"];
1079 [dict setObject: name forKey: @"name"];
1080 [dict setObject: bpath forKey: @"path"];
1081 [viewersTemplates addObject: dict];
1082
1083 if ([vwr hasPreferences]) {
1084 [prefController addPreference: [vwr prefController]];
1085 }
1086
1087 [[NSNotificationCenter defaultCenter]
1088 postNotificationName: GWViewersListDidChangeNotification
1089 object: viewersTemplates];
1090 }
1091 }
1092
1093 - (void)removeViewerWithBundlePath:(NSString *)bpath
1094 {
1095 int i, count;
1096
1097 count = [viewersTemplates count];
1098 for (i = 0; i < count; i++) {
1099 NSDictionary *vdict = [viewersTemplates objectAtIndex: i];
1100 id vwr = [vdict objectForKey: @"viewer"];
1101 NSString *path = [vdict objectForKey: @"path"];
1102
1103 if ([path isEqual: bpath]) {
1104 if ((count - 1) == 0) {
1105 NSRunAlertPanel(NSLocalizedString(@"error", @""),
1106 NSLocalizedString(@"No Viewer found! Quitting now.", @""),
1107 NSLocalizedString(@"OK", @""), nil, nil);
1108 [[NSApplication sharedApplication] terminate: nil];
1109 }
1110
1111 if ([vwr hasPreferences]) {
1112 [prefController removePreference: [vwr prefController]];
1113 }
1114
1115 [viewersTemplates removeObject: vdict];
1116 [[NSNotificationCenter defaultCenter]
1117 postNotificationName: GWViewersListDidChangeNotification
1118 object: viewersTemplates];
1119 break;
1120 }
1121 }
1122 }
1123
1124 - (NSMutableArray *)bundlesWithExtension:(NSString *)extension
1125 inDirectory:(NSString *)dirpath
1126 {
1127 NSMutableArray *bundleList = [NSMutableArray array];
1128 NSEnumerator *enumerator;
1129 NSString *dir;
1130 BOOL isDir;
1131
1132 if (!(([fm fileExistsAtPath: dirpath isDirectory: &isDir]) && isDir)) {
1133 return nil;
1134 }
1135
1136 enumerator = [[fm directoryContentsAtPath: dirpath] objectEnumerator];
1137 while ((dir = [enumerator nextObject])) {
1138 if ([[dir pathExtension] isEqualToString: extension]) {
1139 [bundleList addObject: [dirpath stringByAppendingPathComponent: dir]];
1140 }
1141 }
1142
1143 return bundleList;
1144 }
1145
1146 - (NSArray *)viewersPaths
1147 {
1148 NSMutableArray *vpaths = [NSMutableArray arrayWithCapacity: 1];
1149 int i;
1150
1151 for (i = 0; i < [viewersTemplates count]; i++) {
1152 NSDictionary *vdict = [viewersTemplates objectAtIndex: i];
1153 [vpaths addObject: [vdict objectForKey: @"path"]];
1154 }
1155
1156 return vpaths;
1157 }
1158
1159 - (void)watcherNotification:(NSNotification *)notification
1160 {
1161 NSDictionary *notifdict = (NSDictionary *)[notification object];
1162 NSString *path = [notifdict objectForKey: @"path"];
1163 NSArray *vpaths = [self viewersPaths];
1164
1165 if ([viewersSearchPaths containsObject: path] == NO) {
1166 return;
1167
1168 } else {
1169 NSString *event = [notifdict objectForKey: @"event"];
1170 int i, count;
1171
1172 if (event == GWFileDeletedInWatchedDirectory) {
1173 NSArray *files = [notifdict objectForKey: @"files"];
1174
1175 count = [files count];
1176 for (i = 0; i < count; i++) {
1177 NSString *fname = [files objectAtIndex: i];
1178 NSString *bpath = [path stringByAppendingPathComponent: fname];
1179
1180 if ([vpaths containsObject: bpath]) {
1181 [self removeViewerWithBundlePath: bpath];
1182 i--;
1183 count--;
1184 }
1185 }
1186
1187 } else if (event == GWFileCreatedInWatchedDirectory) {
1188 NSArray *files = [notifdict objectForKey: @"files"];
1189
1190 for (i = 0; i < [files count]; i++) {
1191 NSString *fname = [files objectAtIndex: i];
1192 NSString *bpath = [path stringByAppendingPathComponent: fname];
1193 NSBundle *bundle = [NSBundle bundleWithPath: bpath];
1194
1195 if (bundle) {
1196 Class principalClass = [bundle principalClass];
1197
1198 if (principalClass) {
1199 if ([principalClass conformsToProtocol: @protocol(ViewersProtocol)]) {
1200 id<ViewersProtocol> vwr = AUTORELEASE ([[principalClass alloc] init]);
1201
1202 [self addViewer: vwr withBundlePath: bpath];
1203 }
1204 }
1205 }
1206 }
1207 }
1208 }
1209 }
1210
1211 - (void)viewerHasClosed:(id)sender
1212 {
1213 if (sender != rootViewer) {
1214 [viewers removeObject: sender];
1215 }
1216 }
1217
1218 - (void)setCurrentViewer:(ViewersWindow *)viewer
1219 {
1220 currentViewer = viewer;
1221 }
1222
1223 - (void)iconAnimationChanged:(NSNotification *)notif
1224 {
1225 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
1226
1227 animateChdir = ![defaults boolForKey: @"nochdiranim"];
1228 animateLaunck = ![defaults boolForKey: @"nolaunchanim"];
1229 animateSlideBack = ![defaults boolForKey: @"noslidebackanim"];
1230 }
1231
1232 - (BOOL)showFileOpStatus
1233 {
1234 return showFileOpStatus;
1235 }
1236
1237 - (void)setShowFileOpStatus:(BOOL)value
1238 {
1239 if (showFileOpStatus != value) {
1240 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
1241 showFileOpStatus = value;
1242 [defaults setBool: showFileOpStatus forKey: @"showfopstatus"];
1243 [defaults synchronize];
1244 }
1245 }
1246
1247 - (void)fileSystemWillChange:(NSNotification *)notif
1248 {
1249 NSDictionary *info = [notif userInfo];
1250 NSString *operation = [info objectForKey: @"operation"];
1251 NSString *source = [info objectForKey: @"source"];
1252 NSString *destination = [info objectForKey: @"destination"];
1253 NSArray *files = [info objectForKey: @"files"];
1254 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity: 1];
1255 NSString *opPtr = nil;
1256
1257 if ([operation isEqual: NSWorkspaceMoveOperation]) {
1258 opPtr = NSWorkspaceMoveOperation;
1259 } else if ([operation isEqual: NSWorkspaceCopyOperation]) {
1260 opPtr = NSWorkspaceCopyOperation;
1261 } else if ([operation isEqual: NSWorkspaceLinkOperation]) {
1262 opPtr = NSWorkspaceLinkOperation;
1263 } else if ([operation isEqual: NSWorkspaceDuplicateOperation]) {
1264 opPtr = NSWorkspaceDuplicateOperation;
1265 } else if ([operation isEqual: NSWorkspaceDestroyOperation]) {
1266 opPtr = NSWorkspaceDestroyOperation;
1267 } else if ([operation isEqual: NSWorkspaceRecycleOperation]) {
1268 opPtr = NSWorkspaceRecycleOperation;
1269 } else if ([operation isEqual: GWorkspaceRecycleOutOperation]) {
1270 opPtr = GWorkspaceRecycleOutOperation;
1271 } else if ([operation isEqual: GWorkspaceEmptyRecyclerOperation]) {
1272 opPtr = GWorkspaceEmptyRecyclerOperation;
1273 }
1274
1275 if (opPtr == NSWorkspaceMoveOperation
1276 || opPtr == NSWorkspaceCopyOperation
1277 || opPtr == NSWorkspaceLinkOperation
1278 || opPtr == NSWorkspaceDuplicateOperation
1279 || opPtr == NSWorkspaceRecycleOperation
1280 || opPtr == GWorkspaceRecycleOutOperation) {
1281 if ([viewersSearchPaths containsObject: destination] == NO) {
1282 [GWLib lockFiles: files inDirectoryAtPath: destination];
1283 }
1284 }
1285
1286 if (opPtr == NSWorkspaceMoveOperation
1287 || opPtr == NSWorkspaceDestroyOperation
1288 || opPtr == NSWorkspaceRecycleOperation
1289 || opPtr == GWorkspaceRecycleOutOperation
1290 || opPtr == GWorkspaceEmptyRecyclerOperation) {
1291 if ([viewersSearchPaths containsObject: source] == NO) {
1292 [GWLib lockFiles: files inDirectoryAtPath: source];
1293 }
1294 }
1295
1296 [dict setObject: opPtr forKey: @"operation"];
1297 [dict setObject: source forKey: @"source"];
1298 [dict setObject: destination forKey: @"destination"];
1299 [dict setObject: files forKey: @"files"];
1300
1301 [[NSNotificationCenter defaultCenter]
1302 postNotificationName: GWFileSystemWillChangeNotification
1303 object: dict];
1304 }
1305
1306 - (void)fileSystemDidChange:(NSNotification *)notif
1307 {
1308 NSDictionary *info = [notif userInfo];
1309 NSString *operation = [info objectForKey: @"operation"];
1310 NSString *source = [info objectForKey: @"source"];
1311 NSString *destination = [info objectForKey: @"destination"];
1312 NSArray *files = [info objectForKey: @"files"];
1313 NSArray *origfiles = [info objectForKey: @"origfiles"];
1314 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity: 1];
1315 NSString *opPtr = nil;
1316
1317 if ([operation isEqual: NSWorkspaceMoveOperation]) {
1318 opPtr = NSWorkspaceMoveOperation;
1319 } else if ([operation isEqual: NSWorkspaceCopyOperation]) {
1320 opPtr = NSWorkspaceCopyOperation;
1321 } else if ([operation isEqual: NSWorkspaceLinkOperation]) {
1322 opPtr = NSWorkspaceLinkOperation;
1323 } else if ([operation isEqual: NSWorkspaceDuplicateOperation]) {
1324 opPtr = NSWorkspaceDuplicateOperation;
1325 } else if ([operation isEqual: NSWorkspaceDestroyOperation]) {
1326 opPtr = NSWorkspaceDestroyOperation;
1327 } else if ([operation isEqual: NSWorkspaceRecycleOperation]) {
1328 opPtr = NSWorkspaceRecycleOperation;
1329 } else if ([operation isEqual: GWorkspaceRecycleOutOperation]) {
1330 opPtr = GWorkspaceRecycleOutOperation;
1331 } else if ([operation isEqual: GWorkspaceEmptyRecyclerOperation]) {
1332 opPtr = GWorkspaceEmptyRecyclerOperation;
1333 }
1334
1335 if (opPtr == NSWorkspaceMoveOperation
1336 || opPtr == NSWorkspaceCopyOperation
1337 || opPtr == NSWorkspaceLinkOperation
1338 || opPtr == NSWorkspaceDuplicateOperation
1339 || opPtr == NSWorkspaceRecycleOperation
1340 || opPtr == GWorkspaceRecycleOutOperation) {
1341 [GWLib unLockFiles: origfiles inDirectoryAtPath: destination];
1342 }
1343
1344 if (opPtr == NSWorkspaceMoveOperation
1345 || opPtr == NSWorkspaceDestroyOperation
1346 || opPtr == NSWorkspaceRecycleOperation
1347 || opPtr == GWorkspaceRecycleOutOperation
1348 || opPtr == GWorkspaceEmptyRecyclerOperation) {
1349 [GWLib unLockFiles: origfiles inDirectoryAtPath: source];
1350 }
1351
1352 [dict setObject: opPtr forKey: @"operation"];
1353 [dict setObject: source forKey: @"source"];
1354 [dict setObject: destination forKey: @"destination"];
1355 [dict setObject: files forKey: @"files"];
1356
1357 [[NSNotificationCenter defaultCenter]
1358 postNotificationName: GWFileSystemDidChangeNotification
1359 object: dict];
1360 }
1361
1362 - (void)setSelectedPaths:(NSArray *)paths
1363 {
1364 if (paths && ([selectedPaths isEqualToArray: paths] == NO)) {
1365 ASSIGN (selectedPaths, paths);
1366 if (inspController != nil) {
1367 [inspController setPaths: selectedPaths];
1368 }
1369
1370 [[NSNotificationCenter defaultCenter]
1371 postNotificationName: GWCurrentSelectionChangedNotification
1372 object: nil];
1373 }
1374 }
1375
1376 - (void)setSelectedPaths:(NSArray *)paths fromDesktopView:(DesktopView *)view
1377 {
1378 [rootViewer makeKeyAndOrderFront: nil];
1379 [self setSelectedPaths: paths];
1380 [rootViewer setViewerSelection: paths];
1381 }
1382
1383 - (void)setSelectedPaths:(NSArray *)paths
1384 fromDesktopView:(DesktopView *)view
1385 animateImage:(NSImage *)image
1386 startingAtPoint:(NSPoint)startp
1387 {
1388 #define SELRETURN \
1389 [self setSelectedPaths: paths]; \
1390 [rootViewer setViewerSelection: paths]; \
1391 return
1392
1393 NSPoint endp = [rootViewer positionForSlidedImage];
1394
1395 [rootViewer makeKeyAndOrderFront: nil];
1396
1397 if (animateChdir == NO) {
1398 SELRETURN;
1399 }
1400
1401 if (startp.x <= 0 || startp.y <= 0) {
1402 SELRETURN;
1403 }
1404
1405 if (endp.x <= 0 || endp.y <= 0) {
1406 SELRETURN;
1407 }
1408
1409 [self slideImage: image from: startp to: endp];
1410
1411 SELRETURN;
1412 }
1413
1414 - (NSArray *)selectedPaths
1415 {
1416 return selectedPaths;
1417 }
1418
1419 - (void)closeInspectors
1420 {
1421 [inspController release];
1422 inspController = nil;
1423 }
1424
1425 - (void)newObjectAtPath:(NSString *)basePath isDirectory:(BOOL)directory
1426 {
1427 NSString *fullPath;
1428 NSString *fileName;
1429 NSString *operation;
1430 NSMutableDictionary *notifObj;
1431 int suff;
1432
1433 if ([self verifyFileAtPath: basePath] == NO) {
1434 return;
1435 }
1436
1437 if ([fm isWritableFileAtPath: basePath] == NO) {
1438 NSString *err = NSLocalizedString(@"Error", @"");
1439 NSString *msg = NSLocalizedString(@"You have not write permission\nfor", @"");
1440 NSString *buttstr = NSLocalizedString(@"Continue", @"");
1441 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@ \"%@\"!\n", msg, basePath], buttstr, nil, nil);
1442 return;
1443 }
1444
1445 if (directory == YES) {
1446 fileName = @"NewFolder";
1447 operation = GWorkspaceCreateDirOperation;
1448 } else {
1449 fileName = @"NewFile";
1450 operation = GWorkspaceCreateFileOperation;
1451 }
1452
1453 fullPath = [basePath stringByAppendingPathComponent: fileName];
1454
1455 if ([fm fileExistsAtPath: fullPath] == YES) {
1456 suff = 1;
1457 while (1) {
1458 NSString *s = [fileName stringByAppendingFormat: @"%i", suff];
1459 fullPath = [basePath stringByAppendingPathComponent: s];
1460 if ([fm fileExistsAtPath: fullPath] == NO) {
1461 fileName = [NSString stringWithString: s];
1462 break;
1463 }
1464 suff++;
1465 }
1466 }
1467
1468 notifObj = [NSMutableDictionary dictionaryWithCapacity: 1];
1469 [notifObj setObject: operation forKey: @"operation"];
1470 [notifObj setObject: @"" forKey: @"source"];
1471 [notifObj setObject: basePath forKey: @"destination"];
1472 [notifObj setObject: [NSArray arrayWithObjects: fileName, nil] forKey: @"files"];
1473 [notifObj setObject: [NSArray arrayWithObjects: fileName, nil] forKey: @"origfiles"];
1474
1475 [[NSNotificationCenter defaultCenter]
1476 postNotificationName: GWFileSystemWillChangeNotification
1477 object: notifObj];
1478
1479 if (directory == YES) {
1480 [fm createDirectoryAtPath: fullPath attributes: nil];
1481 } else {
1482 [fm createFileAtPath: fullPath contents: nil attributes: nil];
1483 }
1484
1485 [[NSNotificationCenter defaultCenter]
1486 postNotificationName: GWFileSystemDidChangeNotification
1487 object: notifObj];
1488 }
1489
1490 - (void)duplicateFiles
1491 {
1492 NSString *basePath;
1493 NSMutableArray *files;
1494 int tag, i;
1495
1496 basePath = [NSString stringWithString: [selectedPaths objectAtIndex: 0]];
1497 basePath = [basePath stringByDeletingLastPathComponent];
1498
1499 if ([fm isWritableFileAtPath: basePath] == NO) {
1500 NSString *err = NSLocalizedString(@"Error", @"");
1501 NSString *msg = NSLocalizedString(@"You have not write permission\nfor", @"");
1502 NSString *buttstr = NSLocalizedString(@"Continue", @"");
1503 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@ \"%@\"!\n", msg, basePath], buttstr, nil, nil);
1504 return;
1505 }
1506
1507 files = [NSMutableArray arrayWithCapacity: 1];
1508 for (i = 0; i < [selectedPaths count]; i++) {
1509 [files addObject: [[selectedPaths objectAtIndex: i] lastPathComponent]];
1510 }
1511
1512 [self performFileOperation: NSWorkspaceDuplicateOperation
1513 source: basePath destination: basePath files: files tag: &tag];
1514 }
1515
1516 - (void)deleteFiles
1517 {
1518 NSString *basePath;
1519 NSMutableArray *files;
1520 int tag, i;
1521
1522 basePath = [NSString stringWithString: [selectedPaths objectAtIndex: 0]];
1523 basePath = [basePath stringByDeletingLastPathComponent];
1524
1525 if ([fm isWritableFileAtPath: basePath] == NO) {
1526 NSString *err = NSLocalizedString(@"Error", @"");
1527 NSString *msg = NSLocalizedString(@"You have not write permission\nfor", @"");
1528 NSString *buttstr = NSLocalizedString(@"Continue", @"");
1529 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@ \"%@\"!\n", msg, basePath], buttstr, nil, nil);
1530 return;
1531 }
1532
1533 files = [NSMutableArray arrayWithCapacity: 1];
1534 for (i = 0; i < [selectedPaths count]; i++) {
1535 [files addObject: [[selectedPaths objectAtIndex: i] lastPathComponent]];
1536 }
1537
1538 [self performFileOperation: NSWorkspaceDestroyOperation
1539 source: basePath destination: basePath files: files tag: &tag];
1540 }
1541
1542 - (BOOL)verifyFileAtPath:(NSString *)path
1543 {
1544 if ([fm fileExistsAtPath: path] == NO) {
1545 NSString *err = NSLocalizedString(@"Error", @"");
1546 NSString *msg = NSLocalizedString(@": no such file or directory!", @"");
1547 NSString *buttstr = NSLocalizedString(@"Continue", @"");
1548 NSMutableDictionary *notifObj = [NSMutableDictionary dictionaryWithCapacity: 1];
1549 NSString *basePath = [path stringByDeletingLastPathComponent];
1550
1551 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@%@", path, msg], buttstr, nil, nil);
1552
1553 [notifObj setObject: NSWorkspaceDestroyOperation forKey: @"operation"];
1554 [notifObj setObject: basePath forKey: @"source"];
1555 [notifObj setObject: basePath forKey: @"destination"];
1556 [notifObj setObject: [NSArray arrayWithObjects: path, nil] forKey: @"files"];
1557 [notifObj setObject: [NSArray arrayWithObjects: path, nil] forKey: @"origfiles"];
1558
1559 [[NSNotificationCenter defaultCenter]
1560 postNotificationName: GWFileSystemWillChangeNotification
1561 object: notifObj];
1562
1563 [[NSNotificationCenter defaultCenter]
1564 postNotificationName: GWFileSystemDidChangeNotification
1565 object: notifObj];
1566 return NO;
1567 }
1568
1569 return YES;
1570 }
1571
1572 - (void)setUsesThumbnails:(BOOL)value
1573 {
1574 int i;
1575
1576 if (usesThumbnails == value) {
1577 return;
1578 }
1579
1580 [GWLib setUseThumbnails: value];
1581
1582 usesThumbnails = value;
1583
1584 [rootViewer thumbnailsDidChangeInPaths: nil];
1585 for (i = 0; i < [viewers count]; i++) {
1586 [[viewers objectAtIndex: i] thumbnailsDidChangeInPaths: nil];
1587 }
1588 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
1589 [[desktopWindow desktopView] updateIcons];
1590 }
1591 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
1592 [tshelfWin updateIcons];
1593 }
1594 if (finder != nil) {
1595 [finder updateIcons];
1596 }
1597 }
1598
1599 - (void)thumbnailsDidChange:(NSNotification *)notif
1600 {
1601 NSDictionary *info = [notif userInfo];
1602 NSArray *deleted = [info objectForKey: @"deleted"];
1603 NSArray *created = [info objectForKey: @"created"];
1604 NSMutableArray *tmbdirs = [NSMutableArray array];
1605 int i;
1606
1607 if (usesThumbnails == NO) {
1608 return;
1609 } else {
1610 NSString *thumbnailDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
1611
1612 thumbnailDir = [thumbnailDir stringByAppendingPathComponent: @"Thumbnails"];
1613
1614 if ([deleted count]) {
1615 for (i = 0; i < [deleted count]; i++) {
1616 NSString *path = [deleted objectAtIndex: i];
1617 NSString *dir = [path stringByDeletingLastPathComponent];
1618
1619 if ([tmbdirs containsObject: dir] == NO) {
1620 [tmbdirs addObject: dir];
1621 }
1622 }
1623
1624 [rootViewer thumbnailsDidChangeInPaths: tmbdirs];
1625 for (i = 0; i < [viewers count]; i++) {
1626 [[viewers objectAtIndex: i] thumbnailsDidChangeInPaths: tmbdirs];
1627 }
1628 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
1629 [[desktopWindow desktopView] updateIcons];
1630 }
1631 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
1632 [tshelfWin updateIcons];
1633 }
1634 if (finder != nil) {
1635 [finder updateIcons];
1636 }
1637
1638 [tmbdirs removeAllObjects];
1639 }
1640
1641 if ([created count]) {
1642 NSString *dictName = @"thumbnails.plist";
1643 NSString *dictPath = [thumbnailDir stringByAppendingPathComponent: dictName];
1644 NSDictionary *tdict = [NSDictionary dictionaryWithContentsOfFile: dictPath];
1645
1646 for (i = 0; i < [created count]; i++) {
1647 NSString *key = [created objectAtIndex: i];
1648 NSString *dir = [key stringByDeletingLastPathComponent];
1649 NSString *tumbname = [tdict objectForKey: key];
1650 NSString *tumbpath = [thumbnailDir stringByAppendingPathComponent: tumbname];
1651
1652 if ([fm fileExistsAtPath: tumbpath]) {
1653 if ([tmbdirs containsObject: dir] == NO) {
1654 [tmbdirs addObject: dir];
1655 }
1656 }
1657 }
1658
1659 [rootViewer thumbnailsDidChangeInPaths: tmbdirs];
1660 for (i = 0; i < [viewers count]; i++) {
1661 [[viewers objectAtIndex: i] thumbnailsDidChangeInPaths: tmbdirs];
1662 }
1663 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
1664 [[desktopWindow desktopView] updateIcons];
1665 }
1666 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
1667 [tshelfWin updateIcons];
1668 }
1669 if (finder != nil) {
1670 [finder updateIcons];
1671 }
1672 }
1673 }
1674 }
1675
1676 - (id)connectApplication:(NSString *)appName
1677 {
1678 NSString *host;
1679 NSString *port;
1680 id app = nil;
1681
1682 host = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSHost"];
1683 if (host == nil) {
1684 host = @"";
1685 } else {
1686 NSHost *h = [NSHost hostWithName: host];
1687
1688 if ([h isEqual: [NSHost currentHost]] == YES) {
1689 host = @"";
1690 }
1691 }
1692
1693 port = [appName stringByDeletingPathExtension];
1694
1695 NS_DURING
1696 {
1697 app = [NSConnection rootProxyForConnectionWithRegisteredName: port
1698 host: host];
1699 }
1700 NS_HANDLER
1701 {
1702 app = nil;
1703 }
1704 NS_ENDHANDLER
1705
1706 return app;
1707 }
1708
1709 //
1710 // NSServicesRequests protocol
1711 //
1712
1713 - (id)validRequestorForSendType:(NSString *)sendType
1714 returnType:(NSString *)returnType
1715 {
1716 BOOL sendOK = NO;
1717 BOOL returnOK = NO;
1718
1719 if (sendType == nil) {
1720 sendOK = YES;
1721 } else if ([sendType isEqual: NSFilenamesPboardType] && (selectedPaths != nil)) {
1722 sendOK = YES;
1723 }
1724
1725 if (returnType == nil) {
1726 returnOK = YES;
1727 } else if ([returnType isEqual: NSFilenamesPboardType]) {
1728 returnOK = YES;
1729 }
1730
1731 if (sendOK && returnOK) {
1732 return self;
1733 }
1734
1735 return nil;
1736 }
1737
1738 - (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard
1739 {
1740 if ([[pboard types] indexOfObject: NSFilenamesPboardType] != NSNotFound) {
1741 return YES;
1742 }
1743
1744 return NO;
1745 }
1746
1747 - (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard
1748 types:(NSArray *)types
1749 {
1750 if ([types containsObject: NSFilenamesPboardType] == YES) {
1751 NSArray *typesDeclared = [NSArray arrayWithObject: NSFilenamesPboardType];
1752
1753 [pboard declareTypes: typesDeclared owner: self];
1754
1755 return [pboard setPropertyList: selectedPaths
1756 forType: NSFilenamesPboardType];
1757 }
1758
1759 return NO;
1760 }
1761
1762 //
1763 // Menu Operations
1764 //
1765 - (void)closeMainWin:(id)sender
1766 {
1767 [[[NSApplication sharedApplication] keyWindow] performClose: sender];
1768 }
1769
1770 - (void)showInfo:(id)sender
1771 {
1772 NSMutableDictionary *d = AUTORELEASE ([NSMutableDictionary new]);
1773 [d setObject: @"GWorkspace" forKey: @"ApplicationName"];
1774 [d setObject: NSLocalizedString(@"GNUstep Workspace Manager", @"")
1775 forKey: @"ApplicationDescription"];
1776 [d setObject: @"GWorkspace 0.6" forKey: @"ApplicationRelease"];
1777 [d setObject: @"10 2003" forKey: @"FullVersionID"];
1778 [d setObject: [NSArray arrayWithObjects:
1779 @"Enrico Sersale <enrico@imago.ro>.\n\
1780 InspectorViewer, PlistViewer, StringsViewer\n\
1781 by Fabien Vallon <fabien.vallon@fr.alcove.com>.\n\
1782 Makefiles and configuration scripts\n\
1783 by Alexey I. Froloff <raorn@altlinux.ru>.",
1784 nil]
1785 forKey: @"Authors"];
1786 [d setObject: NSLocalizedString(@"See http://www.gnustep.it/enrico/gworkspace", @"") forKey: @"URL"];
1787 [d setObject: @"Copyright (C) 2003 Free Software Foundation, Inc."
1788 forKey: @"Copyright"];
1789 [d setObject: NSLocalizedString(@"Released under the GNU General Public License 2.0", @"")
1790 forKey: @"CopyrightDescription"];
1791
1792 #ifdef GNUSTEP
1793 [NSApp orderFrontStandardInfoPanelWithOptions: d];
1794 #else
1795 [NSApp orderFrontStandardAboutPanel: d];
1796 #endif
1797 }
1798
1799 - (void)showPreferences:(id)sender
1800 {
1801 [prefController activate];
1802 }
1803
1804 - (void)showViewer:(id)sender
1805 {
1806 if(rootViewer == nil) {
1807 rootViewer = [[ViewersWindow alloc] initWithViewerTemplates: viewersTemplates
1808 forPath: fixPath(@"/", 0) viewPakages: NO
1809 isRootViewer: YES onStart: starting];
1810 } else {
1811 [self newViewerAtPath: fixPath(@"/", 0) canViewApps: NO];
1812 }
1813
1814 [rootViewer activate];
1815 }
1816
1817 - (void)showHistory:(id)sender
1818 {
1819 [history activate];
1820 }
1821
1822 - (void)showInspector:(id)sender
1823 {
1824 if (inspController == nil) {
1825 inspController = [[InspectorsController alloc] initForPaths: selectedPaths];
1826 }
1827 [[inspController myWin] makeKeyAndOrderFront: nil];
1828 }
1829
1830 - (void)showAttributesInspector:(id)sender
1831 {
1832 [self showInspector: nil];
1833 [inspController showAttributes];
1834 }
1835
1836 - (void)showContentsInspector:(id)sender
1837 {
1838 [self showInspector: nil];
1839 [inspController showContents];
1840 }
1841
1842 - (void)showToolsInspector:(id)sender
1843 {
1844 [self showInspector: nil];
1845 [inspController showTools];
1846 }
1847
1848 - (void)showPermissionsInspector:(id)sender
1849 {
1850 [self showInspector: nil];
1851 [inspController showPermissions];
1852 }
1853
1854 - (void)showApps:(id)sender
1855 {
1856 [appsViewer activate];
1857 }
1858
1859 - (void)showFileOps:(id)sender
1860 {
1861 int i;
1862
1863 for (i = 0; i < [operations count]; i++) {
1864 FileOperation *op = [operations objectAtIndex: i];
1865
1866 if ([op showsWindow] == NO) {
1867 [op showProgressWin];
1868 }
1869 }
1870 }
1871
1872 - (void)showFinder:(id)sender
1873 {
1874 if (finder == nil) {
1875 finder = [[FinderController alloc] init];
1876 }
1877 [finder activate];
1878 }
1879
1880 - (void)showFiend:(id)sender
1881 {
1882 NSMenu *menu = [[[NSApp mainMenu] itemWithTitle: NSLocalizedString(@"Tools", @"")] submenu];
1883 menu = [[menu itemWithTitle: NSLocalizedString(@"Fiend", @"")] submenu];
1884
1885 while (1) {
1886 if ([menu numberOfItems] == 0) {
1887 break;
1888 }
1889 [menu removeItemAtIndex: 0];
1890 }
1891
1892 [menu addItemWithTitle: NSLocalizedString(@"Hide Fiend", @"")
1893 action: @selector(hideFiend:) keyEquivalent: @""];
1894 [menu addItemWithTitle: NSLocalizedString(@"Remove Current Layer", @"")
1895 action: @selector(removeFiendLayer:) keyEquivalent: @""];
1896 [menu addItemWithTitle: NSLocalizedString(@"Rename Current Layer", @"")
1897 action: @selector(renameFiendLayer:) keyEquivalent: @""];
1898 [menu addItemWithTitle: NSLocalizedString(@"Add Layer...", @"")
1899 action: @selector(addFiendLayer:) keyEquivalent: @""];
1900
1901 if (fiend == nil) {
1902 fiend = [[Fiend alloc] init];
1903 }
1904 [fiend activate];
1905 }
1906
1907 - (void)hideFiend:(id)sender
1908 {
1909 NSMenu *menu = [[[NSApp mainMenu] itemWithTitle: NSLocalizedString(@"Tools", @"")] submenu];
1910 menu = [[menu itemWithTitle: NSLocalizedString(@"Fiend", @"")] submenu];
1911
1912 while (1) {
1913 if ([menu numberOfItems] == 0) {
1914 break;
1915 }
1916 [menu removeItemAtIndex: 0];
1917 }
1918
1919 [menu addItemWithTitle: NSLocalizedString(@"Show Fiend", @"")
1920 action: @selector(showFiend:) keyEquivalent: @""];
1921
1922 if (fiend != nil) {
1923 [fiend hide];
1924 }
1925 }
1926
1927 - (void)addFiendLayer:(id)sender
1928 {
1929 [fiend addLayer];
1930 }
1931
1932 - (void)removeFiendLayer:(id)sender
1933 {
1934 [fiend removeCurrentLayer];
1935 }
1936
1937 - (void)renameFiendLayer:(id)sender
1938 {
1939 [fiend renameCurrentLayer];
1940 }
1941
1942 - (void)showTShelf:(id)sender
1943 {
1944 NSMenu *menu = [[[NSApp mainMenu] itemWithTitle: NSLocalizedString(@"Tools", @"")] submenu];
1945 menu = [[menu itemWithTitle: NSLocalizedString(@"Tabbed Shelf", @"")] submenu];
1946
1947 while (1) {
1948 if ([menu numberOfItems] == 0) {
1949 break;
1950 }
1951 [menu removeItemAtIndex: 0];
1952 }
1953
1954 [menu addItemWithTitle: NSLocalizedString(@"Hide Tabbed Shelf", @"")
1955 action: @selector(hideTShelf:) keyEquivalent: @""];
1956 [menu addItemWithTitle: NSLocalizedString(@"Remove Current Tab", @"")
1957 action: @selector(removeTShelfTab:) keyEquivalent: @""];
1958 [menu addItemWithTitle: NSLocalizedString(@"Rename Current Tab", @"")
1959 action: @selector(renameTShelfTab:) keyEquivalent: @""];
1960 [menu addItemWithTitle: NSLocalizedString(@"Add Tab...", @"")
1961 action: @selector(addTShelfTab:) keyEquivalent: @""];
1962
1963 if (tshelfWin == nil) {
1964 tshelfWin = [[TShelfWin alloc] init];
1965 [tshelfWin activate];
1966 } else if ([tshelfWin isVisible] == NO) {
1967 [tshelfWin activate];
1968 }
1969 }
1970
1971 - (void)hideTShelf:(id)sender
1972 {
1973 NSMenu *menu = [[[NSApp mainMenu] itemWithTitle: NSLocalizedString(@"Tools", @"")] submenu];
1974 menu = [[menu itemWithTitle: NSLocalizedString(@"Tabbed Shelf", @"")] submenu];
1975
1976 while (1) {
1977 if ([menu numberOfItems] == 0) {
1978 break;
1979 }
1980 [menu removeItemAtIndex: 0];
1981 }
1982
1983 [menu addItemWithTitle: NSLocalizedString(@"Show Tabbed Shelf", @"")
1984 action: @selector(showTShelf:) keyEquivalent: @""];
1985
1986 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
1987 [tshelfWin saveDefaults];
1988 [tshelfWin deactivate];
1989 }
1990 }
1991
1992 - (void)addTShelfTab:(id)sender
1993 {
1994 [tshelfWin addTab];
1995 }
1996
1997 - (void)removeTShelfTab:(id)sender
1998 {
1999 [tshelfWin removeTab];
2000 }
2001
2002 - (void)renameTShelfTab:(id)sender
2003 {
2004 [tshelfWin renameTab];
2005 }
2006
2007 - (void)openWith:(id)sender
2008 {
2009 [self openSelectedPathsWith];
2010 }
2011
2012 - (void)runCommand:(id)sender
2013 {
2014 [runExtController activate];
2015 }
2016
2017 - (void)startXTerm:(id)sender
2018 {
2019 NSString *path;
2020 BOOL isdir;
2021
2022 path = [currentViewer currentViewedPath];
2023
2024 if (path == nil) {
2025 if ([selectedPaths count] > 1) {
2026 path = [[selectedPaths objectAtIndex: 0] stringByDeletingLastPathComponent];
2027 } else {
2028 path = [selectedPaths objectAtIndex: 0];
2029 [fm fileExistsAtPath: path isDirectory: &isdir];
2030 if (isdir == NO) {
2031 path = [path stringByDeletingLastPathComponent];
2032 }
2033 }
2034 }
2035
2036 [self startXTermOnDirectory: path];
2037 }
2038
2039 - (void)emptyRecycler:(id)sender
2040 {
2041 [recycler emptyRecycler];
2042 }
2043
2044 - (void)putAway:(id)sender
2045 {
2046 [recycler putAway];
2047 }
2048
2049 @end
2050
2051
2052

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