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

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