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

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