/[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.16 - (show annotations) (download)
Tue Sep 30 15:38:05 2003 UTC (20 years, 6 months ago) by esersale
Branch: MAIN
Changes since 1.15: +12 -117 lines
*** empty log message ***

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(fileSystemWillChangeNotification:)
653 name: GWFileSystemWillChangeNotification
654 object: nil];
655
656 [[NSDistributedNotificationCenter defaultCenter] addObserver: self
657 selector: @selector(fileSystemDidChangeNotification:)
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)fileSystemWillChangeNotification:(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)fileSystemDidChangeNotification:(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 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity: 1];
1314 NSString *opPtr = nil;
1315
1316 if ([operation isEqual: NSWorkspaceMoveOperation]) {
1317 opPtr = NSWorkspaceMoveOperation;
1318 } else if ([operation isEqual: NSWorkspaceCopyOperation]) {
1319 opPtr = NSWorkspaceCopyOperation;
1320 } else if ([operation isEqual: NSWorkspaceLinkOperation]) {
1321 opPtr = NSWorkspaceLinkOperation;
1322 } else if ([operation isEqual: NSWorkspaceDuplicateOperation]) {
1323 opPtr = NSWorkspaceDuplicateOperation;
1324 } else if ([operation isEqual: NSWorkspaceDestroyOperation]) {
1325 opPtr = NSWorkspaceDestroyOperation;
1326 } else if ([operation isEqual: NSWorkspaceRecycleOperation]) {
1327 opPtr = NSWorkspaceRecycleOperation;
1328 } else if ([operation isEqual: GWorkspaceRecycleOutOperation]) {
1329 opPtr = GWorkspaceRecycleOutOperation;
1330 } else if ([operation isEqual: GWorkspaceEmptyRecyclerOperation]) {
1331 opPtr = GWorkspaceEmptyRecyclerOperation;
1332 }
1333
1334 if (opPtr == NSWorkspaceMoveOperation
1335 || opPtr == NSWorkspaceCopyOperation
1336 || opPtr == NSWorkspaceLinkOperation
1337 || opPtr == NSWorkspaceDuplicateOperation
1338 || opPtr == NSWorkspaceRecycleOperation
1339 || opPtr == GWorkspaceRecycleOutOperation) {
1340 [GWLib unLockFiles: files inDirectoryAtPath: destination];
1341 }
1342
1343 if (opPtr == NSWorkspaceMoveOperation
1344 || opPtr == NSWorkspaceDestroyOperation
1345 || opPtr == NSWorkspaceRecycleOperation
1346 || opPtr == GWorkspaceRecycleOutOperation
1347 || opPtr == GWorkspaceEmptyRecyclerOperation) {
1348 [GWLib unLockFiles: files inDirectoryAtPath: source];
1349 }
1350
1351 [dict setObject: opPtr forKey: @"operation"];
1352 [dict setObject: source forKey: @"source"];
1353 [dict setObject: destination forKey: @"destination"];
1354 [dict setObject: files forKey: @"files"];
1355
1356 [[NSNotificationCenter defaultCenter]
1357 postNotificationName: GWFileSystemDidChangeNotification
1358 object: dict];
1359 }
1360
1361 - (void)setSelectedPaths:(NSArray *)paths
1362 {
1363 if (paths && ([selectedPaths isEqualToArray: paths] == NO)) {
1364 ASSIGN (selectedPaths, paths);
1365 if (inspController != nil) {
1366 [inspController setPaths: selectedPaths];
1367 }
1368
1369 [[NSNotificationCenter defaultCenter]
1370 postNotificationName: GWCurrentSelectionChangedNotification
1371 object: nil];
1372 }
1373 }
1374
1375 - (void)setSelectedPaths:(NSArray *)paths fromDesktopView:(DesktopView *)view
1376 {
1377 [rootViewer makeKeyAndOrderFront: nil];
1378 [self setSelectedPaths: paths];
1379 [rootViewer setViewerSelection: paths];
1380 }
1381
1382 - (void)setSelectedPaths:(NSArray *)paths
1383 fromDesktopView:(DesktopView *)view
1384 animateImage:(NSImage *)image
1385 startingAtPoint:(NSPoint)startp
1386 {
1387 #define SELRETURN \
1388 [self setSelectedPaths: paths]; \
1389 [rootViewer setViewerSelection: paths]; \
1390 return
1391
1392 NSPoint endp = [rootViewer positionForSlidedImage];
1393
1394 [rootViewer makeKeyAndOrderFront: nil];
1395
1396 if (animateChdir == NO) {
1397 SELRETURN;
1398 }
1399
1400 if (startp.x <= 0 || startp.y <= 0) {
1401 SELRETURN;
1402 }
1403
1404 if (endp.x <= 0 || endp.y <= 0) {
1405 SELRETURN;
1406 }
1407
1408 [self slideImage: image from: startp to: endp];
1409
1410 SELRETURN;
1411 }
1412
1413 - (NSArray *)selectedPaths
1414 {
1415 return selectedPaths;
1416 }
1417
1418 - (void)closeInspectors
1419 {
1420 [inspController release];
1421 inspController = nil;
1422 }
1423
1424 - (void)newObjectAtPath:(NSString *)basePath isDirectory:(BOOL)directory
1425 {
1426 NSString *fullPath;
1427 NSString *fileName;
1428 NSString *operation;
1429 NSMutableDictionary *notifObj;
1430 int suff;
1431
1432 if ([self verifyFileAtPath: basePath] == NO) {
1433 return;
1434 }
1435
1436 if ([fm isWritableFileAtPath: basePath] == NO) {
1437 NSString *err = NSLocalizedString(@"Error", @"");
1438 NSString *msg = NSLocalizedString(@"You have not write permission\nfor", @"");
1439 NSString *buttstr = NSLocalizedString(@"Continue", @"");
1440 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@ \"%@\"!\n", msg, basePath], buttstr, nil, nil);
1441 return;
1442 }
1443
1444 if (directory == YES) {
1445 fileName = @"NewFolder";
1446 operation = GWorkspaceCreateDirOperation;
1447 } else {
1448 fileName = @"NewFile";
1449 operation = GWorkspaceCreateFileOperation;
1450 }
1451
1452 fullPath = [basePath stringByAppendingPathComponent: fileName];
1453
1454 if ([fm fileExistsAtPath: fullPath] == YES) {
1455 suff = 1;
1456 while (1) {
1457 NSString *s = [fileName stringByAppendingFormat: @"%i", suff];
1458 fullPath = [basePath stringByAppendingPathComponent: s];
1459 if ([fm fileExistsAtPath: fullPath] == NO) {
1460 fileName = [NSString stringWithString: s];
1461 break;
1462 }
1463 suff++;
1464 }
1465 }
1466
1467 notifObj = [NSMutableDictionary dictionaryWithCapacity: 1];
1468 [notifObj setObject: operation forKey: @"operation"];
1469 [notifObj setObject: @"" forKey: @"source"];
1470 [notifObj setObject: basePath forKey: @"destination"];
1471 [notifObj setObject: [NSArray arrayWithObjects: fileName, nil] forKey: @"files"];
1472
1473 [[NSNotificationCenter defaultCenter]
1474 postNotificationName: GWFileSystemWillChangeNotification
1475 object: notifObj];
1476
1477 if (directory == YES) {
1478 [fm createDirectoryAtPath: fullPath attributes: nil];
1479 } else {
1480 [fm createFileAtPath: fullPath contents: nil attributes: nil];
1481 }
1482
1483 [[NSNotificationCenter defaultCenter]
1484 postNotificationName: GWFileSystemDidChangeNotification
1485 object: notifObj];
1486 }
1487
1488 - (void)duplicateFiles
1489 {
1490 NSString *basePath;
1491 NSMutableArray *files;
1492 int tag, i;
1493
1494 basePath = [NSString stringWithString: [selectedPaths objectAtIndex: 0]];
1495 basePath = [basePath stringByDeletingLastPathComponent];
1496
1497 if ([fm isWritableFileAtPath: basePath] == NO) {
1498 NSString *err = NSLocalizedString(@"Error", @"");
1499 NSString *msg = NSLocalizedString(@"You have not write permission\nfor", @"");
1500 NSString *buttstr = NSLocalizedString(@"Continue", @"");
1501 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@ \"%@\"!\n", msg, basePath], buttstr, nil, nil);
1502 return;
1503 }
1504
1505 files = [NSMutableArray arrayWithCapacity: 1];
1506 for (i = 0; i < [selectedPaths count]; i++) {
1507 [files addObject: [[selectedPaths objectAtIndex: i] lastPathComponent]];
1508 }
1509
1510 [self performFileOperation: NSWorkspaceDuplicateOperation
1511 source: basePath destination: basePath files: files tag: &tag];
1512 }
1513
1514 - (void)deleteFiles
1515 {
1516 NSString *basePath;
1517 NSMutableArray *files;
1518 int tag, i;
1519
1520 basePath = [NSString stringWithString: [selectedPaths objectAtIndex: 0]];
1521 basePath = [basePath stringByDeletingLastPathComponent];
1522
1523 if ([fm isWritableFileAtPath: basePath] == NO) {
1524 NSString *err = NSLocalizedString(@"Error", @"");
1525 NSString *msg = NSLocalizedString(@"You have not write permission\nfor", @"");
1526 NSString *buttstr = NSLocalizedString(@"Continue", @"");
1527 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@ \"%@\"!\n", msg, basePath], buttstr, nil, nil);
1528 return;
1529 }
1530
1531 files = [NSMutableArray arrayWithCapacity: 1];
1532 for (i = 0; i < [selectedPaths count]; i++) {
1533 [files addObject: [[selectedPaths objectAtIndex: i] lastPathComponent]];
1534 }
1535
1536 [self performFileOperation: NSWorkspaceDestroyOperation
1537 source: basePath destination: basePath files: files tag: &tag];
1538 }
1539
1540 - (BOOL)verifyFileAtPath:(NSString *)path
1541 {
1542 if ([fm fileExistsAtPath: path] == NO) {
1543 NSString *err = NSLocalizedString(@"Error", @"");
1544 NSString *msg = NSLocalizedString(@": no such file or directory!", @"");
1545 NSString *buttstr = NSLocalizedString(@"Continue", @"");
1546 NSMutableDictionary *notifObj = [NSMutableDictionary dictionaryWithCapacity: 1];
1547 NSString *basePath = [path stringByDeletingLastPathComponent];
1548
1549 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@%@", path, msg], buttstr, nil, nil);
1550
1551 [notifObj setObject: NSWorkspaceDestroyOperation forKey: @"operation"];
1552 [notifObj setObject: basePath forKey: @"source"];
1553 [notifObj setObject: basePath forKey: @"destination"];
1554 [notifObj setObject: [NSArray arrayWithObjects: path, nil] forKey: @"files"];
1555
1556 [[NSNotificationCenter defaultCenter]
1557 postNotificationName: GWFileSystemWillChangeNotification
1558 object: notifObj];
1559
1560 [[NSNotificationCenter defaultCenter]
1561 postNotificationName: GWFileSystemDidChangeNotification
1562 object: notifObj];
1563 return NO;
1564 }
1565
1566 return YES;
1567 }
1568
1569 - (void)setUsesThumbnails:(BOOL)value
1570 {
1571 int i;
1572
1573 if (usesThumbnails == value) {
1574 return;
1575 }
1576
1577 [GWLib setUseThumbnails: value];
1578
1579 usesThumbnails = value;
1580
1581 [rootViewer thumbnailsDidChangeInPaths: nil];
1582 for (i = 0; i < [viewers count]; i++) {
1583 [[viewers objectAtIndex: i] thumbnailsDidChangeInPaths: nil];
1584 }
1585 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
1586 [[desktopWindow desktopView] updateIcons];
1587 }
1588 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
1589 [tshelfWin updateIcons];
1590 }
1591 if (finder != nil) {
1592 [finder updateIcons];
1593 }
1594 }
1595
1596 - (void)thumbnailsDidChange:(NSNotification *)notif
1597 {
1598 NSDictionary *info = [notif userInfo];
1599 NSArray *deleted = [info objectForKey: @"deleted"];
1600 NSArray *created = [info objectForKey: @"created"];
1601 NSMutableArray *tmbdirs = [NSMutableArray array];
1602 int i;
1603
1604 if (usesThumbnails == NO) {
1605 return;
1606 } else {
1607 NSString *thumbnailDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
1608
1609 thumbnailDir = [thumbnailDir stringByAppendingPathComponent: @"Thumbnails"];
1610
1611 if ([deleted count]) {
1612 for (i = 0; i < [deleted count]; i++) {
1613 NSString *path = [deleted objectAtIndex: i];
1614 NSString *dir = [path stringByDeletingLastPathComponent];
1615
1616 if ([tmbdirs containsObject: dir] == NO) {
1617 [tmbdirs addObject: dir];
1618 }
1619 }
1620
1621 [rootViewer thumbnailsDidChangeInPaths: tmbdirs];
1622 for (i = 0; i < [viewers count]; i++) {
1623 [[viewers objectAtIndex: i] thumbnailsDidChangeInPaths: tmbdirs];
1624 }
1625 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
1626 [[desktopWindow desktopView] updateIcons];
1627 }
1628 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
1629 [tshelfWin updateIcons];
1630 }
1631 if (finder != nil) {
1632 [finder updateIcons];
1633 }
1634
1635 [tmbdirs removeAllObjects];
1636 }
1637
1638 if ([created count]) {
1639 NSString *dictName = @"thumbnails.plist";
1640 NSString *dictPath = [thumbnailDir stringByAppendingPathComponent: dictName];
1641 NSDictionary *tdict = [NSDictionary dictionaryWithContentsOfFile: dictPath];
1642
1643 for (i = 0; i < [created count]; i++) {
1644 NSString *key = [created objectAtIndex: i];
1645 NSString *dir = [key stringByDeletingLastPathComponent];
1646 NSString *tumbname = [tdict objectForKey: key];
1647 NSString *tumbpath = [thumbnailDir stringByAppendingPathComponent: tumbname];
1648
1649 if ([fm fileExistsAtPath: tumbpath]) {
1650 if ([tmbdirs containsObject: dir] == NO) {
1651 [tmbdirs addObject: dir];
1652 }
1653 }
1654 }
1655
1656 [rootViewer thumbnailsDidChangeInPaths: tmbdirs];
1657 for (i = 0; i < [viewers count]; i++) {
1658 [[viewers objectAtIndex: i] thumbnailsDidChangeInPaths: tmbdirs];
1659 }
1660 if ((desktopWindow != nil) && ([desktopWindow isVisible])) {
1661 [[desktopWindow desktopView] updateIcons];
1662 }
1663 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
1664 [tshelfWin updateIcons];
1665 }
1666 if (finder != nil) {
1667 [finder updateIcons];
1668 }
1669 }
1670 }
1671 }
1672
1673 - (id)connectApplication:(NSString *)appName
1674 {
1675 NSString *host;
1676 NSString *port;
1677 id app = nil;
1678
1679 host = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSHost"];
1680 if (host == nil) {
1681 host = @"";
1682 } else {
1683 NSHost *h = [NSHost hostWithName: host];
1684
1685 if ([h isEqual: [NSHost currentHost]] == YES) {
1686 host = @"";
1687 }
1688 }
1689
1690 port = [appName stringByDeletingPathExtension];
1691
1692 NS_DURING
1693 {
1694 app = [NSConnection rootProxyForConnectionWithRegisteredName: port
1695 host: host];
1696 }
1697 NS_HANDLER
1698 {
1699 app = nil;
1700 }
1701 NS_ENDHANDLER
1702
1703 return app;
1704 }
1705
1706 //
1707 // NSServicesRequests protocol
1708 //
1709
1710 - (id)validRequestorForSendType:(NSString *)sendType
1711 returnType:(NSString *)returnType
1712 {
1713 BOOL sendOK = NO;
1714 BOOL returnOK = NO;
1715
1716 if (sendType == nil) {
1717 sendOK = YES;
1718 } else if ([sendType isEqual: NSFilenamesPboardType] && (selectedPaths != nil)) {
1719 sendOK = YES;
1720 }
1721
1722 if (returnType == nil) {
1723 returnOK = YES;
1724 } else if ([returnType isEqual: NSFilenamesPboardType]) {
1725 returnOK = YES;
1726 }
1727
1728 if (sendOK && returnOK) {
1729 return self;
1730 }
1731
1732 return nil;
1733 }
1734
1735 - (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard
1736 {
1737 if ([[pboard types] indexOfObject: NSFilenamesPboardType] != NSNotFound) {
1738 return YES;
1739 }
1740
1741 return NO;
1742 }
1743
1744 - (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard
1745 types:(NSArray *)types
1746 {
1747 if ([types containsObject: NSFilenamesPboardType] == YES) {
1748 NSArray *typesDeclared = [NSArray arrayWithObject: NSFilenamesPboardType];
1749
1750 [pboard declareTypes: typesDeclared owner: self];
1751
1752 return [pboard setPropertyList: selectedPaths
1753 forType: NSFilenamesPboardType];
1754 }
1755
1756 return NO;
1757 }
1758
1759 //
1760 // Menu Operations
1761 //
1762 - (void)closeMainWin:(id)sender
1763 {
1764 [[[NSApplication sharedApplication] keyWindow] performClose: sender];
1765 }
1766
1767 - (void)showInfo:(id)sender
1768 {
1769 NSMutableDictionary *d = AUTORELEASE ([NSMutableDictionary new]);
1770 [d setObject: @"GWorkspace" forKey: @"ApplicationName"];
1771 [d setObject: NSLocalizedString(@"GNUstep Workspace Manager", @"")
1772 forKey: @"ApplicationDescription"];
1773 [d setObject: @"GWorkspace 0.6" forKey: @"ApplicationRelease"];
1774 [d setObject: @"10 2003" forKey: @"FullVersionID"];
1775 [d setObject: [NSArray arrayWithObjects:
1776 @"Enrico Sersale <enrico@imago.ro>.\n\
1777 InspectorViewer, PlistViewer, StringsViewer\n\
1778 by Fabien Vallon <fabien.vallon@fr.alcove.com>.\n\
1779 Makefiles and configuration scripts\n\
1780 by Alexey I. Froloff <raorn@altlinux.ru>.",
1781 nil]
1782 forKey: @"Authors"];
1783 [d setObject: NSLocalizedString(@"See http://www.gnustep.it/enrico/gworkspace", @"") forKey: @"URL"];
1784 [d setObject: @"Copyright (C) 2003 Free Software Foundation, Inc."
1785 forKey: @"Copyright"];
1786 [d setObject: NSLocalizedString(@"Released under the GNU General Public License 2.0", @"")
1787 forKey: @"CopyrightDescription"];
1788
1789 #ifdef GNUSTEP
1790 [NSApp orderFrontStandardInfoPanelWithOptions: d];
1791 #else
1792 [NSApp orderFrontStandardAboutPanel: d];
1793 #endif
1794 }
1795
1796 - (void)showPreferences:(id)sender
1797 {
1798 [prefController activate];
1799 }
1800
1801 - (void)showViewer:(id)sender
1802 {
1803 if(rootViewer == nil) {
1804 rootViewer = [[ViewersWindow alloc] initWithViewerTemplates: viewersTemplates
1805 forPath: fixPath(@"/", 0) viewPakages: NO
1806 isRootViewer: YES onStart: starting];
1807 } else {
1808 [self newViewerAtPath: fixPath(@"/", 0) canViewApps: NO];
1809 }
1810
1811 [rootViewer activate];
1812 }
1813
1814 - (void)showHistory:(id)sender
1815 {
1816 [history activate];
1817 }
1818
1819 - (void)showInspector:(id)sender
1820 {
1821 if (inspController == nil) {
1822 inspController = [[InspectorsController alloc] initForPaths: selectedPaths];
1823 }
1824 [[inspController myWin] makeKeyAndOrderFront: nil];
1825 }
1826
1827 - (void)showAttributesInspector:(id)sender
1828 {
1829 [self showInspector: nil];
1830 [inspController showAttributes];
1831 }
1832
1833 - (void)showContentsInspector:(id)sender
1834 {
1835 [self showInspector: nil];
1836 [inspController showContents];
1837 }
1838
1839 - (void)showToolsInspector:(id)sender
1840 {
1841 [self showInspector: nil];
1842 [inspController showTools];
1843 }
1844
1845 - (void)showPermissionsInspector:(id)sender
1846 {
1847 [self showInspector: nil];
1848 [inspController showPermissions];
1849 }
1850
1851 - (void)showApps:(id)sender
1852 {
1853 [appsViewer activate];
1854 }
1855
1856 - (void)showFileOps:(id)sender
1857 {
1858 int i;
1859
1860 for (i = 0; i < [operations count]; i++) {
1861 FileOperation *op = [operations objectAtIndex: i];
1862
1863 if ([op showsWindow] == NO) {
1864 [op showProgressWin];
1865 }
1866 }
1867 }
1868
1869 - (void)showFinder:(id)sender
1870 {
1871 if (finder == nil) {
1872 finder = [[FinderController alloc] init];
1873 }
1874 [finder activate];
1875 }
1876
1877 - (void)showFiend:(id)sender
1878 {
1879 NSMenu *menu = [[[NSApp mainMenu] itemWithTitle: NSLocalizedString(@"Tools", @"")] submenu];
1880 menu = [[menu itemWithTitle: NSLocalizedString(@"Fiend", @"")] submenu];
1881
1882 while (1) {
1883 if ([menu numberOfItems] == 0) {
1884 break;
1885 }
1886 [menu removeItemAtIndex: 0];
1887 }
1888
1889 [menu addItemWithTitle: NSLocalizedString(@"Hide Fiend", @"")
1890 action: @selector(hideFiend:) keyEquivalent: @""];
1891 [menu addItemWithTitle: NSLocalizedString(@"Remove Current Layer", @"")
1892 action: @selector(removeFiendLayer:) keyEquivalent: @""];
1893 [menu addItemWithTitle: NSLocalizedString(@"Rename Current Layer", @"")
1894 action: @selector(renameFiendLayer:) keyEquivalent: @""];
1895 [menu addItemWithTitle: NSLocalizedString(@"Add Layer...", @"")
1896 action: @selector(addFiendLayer:) keyEquivalent: @""];
1897
1898 if (fiend == nil) {
1899 fiend = [[Fiend alloc] init];
1900 }
1901 [fiend activate];
1902 }
1903
1904 - (void)hideFiend:(id)sender
1905 {
1906 NSMenu *menu = [[[NSApp mainMenu] itemWithTitle: NSLocalizedString(@"Tools", @"")] submenu];
1907 menu = [[menu itemWithTitle: NSLocalizedString(@"Fiend", @"")] submenu];
1908
1909 while (1) {
1910 if ([menu numberOfItems] == 0) {
1911 break;
1912 }
1913 [menu removeItemAtIndex: 0];
1914 }
1915
1916 [menu addItemWithTitle: NSLocalizedString(@"Show Fiend", @"")
1917 action: @selector(showFiend:) keyEquivalent: @""];
1918
1919 if (fiend != nil) {
1920 [fiend hide];
1921 }
1922 }
1923
1924 - (void)addFiendLayer:(id)sender
1925 {
1926 [fiend addLayer];
1927 }
1928
1929 - (void)removeFiendLayer:(id)sender
1930 {
1931 [fiend removeCurrentLayer];
1932 }
1933
1934 - (void)renameFiendLayer:(id)sender
1935 {
1936 [fiend renameCurrentLayer];
1937 }
1938
1939 - (void)showTShelf:(id)sender
1940 {
1941 NSMenu *menu = [[[NSApp mainMenu] itemWithTitle: NSLocalizedString(@"Tools", @"")] submenu];
1942 menu = [[menu itemWithTitle: NSLocalizedString(@"Tabbed Shelf", @"")] submenu];
1943
1944 while (1) {
1945 if ([menu numberOfItems] == 0) {
1946 break;
1947 }
1948 [menu removeItemAtIndex: 0];
1949 }
1950
1951 [menu addItemWithTitle: NSLocalizedString(@"Hide Tabbed Shelf", @"")
1952 action: @selector(hideTShelf:) keyEquivalent: @""];
1953 [menu addItemWithTitle: NSLocalizedString(@"Remove Current Tab", @"")
1954 action: @selector(removeTShelfTab:) keyEquivalent: @""];
1955 [menu addItemWithTitle: NSLocalizedString(@"Rename Current Tab", @"")
1956 action: @selector(renameTShelfTab:) keyEquivalent: @""];
1957 [menu addItemWithTitle: NSLocalizedString(@"Add Tab...", @"")
1958 action: @selector(addTShelfTab:) keyEquivalent: @""];
1959
1960 if (tshelfWin == nil) {
1961 tshelfWin = [[TShelfWin alloc] init];
1962 [tshelfWin activate];
1963 } else if ([tshelfWin isVisible] == NO) {
1964 [tshelfWin activate];
1965 }
1966 }
1967
1968 - (void)hideTShelf:(id)sender
1969 {
1970 NSMenu *menu = [[[NSApp mainMenu] itemWithTitle: NSLocalizedString(@"Tools", @"")] submenu];
1971 menu = [[menu itemWithTitle: NSLocalizedString(@"Tabbed Shelf", @"")] submenu];
1972
1973 while (1) {
1974 if ([menu numberOfItems] == 0) {
1975 break;
1976 }
1977 [menu removeItemAtIndex: 0];
1978 }
1979
1980 [menu addItemWithTitle: NSLocalizedString(@"Show Tabbed Shelf", @"")
1981 action: @selector(showTShelf:) keyEquivalent: @""];
1982
1983 if ((tshelfWin != nil) && ([tshelfWin isVisible])) {
1984 [tshelfWin saveDefaults];
1985 [tshelfWin deactivate];
1986 }
1987 }
1988
1989 - (void)addTShelfTab:(id)sender
1990 {
1991 [tshelfWin addTab];
1992 }
1993
1994 - (void)removeTShelfTab:(id)sender
1995 {
1996 [tshelfWin removeTab];
1997 }
1998
1999 - (void)renameTShelfTab:(id)sender
2000 {
2001 [tshelfWin renameTab];
2002 }
2003
2004 - (void)openWith:(id)sender
2005 {
2006 [self openSelectedPathsWith];
2007 }
2008
2009 - (void)runCommand:(id)sender
2010 {
2011 [runExtController activate];
2012 }
2013
2014 - (void)startXTerm:(id)sender
2015 {
2016 NSString *path;
2017 BOOL isdir;
2018
2019 path = [currentViewer currentViewedPath];
2020
2021 if (path == nil) {
2022 if ([selectedPaths count] > 1) {
2023 path = [[selectedPaths objectAtIndex: 0] stringByDeletingLastPathComponent];
2024 } else {
2025 path = [selectedPaths objectAtIndex: 0];
2026 [fm fileExistsAtPath: path isDirectory: &isdir];
2027 if (isdir == NO) {
2028 path = [path stringByDeletingLastPathComponent];
2029 }
2030 }
2031 }
2032
2033 [self startXTermOnDirectory: path];
2034 }
2035
2036 - (void)emptyRecycler:(id)sender
2037 {
2038 [recycler emptyRecycler];
2039 }
2040
2041 - (void)putAway:(id)sender
2042 {
2043 [recycler putAway];
2044 }
2045
2046 @end
2047
2048
2049

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