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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (show annotations) (download)
Sat Sep 27 10:25:58 2003 UTC (20 years, 7 months ago) by esersale
Branch: MAIN
Changes since 1.7: +458 -465 lines
*** empty log message ***

1 /* GWRemote.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 GWRemote 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 "GWRemote.h"
28 #include "Preferences/PrefController.h"
29 #include "LoginWindow.h"
30 #include "ViewerWindow.h"
31 #include "RemoteEditor.h"
32 #include "FileOpProgress.h"
33 #include "RemoteTerminal.h"
34 #include "Functions.h"
35 #include "Notifications.h"
36 #include "GNUstep.h"
37 #include <GWorkspace/GWProtocol.h>
38
39 static GWRemote *gwremote = nil;
40
41 @implementation GWRemote
42
43 #define byname 0
44 #define bykind 1
45 #define bydate 2
46 #define bysize 3
47 #define byowner 4
48
49 #define CACHED_MAX 20;
50
51 #define CELLS_WIDTH 90
52
53 + (GWRemote *)gwremote
54 {
55 if (gwremote == nil) {
56 gwremote = [[GWRemote alloc] init];
57 }
58 return gwremote;
59 }
60
61 + (void)initialize
62 {
63 static BOOL initialized = NO;
64
65 if (initialized == YES) {
66 return;
67 }
68
69 initialized = YES;
70 }
71
72 + (void)registerForServices
73 {
74 NSArray *sendTypes = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
75 NSArray *returnTypes = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
76 [NSApp registerServicesMenuSendTypes: sendTypes returnTypes: returnTypes];
77 }
78
79 - (void)dealloc
80 {
81 [dstnc removeObserver: self];
82 [nc removeObserver: self];
83
84 if (connectTimer && [connectTimer isValid]) {
85 [connectTimer invalidate];
86 }
87
88 TEST_RELEASE (serversNames);
89 RELEASE (serversDict);
90 TEST_RELEASE (currentServer);
91 TEST_RELEASE (userName);
92 TEST_RELEASE (userPassword);
93
94 RELEASE (prefController);
95 RELEASE (loginWindow);
96
97 RELEASE (viewers);
98 RELEASE (cachedContents);
99 RELEASE (editors);
100 RELEASE (terminals);
101 RELEASE (fileOpIndicators);
102
103 [super dealloc];
104 }
105
106 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
107 {
108 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
109 id entry;
110
111 [isa registerForServices];
112
113 haveServersList = NO;
114
115 fm = [NSFileManager defaultManager];
116 ws = [NSWorkspace sharedWorkspace];
117 nc = [NSNotificationCenter defaultCenter];
118 dstnc = [NSDistributedNotificationCenter defaultCenter];
119
120 serversDict = [NSMutableDictionary new];
121 serversNames = [NSMutableArray new];
122 currentServer = nil;
123 loginServer = nil;
124
125 viewers = [NSMutableArray new];
126 cachedContents = [NSMutableDictionary new];
127 editors = [NSMutableArray new];
128 terminals = [NSMutableArray new];
129 remoteTermRef = [NSNumber numberWithInt: 0];
130 fileOpIndicators = [NSMutableArray new];
131
132 prefController = [[PrefController alloc] init];
133
134 entry = [defaults objectForKey: @"serversnames"];
135 if (entry && [entry count]) {
136 [serversNames addObjectsFromArray: entry];
137 } else {
138 [defaults setObject: serversNames forKey: @"serversnames"];
139 [defaults synchronize];
140
141 NSRunAlertPanel(NULL, NSLocalizedString(@"No gwsd server defined!\n\
142 You must choose one from the preferences!", @""),
143 NSLocalizedString(@"OK", @""), NULL, NULL);
144 [prefController activateServerPref];
145 [self showPreferences: nil];
146 }
147
148 loginWindow = [[LoginWindow alloc] init];
149
150 animateChdir = ![defaults boolForKey: @"nochdiranim"];
151 animateLaunck = ![defaults boolForKey: @"nolaunchanim"];
152 animateSlideBack = ![defaults boolForKey: @"noslidebackanim"];
153
154 showFileOpStatus = [defaults boolForKey: @"showfopstatus"];
155
156 entry = [defaults objectForKey: @"shelfcellswidth"];
157 if (entry == nil) {
158 shelfCellsWidth = CELLS_WIDTH;
159 } else {
160 shelfCellsWidth = [entry intValue];
161 }
162
163 entry = [defaults objectForKey: @"cachedmax"];
164 if (entry) {
165 cachedMax = [entry intValue];
166 } else {
167 cachedMax = CACHED_MAX;
168 }
169 }
170
171 - (BOOL)applicationShouldTerminate:(NSApplication *)app
172 {
173 int i;
174
175 #define TEST_CLOSE(o, w) if ((o) && ([w isVisible])) [w close]
176
177 for (i = 0; i < [editors count]; i++) {
178 if ([[editors objectAtIndex: i] isEdited]) {
179 unsigned result = NSRunAlertPanel(NSLocalizedString(@"Alert", @""),
180 NSLocalizedString(@"There are remote edited files.\n\
181 Do you want to save them?", @""),
182 NSLocalizedString(@"Ok", @""),
183 NSLocalizedString(@"No", @""),
184 NULL);
185
186 if (result == NSAlertDefaultReturn) {
187 return NO;
188 } else {
189 break;
190 }
191 }
192 }
193
194 [self updateDefaults];
195
196 for (i = 0; i < [viewers count]; i++) {
197 id vwr = [viewers objectAtIndex: i];
198 TEST_CLOSE (vwr, vwr);
199 }
200 TEST_CLOSE (prefController, [prefController myWin]);
201
202 return YES;
203 }
204
205 //
206 // GWSdClientProtocol
207 //
208 - (void)setServerConnection:(NSConnection *)conn
209 {
210 id anObject;
211 NSMutableDictionary *dict;
212
213 // [conn setIndependentConversationQueueing: YES];
214
215 anObject = [conn rootObject];
216 [anObject setProtocolForProxy: @protocol(GWSDProtocol)];
217
218 dict = [NSMutableDictionary dictionary];
219 [dict setObject: loginServer forKey: @"name"];
220 [dict setObject: conn forKey: @"connection"];
221 [dict setObject: (id <GWSDProtocol>)anObject forKey: @"server"];
222
223 [serversDict setObject: dict forKey: loginServer];
224
225 [self readDefaultsForServer: loginServer];
226
227 DESTROY (loginServer);
228 DESTROY (userName);
229 DESTROY (userPassword);
230
231 [[NSNotificationCenter defaultCenter] addObserver: self
232 selector: @selector(connectionDidDie:)
233 name: NSConnectionDidDieNotification object: conn];
234 }
235
236 - (NSString *)userName
237 {
238 return userName;
239 }
240
241 - (NSString *)userPassword
242 {
243 return userPassword;
244 }
245
246 - (oneway void)connectionRefused
247 {
248 NSRunAlertPanel(NULL, NSLocalizedString(@"Connection refused!", @""),
249 NSLocalizedString(@"OK", @""), NULL, NULL);
250 DESTROY (loginServer);
251 DESTROY (userName);
252 DESTROY (userPassword);
253 }
254
255 - (int)requestUserConfirmationWithMessage:(NSString *)message
256 title:(NSString *)title
257 {
258 return NSRunAlertPanel(NSLocalizedString(title, @""),
259 NSLocalizedString(message, @""),
260 NSLocalizedString(@"OK", @""),
261 NSLocalizedString(@"Cancel", @""), NULL);
262 }
263
264 - (int)showErrorAlertWithMessage:(NSString *)message
265 {
266 return NSRunAlertPanel(nil, NSLocalizedString(message, @""),
267 NSLocalizedString(@"Continue", @""), nil, nil);
268 }
269
270 - (oneway void)showProgressForFileOperationWithName:(NSString *)name
271 sourcePath:(NSString *)source
272 destinationPath:(NSString *)destination
273 operationRef:(int)ref
274 onServer:(id)server
275 {
276 NSString *sname = [self nameOfServer: server];
277 int count = [fileOpIndicators count];
278 FileOpProgress *fopProgress;
279 NSRect rect;
280
281 if (count) {
282 // NSRect screct = [[NSScreen mainScreen] frame];
283 // int i;
284
285 // for (i = 0; i < count; i++) {
286 // FileOpProgress *fopProgress = [fileOpIndicators objectAtIndex: i];
287 // NSRect r = [fopProgress windowRect];
288 // float w = r.size.width;
289 // float h = r.size.height;
290
291
292
293 // }
294
295 rect = NSZeroRect;
296
297 } else {
298 rect = NSZeroRect;
299 }
300
301 fopProgress = [[FileOpProgress alloc] initWithOperationRef: ref
302 operationName: name sourcePath: source destinationPath: destination
303 serverName: sname windowRect: rect];
304 [fopProgress activate];
305 [fileOpIndicators addObject: fopProgress];
306 RELEASE (fopProgress);
307 }
308
309 - (void)endOfFileOperationWithRef:(int)ref onServer:(id)server
310 {
311 NSString *sname = [self nameOfServer: server];
312
313 if (sname) {
314 int i;
315
316 for (i = 0; i < [fileOpIndicators count]; i++) {
317 FileOpProgress *fopProgress = [fileOpIndicators objectAtIndex: i];
318
319 if ([[fopProgress serverName] isEqual: sname]
320 && ([fopProgress operationRef] == ref)) {
321 [fopProgress done];
322 [fileOpIndicators removeObject: fopProgress];
323 break;
324 }
325 }
326 }
327 }
328
329 - (oneway void)server:(id)aserver fileSystemDidChange:(NSDictionary *)info
330 {
331 NSString *path = [info objectForKey: @"path"];
332 NSString *serverName = [self nameOfServer: aserver];
333 int i;
334
335 [self removeCachedRepresentationForPath: path onServer: serverName];
336
337 for (i = 0; i < [viewers count]; i++) {
338 [[viewers objectAtIndex: i] fileSystemDidChange: info];
339 }
340 }
341
342 - (oneway void)exitedShellTaskWithRef:(NSNumber *)ref
343 {
344 [self _exitedShellTaskWithRef: ref];
345 }
346
347 - (oneway void)remoteShellWithRef:(NSNumber *)ref
348 hasAvailableData:(NSData *)data
349 {
350 [self _remoteShellWithRef: ref hasAvailableData: data];
351 }
352 //
353 // GWSdClientProtocol (end)
354 //
355
356
357 - (void)serversListChanged
358 {
359 haveServersList = YES;
360 }
361
362 - (void)tryLoginOnServer:(NSString *)servername
363 withUserName:(NSString *)usrname
364 userPassword:(NSString *)userpass
365 {
366 id server;
367
368 [[loginWindow myWin] close];
369
370 if ([serversDict objectForKey: servername]) {
371 NSString *message = [NSString stringWithFormat: @"%@ %@!",
372 NSLocalizedString(@"already connected to", @""), servername];
373 NSRunAlertPanel(NULL, message, NSLocalizedString(@"OK", @""), NULL, NULL);
374 return;
375 }
376
377 ASSIGN (loginServer, servername);
378 ASSIGN (userName, usrname);
379 ASSIGN (userPassword, userpass);
380
381 server = [NSConnection rootProxyForConnectionWithRegisteredName: @"gwsd"
382 host: servername];
383 if (server != nil) {
384 connectTimer = [NSTimer scheduledTimerWithTimeInterval: 10.0 target: self
385 selector: @selector(checkConnection:) userInfo: nil repeats: NO];
386
387 [server setProtocolForProxy: @protocol(GWSDProtocol)];
388 server = (id <GWSDProtocol>)server;
389
390 [server registerRemoteClient: self];
391 } else {
392 NSRunAlertPanel(NULL, NSLocalizedString(@"Can't contact the server!", @""),
393 NSLocalizedString(@"OK", @""), NULL, NULL);
394 DESTROY (loginServer);
395 DESTROY (userName);
396 DESTROY (userPassword);
397 }
398 }
399
400 - (void)checkConnection:(id)sender
401 {
402 if (loginServer != nil) {
403 NSRunAlertPanel(NULL, NSLocalizedString(@"Time out contacting the server!", @""),
404 NSLocalizedString(@"OK", @""), NULL, NULL);
405 DESTROY (loginServer);
406 DESTROY (userName);
407 DESTROY (userPassword);
408 }
409 }
410
411 - (void)connectionDidDie:(NSNotification *)notification
412 {
413 id diedconn = [notification object];
414 id <GWSDProtocol> server = [self serverWithConnection: diedconn];
415
416 [[NSNotificationCenter defaultCenter] removeObserver: self
417 name: NSConnectionDidDieNotification object: diedconn];
418
419 if (server) {
420 NSString *name = [self nameOfServer: server];
421 NSArray *sviewers = [self viewersOfServer: name];
422 int i;
423
424 for (i = 0; i < [sviewers count]; i++) {
425 ViewerWindow *viewer = [sviewers objectAtIndex: i];
426
427 [viewer updateDefaults];
428 [viewer close];
429 }
430
431 [serversDict removeObjectForKey: name];
432
433 NSRunAlertPanel(NULL,
434 [NSString stringWithFormat: @"the connection with %@ died!", name],
435 @"OK", NULL, NULL);
436 }
437 }
438
439 - (void)readDefaultsForServer:(NSString *)serverName
440 {
441 NSMutableDictionary *dict = [self dictionaryForServer: serverName];
442 id <GWSDProtocol> server = [dict objectForKey: @"server"];
443 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
444 NSMutableArray *viewersPaths = nil;
445 id sdict = [defaults objectForKey: serverName];
446 int i, count;
447
448 if (sdict) {
449 NSMutableDictionary *serverPrefs = [sdict mutableCopy];
450 NSMutableDictionary *viewersPrefs;
451 NSArray *keys;
452 id entry;
453
454 entry = [serverPrefs objectForKey: @"defaultsorttype"];
455 if (entry == nil) {
456 [serverPrefs setObject: [NSNumber numberWithInt: byname]
457 forKey: @"defaultsorttype"];
458 [dict setObject: [NSNumber numberWithInt: byname]
459 forKey: @"defaultsorttype"];
460 } else {
461 [dict setObject: [NSNumber numberWithInt: [entry intValue]]
462 forKey: @"defaultsorttype"];
463 }
464
465 entry = [serverPrefs objectForKey: @"GSFileBrowserHideDotFiles"];
466 if (entry) {
467 [dict setObject: [NSNumber numberWithBool: [entry boolValue]]
468 forKey: @"GSFileBrowserHideDotFiles"];
469 } else {
470 NSDictionary *domain = [defaults persistentDomainForName: NSGlobalDomain];
471
472 entry = [domain objectForKey: @"GSFileBrowserHideDotFiles"];
473 if (entry) {
474 [dict setObject: [NSNumber numberWithBool: [entry boolValue]]
475 forKey: @"GSFileBrowserHideDotFiles"];
476 } else {
477 [dict setObject: [NSNumber numberWithBool: NO]
478 forKey: @"GSFileBrowserHideDotFiles"];
479 }
480 }
481
482 entry = [serverPrefs objectForKey: @"viewersprefs"];
483 if (entry) {
484 viewersPrefs = [entry mutableCopy];
485 } else {
486 viewersPrefs = [NSMutableDictionary new];
487 }
488 keys = [viewersPrefs allKeys];
489 for (i = 0; i < [keys count]; i++) {
490 NSString *key = [keys objectAtIndex: i];
491
492 if ([key isEqual: @"rootViewer"] == NO) {
493 if([server existsAndIsDirectoryFileAtPath: key] == NO) {
494 [viewersPrefs removeObjectForKey: key];
495 }
496 }
497 }
498 [serverPrefs setObject: viewersPrefs forKey: @"viewersprefs"];
499 RELEASE (viewersPrefs);
500
501 entry = [serverPrefs objectForKey: @"viewerspaths"];
502 if (entry == nil) {
503 viewersPaths = [NSMutableArray new];
504 } else {
505 viewersPaths = [entry mutableCopy];
506 }
507 count = [viewersPaths count];
508 for (i = 0; i < count; i++) {
509 NSString *path = [viewersPaths objectAtIndex: i];
510
511 if([server existsAndIsDirectoryFileAtPath: path] == NO) {
512 [viewersPaths removeObjectAtIndex: i];
513 i--;
514 count--;
515 }
516 }
517 [serverPrefs setObject: viewersPaths forKey: @"viewerspaths"];
518
519 [defaults setObject: serverPrefs forKey: serverName];
520 RELEASE (serverPrefs);
521 } else {
522 [dict setObject: [NSNumber numberWithInt: byname]
523 forKey: @"defaultsorttype"];
524
525 [dict setObject: [NSNumber numberWithBool: NO]
526 forKey: @"GSFileBrowserHideDotFiles"];
527
528 [defaults setObject: [NSDictionary dictionary] forKey: serverName];
529 }
530
531 [defaults synchronize];
532
533 [dict setObject: [NSArray arrayWithObject: [server homeDirectory]]
534 forKey: @"selectedPaths"];
535
536 [dict setObject: [NSMutableArray array]
537 forKey: @"lockedPaths"];
538
539 [dict setObject: [NSMutableArray array]
540 forKey: @"watchedpaths"];
541
542 starting = YES;
543 currentServer = serverName;
544 rootViewer = nil;
545 [self showViewer: nil];
546
547 if (viewersPaths) {
548 for (i = 0; i < [viewersPaths count]; i++) {
549 NSString *path = [viewersPaths objectAtIndex: i];
550
551 if ([path isEqual: fixPath(@"/", 0)] == NO) {
552 BOOL canView = ([server isPakageAtPath: path] ? YES : NO);
553
554 [self server: serverName newViewerAtPath: path canViewApps: canView];
555 }
556 }
557
558 RELEASE (viewersPaths);
559 }
560
561 starting = NO;
562 }
563
564 - (NSMutableDictionary *)dictionaryForServer:(NSString *)serverName
565 {
566 return [serversDict objectForKey: serverName];
567 }
568
569 - (id <GWSDProtocol>)serverWithName:(NSString *)serverName
570 {
571 NSDictionary *serverDict = [self dictionaryForServer: serverName];
572 id <GWSDProtocol> server = [serverDict objectForKey: @"server"];
573
574 return server;
575 }
576
577 - (id <GWSDProtocol>)serverWithConnection:(NSConnection *)conn
578 {
579 NSArray *names = [serversDict allKeys];
580 int i;
581
582 for (i = 0; i < [names count]; i++) {
583 NSString *name = [names objectAtIndex: i];
584 NSDictionary *dict = [serversDict objectForKey: name];
585 id <GWSDProtocol> server = [dict objectForKey: @"server"];
586 NSConnection *connection = [dict objectForKey: @"connection"];
587
588 if (connection == conn) {
589 return server;
590 }
591 }
592
593 return nil;
594 }
595
596 - (NSString *)nameOfServer:(id)server
597 {
598 NSArray *names = [serversDict allKeys];
599 int i;
600
601 for (i = 0; i < [names count]; i++) {
602 NSString *name = [names objectAtIndex: i];
603 NSDictionary *dict = [serversDict objectForKey: name];
604 id srwr = [dict objectForKey: @"server"];
605
606 if (srwr == server) {
607 return name;
608 }
609 }
610
611 return nil;
612 }
613
614 - (NSArray *)viewersOfServer:(NSString *)serverName
615 {
616 NSMutableArray *vwrs = [NSMutableArray array];
617 int i;
618
619 for (i = 0; i < [viewers count]; i++) {
620 ViewerWindow *viewer = [viewers objectAtIndex: i];
621
622 if ([[viewer serverName] isEqual: serverName]) {
623 [vwrs addObject: viewer];
624 }
625 }
626
627 if ([vwrs count]) {
628 return vwrs;
629 }
630
631 return nil;
632 }
633
634 - (NSString *)homeDirectoryForServerWithName:(NSString *)serverName
635 {
636 NSDictionary *serverDict = [self dictionaryForServer: serverName];
637 id <GWSDProtocol> server = [serverDict objectForKey: @"server"];
638
639 return [server homeDirectory];
640 }
641
642 - (BOOL)server:(NSString *)serverName fileExistsAtPath:(NSString *)path
643 {
644 return [[self serverWithName: serverName] existsFileAtPath: path];
645 }
646
647 - (BOOL)server:(NSString *)serverName
648 existsAndIsDirectoryFileAtPath:(NSString *)path
649 {
650 return [[self serverWithName: serverName] existsAndIsDirectoryFileAtPath: path];
651 }
652
653 - (NSString *)server:(NSString *)serverName typeOfFileAt:(NSString *)path
654 {
655 return [[self serverWithName: serverName] typeOfFileAt: path];
656 }
657
658 - (BOOL)server:(NSString *)serverName isWritableFileAtPath:(NSString *)path
659 {
660 return [[self serverWithName: serverName] isWritableFileAtPath: path];
661 }
662
663 - (BOOL)server:(NSString *)serverName isPakageAtPath:(NSString *)path
664 {
665 return NO;
666 }
667
668 - (BOOL)server:(NSString *)serverName isLockedPath:(NSString *)aPath
669 {
670 return NO;
671 }
672
673 - (NSDictionary *)server:(NSString *)serverName
674 fileSystemAttributesAtPath:(NSString *)path
675 {
676 return [[self serverWithName: serverName] fileSystemAttributesAtPath: path];
677 }
678
679 - (int)server:(NSString *)serverName sortTypeForPath:(NSString *)aPath
680 {
681 return byname;
682 }
683
684 - (void)server:(NSString *)serverName
685 setSortType:(int)type
686 atPath:(NSString *)aPath
687 {
688 [[self serverWithName: serverName] setSortType: type
689 forDirectoryAtPath: aPath];
690 }
691
692 - (BOOL)server:(NSString *)serverName verifyFileAtPath:(NSString *)path
693 {
694 if ([[self serverWithName: serverName] existsFileAtPath: path] == NO) {
695 NSString *err = NSLocalizedString(@"Error", @"");
696 NSString *msg = NSLocalizedString(@": no such file or directory!", @"");
697 NSString *buttstr = NSLocalizedString(@"Continue", @"");
698 NSMutableDictionary *notifObj = [NSMutableDictionary dictionaryWithCapacity: 1];
699 NSString *basePath = [path stringByDeletingLastPathComponent];
700
701 NSRunAlertPanel(err, [NSString stringWithFormat: @"%@%@", path, msg], buttstr, nil, nil);
702
703 [notifObj setObject: NSWorkspaceDestroyOperation forKey: @"operation"];
704 [notifObj setObject: basePath forKey: @"source"];
705 [notifObj setObject: basePath forKey: @"destination"];
706 [notifObj setObject: [NSArray arrayWithObjects: path, nil] forKey: @"files"];
707
708 [nc postNotificationName: GWFileSystemWillChangeNotification
709 object: notifObj];
710
711 [nc postNotificationName: GWFileSystemDidChangeNotification
712 object: notifObj];
713 return NO;
714 }
715
716 return YES;
717 }
718
719 - (NSArray *)server:(NSString *)serverName
720 sortedDirectoryContentsAtPath:(NSString *)path
721 {
722 id <GWSDProtocol>server = [self serverWithName: serverName];
723
724 if (server) {
725 NSDictionary *contentsDict = [self cachedRepresentationForPath: path
726 onServer: serverName];
727 if (contentsDict) {
728 return [contentsDict objectForKey: @"files"];
729 }
730
731 contentsDict = [server directoryContentsAtPath: path];
732
733 if (contentsDict) {
734 if ([self entriesInCacheOfServer: serverName] >= cachedMax) {
735 [self removeOlderCachedForServer: serverName];
736 }
737
738 [self addCachedRepresentation: contentsDict
739 ofDirectory: path
740 onServer: serverName];
741
742 return [contentsDict objectForKey: @"files"];
743 }
744 }
745
746 return nil;
747 }
748
749 - (NSArray *)server:(NSString *)serverName
750 checkHiddenFiles:(NSArray *)files
751 atPath:(NSString *)path
752 {
753 return files;
754 }
755
756 - (NSMutableDictionary *)cachedRepresentationForPath:(NSString *)path
757 onServer:(NSString *)serverName
758 {
759 NSMutableDictionary *serverCache = [cachedContents objectForKey: serverName];
760
761 if (serverCache == nil) {
762 [cachedContents setObject: [NSMutableDictionary dictionary]
763 forKey: serverName];
764 return nil;
765
766 } else {
767 NSMutableDictionary *contents = [serverCache objectForKey: path];
768
769 if (contents) {
770 NSDate *modDate = [contents objectForKey: @"moddate"];
771 id <GWSDProtocol>server = [self serverWithName: serverName];
772 NSDate *date = [server modificationDateForPath: path];
773
774 if ([modDate isEqualToDate: date]) {
775 return contents;
776 } else {
777 [serverCache removeObjectForKey: path];
778 }
779 }
780 }
781
782 return nil;
783 }
784
785 - (void)addCachedRepresentation:(NSDictionary *)contentsDict
786 ofDirectory:(NSString *)path
787 onServer:(NSString *)serverName
788 {
789 NSMutableDictionary *serverCache = [cachedContents objectForKey: serverName];
790 NSMutableArray *watchedPaths = [[self dictionaryForServer: serverName]
791 objectForKey: @"watchedpaths"];
792
793 [serverCache setObject: contentsDict forKey: path];
794
795 if ([watchedPaths containsObject: path] == NO) {
796 [watchedPaths addObject: path];
797 [self server: serverName addWatcherForPath: path];
798 }
799 }
800
801 - (void)removeCachedRepresentationForPath:(NSString *)path
802 onServer:(NSString *)serverName
803 {
804 NSMutableDictionary *serverCache = [cachedContents objectForKey: serverName];
805 NSMutableArray *watchedPaths = [[self dictionaryForServer: serverName]
806 objectForKey: @"watchedpaths"];
807
808 [serverCache removeObjectForKey: path];
809
810 if ([watchedPaths containsObject: path]) {
811 [self server: serverName removeWatcherForPath: path];
812 [watchedPaths removeObject: path];
813 }
814 }
815
816 - (void)removeOlderCachedForServer:(NSString *)serverName
817 {
818 NSMutableDictionary *serverCache = [cachedContents objectForKey: serverName];
819 NSMutableArray *watchedPaths = [[self dictionaryForServer: serverName]
820 objectForKey: @"watchedpaths"];
821
822 if (serverCache) {
823 NSArray *keys = [serverCache allKeys];
824 NSDate *date = [NSDate date];
825 NSString *removeKey = nil;
826 int i;
827
828 if ([keys count]) {
829 for (i = 0; i < [keys count]; i++) {
830 NSString *key = [keys objectAtIndex: i];
831 NSDate *stamp = [[serverCache objectForKey: key] objectForKey: @"datestamp"];
832 NSDate *d = [date earlierDate: stamp];
833
834 if ([date isEqualToDate: d] == NO) {
835 date = d;
836 removeKey = key;
837 }
838 }
839
840 if (removeKey == nil) {
841 removeKey = [keys objectAtIndex: 0];
842 }
843
844 [serverCache removeObjectForKey: removeKey];
845
846 if ([watchedPaths containsObject: removeKey]) {
847 [self server: serverName removeWatcherForPath: removeKey];
848 [watchedPaths removeObject: removeKey];
849 }
850 }
851 }
852 }
853
854 - (int)entriesInCacheOfServer:(NSString *)serverName
855 {
856 return [[cachedContents objectForKey: serverName] count];
857 }
858
859 - (NSArray *)selectedPathsForServerWithName:(NSString *)serverName
860 {
861 return [[self dictionaryForServer: serverName] objectForKey: @"selectedPaths"];
862 }
863
864 - (void)server:(NSString *)serverName setSelectedPaths:(NSArray *)paths
865 {
866 NSMutableDictionary *dict = [self dictionaryForServer: serverName];
867
868 [dict setObject: paths forKey: @"selectedPaths"];
869 }
870
871 - (void)server:(NSString *)serverName
872 openSelectedPaths:(NSArray *)paths
873 newViewer:(BOOL)newv
874 {
875 int i, j;
876
877 [self server: serverName setSelectedPaths: paths];
878
879 for (i = 0; i < [paths count]; i++) {
880 NSString *apath = [paths objectAtIndex: i];
881 NSString *type = [self server: serverName typeOfFileAt: apath];
882
883 if ([type isEqual: NSDirectoryFileType]
884 || [type isEqual: NSFilesystemFileType]) {
885 if (newv) {
886 [self server: serverName newViewerAtPath: apath canViewApps: NO];
887 }
888 } else if ([type isEqual: NSPlainFileType]
889 || [type isEqual: NSShellCommandFileType]) {
890 if ([self server: serverName isPakageAtPath: apath]) {
891 if (newv) {
892 [self server: serverName newViewerAtPath: apath canViewApps: YES];
893 } else {
894 // [self openFile: apath];
895 }
896 } else {
897 BOOL found = NO;
898
899 for (j = 0; j < [editors count]; j++) {
900 RemoteEditor *editor = [editors objectAtIndex: j];
901
902 if (([serverName isEqual: [editor serverName]])
903 && ([apath isEqual: [editor filePath]])) {
904 [editor activate];
905 found = YES;
906 break;
907 }
908 }
909
910 if (found == NO) {
911 id <GWSDProtocol> server = [self serverWithName: serverName];
912 NSString *contents = [server contentsOfFileAt: apath];
913
914 if (contents) {
915 RemoteEditor *editor = [[RemoteEditor alloc] initForEditFile: apath
916 withContents: contents onRemoteHost: serverName];
917 [editors addObject: editor];
918 RELEASE (editor);
919 } else {
920 NSRunAlertPanel(NULL, NSLocalizedString(@"This file is too big!\n\
921 To edit it increase the maxim remote file size from the Preferences", @""),
922 NSLocalizedString(@"OK", @""), NULL, NULL);
923 }
924 }
925
926 // [self openFile: apath];
927 }
928 } else if ([type isEqual: NSApplicationFileType]) {
929 if (newv) {
930 [self server: serverName newViewerAtPath: apath canViewApps: YES];
931 } else {
932 // [ws launchApplication: apath];
933 }
934 }
935 }
936 }
937
938 - (void)server:(NSString *)serverName
939 newObjectAtPath:(NSString *)basePath
940 isDirectory:(BOOL)directory
941 {
942 id <GWSDProtocol> server = [self serverWithName: serverName];
943
944 if (server) {
945 [server newObjectAtPath: basePath isDirectory: directory];
946 }
947 }
948
949 - (void)duplicateFilesOnServerName:(NSString *)serverName
950 {
951 id <GWSDProtocol> server = [self serverWithName: serverName];
952
953 if (server) {
954 NSArray *selection = [self selectedPathsForServerWithName: serverName];
955 NSString *basePath = [NSString stringWithString: [selection objectAtIndex: 0]];
956 NSMutableArray *files = [NSMutableArray array];
957 int i;
958
959 basePath = [basePath stringByDeletingLastPathComponent];
960
961 for (i = 0; i < [selection count]; i++) {
962 [files addObject: [[selection objectAtIndex: i] lastPathComponent]];
963 }
964
965 [server duplicateFiles: files inDirectory: basePath];
966 }
967 }
968
969 - (void)deleteFilesOnServerName:(NSString *)serverName
970 {
971 id <GWSDProtocol> server = [self serverWithName: serverName];
972
973 if (server) {
974 NSArray *selection = [self selectedPathsForServerWithName: serverName];
975 NSString *basePath = [NSString stringWithString: [selection objectAtIndex: 0]];
976 NSMutableArray *files = [NSMutableArray array];
977 int i;
978
979 basePath = [basePath stringByDeletingLastPathComponent];
980
981 for (i = 0; i < [selection count]; i++) {
982 [files addObject: [[selection objectAtIndex: i] lastPathComponent]];
983 }
984
985 [server deleteFiles: files inDirectory: basePath];
986 }
987 }
988
989 - (void)server:(NSString *)serverName
990 renamePath:(NSString *)oldname
991 toNewName:(NSString *)newname
992 {
993 [[self serverWithName: serverName] renamePath: oldname toNewName: newname];
994 }
995
996 - (void)performFileOperationWithDictionary:(id)opdict
997 fromSourceHost:(NSString *)fromName
998 toDestinationHost:(NSString *)toName
999 {
1000 if ([fromName isEqual: toName]) {
1001 id <GWSDProtocol> server = [self serverWithName: toName];
1002
1003 if (server) {
1004 [server performLocalFileOperationWithDictionary: opdict];
1005 }
1006 }
1007 }
1008
1009 - (BOOL)pauseFileOperationWithRef:(int)ref
1010 onServerWithName:(NSString *)serverName
1011 {
1012 id <GWSDProtocol> server = [self serverWithName: serverName];
1013
1014 if (server) {
1015 return [server pauseFileOpeRationWithRef: ref];
1016 }
1017
1018 return NO;
1019 }
1020
1021 - (BOOL)continueFileOperationWithRef:(int)ref
1022 onServerWithName:(NSString *)serverName
1023 {
1024 id <GWSDProtocol> server = [self serverWithName: serverName];
1025
1026 if (server) {
1027 return [server continueFileOpeRationWithRef: ref];
1028 }
1029
1030 return NO;
1031 }
1032
1033 - (BOOL)stopFileOperationWithRef:(int)ref
1034 onServerWithName:(NSString *)serverName
1035 {
1036 id <GWSDProtocol> server = [self serverWithName: serverName];
1037
1038 if (server) {
1039 return [server stopFileOpeRationWithRef: ref];
1040 }
1041
1042 return NO;
1043 }
1044
1045 - (void)fileSystemWillChangeNotification:(NSNotification *)notif
1046 {
1047 }
1048
1049 - (void)fileSystemDidChangeNotification:(NSNotification *)notif
1050 {
1051 }
1052
1053 - (void)server:(NSString *)serverName addWatcherForPath:(NSString *)path
1054 {
1055 [[self serverWithName: serverName] addWatcherForPath: path];
1056 }
1057
1058 - (void)server:(NSString *)serverName removeWatcherForPath:(NSString *)path
1059 {
1060 [[self serverWithName: serverName] removeWatcherForPath: path];
1061 }
1062
1063 - (ViewerWindow *)server:(NSString *)serverName
1064 newViewerAtPath:(NSString *)path
1065 canViewApps:(BOOL)viewapps
1066 {
1067 ViewerWindow *viewer = [[ViewerWindow alloc] initForPath: path
1068 onServer: currentServer viewPakages: viewapps
1069 isRootViewer: NO onStart: starting];
1070 [viewer activate];
1071 [viewers addObject: viewer];
1072 RELEASE (viewer);
1073
1074 return [viewers objectAtIndex: [viewers count] -1];
1075 }
1076
1077 - (void)setCurrentViewer:(ViewerWindow *)viewer
1078 {
1079 currentViewer = viewer;
1080 }
1081
1082 - (id)rootViewer
1083 {
1084 return rootViewer;
1085 }
1086
1087 - (void)viewerHasClosed:(id)sender
1088 {
1089 if (sender != rootViewer) {
1090 [viewers removeObject: sender];
1091 }
1092 }
1093
1094 - (BOOL)editor:(RemoteEditor *)editor
1095 didEditContents:(NSString *)contents
1096 ofFile:(NSString *)filepath
1097 onRemoteHost:(NSString *)serverName
1098 {
1099 id <GWSDProtocol> server = [self serverWithName: serverName];
1100
1101 if ([server saveString: contents atPath: filepath] == NO) {
1102 NSRunAlertPanel(NULL, NSLocalizedString(@"Error in saving the remote file!", @""),
1103 NSLocalizedString(@"OK", @""), NULL, NULL);
1104 return NO;
1105 }
1106
1107 return YES;
1108 }
1109
1110 - (void)remoteEditorHasClosed:(RemoteEditor *)editor
1111 {
1112 [editors removeObject: editor];
1113 }
1114
1115 - (void)newTerminal
1116 {
1117 NSString *serverName = [currentViewer serverName];
1118 id <GWSDProtocol> server = [self serverWithName: serverName];
1119 NSString *path = [currentViewer currentViewedPath];
1120 NSNumber *tref = [self remoteTerminalRef];
1121 RemoteTerminal *terminal = [[RemoteTerminal alloc] initForRemoteHost: serverName
1122 refNumber: tref];
1123
1124 if (path == nil) {
1125 NSArray *selPaths = [self selectedPathsForServerWithName: serverName];
1126
1127 if ([selPaths count] > 1) {
1128 path = [[selPaths objectAtIndex: 0] stringByDeletingLastPathComponent];
1129 } else {
1130 path = [selPaths objectAtIndex: 0];
1131
1132 if ([server existsAndIsDirectoryFileAtPath: path] == NO) {
1133 path = [path stringByDeletingLastPathComponent];
1134 }
1135 }
1136 }
1137
1138 [terminal activate];
1139 [terminals addObject: terminal];
1140 RELEASE (terminal);
1141
1142 [server openShellOnPath: path refNumber: tref];
1143 }
1144
1145 - (void)remoteTerminalHasClosed:(RemoteTerminal *)terminal
1146 {
1147 NSString *serverName = [terminal serverName];
1148 NSNumber *refNumber = [terminal refNumber];
1149 id <GWSDProtocol> server = [self serverWithName: serverName];
1150
1151 [terminals removeObject: terminal];
1152
1153 [server closedRemoteTerminalWithRefNumber: refNumber];
1154 }
1155
1156 - (void)_exitedShellTaskWithRef:(NSNumber *)ref
1157 {
1158 RemoteTerminal *terminal = [self remoteTerminalWithRef: ref];
1159
1160 if (terminal) {
1161 [terminal shellDidExit];
1162 [terminals removeObject: terminal];
1163 }
1164 }
1165
1166 - (RemoteTerminal *)remoteTerminalWithRef:(NSNumber *)ref
1167 {
1168 int i;
1169
1170 for (i = 0; i < [terminals count]; i++) {
1171 RemoteTerminal *terminal = [terminals objectAtIndex: i];
1172 NSNumber *tref = [terminal refNumber];
1173
1174 if ([tref isEqual: ref]) {
1175 return terminal;
1176 }
1177 }
1178
1179 return nil;
1180 }
1181
1182 - (void)_remoteShellWithRef:(NSNumber *)ref hasAvailableData:(NSData *)data
1183 {
1184 RemoteTerminal *terminal = [self remoteTerminalWithRef: ref];
1185
1186 if (terminal) {
1187 NSString *str = [[NSString alloc] initWithData: data
1188 encoding: [NSString defaultCStringEncoding]];
1189 [terminal shellOutput: str];
1190 RELEASE (str);
1191 }
1192 }
1193
1194 - (void)terminalWithRef:(NSNumber *)ref newCommandLine:(NSString *)line
1195 {
1196 RemoteTerminal *terminal = [self remoteTerminalWithRef: ref];
1197 NSString *serverName = [terminal serverName];
1198 id <GWSDProtocol> server = [self serverWithName: serverName];
1199
1200 [server remoteShellWithRef: ref newCommandLine: line];
1201 }
1202
1203 - (NSNumber *)remoteTerminalRef
1204 {
1205 int ref = [remoteTermRef intValue];
1206
1207 ref++;
1208 if (ref == 1000) {
1209 ref = 0;
1210 }
1211 remoteTermRef = [NSNumber numberWithInt: ref];
1212
1213 return remoteTermRef;
1214 }
1215
1216 - (NSImage *)iconForFile:(NSString *)fullPath ofType:(NSString *)type
1217 {
1218 NSImage *icon = nil;
1219
1220 if ([type isEqual: NSDirectoryFileType]
1221 || [type isEqual: NSFilesystemFileType]
1222 || [type isEqual: NSApplicationFileType]) {
1223 icon = [self folderImage];
1224 } else {
1225 icon = [self unknownFiletypeImage];
1226 }
1227
1228 return icon;
1229 }
1230
1231 - (NSImage *)getImageWithName:(NSString *)name
1232 alternate:(NSString *)alternate
1233 {
1234 NSImage *image = nil;
1235
1236 image = [NSImage imageNamed: name];
1237
1238 if (image == nil) {
1239 image = [NSImage imageNamed: alternate];
1240 }
1241
1242 return image;
1243 }
1244
1245 - (NSImage *)folderImage
1246 {
1247 static NSImage *image = nil;
1248
1249 if (image == nil) {
1250 image = RETAIN ([self getImageWithName: @"Folder.tiff"
1251 alternate: @"common_Folder.tiff"]);
1252 }
1253
1254 return image;
1255 }
1256
1257 - (NSImage *)unknownFiletypeImage
1258 {
1259 static NSImage *image = nil;
1260
1261 if (image == nil) {
1262 image = RETAIN([self getImageWithName: @"Unknown.tiff"
1263 alternate: @"common_Unknown.tiff"]);
1264 }
1265
1266 return image;
1267 }
1268
1269 - (int)shelfCellsWidth
1270 {
1271 return shelfCellsWidth;
1272 }
1273
1274 - (int)defaultShelfCellsWidth
1275 {
1276 [self setShelfCellsWidth: 90];
1277 return 90;
1278 }
1279
1280 - (void)setShelfCellsWidth:(int)w
1281 {
1282 shelfCellsWidth = w;
1283
1284 [nc postNotificationName: GWShelfCellsWidthChangedNotification
1285 object: nil];
1286 }
1287
1288 - (BOOL)usesContestualMenu
1289 {
1290 return NO;
1291 }
1292
1293 - (void)updateDefaults
1294 {
1295 NSUserDefaults *defaults;
1296 NSArray *snames;
1297 int i, j;
1298
1299 defaults = [NSUserDefaults standardUserDefaults];
1300 [defaults setObject: [NSString stringWithFormat: @"%i", shelfCellsWidth]
1301 forKey: @"shelfcellswidth"];
1302
1303 [defaults setBool: !animateChdir forKey: @"nochdiranim"];
1304 [defaults setBool: !animateLaunck forKey: @"nolaunchanim"];
1305 [defaults setBool: !animateSlideBack forKey: @"noslidebackanim"];
1306
1307 snames = [serversDict allKeys];
1308
1309 for (i = 0; i < [snames count]; i++) {
1310 NSString *serverName = [snames objectAtIndex: i];
1311 NSDictionary *serverDict = [self dictionaryForServer: serverName];
1312 NSMutableDictionary *serverPrefs;
1313 NSArray *sviewers;
1314 id entry;
1315
1316 entry = [defaults objectForKey: serverName];
1317 if (entry) {
1318 serverPrefs = [entry mutableCopy];
1319 [serverPrefs removeObjectForKey: @"viewerspaths"];
1320 } else {
1321 serverPrefs = [NSMutableDictionary new];
1322 }
1323
1324 [serverPrefs setObject: [serverDict objectForKey: @"defaultsorttype"]
1325 forKey: @"defaultsorttype"];
1326
1327 [serverPrefs setObject: [serverDict objectForKey: @"GSFileBrowserHideDotFiles"]
1328 forKey: @"GSFileBrowserHideDotFiles"];
1329
1330 sviewers = [self viewersOfServer: serverName];
1331
1332 if (sviewers) {
1333 NSMutableArray *viewersPaths = [NSMutableArray array];
1334
1335 for (j = 0; j < [sviewers count]; j++) {
1336 ViewerWindow *viewer = [sviewers objectAtIndex: j];
1337
1338 if ([viewer isVisible]) {
1339 [viewersPaths addObject: [viewer rootPath]];
1340 }
1341 }
1342
1343 [serverPrefs setObject: viewersPaths forKey: @"viewerspaths"];
1344 }
1345
1346 [defaults setObject: serverPrefs forKey: serverName];
1347 RELEASE (serverPrefs);
1348 }
1349
1350 [defaults synchronize];
1351
1352 if ([[prefController myWin] isVisible]) {
1353 [prefController updateDefaults];
1354 }
1355
1356 for (i = 0; i < [viewers count]; i++) {
1357 [[viewers objectAtIndex: i] updateDefaults];
1358 }
1359 }
1360
1361 //
1362 // Menu Operations
1363 //
1364 - (void)showViewer:(id)sender
1365 {
1366 if(rootViewer == nil) {
1367 rootViewer = [[ViewerWindow alloc] initForPath: fixPath(@"/", 0)
1368 onServer: currentServer viewPakages: NO
1369 isRootViewer: YES onStart: starting];
1370 [viewers addObject: rootViewer];
1371 RELEASE (rootViewer);
1372 } else {
1373 [self server: currentServer
1374 newViewerAtPath: fixPath(@"/", 0) canViewApps: NO];
1375 }
1376
1377 [rootViewer activate];
1378 }
1379
1380 - (void)openRemoteTerminal:(id)sender
1381 {
1382 [self newTerminal];
1383 }
1384
1385 - (void)closeMainWin:(id)sender
1386 {
1387 [[[NSApplication sharedApplication] keyWindow] performClose: sender];
1388 }
1389
1390 - (void)showPreferences:(id)sender
1391 {
1392 [prefController activate];
1393 }
1394
1395 - (void)showLoginWindow:(id)sender
1396 {
1397 [loginWindow activate];
1398 }
1399
1400 - (void)logout:(id)sender
1401 {
1402 NSString *serverName = [currentViewer serverName];
1403 NSDictionary *dict = [serversDict objectForKey: serverName];
1404 NSArray *sviewers = [self viewersOfServer: serverName];
1405 int i;
1406
1407 if (NSRunAlertPanel(@"Logout",
1408 [NSString stringWithFormat: @"Logout from %@?", serverName],
1409 @"Ok", @"No", NULL) != NSAlertDefaultReturn) {
1410 return;
1411 }
1412
1413 for (i = 0; i < [sviewers count]; i++) {
1414 ViewerWindow *viewer = [sviewers objectAtIndex: i];
1415
1416 [viewer updateDefaults];
1417 [viewer close];
1418 }
1419
1420 [self updateDefaults];
1421
1422 if (dict) {
1423 [serversDict removeObjectForKey: serverName];
1424 }
1425 }
1426
1427 - (void)showInfo:(id)sender
1428 {
1429 NSMutableDictionary *d = AUTORELEASE ([NSMutableDictionary new]);
1430 [d setObject: @"GWRemote" forKey: @"ApplicationName"];
1431 [d setObject: NSLocalizedString(@"GNUstep Remote Workspace Manager", @"")
1432 forKey: @"ApplicationDescription"];
1433 [d setObject: @"GWRemote 0.2" forKey: @"ApplicationRelease"];
1434 [d setObject: @"06 2003" forKey: @"FullVersionID"];
1435 [d setObject: [NSArray arrayWithObjects: @"Enrico Sersale <enrico@imago.ro>.", nil]
1436 forKey: @"Authors"];
1437 [d setObject: NSLocalizedString(@"See http://www.gnustep.it/enrico/gwremote", @"") forKey: @"URL"];
1438 [d setObject: @"Copyright (C) 2003 Free Software Foundation, Inc."
1439 forKey: @"Copyright"];
1440 [d setObject: NSLocalizedString(@"Released under the GNU General Public License 2.0", @"")
1441 forKey: @"CopyrightDescription"];
1442
1443 #ifdef GNUSTEP
1444 [NSApp orderFrontStandardInfoPanelWithOptions: d];
1445 #else
1446 [NSApp orderFrontStandardAboutPanel: d];
1447 #endif
1448 }
1449
1450 - (BOOL)validateMenuItem:(NSMenuItem *)anItem
1451 {
1452 NSString *title = [anItem title];
1453
1454 if ([title isEqual: NSLocalizedString(@"Viewer", @"")]) {
1455 return (currentServer != nil);
1456 }
1457
1458 if ([title isEqual: NSLocalizedString(@"Logout", @"")]) {
1459 return (currentServer != nil);
1460 }
1461
1462 if ([title isEqual: NSLocalizedString(@"Remote Terminal", @"")]) {
1463 return (currentServer != nil);
1464 }
1465
1466 return YES;
1467 }
1468
1469 @end

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