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

Contents of /gnustep/usr-apps/gworkspace/GWLib/BIcon.m

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /* BIcon.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 "GWProtocol.h"
29 #include "GWFunctions.h"
30 #include "GWNotifications.h"
31 #include "GWLib.h"
32 #include "BIcon.h"
33 #include "BIconLabel.h"
34 #include "GNUstep.h"
35
36 #define CHECK_LOCK if (locked) return
37 #define CHECK_LOCK_RET(x) if (locked) return x
38
39 @implementation BIcon
40
41 - (void)dealloc
42 {
43 [[NSNotificationCenter defaultCenter] removeObserver: self];
44 TEST_RELEASE (paths);
45 TEST_RELEASE (fullpath);
46 TEST_RELEASE (name);
47 TEST_RELEASE (hostname);
48 TEST_RELEASE (remoteHostName);
49 TEST_RELEASE (type);
50 TEST_RELEASE (icon);
51 RELEASE (namelabel);
52 RELEASE (highlight);
53 RELEASE (arrow);
54 [super dealloc];
55 }
56
57 - (id)initForRemoteHost:(NSString *)rhost
58 {
59 self = [super init];
60
61 if (self) {
62 #ifdef GNUSTEP
63 Class gwclass = [[NSBundle mainBundle] principalClass];
64 #else
65 Class gwclass = [[NSBundle mainBundle] classNamed: @"GWorkspace"];
66 #endif
67
68 gworkspace = (id<GWProtocol>)[gwclass gworkspace];
69
70 if (rhost) {
71 isRemote = YES;
72 ASSIGN (remoteHostName, rhost);
73 } else {
74 isRemote = NO;
75 remoteHostName = nil;
76 }
77
78 fm = [NSFileManager defaultManager];
79
80 ASSIGN (highlight, [NSImage imageNamed: @"CellHighlight.tiff"]);
81 ASSIGN (arrow, [NSImage imageNamed: @"common_3DArrowRight.tiff"]);
82
83 namelabel = [[BIconLabel alloc] initForIcon: self];
84 [namelabel setFont: [NSFont systemFontOfSize: 12]];
85 [namelabel setBezeled: NO];
86 [namelabel setEditable: NO];
87 [namelabel setSelectable: NO];
88 [namelabel setAlignment: NSCenterTextAlignment];
89 [namelabel setBackgroundColor: [NSColor windowBackgroundColor]];
90
91 contestualMenu = [gworkspace usesContestualMenu];
92
93 paths = nil;
94 fullpath = nil;
95 hostname = nil;
96 icon = nil;
97 isbranch = NO;
98 dimmed = NO;
99 locked = NO;
100 isPakage = NO;
101 singlepath = YES;
102 isSelect = NO;
103 dragdelay = 0;
104 isDragTarget = NO;
105 onSelf = NO;
106 isRootIcon = NO;
107
108 if (isRemote == NO) {
109 [self registerForDraggedTypes: [NSArray arrayWithObject: NSFilenamesPboardType]];
110 } else {
111 [self registerForDraggedTypes: [NSArray arrayWithObject: GWRemoteFilenamesPboardType]];
112 }
113 }
114
115 return self;
116 }
117
118 - (void)setPaths:(NSArray *)p
119 {
120 float width, labwidth;
121 int i, count;
122
123 if ([p isEqualToArray: paths]) {
124 return;
125 }
126
127 if (p == nil) {
128 TEST_RELEASE (paths);
129 paths = nil;
130 TEST_RELEASE (fullpath);
131 fullpath = nil;
132 ASSIGN (name, @"");
133 TEST_RELEASE (type);
134 type = nil;
135 isPakage = NO;
136 TEST_RELEASE (icon);
137 icon = nil;
138 dimmed = YES;
139 [self setNeedsDisplay: YES];
140 return;
141 }
142
143 dimmed = NO;
144
145 ASSIGN (paths, p);
146 count = [paths count];
147
148 if (count == 1) {
149 singlepath = YES;
150 ASSIGN (fullpath, [paths objectAtIndex: 0]);
151 if ([fullpath isEqualToString: fixPath(@"/", 0)]) {
152 ASSIGN (name, fullpath);
153 isRootIcon = YES;
154 } else {
155 ASSIGN (name, [fullpath lastPathComponent]);
156 isRootIcon = NO;
157 }
158
159 ASSIGN (type, [gworkspace server: remoteHostName typeOfFileAt: fullpath]);
160 isPakage = [gworkspace server: remoteHostName isPakageAtPath: fullpath];
161
162 } else {
163 fullpath = nil;
164 singlepath = NO;
165 ASSIGN (name, ([NSString stringWithFormat: @"%i items", count]));
166 type = nil;
167 isRootIcon = NO;
168 isPakage = NO;
169 }
170
171 if (singlepath == YES) {
172 ASSIGN (icon, [gworkspace iconForFile: fullpath ofType: type]);
173 } else {
174 ASSIGN (icon, [NSImage imageNamed: @"MultipleSelection.tiff"]);
175 }
176
177 width = [self frame].size.width;
178 labwidth = [[namelabel font] widthOfString: name] + 8;
179 if (labwidth > width) {
180 labwidth = width;
181 }
182 [namelabel setFrame: NSMakeRect(0, 0, labwidth, 14)];
183
184 if (isRootIcon == NO) {
185 [namelabel setStringValue: cutFileLabelText(name, namelabel, labwidth)];
186 } else {
187 if (isRemote == NO) {
188 NSHost *host = [NSHost currentHost];
189 NSString *hname = [host name];
190 NSRange range = [hname rangeOfString: @"."];
191
192 if (range.length != 0) {
193 hname = [hname substringToIndex: range.location];
194 }
195 ASSIGN (hostname, hname);
196 [namelabel setStringValue: hostname];
197 } else {
198 ASSIGN (hostname, remoteHostName);
199 [namelabel setStringValue: remoteHostName];
200 }
201 }
202
203 [self setLocked: NO];
204
205 for (i = 0; i < [paths count]; i++) {
206 NSString *path = [paths objectAtIndex: i];
207
208 if ([gworkspace server: remoteHostName isLockedPath: path]) {
209 [self setLocked: YES];
210 break;
211 }
212 }
213
214 [delegate icon: self setFrameOfLabel: namelabel];
215 [self setNeedsDisplay: YES];
216 }
217
218 - (void)setFrame:(NSRect)frameRect
219 {
220 float width, labwidth;
221
222 [super setFrame: frameRect];
223
224 width = [self frame].size.width;
225
226 if (isRootIcon == NO) {
227 labwidth = [[namelabel font] widthOfString: name] + 8;
228 } else {
229 labwidth = [[namelabel font] widthOfString: hostname] + 8;
230 }
231 if (labwidth > width) {
232 labwidth = width;
233 }
234
235 [namelabel setFrame: NSMakeRect(0, 0, labwidth, 14)];
236
237 if (isRootIcon == NO) {
238 [namelabel setStringValue: cutFileLabelText(name, namelabel, labwidth)];
239 } else {
240 [namelabel setStringValue: hostname];
241 }
242
243 [delegate icon: self setFrameOfLabel: namelabel];
244
245 [self setNeedsDisplay: YES];
246 }
247
248 - (void)select
249 {
250 if (isSelect || dimmed) {
251 return;
252 }
253
254 isSelect = YES;
255 [namelabel setBackgroundColor: [NSColor whiteColor]];
256 [delegate unselectOtherIcons: self];
257 [self setNeedsDisplay: YES];
258 [namelabel setNeedsDisplay: YES];
259 }
260
261 - (void)unselect
262 {
263 isSelect = NO;
264 [namelabel setBackgroundColor: [NSColor windowBackgroundColor]];
265 [self setNeedsDisplay: YES];
266 [namelabel setNeedsDisplay: YES];
267 }
268
269 - (void)renewIcon
270 {
271 if (singlepath == YES) {
272 ASSIGN (icon, [gworkspace iconForFile: fullpath ofType: type]);
273 } else {
274 ASSIGN (icon, [NSImage imageNamed: @"MultipleSelection.tiff"]);
275 }
276 [self setNeedsDisplay: YES];
277 }
278
279 - (void)openWithApp:(id)sender
280 {
281 if (isRemote == NO) {
282 NSString *appName = [[sender representedObject] objectForKey: @"appName"];
283 NSString *fullPath = [[sender representedObject] objectForKey: @"fullPath"];
284
285 [[NSWorkspace sharedWorkspace] openFile: fullPath withApplication: appName];
286 }
287 }
288
289 - (void)openWith:(id)sender
290 {
291 if (isRemote == NO) {
292 [gworkspace openSelectedPathsWith];
293 }
294 }
295
296 - (BOOL)isSelect
297 {
298 return isSelect;
299 }
300
301 - (NSTextField *)label
302 {
303 return namelabel;
304 }
305
306 - (void)setBranch:(BOOL)value
307 {
308 if (isbranch != value) {
309 isbranch = value;
310 [self setDimmed: NO];
311 [self setNeedsDisplay: YES];
312 }
313 }
314
315 - (BOOL)isBranch
316 {
317 return isbranch;
318 }
319
320 - (void)setDimmed:(BOOL)value
321 {
322 if (dimmed != value) {
323 dimmed = value;
324 }
325 }
326
327 - (BOOL)isDimmed
328 {
329 return dimmed;
330 }
331
332 - (void)setLocked:(BOOL)value
333 {
334 if (locked == value) {
335 return;
336 }
337 locked = value;
338 [namelabel setTextColor: (locked ? [NSColor disabledControlTextColor]
339 : [NSColor controlTextColor])];
340 [self setNeedsDisplay: YES];
341 [namelabel setNeedsDisplay: YES];
342 }
343
344 - (BOOL)isLocked
345 {
346 return locked;
347 }
348
349 - (BOOL)isRootIcon
350 {
351 return isRootIcon;
352 }
353
354 - (NSArray *)paths
355 {
356 return paths;
357 }
358
359 - (NSString *)name
360 {
361 return name;
362 }
363
364 - (NSString *)hostname
365 {
366 return hostname;
367 }
368
369 - (NSString *)type
370 {
371 return type;
372 }
373
374 - (NSImage *)icon
375 {
376 return icon;
377 }
378
379 - (NSSize)iconShift
380 {
381 NSRect r = [self frame];
382 NSSize s = [icon size];
383
384 return NSMakeSize((r.size.width - s.width) / 2, (r.size.height - s.height) / 2);
385 }
386
387 - (void)clickOnLabel
388 {
389 CHECK_LOCK;
390 [self select];
391 [delegate clickOnIcon: self];
392 }
393
394 - (void)mouseUp:(NSEvent *)theEvent
395 {
396 CHECK_LOCK;
397
398 if([theEvent clickCount] > 1) {
399 unsigned int modifier = [theEvent modifierFlags];
400 [delegate doubleClickOnIcon: self newViewer: (modifier == NSControlKeyMask)];
401 }
402 }
403
404 - (void)mouseDown:(NSEvent *)theEvent
405 {
406 NSEvent *nextEvent;
407 BOOL startdnd = NO;
408 NSPoint p;
409
410 CHECK_LOCK;
411
412 if (dimmed) {
413 return;
414 }
415
416 p = [theEvent locationInWindow];
417 p = [self convertPoint: p fromView: nil];
418
419 if (ONICON(p, [self frame].size, [icon size]) == NO) {
420 return;
421 }
422
423 if ([theEvent clickCount] == 1) {
424 if (isSelect == NO) {
425 [self select];
426 [delegate unselectNameEditor];
427 }
428
429 while (1) {
430 nextEvent = [[self window] nextEventMatchingMask:
431 NSLeftMouseUpMask | NSLeftMouseDraggedMask];
432
433 if ([nextEvent type] == NSLeftMouseUp) {
434 [delegate clickOnIcon: self];
435 break;
436
437 } else if ([nextEvent type] == NSLeftMouseDragged) {
438 if(dragdelay < 5) {
439 dragdelay++;
440 } else {
441 startdnd = YES;
442 break;
443 }
444 }
445 }
446
447 if (startdnd == YES) {
448 [self startExternalDragOnEvent: nextEvent];
449 }
450 }
451 }
452
453 - (NSMenu *)menuForEvent:(NSEvent *)theEvent
454 {
455 if (([theEvent type] != NSRightMouseDown) || (isSelect == NO)) {
456 return [super menuForEvent: theEvent];
457 } else if ([theEvent modifierFlags] == NSControlKeyMask) {
458 return [super menuForEvent: theEvent];
459 }
460 if ((name == nil) || ([[name pathExtension] length] == 0) || isRemote) {
461 return [super menuForEvent: theEvent];
462 }
463 if (contestualMenu == NO) {
464 return [super menuForEvent: theEvent];
465 }
466
467 if ((type == NSPlainFileType) || ([type isEqual: NSShellCommandFileType])) {
468 NSMenu *menu = [[NSMenu alloc] initWithTitle: NSLocalizedString(@"Open with", @"")];
469 NSString *ext = [name pathExtension];
470 NSDictionary *apps = [[NSWorkspace sharedWorkspace] infoForExtension: ext];
471 NSEnumerator *app_enum = [[apps allKeys] objectEnumerator];
472 NSMenuItem *menuItem;
473 id key;
474
475 while ((key = [app_enum nextObject])) {
476 NSDictionary *dict = [apps objectForKey: key];
477 NSString *role = [dict objectForKey: @"NSRole"];
478 NSMutableDictionary *repObjDict = [NSMutableDictionary dictionary];
479
480 menuItem = [NSMenuItem new];
481
482 if (role) {
483 [menuItem setTitle: [NSString stringWithFormat: @"%@ - %@", key, role]];
484 } else {
485 [menuItem setTitle: [NSString stringWithFormat: @"%@", key]];
486 }
487
488 [menuItem setTarget: self];
489 [menuItem setAction: @selector(openWithApp:)];
490 [repObjDict setObject: key forKey: @"appName"];
491 [repObjDict setObject: fullpath forKey: @"fullPath"];
492 [menuItem setRepresentedObject: repObjDict];
493 [menu addItem: menuItem];
494 RELEASE (menuItem);
495 }
496
497 menuItem = [NSMenuItem new];
498 [menuItem setTitle: NSLocalizedString(@"Open with...", @"")];
499 [menuItem setTarget: self];
500 [menuItem setAction: @selector(openWith:)];
501 [menu addItem: menuItem];
502 RELEASE (menuItem);
503
504 AUTORELEASE (menu);
505 return menu;
506 }
507
508 return [super menuForEvent: theEvent];
509 }
510
511 /*
512 - (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent
513
514 Overridden by subclasses to allow the user to drag images from the receiver without its window moving forward and possibly obscuring the
515 destination, and without activating the application. If this method returns YES, the normal window ordering and activation mechanism is delayed
516 (not necessarily prevented) until the next mouse-up event. If it returns NO then normal ordering and activation occurs. Never invoke this
517 method directly; it's invoked automatically for each mouse-down event directed at the NSView.
518
519 An NSView subclass that allows dragging should implement this method to return YES if theEvent, an initial mouse-down event, is potentially
520 the beginning of a dragging session or of some other context where window ordering isn't appropriate. This method is invoked before a
521 mouseDown: message for theEvent is sent. NSView's implementation returns NO.
522
523 If, after delaying window ordering, the receiver actually initiates a dragging session or similar operation, it should also send a
524 preventWindowOrdering message to NSApp, which completely prevents the window from ordering forward and the activation from becoming
525 active. preventWindowOrdering is sent automatically by NSView's dragImage:... and dragFile:... methods.
526 */
527
528 - (BOOL)isSinglePath
529 {
530 return singlepath;
531 }
532
533 - (id)delegate
534 {
535 return delegate;
536 }
537
538 - (void)setDelegate:(id)aDelegate
539 {
540 ASSIGN (delegate, aDelegate);
541 AUTORELEASE (delegate);
542 }
543
544 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
545 {
546 return YES;
547 }
548
549 - (void)drawRect:(NSRect)rect
550 {
551 if (dimmed == YES) {
552 return;
553 }
554
555 if(isSelect) {
556 [highlight compositeToPoint: ICONPOSITION(rect.size, [highlight size])
557 operation: NSCompositeSourceOver];
558 }
559
560 if (icon != nil) {
561 if (locked == NO) {
562 [icon compositeToPoint: ICONPOSITION(rect.size, [icon size])
563 operation: NSCompositeSourceOver];
564 } else {
565 [icon dissolveToPoint: ICONPOSITION(rect.size, [icon size]) fraction: 0.3];
566 }
567 }
568
569 if (isbranch == YES) {
570 [arrow compositeToPoint: NSMakePoint(rect.size.width - 15, 26)
571 operation: NSCompositeSourceOver];
572 }
573 }
574
575 @end
576
577
578 @implementation BIcon (DraggingSource)
579
580 - (void)startExternalDragOnEvent:(NSEvent *)event
581 {
582 NSEvent *nextEvent;
583 NSPoint dragPoint;
584 NSPasteboard *pb;
585
586 nextEvent = [[self window] nextEventMatchingMask:
587 NSLeftMouseUpMask | NSLeftMouseDraggedMask];
588
589 if([nextEvent type] != NSLeftMouseDragged) {
590 [self unselect];
591 return;
592 }
593
594 dragPoint = [nextEvent locationInWindow];
595 dragPoint = [self convertPoint: dragPoint fromView: nil];
596
597 pb = [NSPasteboard pasteboardWithName: NSDragPboard];
598 [self declareAndSetShapeOnPasteboard: pb];
599
600 [self dragImage: icon
601 at: dragPoint
602 offset: NSZeroSize
603 event: nextEvent
604 pasteboard: pb
605 source: self
606 slideBack: [gworkspace animateSlideBack]];
607 }
608
609 - (void)declareAndSetShapeOnPasteboard:(NSPasteboard *)pb
610 {
611 NSArray *dndtypes;
612 NSData *pbData;
613
614 if (isRemote == NO) {
615 dndtypes = [NSArray arrayWithObject: NSFilenamesPboardType];
616 [pb declareTypes: dndtypes owner: nil];
617
618 if ([pb setPropertyList: paths forType: NSFilenamesPboardType] == NO) {
619 return;
620 }
621 } else {
622 NSMutableDictionary *pbDict = [NSMutableDictionary dictionary];
623 dndtypes = [NSArray arrayWithObject: GWRemoteFilenamesPboardType];
624 [pb declareTypes: dndtypes owner: nil];
625 [pbDict setObject: remoteHostName forKey: @"host"];
626 [pbDict setObject: paths forKey: @"paths"];
627 pbData = [NSArchiver archivedDataWithRootObject: pbDict];
628 [pb setData: pbData forType: GWRemoteFilenamesPboardType];
629 }
630 }
631
632 - (unsigned int)draggingSourceOperationMaskForLocal:(BOOL)flag
633 {
634 return NSDragOperationAll;
635 }
636
637 - (void)draggedImage:(NSImage *)anImage
638 endedAt:(NSPoint)aPoint
639 deposited:(BOOL)flag
640 {
641 dragdelay = 0;
642 onSelf = NO;
643 [self setNeedsDisplay: YES];
644 [delegate restoreSelectionAfterDndOfIcon: self];
645 }
646
647 @end
648
649
650 @implementation BIcon (DraggingDestination)
651
652 - (unsigned int)draggingEntered:(id <NSDraggingInfo>)sender
653 {
654 NSPasteboard *pb;
655 NSDragOperation sourceDragMask;
656 NSData *pbData;
657 NSArray *sourcePaths;
658 NSString *fromPath;
659 NSString *buff;
660 NSString *iconPath;
661 int i, count;
662
663 CHECK_LOCK_RET (NSDragOperationNone);
664
665 isDragTarget = NO;
666
667 if ((([type isEqualToString: NSDirectoryFileType] == NO)
668 && ([type isEqualToString: NSFilesystemFileType] == NO)) || isPakage) {
669 return NSDragOperationNone;
670 }
671
672 pb = [sender draggingPasteboard];
673
674 if (isRemote == NO) {
675 if ([[pb types] indexOfObject: NSFilenamesPboardType] == NSNotFound) {
676 return NSDragOperationNone;
677 }
678 } else {
679 if ([[pb types] indexOfObject: GWRemoteFilenamesPboardType] == NSNotFound) {
680 return NSDragOperationNone;
681 }
682 }
683
684 if (isRemote == NO) {
685 sourcePaths = [pb propertyListForType: NSFilenamesPboardType];
686 } else {
687 NSDictionary *dndDict;
688
689 pbData = [pb dataForType: GWRemoteFilenamesPboardType];
690 dndDict = [NSUnarchiver unarchiveObjectWithData: pbData];
691
692 sourcePaths = [dndDict objectForKey: @"paths"];
693 }
694
695 count = [sourcePaths count];
696 fromPath = [[sourcePaths objectAtIndex: 0] stringByDeletingLastPathComponent];
697
698 if (count == 0) {
699 return NSDragOperationNone;
700 }
701
702 if ([gworkspace server: remoteHostName isWritableFileAtPath: fullpath] == NO) {
703 return NSDragOperationNone;
704 }
705
706 if ([paths isEqualToArray: sourcePaths]) {
707 onSelf = YES;
708 }
709
710 if ([fullpath isEqualToString: fromPath]) {
711 return NSDragOperationNone;
712 }
713
714 for (i = 0; i < count; i++) {
715 if ([fullpath isEqualToString: [sourcePaths objectAtIndex: i]]) {
716 return NSDragOperationNone;
717 }
718 }
719
720 buff = [NSString stringWithString: fullpath];
721 while (1) {
722 for (i = 0; i < count; i++) {
723 if ([buff isEqualToString: [sourcePaths objectAtIndex: i]]) {
724 return NSDragOperationNone;
725 }
726 }
727 if ([buff isEqualToString: fixPath(@"/", 0)] == YES) {
728 break;
729 }
730 buff = [buff stringByDeletingLastPathComponent];
731 }
732
733 isDragTarget = YES;
734
735 iconPath = [fullpath stringByAppendingPathComponent: @".opendir.tiff"];
736
737 if ((isRemote == NO) && ([fm isReadableFileAtPath: iconPath])) {
738 NSImage *img = [[NSImage alloc] initWithContentsOfFile: iconPath];
739
740 if (img) {
741 ASSIGN (icon, img);
742 RELEASE (img);
743 } else {
744 ASSIGN (icon, [NSImage imageNamed: @"FileIcon_Directory_Open.tiff"]);
745 }
746 } else {
747 ASSIGN (icon, [NSImage imageNamed: @"FileIcon_Directory_Open.tiff"]);
748 }
749
750 [self setNeedsDisplay: YES];
751
752 sourceDragMask = [sender draggingSourceOperationMask];
753
754 if (sourceDragMask == NSDragOperationCopy) {
755 return NSDragOperationCopy;
756 } else if (sourceDragMask == NSDragOperationLink) {
757 return NSDragOperationLink;
758 } else {
759 return NSDragOperationAll;
760 }
761
762 return NSDragOperationNone;
763 }
764
765 - (unsigned int)draggingUpdated:(id <NSDraggingInfo>)sender
766 {
767 NSDragOperation sourceDragMask;
768
769 CHECK_LOCK_RET (NSDragOperationNone);
770
771 if (isPakage) {
772 return NSDragOperationNone;
773 }
774 if (isDragTarget == NO) {
775 return NSDragOperationNone;
776 }
777
778 sourceDragMask = [sender draggingSourceOperationMask];
779
780 if (sourceDragMask == NSDragOperationCopy) {
781 return NSDragOperationCopy;
782 } else if (sourceDragMask == NSDragOperationLink) {
783 return NSDragOperationLink;
784 } else {
785 return NSDragOperationAll;
786 }
787
788 return NSDragOperationNone;
789 }
790
791 - (void)draggingExited:(id <NSDraggingInfo>)sender
792 {
793 if(isDragTarget == YES) {
794 isDragTarget = NO;
795 onSelf = NO;
796 ASSIGN (icon, [gworkspace iconForFile: fullpath ofType: type]);
797 [self setNeedsDisplay: YES];
798 }
799 }
800
801 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
802 {
803 CHECK_LOCK_RET (NO);
804 return isDragTarget;
805 }
806
807 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
808 {
809 CHECK_LOCK_RET (NO);
810 return YES;
811 }
812
813 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
814 {
815 NSPasteboard *pb;
816 NSDragOperation sourceDragMask;
817 NSData *pbData;
818 NSArray *sourcePaths;
819 NSString *operation, *source;
820 NSMutableArray *files;
821 NSMutableDictionary *opDict;
822 NSString *trashPath;
823 NSString *sourceHost;
824 int i;
825
826 CHECK_LOCK;
827
828 isDragTarget = NO;
829
830 if (onSelf == YES) {
831 onSelf = NO;
832 return;
833 }
834
835 ASSIGN (icon, [gworkspace iconForFile: fullpath ofType: type]);
836 [self setNeedsDisplay: YES];
837
838 sourceDragMask = [sender draggingSourceOperationMask];
839 pb = [sender draggingPasteboard];
840
841 sourceHost = nil;
842
843 if (isRemote == NO) {
844 sourcePaths = [pb propertyListForType: NSFilenamesPboardType];
845 } else {
846 NSDictionary *dndDict;
847
848 pbData = [pb dataForType: GWRemoteFilenamesPboardType];
849 dndDict = [NSUnarchiver unarchiveObjectWithData: pbData];
850
851 sourcePaths = [dndDict objectForKey: @"paths"];
852 sourceHost = [dndDict objectForKey: @"host"];
853 }
854
855 source = [[sourcePaths objectAtIndex: 0] stringByDeletingLastPathComponent];
856
857 if (isRemote == NO) {
858 trashPath = [gworkspace trashPath];
859
860 if ([source isEqual: trashPath]) {
861 operation = GWorkspaceRecycleOutOperation;
862 } else {
863 if (sourceDragMask == NSDragOperationCopy) {
864 operation = NSWorkspaceCopyOperation;
865 } else if (sourceDragMask == NSDragOperationLink) {
866 operation = NSWorkspaceLinkOperation;
867 } else {
868 operation = NSWorkspaceMoveOperation;
869 }
870 }
871 } else {
872 if (sourceDragMask == NSDragOperationCopy) {
873 operation = NSWorkspaceCopyOperation;
874 } else if (sourceDragMask == NSDragOperationLink) {
875 operation = NSWorkspaceLinkOperation;
876 } else {
877 operation = NSWorkspaceMoveOperation;
878 }
879 }
880
881 files = [NSMutableArray arrayWithCapacity: 1];
882 for(i = 0; i < [sourcePaths count]; i++) {
883 [files addObject: [[sourcePaths objectAtIndex: i] lastPathComponent]];
884 }
885
886 opDict = [NSMutableDictionary dictionaryWithCapacity: 4];
887 [opDict setObject: operation forKey: @"operation"];
888 [opDict setObject: source forKey: @"source"];
889 [opDict setObject: fullpath forKey: @"destination"];
890 [opDict setObject: files forKey: @"files"];
891
892 [gworkspace performFileOperationWithDictionary: opDict
893 fromSourceHost: sourceHost
894 toDestinationHost: remoteHostName];
895 }
896
897 @end
898

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