/[gnustep]/gnustep/usr-apps/gworkspace/GWorkspace/TShelf/TShelfIcon.m
ViewVC logotype

Contents of /gnustep/usr-apps/gworkspace/GWorkspace/TShelf/TShelfIcon.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations) (download)
Mon Aug 25 17:19:14 2003 UTC (20 years, 7 months ago) by esersale
Branch: MAIN
Changes since 1.1: +19 -18 lines
*** empty log message ***

1 /* TShelfIcon.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 #ifdef GNUSTEP
29 #include "GWFunctions.h"
30 #include "GWNotifications.h"
31 #include "GWLib.h"
32 #else
33 #include <GWorkspace/GWFunctions.h>
34 #include <GWorkspace/GWNotifications.h>
35 #include <GWorkspace/GWLib.h>
36 #endif
37 #include "TShelfIcon.h"
38 #include "TShelfIconsView.h"
39 #include "GWorkspace.h"
40 #include "GNUstep.h"
41
42 #define CHECK_LOCK if (locked) return
43 #define CHECK_LOCK_RET(x) if (locked) return x
44
45 @implementation TShelfIcon
46
47 - (void)dealloc
48 {
49 RELEASE (paths);
50 TEST_RELEASE (fullPath);
51 RELEASE (name);
52 TEST_RELEASE (hostname);
53 RELEASE (type);
54 RELEASE (namelabel);
55 RELEASE (icon);
56 RELEASE (highlight);
57 [super dealloc];
58 }
59
60 - (id)initForPaths:(NSArray *)fpaths
61 inIconsView:(TShelfIconsView *)aview
62 {
63 self = [super init];
64 if (self) {
65 NSFont *font;
66 NSString *defApp = nil, *t = nil;
67 int count;
68
69 fm = [NSFileManager defaultManager];
70 ws = [NSWorkspace sharedWorkspace];
71 gw = [GWorkspace gworkspace];
72
73 [self setFrame: NSMakeRect(0, 0, 64, 52)];
74 paths = [[NSMutableArray alloc] initWithCapacity: 1];
75 [paths addObjectsFromArray: fpaths];
76 tview = aview;
77 labelWidth = [tview cellsWidth] - 4;
78 font = [NSFont systemFontOfSize: 12];
79 isSelect = NO;
80 locked = NO;
81 count = [paths count];
82
83 if (count == 1) {
84 singlepath = YES;
85 ASSIGN (fullPath, [paths objectAtIndex: 0]);
86
87 if ([fullPath isEqualToString: fixPath(@"/", 0)]) {
88 ASSIGN (name, fullPath);
89 isRootIcon = YES;
90 } else {
91 ASSIGN (name, [fullPath lastPathComponent]);
92 isRootIcon = NO;
93 }
94
95 [ws getInfoForFile: fullPath application: &defApp type: &t];
96 ASSIGN (type, t);
97 isPakage = [gw isPakageAtPath: fullPath];
98
99 } else {
100 fullPath = nil;
101 singlepath = NO;
102 type = nil;
103 isRootIcon = NO;
104 isPakage = NO;
105 name = [[NSString alloc] initWithFormat: @"%i items", count];
106 }
107
108 if (singlepath == YES) {
109 ASSIGN (icon, [gw iconForFile: fullPath ofType: type]);
110 } else {
111 ASSIGN (icon, [NSImage imageNamed: @"MultipleSelection.tiff"]);
112 }
113
114 ASSIGN (highlight, [NSImage imageNamed: @"CellHighlight.tiff"]);
115
116 if (isRootIcon == YES) {
117 NSHost *host = [NSHost currentHost];
118 NSString *hname = [host name];
119 NSRange range = [hname rangeOfString: @"."];
120
121 if (range.length != 0) {
122 hname = [hname substringToIndex: range.location];
123 }
124 ASSIGN (hostname, hname);
125 } else {
126 hostname = nil;
127 }
128
129 namelabel = [NSTextField new];
130 [namelabel setFont: font];
131 [namelabel setBezeled: NO];
132 [namelabel setEditable: NO];
133 [namelabel setSelectable: NO];
134 [namelabel setAlignment: NSCenterTextAlignment];
135 [namelabel setBackgroundColor: [NSColor windowBackgroundColor]];
136 [namelabel setTextColor: [NSColor blackColor]];
137 [self setLabelWidth];
138
139 [self registerForDraggedTypes: [NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
140
141 position = NSMakePoint(0, 0);
142 gridindex = -1;
143 dragdelay = 0;
144 isDragTarget = NO;
145 onSelf = NO;
146 }
147
148 return self;
149 }
150
151 - (id)initForPaths:(NSArray *)fpaths
152 atPosition:(NSPoint)pos
153 inIconsView:(TShelfIconsView *)aview
154 {
155 [self initForPaths: fpaths inIconsView: aview];
156 position = NSMakePoint(pos.x, pos.y);
157 return self;
158 }
159
160 - (id)initForPaths:(NSArray *)fpaths
161 gridIndex:(int)index
162 inIconsView:(TShelfIconsView *)aview
163 {
164 [self initForPaths: fpaths inIconsView: aview];
165 gridindex = index;
166 return self;
167 }
168
169 - (void)setPaths:(NSArray *)fpaths
170 {
171 NSString *defApp = nil, *t = nil;
172 int count;
173
174 TEST_RELEASE (paths);
175 paths = [[NSMutableArray alloc] initWithCapacity: 1];
176 [paths addObjectsFromArray: fpaths];
177 count = [paths count];
178
179 if (count == 1) {
180 singlepath = YES;
181 ASSIGN (fullPath, [paths objectAtIndex: 0]);
182 if ([fullPath isEqualToString: fixPath(@"/", 0)]) {
183 ASSIGN (name, fullPath);
184 isRootIcon = YES;
185 } else {
186 ASSIGN (name, [fullPath lastPathComponent]);
187 isRootIcon = NO;
188 }
189 [ws getInfoForFile: fullPath application: &defApp type: &t];
190 ASSIGN (type, t);
191 isPakage = [gw isPakageAtPath: fullPath];
192 } else {
193 TEST_RELEASE (fullPath);
194 fullPath = nil;
195 singlepath = NO;
196 type = nil;
197 isRootIcon = NO;
198 isPakage = NO;
199 name = [[NSString alloc] initWithFormat: @"%i items", count];
200 }
201
202 if (singlepath == YES) {
203 ASSIGN (icon, [gw iconForFile: fullPath ofType: type]);
204 } else {
205 ASSIGN (icon, [NSImage imageNamed: @"MultipleSelection.tiff"]);
206 }
207
208 if (isRootIcon == YES) {
209 NSHost *host = [NSHost currentHost];
210 NSString *hname = [host name];
211 NSRange range = [hname rangeOfString: @"."];
212
213 if (range.length != 0) {
214 hname = [hname substringToIndex: range.location];
215 }
216 ASSIGN (hostname, hname);
217 } else {
218 TEST_RELEASE (hostname);
219 hostname = nil;
220 }
221
222 [self setLabelWidth];
223 [tview setLabelRectOfIcon: self];
224 }
225
226 - (void)setPosition:(NSPoint)pos
227 {
228 position = NSMakePoint(pos.x, pos.y);
229 }
230
231 - (void)setPosition:(NSPoint)pos gridIndex:(int)index
232 {
233 position = NSMakePoint(pos.x, pos.y);
234 gridindex = index;
235 }
236
237 - (NSPoint)position
238 {
239 return position;
240 }
241
242 - (void)setGridIndex:(int)index
243 {
244 gridindex = index;
245 }
246
247 - (int)gridindex
248 {
249 return gridindex;
250 }
251
252 - (void)select
253 {
254 isSelect = YES;
255 if (locked == NO) {
256 [namelabel setTextColor: [NSColor controlTextColor]];
257 }
258 [self setNeedsDisplay: YES];
259 }
260
261 - (void)unselect
262 {
263 isSelect = NO;
264 if (locked == NO) {
265 [namelabel setTextColor: [NSColor controlTextColor]];
266 }
267 [self setNeedsDisplay: YES];
268 }
269
270 - (void)renewIcon
271 {
272 if (singlepath == YES) {
273 ASSIGN (icon, [gw iconForFile: fullPath ofType: type]);
274 } else {
275 ASSIGN (icon, [NSImage imageNamed: @"MultipleSelection.tiff"]);
276 }
277 [self setNeedsDisplay: YES];
278 }
279
280 - (void)setLabelWidth
281 {
282 NSFont *font = [NSFont systemFontOfSize: 12];
283 NSRect rect = [namelabel frame];
284 NSString *nstr = isRootIcon ? hostname : name;
285
286 labelWidth = [tview cellsWidth] - 8;
287
288 if (isSelect == YES) {
289 [namelabel setFrame: NSMakeRect(0, 0, [font widthOfString: nstr] + 8, 14)];
290 [namelabel setStringValue: nstr];
291 } else {
292 int width = (int)[[namelabel font] widthOfString: nstr] + 8;
293 if (width > labelWidth) {
294 width = labelWidth;
295 }
296 [namelabel setFrame: NSMakeRect(0, 0, width, 14)];
297 [namelabel setStringValue: cutFileLabelText(nstr, namelabel, width - 8)];
298 }
299
300 [(NSView *)tview setNeedsDisplayInRect: rect];
301 }
302
303 - (NSTextField *)myLabel
304 {
305 return namelabel;
306 }
307
308 - (NSString *)type
309 {
310 return type;
311 }
312
313 - (NSArray *)paths
314 {
315 return paths;
316 }
317
318 - (NSString *)name
319 {
320 return name;
321 }
322
323 - (NSString *)hostname
324 {
325 return hostname;
326 }
327
328 - (BOOL)isSinglePath
329 {
330 return singlepath;
331 }
332
333 - (BOOL)isSelect
334 {
335 return isSelect;
336 }
337
338 - (void)setLocked:(BOOL)value
339 {
340 if (locked == value) {
341 return;
342 }
343 locked = value;
344 [namelabel setTextColor: (locked ? [NSColor disabledControlTextColor]
345 : [NSColor controlTextColor])];
346 [self setNeedsDisplay: YES];
347 [namelabel setNeedsDisplay: YES];
348 }
349
350 - (BOOL)isLocked
351 {
352 return locked;
353 }
354
355 - (BOOL)isRootIcon
356 {
357 return isRootIcon;
358 }
359
360 - (BOOL)isPakage
361 {
362 return isPakage;
363 }
364
365 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
366 {
367 return YES;
368 }
369
370 - (void)mouseUp:(NSEvent *)theEvent
371 {
372 if ([theEvent clickCount] > 1) {
373 if (locked == NO) {
374 [tview openCurrentSelection: paths];
375 }
376
377 [self unselect];
378 return;
379 }
380 }
381
382 - (void)mouseDown:(NSEvent *)theEvent
383 {
384 NSEvent *nextEvent;
385 BOOL startdnd = NO;
386
387 if ([theEvent clickCount] == 1) {
388 if (isSelect == NO) {
389 [self select];
390 }
391
392 while (1) {
393 nextEvent = [[self window] nextEventMatchingMask:
394 NSLeftMouseUpMask | NSLeftMouseDraggedMask];
395
396 if ([nextEvent type] == NSLeftMouseUp) {
397 NSSize ss = [self frame].size;
398 NSSize is = [icon size];
399 NSPoint p = NSMakePoint((ss.width - is.width) / 2, (ss.height - is.height) / 2);
400
401 p = [self convertPoint: p toView: nil];
402 p = [[self window] convertBaseToScreen: p];
403
404 [tview setCurrentSelection: paths];
405
406 [self unselect];
407 break;
408
409 } else if ([nextEvent type] == NSLeftMouseDragged) {
410 if(dragdelay < 5) {
411 dragdelay++;
412 } else {
413 startdnd = YES;
414 break;
415 }
416 }
417 }
418
419 if (startdnd == YES) {
420 [self startExternalDragOnEvent: nextEvent];
421 }
422 }
423 }
424
425 - (void)mouseDragged:(NSEvent *)theEvent
426 {
427 CHECK_LOCK;
428
429 if(dragdelay < 5) {
430 dragdelay++;
431 return;
432 }
433
434 [self startExternalDragOnEvent: theEvent];
435 }
436
437 - (NSMenu *)menuForEvent:(NSEvent *)theEvent
438 {
439 return [super menuForEvent: theEvent];
440 }
441
442 - (void)drawRect:(NSRect)rect
443 {
444 NSPoint p;
445 NSSize s;
446
447 if(isSelect) {
448 [highlight compositeToPoint: NSZeroPoint operation: NSCompositeSourceOver];
449 }
450
451 s = [icon size];
452 p = NSMakePoint((rect.size.width - s.width) / 2, (rect.size.height - s.height) / 2);
453 if (locked == NO) {
454 [icon compositeToPoint: p operation: NSCompositeSourceOver];
455 } else {
456 [icon dissolveToPoint: p fraction: 0.3];
457 }
458 }
459
460 @end
461
462 @implementation TShelfIcon (DraggingSource)
463
464 - (void)startExternalDragOnEvent:(NSEvent *)event
465 {
466 NSEvent *nextEvent;
467 NSPoint dragPoint;
468 NSPasteboard *pb;
469
470 nextEvent = [[self window] nextEventMatchingMask:
471 NSLeftMouseUpMask | NSLeftMouseDraggedMask];
472
473 if([nextEvent type] != NSLeftMouseDragged) {
474 [self unselect];
475 return;
476 }
477
478 dragPoint = [nextEvent locationInWindow];
479 dragPoint = [self convertPoint: dragPoint fromView: nil];
480
481 pb = [NSPasteboard pasteboardWithName: NSDragPboard];
482 [self declareAndSetShapeOnPasteboard: pb];
483
484 [self dragImage: icon
485 at: dragPoint
486 offset: NSZeroSize
487 event: event
488 pasteboard: pb
489 source: self
490 slideBack: NO];
491 }
492
493 - (void)declareAndSetShapeOnPasteboard:(NSPasteboard *)pb
494 {
495 NSArray *dndtypes = [NSArray arrayWithObject: NSFilenamesPboardType];
496 [pb declareTypes: dndtypes owner: nil];
497
498 if ([pb setPropertyList: paths forType: NSFilenamesPboardType] == NO) {
499 return;
500 }
501 }
502
503 - (void)draggedImage:(NSImage *)anImage
504 endedAt:(NSPoint)aPoint
505 deposited:(BOOL)flag
506 {
507 if (flag == NO) {
508 NSRect r1 = [self frame];
509 NSRect r2 = [namelabel frame];
510
511 r1.origin.x = r1.origin.y = r2.origin.x = r2.origin.y = 0;
512
513 aPoint = [[self window] convertScreenToBase: aPoint];
514 aPoint = [self convertPoint: aPoint fromView: nil];
515
516 if (NSPointInRect(aPoint, r1) || NSPointInRect(aPoint, r2)) {
517 dragdelay = 0;
518 onSelf = NO;
519 [self unselect];
520 return;
521 }
522
523 [tview removeIcon: self];
524 } else {
525 dragdelay = 0;
526 onSelf = NO;
527 [self unselect];
528 }
529 }
530
531 - (unsigned int)draggingSourceOperationMaskForLocal:(BOOL)flag
532 {
533 return NSDragOperationAll;
534 }
535
536 @end
537
538 @implementation TShelfIcon (DraggingDestination)
539
540 - (unsigned int)draggingEntered:(id <NSDraggingInfo>)sender
541 {
542 NSPasteboard *pb;
543 NSDragOperation sourceDragMask;
544 NSArray *sourcePaths;
545 NSString *fromPath;
546 NSString *buff;
547 NSString *iconPath;
548 int i, count;
549
550 CHECK_LOCK_RET (NSDragOperationNone);
551
552 isDragTarget = NO;
553
554 pb = [sender draggingPasteboard];
555 if([[pb types] indexOfObject: NSFilenamesPboardType] != NSNotFound) {
556 sourcePaths = [pb propertyListForType: NSFilenamesPboardType];
557
558 if ([paths isEqualToArray: sourcePaths]) {
559 onSelf = YES;
560 isDragTarget = YES;
561 return NSDragOperationAll;
562 }
563
564 if ((([type isEqualToString: NSDirectoryFileType] == NO)
565 && ([type isEqualToString: NSFilesystemFileType] == NO)) || isPakage) {
566 return NSDragOperationNone;
567 }
568
569 count = [sourcePaths count];
570 fromPath = [[sourcePaths objectAtIndex: 0] stringByDeletingLastPathComponent];
571
572 if (count == 0) {
573 return NSDragOperationNone;
574 }
575
576 if ([fm isWritableFileAtPath: fullPath] == NO) {
577 return NSDragOperationNone;
578 }
579
580 if ([fullPath isEqualToString: fromPath]) {
581 return NSDragOperationNone;
582 }
583
584 for (i = 0; i < count; i++) {
585 if ([fullPath isEqualToString: [sourcePaths objectAtIndex: i]]) {
586 return NSDragOperationNone;
587 }
588 }
589
590 buff = [NSString stringWithString: fullPath];
591 while (1) {
592 for (i = 0; i < count; i++) {
593 if ([buff isEqualToString: [sourcePaths objectAtIndex: i]]) {
594 return NSDragOperationNone;
595 }
596 }
597 if ([buff isEqualToString: fixPath(@"/", 0)] == YES) {
598 break;
599 }
600 buff = [buff stringByDeletingLastPathComponent];
601 }
602
603 isDragTarget = YES;
604
605 iconPath = [fullPath stringByAppendingPathComponent: @".opendir.tiff"];
606
607 if ([fm isReadableFileAtPath: iconPath]) {
608 NSImage *img = [[NSImage alloc] initWithContentsOfFile: iconPath];
609
610 if (img) {
611 ASSIGN (icon, img);
612 RELEASE (img);
613 } else {
614 ASSIGN (icon, [NSImage imageNamed: @"FileIcon_Directory_Open.tiff"]);
615 }
616 } else {
617 ASSIGN (icon, [NSImage imageNamed: @"FileIcon_Directory_Open.tiff"]);
618 }
619
620 [self setNeedsDisplay: YES];
621
622 sourceDragMask = [sender draggingSourceOperationMask];
623
624 if (sourceDragMask == NSDragOperationCopy) {
625 return NSDragOperationCopy;
626 } else if (sourceDragMask == NSDragOperationLink) {
627 return NSDragOperationLink;
628 } else {
629 return NSDragOperationAll;
630 }
631 }
632
633 return NSDragOperationNone;
634 }
635
636 - (unsigned int)draggingUpdated:(id <NSDraggingInfo>)sender
637 {
638 NSDragOperation sourceDragMask;
639
640 if (!isDragTarget || locked || isPakage) {
641 return NSDragOperationNone;
642 }
643
644 sourceDragMask = [sender draggingSourceOperationMask];
645
646 if (sourceDragMask == NSDragOperationCopy) {
647 return NSDragOperationCopy;
648 } else if (sourceDragMask == NSDragOperationLink) {
649 return NSDragOperationLink;
650 } else {
651 return NSDragOperationAll;
652 }
653
654 return NSDragOperationNone;
655 }
656
657 - (void)draggingExited:(id <NSDraggingInfo>)sender
658 {
659 if(isDragTarget == YES) {
660 isDragTarget = NO;
661 if (onSelf == NO) {
662 ASSIGN (icon, [gw iconForFile: fullPath ofType: type]);
663 [self setNeedsDisplay: YES];
664 }
665 onSelf = NO;
666 }
667 }
668
669 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
670 {
671 return isDragTarget;
672 }
673
674 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
675 {
676 return YES;
677 }
678
679 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
680 {
681 NSPasteboard *pb;
682 NSDragOperation sourceDragMask;
683 NSArray *sourcePaths;
684 NSString *operation, *source;
685 NSMutableArray *files;
686 NSMutableDictionary *opDict;
687 int i;
688
689 isDragTarget = NO;
690
691 if (onSelf == YES) {
692 onSelf = NO;
693 return;
694 }
695
696 ASSIGN (icon, [gw iconForFile: fullPath ofType: type]);
697 [self setNeedsDisplay: YES];
698
699 sourceDragMask = [sender draggingSourceOperationMask];
700 pb = [sender draggingPasteboard];
701 sourcePaths = [pb propertyListForType: NSFilenamesPboardType];
702 source = [[sourcePaths objectAtIndex: 0] stringByDeletingLastPathComponent];
703
704 if ([source isEqualToString: [gw trashPath]]) {
705 operation = GWorkspaceRecycleOutOperation;
706 } else {
707 if (sourceDragMask == NSDragOperationCopy) {
708 operation = NSWorkspaceCopyOperation;
709 } else if (sourceDragMask == NSDragOperationLink) {
710 operation = NSWorkspaceLinkOperation;
711 } else {
712 operation = NSWorkspaceMoveOperation;
713 }
714 }
715
716 files = [NSMutableArray arrayWithCapacity: 1];
717 for(i = 0; i < [sourcePaths count]; i++) {
718 [files addObject: [[sourcePaths objectAtIndex: i] lastPathComponent]];
719 }
720
721 opDict = [NSMutableDictionary dictionaryWithCapacity: 4];
722 [opDict setObject: operation forKey: @"operation"];
723 [opDict setObject: source forKey: @"source"];
724 [opDict setObject: fullPath forKey: @"destination"];
725 [opDict setObject: files forKey: @"files"];
726
727 [gw performFileOperationWithDictionary: opDict];
728 }
729
730 @end

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