/[gnustep]/gnustep/usr-apps/gworkspace/Viewers/IconsViewer/IconsPath.m
ViewVC logotype

Contents of /gnustep/usr-apps/gworkspace/Viewers/IconsViewer/IconsPath.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations) (download)
Tue Sep 30 15:38:06 2003 UTC (20 years, 6 months ago) by esersale
Branch: MAIN
Changes since 1.3: +3 -8 lines
*** empty log message ***

1 /* IconsPath.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
26 #include <Foundation/Foundation.h>
27 #include <AppKit/AppKit.h>
28 #include <math.h>
29 #ifdef GNUSTEP
30 #include "GWLib.h"
31 #include "GWProtocol.h"
32 #include "GWFunctions.h"
33 #include "GWNotifications.h"
34 #include "BNameEditor.h"
35 #else
36 #include <GWorkspace/GWLib.h>
37 #include <GWorkspace/GWProtocol.h>
38 #include <GWorkspace/GWFunctions.h>
39 #include <GWorkspace/GWNotifications.h>
40 #include <GWorkspace/BNameEditor.h>
41 #endif
42 #include "IconsPath.h"
43 #include "PathIcon.h"
44 #include "GNUstep.h"
45
46 #define LABEL_MARGIN 8
47 #define EDIT_MARGIN 4
48 #define LABEL_HEIGHT 14
49 #define LABEL_V_SHIFT 14
50 #define ICON_VOFFSET 14
51 #define ICON_FRAME_HEIGHT 52
52 #define ICON_V_SHIFT 18
53 #define LABEL_VOFFSET 4
54 #define LABEL_HEIGHT 14
55 #define LAST_ICON_COMP 4
56
57 @implementation IconsPath
58
59 - (void)dealloc
60 {
61 RELEASE (root);
62 TEST_RELEASE (currentPath);
63 RELEASE (icons);
64 RELEASE (nameEditor);
65 RELEASE (editorFont);
66 [super dealloc];
67 }
68
69 - (id)initWithRootAtPath:(NSString *)rpath
70 columnsWidth:(float)cwidth
71 delegate:(id)adelegate
72 {
73 self = [super init];
74
75 if (self) {
76 ASSIGN (root, rpath);
77 columnsWidth = cwidth;
78 [self setDelegate: adelegate];
79 [self setAutoresizingMask: (NSViewWidthSizable)];
80 icons = [[NSMutableArray alloc] initWithCapacity: 1];
81
82 nameEditor = [[BNameEditor alloc] init];
83 [nameEditor setDelegate: self];
84 [nameEditor setTarget: self];
85 [nameEditor setAction: @selector(editorAction:)];
86 ASSIGN (editorFont, [NSFont systemFontOfSize: 12]);
87 [nameEditor setFont: editorFont];
88 [nameEditor setBezeled: NO];
89 [nameEditor setAlignment: NSCenterTextAlignment];
90 [nameEditor setBackgroundColor: [NSColor whiteColor]];
91 edIcon = nil;
92 }
93
94 return self;
95 }
96
97 - (void)setIconsForSelection:(NSArray *)selection
98 {
99 NSString *fullPath;
100 NSArray *components;
101 NSMutableArray *subpaths;
102 NSString *path;
103 PathIcon *icon;
104 int i, count;
105
106 fullPath = [NSString stringWithString: [selection objectAtIndex: 0]];
107 subpaths = [NSMutableArray arrayWithCapacity: 1];
108 path = [NSString string];
109 components = [fullPath pathComponents];
110
111 for (i = 0; i < [components count]; i++) {
112 path = [path stringByAppendingPathComponent: [components objectAtIndex: i]];
113 if (subPathOfPath(path, root) == NO) {
114 [subpaths addObject: path];
115 }
116 }
117
118 count = [subpaths count];
119 [self renewIcons: count];
120
121 for (i = 0; i < count; i++) {
122 icon = [icons objectAtIndex: i];
123 [icon setBranch: YES];
124 [icon setPaths: [NSArray arrayWithObject: [subpaths objectAtIndex: i]]];
125 }
126
127 if (count > 0) {
128 icon = [icons objectAtIndex: count - 1];
129 [icon setBranch: NO];
130 [icon setPaths: selection];
131 [icon select];
132 }
133
134 [self setIconsPositions];
135 }
136
137 - (void)setColumnWidth:(float)width
138 {
139 columnsWidth = width;
140 [self setIconsPositions];
141 }
142
143 - (void)renewIcons:(int)n
144 {
145 while ([icons count] > n) {
146 PathIcon *icon = [self lastIcon];
147
148 if (icon) {
149 [self removeIcon: icon];
150 }
151 }
152 while ([icons count] < n) {
153 [self addIcon];
154 }
155 }
156
157 - (void)addIcon
158 {
159 PathIcon *icon = [[PathIcon alloc] initWithDelegate: self];
160 [self addSubview: icon];
161 [self addSubview: [icon label]];
162 [icons addObject: icon];
163 RELEASE (icon);
164 [self setIconsPositions];
165 }
166
167 - (void)removeIcon:(PathIcon *)icon
168 {
169 NSTextField *label = [icon label];
170 [label setDelegate: nil];
171 [label setEditable: NO];
172 [label removeFromSuperview];
173 [icon removeFromSuperview];
174 [icons removeObject: icon];
175 [self setIconsPositions];
176 }
177
178 - (void)removeIconAtIndex:(int)index
179 {
180 [self removeIcon: [self iconAtIndex: index]];
181 }
182
183 - (void)lockIconsFromPath:(NSString *)path
184 {
185 int index = [self indexOfIconWithPath: path];
186
187 if (index != -1) {
188 int i;
189
190 for (i = index + 1; i < [icons count]; i++) {
191 [[icons objectAtIndex: i] setLocked: YES];
192 }
193 }
194 }
195
196 - (void)unlockIconsFromPath:(NSString *)path
197 {
198 int index = [self indexOfIconWithPath: path];
199
200 if (index != -1) {
201 int i;
202
203 for (i = index; i < [icons count]; i++) {
204 [[icons objectAtIndex: i] setLocked: NO];
205 }
206 }
207 }
208
209 - (void)setIconsPositions
210 {
211 float posx = 0.0;
212 int count = [icons count];
213 int i;
214
215 for (i = 0; i < count; i++) {
216 PathIcon *icon = [icons objectAtIndex: i];
217 NSRect r = NSMakeRect(posx, ICON_V_SHIFT, columnsWidth, ICON_FRAME_HEIGHT);
218
219 if (i == (count - 1)) {
220 r.size.width -= LAST_ICON_COMP;
221 }
222
223 [icon setFrame: r];
224 [icon setNeedsDisplay: YES];
225 posx += columnsWidth;
226 }
227
228 posx -= LAST_ICON_COMP;
229
230 if (posx != [self frame].size.width) {
231 [self setFrame: NSMakeRect(0, 0, posx, 70)];
232 }
233
234 [self updateNameEditor];
235
236 [self setNeedsDisplay: YES];
237 }
238
239 - (void)setLabelRectOfIcon:(PathIcon *)icon
240 {
241 NSTextField *label;
242 float labwidth, labxpos;
243 NSRect labelRect;
244
245 label = [icon label];
246 labwidth = [label frame].size.width;
247
248 if(columnsWidth > labwidth) {
249 labxpos = [icon frame].origin.x + ((columnsWidth - labwidth) / 2);
250 } else {
251 labxpos = [icon frame].origin.x - ((labwidth - columnsWidth) / 2);
252 }
253
254 labelRect = NSMakeRect(labxpos, LABEL_VOFFSET, labwidth, LABEL_HEIGHT);
255 [label setFrame: labelRect];
256 [label setNeedsDisplay: YES];
257 }
258
259 - (void)resizeWithOldSuperviewSize:(NSSize)oldFrameSize
260 {
261 [self setIconsPositions];
262 }
263
264 - (void)unselectOtherIcons:(PathIcon *)icon
265 {
266 int i;
267
268 for (i = 0; i < [icons count]; i++) {
269 PathIcon *icn = [icons objectAtIndex: i];
270 if (icn != icon) {
271 [icn unselect];
272 }
273 }
274 }
275
276 - (void)selectIconAtIndex:(int)index
277 {
278 if (index < [icons count]) {
279 [[icons objectAtIndex: index] select];
280 }
281 }
282
283 - (void)startEditing
284 {
285 [nameEditor selectText: nil];
286 }
287
288 - (NSArray *)icons
289 {
290 return icons;
291 }
292
293 - (PathIcon *)iconAtIndex:(int)index
294 {
295 if (index < [icons count]) {
296 return [icons objectAtIndex: index];
297 }
298 return nil;
299 }
300
301 - (int)indexOfIcon:(PathIcon *)icon
302 {
303 int i;
304
305 for (i = 0; i < [icons count]; i++) {
306 PathIcon *icn = [icons objectAtIndex: i];
307 if (icn == icon) {
308 return i;
309 }
310 }
311
312 return i;
313 }
314
315 - (int)indexOfIconWithPath:(NSString *)path
316 {
317 int i;
318
319 for (i = 0; i < [icons count]; i++) {
320 PathIcon *icon = [icons objectAtIndex: i];
321 NSArray *ipaths = [icon paths];
322 if (ipaths && [ipaths containsObject: path]) {
323 return i;
324 }
325 }
326
327 return -1;
328 }
329
330 - (PathIcon *)iconWithPath:(NSString *)path
331 {
332 int i;
333
334 for (i = 0; i < [icons count]; i++) {
335 PathIcon *icon = [icons objectAtIndex: i];
336 NSArray *ipaths = [icon paths];
337 if (ipaths && [ipaths containsObject: path]) {
338 return icon;
339 }
340 }
341
342 return nil;
343 }
344
345 - (PathIcon *)lastIcon
346 {
347 int count = [icons count];
348
349 if(count) {
350 return [icons objectAtIndex: count - 1];
351 }
352
353 return nil;
354 }
355
356 - (NSPoint)positionOfLastIcon
357 {
358 PathIcon *icon = [self lastIcon];
359
360 if (icon) {
361 NSRect r = [icon frame];
362 NSSize s = [icon iconShift];
363 float xshift = fabs([self visibleRect].origin.x);
364
365 return NSMakePoint(r.origin.x + s.width - xshift,
366 r.origin.y + s.height + ICON_VOFFSET);
367 }
368
369 return NSZeroPoint;
370 }
371
372 - (NSPoint)positionForSlidedImage
373 {
374 return [self positionOfLastIcon];
375 }
376
377 - (int)numberOfIcons
378 {
379 return [icons count];
380 }
381
382 - (void)updateNameEditor
383 {
384 PathIcon *icon = [self lastIcon];
385
386 if (icon == nil) {
387 return;
388 }
389
390 if ([[self subviews] containsObject: nameEditor]) {
391 NSRect edrect = [nameEditor frame];
392
393 [nameEditor abortEditing];
394 [nameEditor setName: nil paths: nil index: -1];
395 [nameEditor removeFromSuperview];
396 [self setNeedsDisplayInRect: edrect];
397 edIcon = nil;
398 }
399
400 if (icon) {
401 NSArray *paths = [icon paths];
402 NSString *name = [icon isRootIcon] ? [icon hostname] : [icon name];
403 BOOL locked = [icon isLocked];
404 BOOL canedit = ((!locked) && (paths && [paths count] == 1) && (![icon isRootIcon]));
405 NSRect r = [icon frame];
406 float bw = [self bounds].size.width - EDIT_MARGIN;
407 float centerx = r.origin.x + (r.size.width / 2);
408 float labwidth = [editorFont widthOfString: name] + LABEL_MARGIN;
409 int index = [icons count] - 1;
410
411 [[icon label] setFrame: NSMakeRect(centerx, r.origin.y, 1, 1)];
412
413 if ((centerx + (labwidth / 2)) >= bw) {
414 centerx -= (centerx + (labwidth / 2) - bw);
415 } else if ((centerx - (labwidth / 2)) < LABEL_MARGIN) {
416 centerx += fabs(centerx - (labwidth / 2)) + LABEL_MARGIN;
417 }
418
419 r = NSMakeRect(centerx - (labwidth / 2), r.origin.y - LABEL_V_SHIFT, labwidth, LABEL_HEIGHT);
420 [nameEditor setFrame: r];
421 [nameEditor setName: name paths: paths index: index];
422 [nameEditor setBackgroundColor: [NSColor whiteColor]];
423 [nameEditor setTextColor: (locked ? [NSColor disabledControlTextColor]
424 : [NSColor controlTextColor])];
425 [nameEditor setEditable: canedit];
426 [nameEditor setSelectable: canedit];
427 [self addSubview: nameEditor];
428 }
429 }
430
431 - (void)controlTextDidChange:(NSNotification *)aNotification
432 {
433 static NSRect edr = {{0, 0}, {0, 0}};
434 static float crx = 0;
435 static float ory = 0;
436 static float bw = 0;
437 NSString *s;
438 float labwidth;
439 float labcenter;
440
441 if (edIcon == nil) {
442 edIcon = [self lastIcon];
443 edr = [edIcon frame];
444 crx = edr.origin.x + (edr.size.width / 2);
445 ory = [nameEditor frame].origin.y;
446 bw = [self bounds].size.width - EDIT_MARGIN;
447 }
448
449 s = [nameEditor stringValue];
450 labwidth = [editorFont widthOfString: s] + LABEL_MARGIN;
451
452 labcenter = crx;
453
454 while ((labcenter + (labwidth / 2)) > bw) {
455 labcenter -= EDIT_MARGIN;
456 if (labcenter < EDIT_MARGIN) {
457 break;
458 }
459 }
460
461 while ((labcenter - (labwidth / 2)) < EDIT_MARGIN) {
462 labcenter += EDIT_MARGIN;
463 if (labcenter >= bw) {
464 break;
465 }
466 }
467
468 [self setNeedsDisplayInRect: [nameEditor frame]];
469 [nameEditor setFrame: NSMakeRect((labcenter - (labwidth / 2)), ory, labwidth, LABEL_HEIGHT)];
470 }
471
472 - (void)controlTextDidEndEditing:(NSNotification *)aNotification
473 {
474 NSString *oldpath = [[nameEditor paths] objectAtIndex: 0];
475 NSString *basepath = [oldpath stringByDeletingLastPathComponent];
476 NSString *oldname = [nameEditor name];
477 NSString *newname = [nameEditor stringValue];
478 NSString *newpath = [basepath stringByAppendingPathComponent: newname];
479 NSFileManager *fm = [NSFileManager defaultManager];
480
481 #define CLEAREDITING \
482 [self updateNameEditor]; \
483 return
484
485 [nameEditor setAlignment: NSCenterTextAlignment];
486
487 if ([fm isWritableFileAtPath: oldpath] == NO) {
488 NSRunAlertPanel(NSLocalizedString(@"Error", @""),
489 [NSString stringWithFormat: @"%@\"%@\"!\n",
490 NSLocalizedString(@"You have not write permission\nfor ", @""),
491 oldpath], NSLocalizedString(@"Continue", @""), nil, nil);
492 CLEAREDITING;
493
494 } else if ([fm isWritableFileAtPath: basepath] == NO) {
495 NSRunAlertPanel(NSLocalizedString(@"Error", @""),
496 [NSString stringWithFormat: @"%@\"%@\"!\n",
497 NSLocalizedString(@"You have not write permission\nfor ", @""),
498 basepath], NSLocalizedString(@"Continue", @""), nil, nil);
499 CLEAREDITING;
500
501 } else {
502 NSCharacterSet *notAllowSet = [NSCharacterSet characterSetWithCharactersInString: @"/\\*$|~\'\"`^!?"];
503 NSRange range = [newname rangeOfCharacterFromSet: notAllowSet];
504 NSArray *dirContents = [fm directoryContentsAtPath: basepath];
505 NSMutableDictionary *notifObj = [NSMutableDictionary dictionaryWithCapacity: 1];
506
507 if (range.length > 0) {
508 NSRunAlertPanel(NSLocalizedString(@"Error", @""),
509 NSLocalizedString(@"Invalid char in name", @""),
510 NSLocalizedString(@"Continue", @""), nil, nil);
511 CLEAREDITING;
512 }
513
514 if ([dirContents containsObject: newname]) {
515 if ([newname isEqualToString: oldname]) {
516 CLEAREDITING;
517 } else {
518 NSRunAlertPanel(NSLocalizedString(@"Error", @""),
519 [NSString stringWithFormat: @"%@\"%@\" %@\n",
520 NSLocalizedString(@"The name ", @""),
521 newname, NSLocalizedString(@" is already in use!", @"")],
522 NSLocalizedString(@"Continue", @""), nil, nil);
523 CLEAREDITING;
524 }
525 }
526
527 [notifObj setObject: GWorkspaceRenameOperation forKey: @"operation"];
528 [notifObj setObject: oldpath forKey: @"source"];
529 [notifObj setObject: newpath forKey: @"destination"];
530 [notifObj setObject: [NSArray arrayWithObject: @""] forKey: @"files"];
531
532 [[NSNotificationCenter defaultCenter]
533 postNotificationName: GWFileSystemWillChangeNotification
534 object: notifObj];
535
536 [fm movePath: oldpath toPath: newpath handler: self];
537
538 [[NSNotificationCenter defaultCenter]
539 postNotificationName: GWFileSystemDidChangeNotification
540 object: notifObj];
541
542 [self updateNameEditor];
543 }
544 }
545
546 - (void)editorAction:(id)sender
547 {
548 }
549
550 - (BOOL)fileManager:(NSFileManager *)manager
551 shouldProceedAfterError:(NSDictionary *)errorDict
552 {
553 NSString *title = NSLocalizedString(@"Error", @"");
554 NSString *msg1 = NSLocalizedString(@"Cannot rename ", @"");
555 NSString *name = [nameEditor name];
556 NSString *msg2 = NSLocalizedString(@"Continue", @"");
557
558 NSRunAlertPanel(title, [NSString stringWithFormat: @"%@'%@'!", msg1, name], msg2, nil, nil);
559
560 return NO;
561 }
562
563 - (void)fileManager:(NSFileManager *)manager willProcessPath:(NSString *)path
564 {
565 }
566
567 - (id)delegate
568 {
569 return delegate;
570 }
571
572 - (void)setDelegate:(id)anObject
573 {
574 delegate = anObject;
575 }
576
577 @end
578
579 //
580 // PathIcon Delegate Methods
581 //
582
583 @implementation IconsPath (PathIconDelegateMethods)
584
585 - (void)setLabelFrameOfIcon:(id)anicon
586 {
587 [self setLabelRectOfIcon: anicon];
588 }
589
590 - (void)unselectIconsDifferentFrom:(id)anicon
591 {
592 [self unselectOtherIcons: anicon];
593 }
594
595 - (void)clickedIcon:(id)anicon
596 {
597 [delegate clickedIcon: anicon];
598 }
599
600 - (void)doubleClickedIcon:(id)anicon newViewer:(BOOL)isnew
601 {
602 [delegate doubleClickedIcon: anicon newViewer: isnew];
603 }
604
605 - (void)unselectNameEditor
606 {
607 [nameEditor setBackgroundColor: [NSColor windowBackgroundColor]];
608 [self setNeedsDisplayInRect: [nameEditor frame]];
609 }
610
611 - (void)restoreSelectionAfterDndOfIcon:(id)dndicon
612 {
613 PathIcon *icon = [self lastIcon];
614
615 if (icon) {
616 [icon select];
617 }
618
619 [nameEditor setBackgroundColor: [NSColor whiteColor]];
620 [self updateNameEditor];
621 }
622
623 @end

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