-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathSSYFileDropView.m
208 lines (160 loc) · 5.15 KB
/
SSYFileDropView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#import "SSYFileDropView.h"
@interface SSYFileDropView ()
@property (copy) NSString* filePath ;
@end
@implementation SSYFileDropView
@synthesize filePath = m_filePath ;
- (void)dealloc {
[m_filePath release] ;
[super dealloc] ;
}
// When I first wrote this subclass, -target and -action would return
// nil even after -setTarget and -setAction. The reason is given in
// ADC Home > Reference Library > Guides > Cocoa > Events & Other Input > Action Messages.
// "NSControl provides methods for setting and using the target object and the action method.
// However, these methods require that an NSControl’s cell (or cells) be NSActionCells or
// custom cells that hold action and target as instance variables and can respond to the
// NSControl methods."
// The fix is found in http://www.cocoabuilder.com/archive/message/cocoa/2003/4/14/75930
// FROM : Pierre-Loïc Raynaud DATE : Mon Apr 14 11:45:55 2003
// If you wrote a NSControl subclass without using cells, and you want to
// use target/actions, you just have to link your Control with a
// NSActionCell by adding in your NSControl subclass implementation:
+ (Class) cellClass {
return [NSActionCell class];
}
// Like magic, it works!
// This method is never invoked ?!?
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]] ;
[image registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]] ;
}
return self ;
}
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]] ;
[self display] ;
}
return self;
}
- (void)setPath:(NSString*)path
{
// Set instance variable
[self setFilePath:path];
NSString* displayName ;
NSImage* displayImage ;
NSString* displayToolTip ;
if (path) {
// Path is not specified
// displayName
displayName = NSLocalizedString(@"dropFileOrDriveHere", nil) ;
// image
displayImage = [NSImage imageNamed:@"DropItHere"] ;
// toolTip
displayToolTip = NSLocalizedString(@"youNeedADestinationToBackUpYourDataTo", nil) ;
}
else {
NSFileManager* fm = [NSFileManager defaultManager] ;
if ([fm fileExistsAtPath:path]) {
// Path is specified and is available
// image
displayImage = [[NSWorkspace sharedWorkspace] iconForFile:path] ;
if (!displayImage) {
displayImage = [NSImage imageNamed:@"DiskOrFileNotAvailable"] ;
}
[displayImage setScalesWhenResized:YES] ;
[displayImage setSize:NSMakeSize(48.0, 48.0)] ;
// displayName
displayName = [fm displayNameAtPath:path] ;
// toolTip
displayToolTip = path ;
}
else {
// Path is specified but is not available
// image
displayImage = [NSImage imageNamed:@"DiskOrFileNotAvailable"] ;
// displayName
displayName = [NSString stringWithFormat:@"%@:\n%@",
NSLocalizedString(@"notAvailable", nil),
[[NSFileManager defaultManager] displayNameAtPath:path] ] ;
// toolTip
displayToolTip = path ;
}
}
// Write to UI
[label setStringValue:displayName] ;
[image setImage:displayImage] ;
[self setToolTip: displayToolTip] ;
[self display] ;
}
- (NSString*)path {
return [self filePath] ;
}
- (void)setObjectValue:(id)objectValue {
[self setPath:objectValue] ;
}
- (id)objectValue {
return [self path] ;
}
// Draw method is overridden to do drop highlighing
- (void)drawRect:(NSRect)rect
{
// Draw the normal frame first
[super drawRect:rect];
// Then do the highlighting
if (highlight) {
[[NSColor grayColor] set];
[NSBezierPath setDefaultLineWidth:5];
[NSBezierPath strokeRect:rect];
}
}
//////////////////////////////////
// Dragging Destination methods
//////////////////////////////////
// Called whenever a drag enters our drop zone:
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
highlight = YES;
[self setNeedsDisplay:YES];
return NSDragOperationCopy; // Accept data as a copy operation
}
// Called whenever a drag exits our drop zone
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
highlight = NO;
[self setNeedsDisplay:YES];
}
// Method to determine if we can accept the drop
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
// Drag is finished, so remove any highlighting
highlight = NO;
[self setNeedsDisplay:YES];
// Later, fix this verify that the dragged item is a volume
// But for now, just
return YES;
}
// This is to actually accept the drop
- (BOOL)performDragOperation:(id <NSDraggingInfo>)info
{
NSPasteboard *pboard = [info draggingPasteboard];
// Dragging Filenames From Finder or the List
if ([[pboard types] containsObject:NSFilenamesPboardType]) {
NSArray * files = [pboard propertyListForType:NSFilenamesPboardType];
NSEnumerator * enumerator = [files objectEnumerator];
NSString * filePath;
// If the first file exists, process and display the result, and
// then tell super to send our action to our target
if (filePath = [enumerator nextObject]) {
[self setPath:filePath];
[super sendAction:[self action] to:[self target]] ;
}
return YES;
}
return NO;
}
@end