1/* GormMatrixEditor.m - Editor for matrices. 2 * 3 * Copyright (C) 2001 Free Software Foundation, Inc. 4 * 5 * Authors: Adam Fedor <fedor@gnu.org> 6 * Pierre-Yves Rivaille <pyrivail@ens-lyon.fr> 7 * Date: Sep 2001 8 * Aug 2002 9 * 10 * This file is part of GNUstep. 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. 25 */ 26 27#include <InterfaceBuilder/IBObjectAdditions.h> 28#include <AppKit/AppKit.h> 29 30#include "GormPrivate.h" 31#include "GormImage.h" 32#include "GormViewEditor.h" 33#include "GormMatrixEditor.h" 34#include "GormViewWithSubviewsEditor.h" 35#include "GormPlacementInfo.h" 36#include "GormFontViewController.h" 37#include "GormViewKnobs.h" 38 39#define _EO ((NSMatrix*)_editedObject) 40 41@interface GormViewEditor (Private) 42- (void) _displayFrame: (NSRect) frame 43 withPlacementInfo: (GormPlacementInfo*)gpi; 44@end 45 46@implementation NSMatrix (IBObjectAdditions) 47- (NSString*) editorClassName 48{ 49 return @"GormMatrixEditor"; 50} 51@end 52 53@interface NSForm (GormAdditions) 54- (CGFloat) titleWidth; 55@end 56 57@implementation NSForm (GormAdditions) 58 59- (CGFloat)titleWidth 60{ 61 NSInteger i, count = [self numberOfRows]; 62 float new_title_width = 0; 63 float candidate_title_width = 0; 64 65 // Compute max of title width in the cells 66 for (i = 0; i < count; i++) 67 { 68 candidate_title_width = [_cells[i][0] titleWidth]; 69 if (candidate_title_width > new_title_width) 70 new_title_width = candidate_title_width; 71 } 72 return new_title_width; 73} 74 75@end 76 77@implementation GormMatrixEditor 78 79- (void) copySelection 80{ 81 if (selected != nil) 82 { 83 [document copyObjects: [self selection] 84 type: IBViewPboardType 85 toPasteboard: [NSPasteboard generalPasteboard]]; 86 } 87} 88 89- (void) deleteSelection 90{ 91 NSDebugLog(@"Cannot delete Matrix cell\n"); 92} 93 94static BOOL done_editing; 95 96- (void) handleNotification: (NSNotification*)aNotification 97{ 98 NSString *name = [aNotification name]; 99 if ([name isEqual: NSControlTextDidEndEditingNotification] == YES) 100 { 101 done_editing = YES; 102 } 103 else 104 NSLog(@"GormMatrixEditor got unhandled notification %@", name); 105} 106 107 108/* 109 * Initialisation 110 */ 111- (id) initWithObject: (id)anObject inDocument: (id<IBDocuments>)aDocument 112{ 113 NSMutableArray *draggedTypes = [NSMutableArray array]; 114 115 opened = NO; 116 selected = nil; 117 selectedCol = -1; 118 selectedRow = -1; 119 _displaySelection = YES; 120 self = [super initWithObject: anObject 121 inDocument: aDocument]; 122 123 // dragged types... 124 [draggedTypes addObject: GormImagePboardType]; 125 [draggedTypes addObject: GormLinkPboardType]; 126 [draggedTypes addObject: GormSoundPboardType]; 127 128 // register... 129 [self registerForDraggedTypes: draggedTypes]; 130 131 return self; 132} 133 134/* Called when we double-click on a text/editable cell or form. Overlay 135 a text field so the user can edit the title. */ 136- (void) editTitleWithEvent: (NSEvent *)theEvent 137{ 138 NSInteger row, col; 139 unsigned eventMask; 140 id edit_view; 141 BOOL isForm; 142 NSRect frame; 143 NSTextField *editField; 144 NSDate *future = [NSDate distantFuture]; 145 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 146 147 isForm = [_EO isKindOfClass: [NSForm class]]; 148 if (isForm == NO && [selected type] != NSTextCellType) 149 return; 150 151 // get the superview we are to edit from. 152 edit_view = [_EO superview]; 153 154 [_EO getRow: &row column: &col ofCell: selected]; 155 frame = [_EO cellFrameAtRow: row column: col]; 156 frame.origin.x += NSMinX([_EO frame]); 157 if (isForm) 158 frame.size.width = [(NSForm *)_EO titleWidth]; 159 else 160 frame = [selected titleRectForBounds: frame]; 161 if ([_EO isFlipped]) 162 { 163 frame.origin.y = NSMaxY([_EO frame]) - NSMaxY(frame); 164 } 165 else 166 { 167 frame.origin.y = NSMinY([_EO frame]) + NSMinY(frame); 168 } 169 170 /* Now create an edit field and allow the user to edit the text */ 171 editField = [[NSTextField alloc] initWithFrame: frame]; 172 [editField setEditable: YES]; 173 [editField setSelectable: YES]; 174 [editField setBezeled: NO]; 175 [editField setEnabled: YES]; 176 if (isForm) 177 [editField setStringValue: [(NSFormCell *)selected title]]; 178 else 179 [editField setStringValue: [selected stringValue]]; 180 [edit_view addSubview: editField]; 181 // [edit_view displayRect: frame]; 182 [edit_view display]; 183 [[edit_view window] flushWindow]; 184 [nc addObserver: self 185 selector: @selector(handleNotification:) 186 name: NSControlTextDidEndEditingNotification 187 object: nil]; 188 189 /* Do some modal editing */ 190 [editField selectText: self]; 191 eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask | 192 NSKeyDownMask | NSKeyUpMask | NSFlagsChangedMask; 193 194 done_editing = NO; 195 while (!done_editing) 196 { 197 NSEvent *e; 198 NSEventType eType; 199 e = [NSApp nextEventMatchingMask: eventMask 200 untilDate: future 201 inMode: NSEventTrackingRunLoopMode 202 dequeue: YES]; 203 eType = [e type]; 204 switch (eType) 205 { 206 case NSLeftMouseDown: 207 { 208 NSPoint dp = [edit_view convertPoint: [e locationInWindow] 209 fromView: nil]; 210 if (NSMouseInRect(dp, frame, NO) == NO) 211 { 212 done_editing = YES; 213 break; 214 } 215 } 216 [[editField currentEditor] mouseDown: e]; 217 break; 218 case NSLeftMouseUp: 219 [[editField currentEditor] mouseUp: e]; 220 break; 221 case NSLeftMouseDragged: 222 [[editField currentEditor] mouseDragged: e]; 223 break; 224 case NSKeyDown: 225 [[editField currentEditor] keyDown: e]; 226 break; 227 case NSKeyUp: 228 [[editField currentEditor] keyUp: e]; 229 break; 230 case NSFlagsChanged: 231 [[editField currentEditor] flagsChanged: e]; 232 break; 233 default: 234 NSLog(@"Internal Error: Unhandled event during editing: %@", e); 235 break; 236 } 237 } 238 239 [nc removeObserver: self 240 name: NSControlTextDidEndEditingNotification 241 object: nil]; 242 243 [self makeSelectionVisible: NO]; 244 if (isForm) 245 { 246 /* Set the new title and resize the form to match the titles */ 247 CGFloat oldTitleWidth, titleWidth; 248 NSRect oldFrame; 249 oldTitleWidth = [(NSForm *)_EO titleWidth]; 250 [(NSFormCell *)selected setTitle: [editField stringValue]]; 251 [(NSForm *)_EO calcSize]; 252 titleWidth = [(NSForm *)_EO titleWidth]; 253 oldFrame = frame = [_EO frame]; 254 frame.origin.x -= (titleWidth - oldTitleWidth); 255 frame.size.width += (titleWidth - oldTitleWidth); 256 [(NSForm *)_EO setEntryWidth: NSWidth(frame)]; 257 [(NSForm *)_EO setFrame: frame]; 258 frame = NSUnionRect(frame, oldFrame); 259 } 260 else 261 [selected setStringValue: [editField stringValue]]; 262 263 [edit_view removeSubview: editField]; 264 [edit_view displayRect: frame]; 265 [self makeSelectionVisible: YES]; 266 267 RELEASE(editField); 268} 269 270- (BOOL) canBeOpened 271{ 272 return YES; 273} 274 275- (void) setOpened: (BOOL) value 276{ 277 if (value) 278 { 279 opened = YES; 280 } 281 else 282 { 283 opened = NO; 284 selected = nil; 285 selectedCol = -1; 286 selectedRow = -1; 287 } 288} 289 290- (void) mouseDown: (NSEvent *)theEvent 291{ 292 BOOL onKnob = NO; 293 294 { 295 if ([[parent selection] containsObject: _EO]) 296 { 297 IBKnobPosition knob = IBNoneKnobPosition; 298 NSPoint mouseDownPoint = 299 [self convertPoint: [theEvent locationInWindow] 300 fromView: nil]; 301 knob = GormKnobHitInRect([self bounds], 302 mouseDownPoint); 303 if (knob != IBNoneKnobPosition) 304 onKnob = YES; 305 } 306 if (onKnob == YES) 307 { 308 if (_next_responder) 309 return [_next_responder mouseDown: theEvent]; 310 else 311 return [self noResponderFor: @selector(mouseDown:)]; 312 } 313 } 314 315 if (opened == NO) 316 { 317 [super mouseDown: theEvent]; 318 return; 319 } 320 321 322 { 323 NSInteger row, col; 324 NSPoint mouseDownPoint = 325 [_EO 326 convertPoint: [theEvent locationInWindow] 327 fromView: nil]; 328 329 if ([_EO 330 getRow: &row 331 column: &col 332 forPoint: mouseDownPoint] == YES) 333 { 334 selectedRow = row; 335 selectedCol = col; 336 selected = [_EO cellAtRow: row 337 column: col]; 338 339 [document setSelectionFromEditor: self]; 340 if (selected != nil && ([theEvent clickCount] == 2) ) 341 { 342 [self editTitleWithEvent: theEvent]; 343 return; 344 } 345 346 [self setNeedsDisplay: YES]; 347 } 348 else 349 { 350 selected = nil; 351 selectedRow = -1; 352 selectedCol = -1; 353 [document setSelectionFromEditor: self]; 354 } 355 } 356} 357 358- (void) makeSelectionVisible: (BOOL)flag 359{ 360 if (selected != nil) 361 { 362 NSInteger row, col; 363 if ([_EO getRow: &row column: &col ofCell: selected]) 364 { 365 NSRect frame = [_EO cellFrameAtRow: row column: col]; 366 if (flag == YES) 367 [_EO selectCellAtRow: row column: col]; 368 [_EO lockFocus]; 369 [[NSColor controlShadowColor] set]; 370 NSHighlightRect(frame); 371 [_EO unlockFocus]; 372 } 373 } 374 else 375 { 376 [_EO deselectAllCells]; 377 } 378 [_EO display]; 379 [[_EO window] flushWindow]; 380} 381 382 383- (void) selectObjects: (NSArray*)anArray 384{ 385 id obj = [anArray lastObject]; 386 [self makeSelectionVisible: NO]; 387 selected = obj; 388 [document setSelectionFromEditor: self]; 389 [self makeSelectionVisible: YES]; 390} 391 392- (NSArray*) selection 393{ 394 if (selected == nil) 395 return [NSArray arrayWithObject: _EO]; 396 else 397 return [NSArray arrayWithObject: selected]; 398} 399 400- (BOOL) acceptsTypeFromArray: (NSArray*)types 401{ 402 return ([types containsObject: IBObjectPboardType] || [types containsObject: GormImagePboardType]); 403} 404 405- (void) postDraw: (NSRect) rect 406{ 407 if (_displaySelection) 408 { 409 if ((selectedRow != -1) && (selectedCol != -1)) 410 { 411 NSDebugLog(@"highlighting %@", 412 NSStringFromRect([_EO 413 cellFrameAtRow: selectedRow 414 column: selectedCol])); 415 [[NSColor blackColor] set]; 416 NSHighlightRect([_EO 417 convertRect: 418 [_EO 419 cellFrameAtRow: selectedRow 420 column: selectedCol] 421 toView: self]); 422 423 } 424 } 425} 426 427- (NSRect) _constrainedFrame: (NSRect) frame 428 withEvent: (NSEvent *)theEvent 429 andKnob: (IBKnobPosition) knob 430{ 431 NSInteger width; 432 NSInteger height; 433 434 if ([theEvent modifierFlags] & NSAlternateKeyMask) 435 { 436 NSInteger rows = [_EO numberOfRows]; 437 NSInteger cols = [_EO numberOfColumns]; 438 NSSize interSize = [_EO intercellSpacing]; 439 440 NSInteger colWidth = ([_EO frame].size.width - 441 (cols - 1) * interSize.width) / cols; 442 NSInteger rowHeight = ([_EO frame].size.height - 443 (rows - 1) * interSize.height) / rows; 444 445 NSInteger widthIncrement = colWidth + interSize.width; 446 NSInteger heightIncrement = rowHeight + interSize.height; 447 448 if (frame.size.width < colWidth) 449 { 450 width = colWidth; 451 rows = 1; 452 } 453 else 454 { 455 width = frame.size.width - [_EO frame].size.width; 456 rows = width / widthIncrement; 457 width = rows * widthIncrement + [_EO frame].size.width; 458 } 459 460 if (frame.size.height < rowHeight) 461 { 462 height = rowHeight; 463 cols = 1; 464 } 465 else 466 { 467 height = frame.size.height - [_EO frame].size.height; 468 cols = height / heightIncrement; 469 height = cols * heightIncrement + [_EO frame].size.height; 470 } 471 } 472 else if ([theEvent modifierFlags] & NSControlKeyMask) 473 { 474 NSInteger rows = [_EO numberOfRows]; 475 NSInteger cols = [_EO numberOfColumns]; 476 NSSize cellSize = [_EO cellSize]; 477 478 height = width = 0; 479 if (cols > 1) 480 width = ( frame.size.width - cellSize.width * cols) / (cols - 1); 481 if (rows > 1) 482 height = ( frame.size.height - cellSize.height * rows ) / (rows - 1); 483 484 width *= (cols - 1); 485 width += cellSize.width * cols; 486 height *= (rows - 1); 487 height += cellSize.height * rows; 488 } 489 else 490 { 491 NSInteger rows = [_EO numberOfRows]; 492 NSInteger cols = [_EO numberOfColumns]; 493 NSSize interSize = [_EO intercellSpacing]; 494 495 width = ( frame.size.width - interSize.width * (cols - 1) ) / cols; 496 width *= cols; 497 width += (interSize.width * (cols - 1)); 498 499 height = ( frame.size.height - interSize.height * (rows - 1) ) / rows; 500 height *= rows; 501 height += (interSize.height * (rows - 1)); 502 } 503 504 switch (knob) 505 { 506 case IBBottomLeftKnobPosition: 507 case IBMiddleLeftKnobPosition: 508 case IBTopLeftKnobPosition: 509 frame.origin.x = NSMaxX(frame) - width; 510 frame.size.width = width; 511 break; 512 case IBTopRightKnobPosition: 513 case IBMiddleRightKnobPosition: 514 case IBBottomRightKnobPosition: 515 frame.size.width = width; 516 break; 517 case IBTopMiddleKnobPosition: 518 case IBBottomMiddleKnobPosition: 519 case IBNoneKnobPosition: 520 break; 521 } 522 523 524 switch (knob) 525 { 526 case IBBottomLeftKnobPosition: 527 case IBBottomRightKnobPosition: 528 case IBBottomMiddleKnobPosition: 529 frame.origin.y = NSMaxY(frame) - height; 530 frame.size.height = height; 531 break; 532 case IBTopMiddleKnobPosition: 533 case IBTopRightKnobPosition: 534 case IBTopLeftKnobPosition: 535 frame.size.height = height; 536 break; 537 case IBMiddleLeftKnobPosition: 538 case IBMiddleRightKnobPosition: 539 case IBNoneKnobPosition: 540 break; 541 } 542 543 return frame; 544} 545 546 547- (void) updateResizingWithFrame: (NSRect) frame 548 andEvent: (NSEvent *)theEvent 549 andPlacementInfo: (GormPlacementInfo*) gpi 550{ 551 gpi->lastFrame = [self _constrainedFrame: frame 552 withEvent: theEvent 553 andKnob: gpi->knob]; 554 555 [self _displayFrame: gpi->lastFrame 556 withPlacementInfo: gpi]; 557} 558 559 560 561- (void) validateFrame: (NSRect) frame 562 withEvent: (NSEvent *) theEvent 563 andPlacementInfo: (GormPlacementInfo*)gpi 564{ 565 frame = gpi->lastFrame; 566 567 if ([theEvent modifierFlags] & (NSControlKeyMask | NSShiftKeyMask)) 568 { 569 NSInteger rows = [_EO numberOfRows]; 570 NSInteger cols = [_EO numberOfColumns]; 571 NSSize interSize = [_EO intercellSpacing]; 572 573 NSInteger colWidth = ([_EO frame].size.width - 574 (cols - 1) * interSize.width) / cols; 575 NSInteger rowHeight = ([_EO frame].size.height - 576 (rows - 1) * interSize.height) / rows; 577 578 NSInteger widthIncrement = colWidth + interSize.width; 579 NSInteger heightIncrement = rowHeight + interSize.height; 580 581 NSInteger newCols = (frame.size.width - [_EO frame].size.width) / 582 widthIncrement; 583 NSInteger newRows = (frame.size.height - [_EO frame].size.height) / 584 heightIncrement; 585 586 NSInteger i, j; 587 588 if (newCols > 0) 589 { 590 for (j = cols; j < cols + newCols; j++) 591 { 592 [_EO addColumn]; 593 for (i = 0; i < rows; i++) 594 { 595 [document attachObject: [_EO cellAtRow: i column: j] 596 toParent: _EO]; 597 } 598 } 599 } 600 else if (newCols < 0) 601 { 602 for (j = cols - 1; j >= cols - newCols; j--) 603 { 604 for (i = 0; i < rows; i++) 605 { 606 [document detachObject: [_EO cellAtRow: i column: j]]; 607 } 608 [_EO removeColumn: j]; 609 } 610 } 611 612 if (newRows > 0) 613 { 614 for (i = rows; i < rows + newRows; i++) 615 { 616 [_EO addRow]; 617 for (j = 0; j < cols + newCols; j++) 618 { 619 [document attachObject: [_EO cellAtRow: i column: j] 620 toParent: _EO]; 621 } 622 } 623 } 624 else if (newRows < 0) 625 { 626 for (i = rows - 1; i >= rows + newRows; i--) 627 { 628 for (j = 0; j < cols + newCols; j++) 629 { 630 [document detachObject: [_EO cellAtRow: i column: j]]; 631 } 632 [_EO removeRow: i]; 633 } 634 } 635 [_EO setFrame: frame]; 636 } 637 else if ([theEvent modifierFlags] & NSControlKeyMask) 638 { 639 NSInteger width; 640 NSInteger height; 641 NSInteger rows = [_EO numberOfRows]; 642 NSInteger cols = [_EO numberOfColumns]; 643 NSSize cellSize = [_EO cellSize]; 644 645 646 [self setFrame: frame]; 647 648 649 height = width = 0; 650 if (cols > 1) 651 width = ( frame.size.width - cellSize.width * cols) / (cols - 1); 652 if (rows > 1) 653 height = ( frame.size.height - cellSize.height * rows ) / (rows - 1); 654 655 [_EO setIntercellSpacing: NSMakeSize(width, height)]; 656 } 657 else 658 { 659 NSInteger width; 660 NSInteger height; 661 NSInteger rows = [_EO numberOfRows]; 662 NSInteger cols = [_EO numberOfColumns]; 663 NSSize interSize = [_EO intercellSpacing]; 664 665 666 [self setFrame: frame]; 667 668 669 width = ( frame.size.width - interSize.width * (cols - 1) ) / cols; 670 height = ( frame.size.height - interSize.height * (rows - 1) ) / rows; 671 672 [_EO setCellSize: NSMakeSize(width, height)]; 673 } 674} 675 676- (void) changeFont: (id)sender 677{ 678 NSEnumerator *enumerator = [[self selection] objectEnumerator]; 679 id anObject; 680 NSFont *newFont; 681 682 NSDebugLog(@"In %@ changing font for %@",[self className],[self selection]); 683 while ((anObject = [enumerator nextObject])) 684 { 685 if([anObject respondsToSelector: @selector(setTitleFont:)] && 686 [anObject respondsToSelector: @selector(setTextFont:)]) 687 { 688 newFont = [sender convertFont: [anObject font]]; 689 newFont = [[GormFontViewController sharedGormFontViewController] 690 convertFont: newFont]; 691 [anObject setTitleFont: newFont]; 692 [anObject setTextFont: newFont]; 693 } 694 else if ([anObject respondsToSelector: @selector(font)] && 695 [anObject respondsToSelector: @selector(setFont:)]) 696 { 697 newFont = [sender convertFont: [anObject font]]; 698 newFont = [[GormFontViewController sharedGormFontViewController] 699 convertFont: newFont]; 700 [anObject setFont: newFont]; 701 } 702 } 703 704 return; 705} 706 707- (id) connectTargetAtPoint: (NSPoint)mouseLoc 708{ 709 NSInteger row, col; 710 711 if ([_EO getRow: &row column: &col forPoint: mouseLoc] == YES) 712 { 713 /* If a matrix has small intercell spacing (less than 1 pixel), it 714 becomes impossible to make connections to the whole matrix, since 715 -getRow:column:forPoint: returns YES for every location within the 716 matrix's bounds. Therefore, we accept connection to matrix cells 717 only if the mouse is strictly inside the cell. */ 718 NSRect cellFrame = [_EO cellFrameAtRow: row column: col]; 719 720 if (mouseLoc.x != NSMinX(cellFrame) && 721 mouseLoc.x != NSMaxX(cellFrame) && 722 mouseLoc.y != NSMinY(cellFrame) && 723 mouseLoc.y != NSMaxY(cellFrame)) 724 { 725 return [_EO cellAtRow: row column: col]; 726 } 727 } 728 729 return _EO; 730} 731 732- (NSDragOperation) draggingEntered: (id<NSDraggingInfo>)sender 733{ 734 NSPasteboard *dragPb; 735 NSArray *types; 736 737 dragPb = [sender draggingPasteboard]; 738 types = [dragPb types]; 739 if ([types containsObject: GormLinkPboardType] == YES) 740 { 741 NSPoint loc = [sender draggingLocation]; 742 NSPoint mouseDownPoint = [_EO convertPoint: loc fromView: nil]; 743 744 [NSApp displayConnectionBetween: [NSApp connectSource] 745 and: [self connectTargetAtPoint: mouseDownPoint]]; 746 return NSDragOperationLink; 747 } 748 return [super draggingEntered: sender]; 749} 750 751- (BOOL) performDragOperation: (id<NSDraggingInfo>)sender 752{ 753 NSPasteboard *dragPb; 754 NSArray *types; 755 NSPoint dropPoint = [sender draggedImageLocation]; 756 NSPoint mouseDownPoint = [_EO convertPoint: dropPoint fromView: nil]; 757 758 dragPb = [sender draggingPasteboard]; 759 types = [dragPb types]; 760 761 if ([types containsObject: GormLinkPboardType]) 762 { 763 [NSApp displayConnectionBetween: [NSApp connectSource] 764 and: [self connectTargetAtPoint: mouseDownPoint]]; 765 [NSApp startConnecting]; 766 } 767 else if ([types containsObject: GormImagePboardType] == YES || 768 [types containsObject: GormSoundPboardType] == YES) 769 { 770 NSInteger row, col; 771 if ([_EO getRow: &row column: &col forPoint: mouseDownPoint] == YES) 772 { 773 id object = [_EO cellAtRow: row column: col]; 774 if ([types containsObject: GormImagePboardType] == YES) 775 { 776 NSString *name = [dragPb stringForType: GormImagePboardType]; 777 NSImage *image = [NSImage imageNamed: name]; 778 [image setArchiveByName: NO]; 779 if ([object respondsToSelector: @selector(setSound:)]) 780 { 781 [object setImage: image]; 782 } 783 else 784 { 785 return NO; 786 } 787 788 return YES; 789 } 790 else if ([types containsObject: GormSoundPboardType] == YES) 791 { 792 NSString *name; 793 name = [dragPb stringForType: GormSoundPboardType]; 794 if ([object respondsToSelector: @selector(setSound:)]) 795 { 796 [object setSound: [NSSound soundNamed: name]]; 797 } 798 else 799 { 800 return NO; 801 } 802 803 return YES; 804 } 805 } 806 } 807 808 return NO; 809} 810 811@end 812 813 814 815