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 |