1// ADPersonPropertyView+Events.m (this is -*- ObjC -*-) 2// 3// Authors: Bj�rn Giesler <giesler@ira.uka.de> 4// Riccardo Mottola <rm@gnu.org> 5// 6// Address View Framework for GNUstep 7// 8 9 10/* system includes */ 11/* (none) */ 12 13/* my includes */ 14#import "ADPersonPropertyView.h" 15#import "ADPersonView.h" 16 17@implementation ADPersonPropertyView (Events) 18- (void) mouseDown: (NSEvent*) event 19{ 20 int i; id c = nil; id details; ADMutableMultiValue *mv; 21 NSPoint p; 22 23 _mouseDownOnSelf = YES; 24 _mouseDownCell = nil; 25 26 p = [self convertPoint: [event locationInWindow] 27 fromView: nil]; 28 29 for(i=0; i<[_cells count]; i++) 30 { 31 c = [_cells objectAtIndex: i]; 32 if(NSPointInRect(p, [c rect])) 33 { 34 _mouseDownCell = c; 35 break; 36 } 37 } 38 if(i == [_cells count]) return; 39 40 details = [c details]; 41 42 if([c isEditable] && ![self isEditable]) 43 _propertyForDrag = [[self propertyForDragWithDetails: [c details]] 44 retain]; 45 else 46 { 47 [_propertyForDrag release]; 48 _propertyForDrag = nil; 49 } 50 51 if([c isKindOfClass: [ADPersonActionCell class]]) 52 { 53 ADActionType type; NSString *ident, *label; 54 NSUInteger index; 55 56 type = [c actionType]; 57 58 switch(type) 59 { 60 case ADAddAction: 61 mv = [[[ADMutableMultiValue alloc] 62 initWithMultiValue: [_person valueForProperty: _property]] 63 autorelease]; 64 ident = [mv addValue: [self emptyValue] 65 withLabel: [self defaultLabel]]; 66 [_person setValue: mv forProperty: _property]; 67 [[self superview] setNeedsDisplay: YES]; 68 [self layout]; 69 break; 70 71 case ADRemoveAction: 72 ident = [details objectForKey: @"Identifier"]; 73 label = [details objectForKey: @"Label"]; 74 if(!ident || !label) 75 { 76 NSLog(@"Ident %@ or label %@ are nil!\n", ident, label); 77 return; 78 } 79 index = [[_person valueForProperty: _property] 80 indexForIdentifier: ident]; 81 if(index == NSNotFound) 82 { 83 NSLog(@"Property %@ (%@) doesn't know identifier %@\n", 84 _property, [_person valueForProperty: _property], 85 ident); 86 return; 87 } 88 89 mv = [[[ADMutableMultiValue alloc] 90 initWithMultiValue: [_person valueForProperty: _property]] 91 autorelease]; 92 [mv removeValueAndLabelAtIndex: index]; 93 [_person setValue: mv forProperty: _property]; 94 [[self superview] setNeedsDisplay: YES]; 95 [self layout]; 96 break; 97 98 case ADChangeAction: 99 ident = [details objectForKey: @"Identifier"]; 100 label = [details objectForKey: @"Label"]; 101 if(!ident || !label) 102 { 103 NSLog(@"Ident %@ or label %@ are nil!\n", ident, label); 104 return; 105 } 106 index = [[_person valueForProperty: _property] 107 indexForIdentifier: ident]; 108 if(index == NSNotFound) 109 { 110 NSLog(@"Property %@ (%@) doesn't know identifier %@\n", 111 _property, [_person valueForProperty: _property], 112 ident); 113 return; 114 } 115 label = [self nextLabelAfter: label]; 116 117 mv = [[[ADMutableMultiValue alloc] 118 initWithMultiValue: [_person valueForProperty: _property]] 119 autorelease]; 120 [mv replaceLabelAtIndex: index withLabel: label]; 121 [_person setValue: mv forProperty: _property]; 122 [self layout]; 123 break; 124 125 default: 126 NSLog(@"Unknown action type %d\n", type); 127 } 128 129 return; 130 } 131 132 if(_editable) 133 { 134 if(_delegate) 135 [_delegate viewWillBeginEditing: self]; 136 [self beginEditingInCellWithDetails: details 137 becauseOfEvent: event]; 138 139 [self setNeedsDisplay: YES]; 140 } 141} 142 143- (void) mouseDragged: (NSEvent*) event 144{ 145 NSPasteboard *pb; 146 147 if(!_mouseDownOnSelf || !_delegate || _editable) 148 return; 149 150 pb = [NSPasteboard pasteboardWithName: NSDragPboard]; 151 152 if(_propertyForDrag && 153 [_delegate respondsToSelector: @selector(personPropertyView:willDragValue:forProperty:)] && 154 [_delegate personPropertyView: self 155 willDragValue: _propertyForDrag 156 forProperty: _property]) 157 { 158 [pb declareTypes: [NSArray arrayWithObject: NSStringPboardType] 159 owner: self]; 160 [pb setData: [_person vCardRepresentation] 161 forType: @"NSVCardPboardType"]; 162 [pb setString: _propertyForDrag forType: NSStringPboardType]; 163 164 [self dragImage: [self imageForDraggedProperty: _propertyForDrag] 165 at: NSZeroPoint 166 offset: NSZeroSize 167 event: event 168 pasteboard: pb 169 source: self 170 slideBack: YES]; 171 } 172 else if(!_propertyForDrag && 173 [_delegate respondsToSelector: @selector(personPropertyView:willDragPerson:)] && 174 [_delegate personPropertyView: self 175 willDragPerson: _person]) 176 { 177 NSString *str; 178 NSMutableDictionary *dict; 179 180 [pb declareTypes: [NSArray arrayWithObjects: @"NSVCardPboardType", 181 @"NSFilesPromisePboardType", 182 NSStringPboardType, 183 ADPeoplePboardType, 184 nil] 185 owner: self]; 186 [pb setData: [_person vCardRepresentation] 187 forType: @"NSVCardPboardType"]; 188 189 dict = [NSMutableDictionary dictionary]; 190 [dict setObject: [NSString stringWithFormat: @"%d", 191 [[NSProcessInfo processInfo] 192 processIdentifier]] 193 forKey: @"PID"]; 194 if([_person uniqueId]) 195 [dict setObject: [_person uniqueId] 196 forKey: @"UID"]; 197 if([_person addressBook]) 198 [dict setObject: [[_person addressBook] addressBookDescription] 199 forKey: @"AB"]; 200 [pb setPropertyList: [NSArray arrayWithObject: dict] 201 forType: ADPeoplePboardType]; 202 203 if([[_person valueForProperty: ADEmailProperty] count]) 204 str = [NSString stringWithFormat: @"%@ <%@>", 205 [_person screenNameWithFormat: ADScreenNameFirstNameFirst], 206 [[_person valueForProperty: ADEmailProperty] 207 valueAtIndex: 0]]; 208 else 209 str = [_person screenName]; 210 [pb setString: str forType: NSStringPboardType]; 211 212 [self dragImage: [_delegate draggingImage] 213 at: NSZeroPoint 214 offset: NSZeroSize 215 event: event 216 pasteboard: pb 217 source: self 218 slideBack: YES]; 219 } 220 221 _mouseDownCell = nil; 222} 223 224- (void) mouseUp: (NSEvent*) event 225{ 226 if(_editable) 227 return; 228 229 if(_mouseDownCell && _delegate && [_mouseDownCell isEditable] && 230 [_delegate respondsToSelector: _clickSel]) 231 [_delegate clickedOnProperty: _property 232 withValue: [_mouseDownCell stringValue] 233 inView: self]; 234 235 [_propertyForDrag release]; 236 _propertyForDrag = nil; 237 238 _mouseDownOnSelf = NO; 239 _mouseDownCell = nil; 240} 241 242- (unsigned int) draggingSourceOperationMaskForLocal: (BOOL) isLocal 243{ 244 return NSDragOperationCopy|NSDragOperationLink; 245} 246 247- (void) beginEditingInCellWithDetails: (id) details 248 becauseOfEvent: (NSEvent*) e 249{ 250 ADPersonPropertyCell *c; 251 NSRect r; 252 NSText *t; 253 int i; 254 255 [[details retain] autorelease]; 256 [self endEditing]; 257 258 i = [self indexOfEditableCellWithDetails: details]; 259 260 c = [_cells objectAtIndex: i]; 261 262 if(![c isEditable]) return; 263 _editingCellIndex = i; 264 r = [c rect]; 265 266 t = [_window fieldEditor: YES forObject: c]; 267 _textObject = [c setUpFieldEditorAttributes: t]; 268 [_textObject setBackgroundColor: [NSColor orangeColor]]; 269 [_textObject setTextColor: [NSColor blackColor]]; 270 [_textObject setDrawsBackground: YES]; 271 [_textObject setString: [c stringValue]]; 272 273 if([[c stringValue] hasPrefix: @"["]) 274 { 275 [c setStringValue: @""]; 276 r.size.width = [[c font] widthOfString: @""]; 277 } 278 279 r.size.width += 4; // make the cursor fit too 280 281 if(e) 282 [c editWithFrame: r 283 inView: self 284 editor: _textObject 285 delegate: self 286 event: e]; 287 else 288 { 289 // HACK: We must create our own event here, since we can't 290 // pass nil as event argument to 291 // editWithFrame:inView:... 292 // REASON: In that method, the event is asked for its event 293 // type, which (for a nil event) is 0==NSLeftMouseDown. The 294 // effect is that the NSCell sits there waiting for the 295 // mouse up :-) 296 // REMEDY: Maybe fix this by checking for nil event in 297 // NSCell editWithFrame:inView:...? 298 e = [NSEvent keyEventWithType: NSKeyDown 299 location: NSMakePoint(0, 0) 300 modifierFlags: 0 301 timestamp: 0 302 windowNumber: 0 303 context: nil 304 characters: @"\t" 305 charactersIgnoringModifiers: @"\t" 306 isARepeat: NO 307 keyCode: '\t']; 308 [c editWithFrame: r 309 inView: self 310 editor: _textObject 311 delegate: self 312 event: e]; 313 [_textObject setSelectedRange: NSMakeRange(0, [[c stringValue] 314 length])]; 315 } 316 317 [c setStringValue: @""]; 318 319 [self setNeedsDisplay: YES]; 320} 321 322- (void) beginEditingInCellAtIndex: (NSUInteger) i 323 becauseOfEvent: (NSEvent*) e 324{ 325 id cell = [_cells objectAtIndex: i]; 326 return [self beginEditingInCellWithDetails: [cell details] 327 becauseOfEvent: e]; 328} 329 330@end 331