1/* GWViewerIconsPath.m 2 * 3 * Copyright (C) 2004-2016 Free Software Foundation, Inc. 4 * 5 * Author: Enrico Sersale <enrico@imago.ro> 6 * Riccardo Mottola <rm@gnu.org> 7 * Date: July 2004 8 * 9 * This file is part of the GNUstep GWorkspace application 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. 24 */ 25 26#include <math.h> 27#include <sys/types.h> 28#include <unistd.h> 29 30#import <AppKit/AppKit.h> 31 32#import "FSNIcon.h" 33#import "FSNFunctions.h" 34#import "GWViewerIconsPath.h" 35#import "GWViewer.h" 36#import "GWorkspace.h" 37 38#define DEF_ICN_SIZE 48 39#define DEF_TEXT_SIZE 12 40#define DEF_ICN_POS NSImageAbove 41 42#define X_MARGIN (10) 43#define Y_MARGIN (12) 44 45#define EDIT_MARGIN (4) 46 47 48@implementation GWViewerIconsPath 49 50- (void)dealloc 51{ 52 RELEASE (icons); 53 RELEASE (extInfoType); 54 RELEASE (labelFont); 55 RELEASE (backColor); 56 RELEASE (textColor); 57 RELEASE (disabledTextColor); 58 59 [super dealloc]; 60} 61 62- (id)initWithFrame:(NSRect)frameRect 63 visibleIcons:(int)vicns 64 forViewer:(id)vwr 65 ownsScroller:(BOOL)ownscr 66{ 67 self = [super initWithFrame: frameRect]; 68 69 if (self) { 70 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 71 id defentry; 72 73 fsnodeRep = [FSNodeRep sharedInstance]; 74 75 visibleIcons = vicns; 76 viewer = vwr; 77 ownScroller = ownscr; 78 79 firstVisibleIcon = 0; 80 lastVisibleIcon = visibleIcons - 1; 81 shift = 0; 82 83 defentry = [defaults dictionaryForKey: @"backcolor"]; 84 if (defentry) { 85 float red = [[(NSDictionary *)defentry objectForKey: @"red"] floatValue]; 86 float green = [[(NSDictionary *)defentry objectForKey: @"green"] floatValue]; 87 float blue = [[(NSDictionary *)defentry objectForKey: @"blue"] floatValue]; 88 float alpha = [[(NSDictionary *)defentry objectForKey: @"alpha"] floatValue]; 89 90 ASSIGN (backColor, [NSColor colorWithCalibratedRed: red 91 green: green 92 blue: blue 93 alpha: alpha]); 94 } else { 95 ASSIGN (backColor, [[NSColor windowBackgroundColor] colorUsingColorSpaceName: NSDeviceRGBColorSpace]); 96 } 97 98 defentry = [defaults dictionaryForKey: @"textcolor"]; 99 if (defentry) { 100 float red = [[(NSDictionary *)defentry objectForKey: @"red"] floatValue]; 101 float green = [[(NSDictionary *)defentry objectForKey: @"green"] floatValue]; 102 float blue = [[(NSDictionary *)defentry objectForKey: @"blue"] floatValue]; 103 float alpha = [[(NSDictionary *)defentry objectForKey: @"alpha"] floatValue]; 104 105 ASSIGN (textColor, [NSColor colorWithCalibratedRed: red 106 green: green 107 blue: blue 108 alpha: alpha]); 109 } else { 110 ASSIGN (textColor, [[NSColor controlTextColor] colorUsingColorSpaceName: NSDeviceRGBColorSpace]); 111 } 112 113 ASSIGN (disabledTextColor, [textColor highlightWithLevel: NSDarkGray]); 114 115 iconSize = DEF_ICN_SIZE; 116 117 defentry = [defaults objectForKey: @"labeltxtsize"]; 118 labelTextSize = defentry ? [defentry intValue] : DEF_TEXT_SIZE; 119 ASSIGN (labelFont, [NSFont systemFontOfSize: labelTextSize]); 120 121 iconPosition = DEF_ICN_POS; 122 123 defentry = [defaults objectForKey: @"fsn_info_type"]; 124 infoType = defentry ? [defentry intValue] : FSNInfoNameType; 125 extInfoType = nil; 126 127 if (infoType == FSNInfoExtendedType) { 128 defentry = [defaults objectForKey: @"extended_info_type"]; 129 130 if (defentry) { 131 NSArray *availableTypes = [fsnodeRep availableExtendedInfoNames]; 132 133 if ([availableTypes containsObject: defentry]) { 134 ASSIGN (extInfoType, defentry); 135 } 136 } 137 138 if (extInfoType == nil) { 139 infoType = FSNInfoNameType; 140 } 141 } 142 143 icons = [NSMutableArray new]; 144 145 nameEditor = [FSNIconNameEditor new]; 146 [nameEditor setDelegate: self]; 147 [nameEditor setFont: labelFont]; 148 [nameEditor setBezeled: NO]; 149 [nameEditor setAlignment: NSCenterTextAlignment]; 150 [nameEditor setBackgroundColor: backColor]; 151 [nameEditor setTextColor: textColor]; 152 [nameEditor setEditable: NO]; 153 [nameEditor setSelectable: NO]; 154 editIcon = nil; 155 156 [self calculateGridSize]; 157 } 158 159 return self; 160} 161 162- (void)setOwnsScroller:(BOOL)ownscr 163{ 164 ownScroller = ownscr; 165 [self setFrame: [[self superview] bounds]]; 166 [self tile]; 167} 168 169- (void)showPathComponents:(NSArray *)components 170 selection:(NSArray *)selection 171{ 172 FSNode *node = [selection objectAtIndex: 0]; 173 int count = [components count]; 174 FSNIcon *icon; 175 int icncount; 176 int i; 177 178 [self stopRepNameEditing]; 179 180 while ([icons count] > count) { 181 icon = [self lastIcon]; 182 if (icon) { 183 [self removeRep: icon]; 184 } 185 } 186 187 icncount = [icons count]; 188 189 for (i = 0; i < [components count]; i++) { 190 FSNode *component = [components objectAtIndex: i]; 191 192 if (i < icncount) { 193 icon = [icons objectAtIndex: i]; 194 [icon setNode: component]; 195 } else { 196 icon = [self addRepForSubnode: component]; 197 } 198 199 [icon setLeaf: NO]; 200 [icon setNameEdited: NO]; 201 [icon setGridIndex: i]; 202 } 203 204 if ([node isEqual: [components objectAtIndex: (count -1)]] == NO) { 205 icon = [self addRepForSubnode: node]; 206 207 if ([selection count] > 1) { 208 NSMutableArray *selnodes = [NSMutableArray array]; 209 210 for (i = 0; i < [selection count]; i++) { 211 FSNode *selnode = [selection objectAtIndex: i]; 212 [selnodes addObject: selnode]; 213 } 214 215 [icon showSelection: selnodes]; 216 } 217 } 218 219 icon = [self lastIcon]; 220 [icon setLeaf: YES]; 221 [icon select]; 222 223 editIcon = nil; 224 225 [self tile]; 226} 227 228- (void)setSelectableIconsRange:(NSRange)range 229{ 230 int cols = range.length; 231 232 if (cols != visibleIcons) { 233 [self setFrame: [[self superview] bounds]]; 234 visibleIcons = cols; 235 } 236 237 firstVisibleIcon = range.location; 238 lastVisibleIcon = firstVisibleIcon + visibleIcons - 1; 239 shift = 0; 240 241 if (([icons count] - 1) < lastVisibleIcon) { 242 shift = lastVisibleIcon - [icons count] + 1; 243 } 244 245 [self tile]; 246} 247 248- (int)firstVisibleIcon 249{ 250 return firstVisibleIcon; 251} 252 253- (int)lastVisibleIcon 254{ 255 return lastVisibleIcon; 256} 257 258- (id)lastIcon 259{ 260 int count = [icons count]; 261 return (count ? [icons objectAtIndex: (count - 1)] : nil); 262} 263 264- (void)updateLastIcon 265{ 266 FSNIcon *icon = [self lastIcon]; 267 268 if (icon) { 269 NSArray *selection = [icon selection]; 270 271 if (selection) { 272 [icon showSelection: selection]; 273 } else { 274 [icon setNode: [icon node]]; 275 } 276 } 277} 278 279- (void)calculateGridSize 280{ 281 NSSize highlightSize = NSZeroSize; 282 NSSize labelSize = NSZeroSize; 283 284 highlightSize.width = ceil(iconSize / 3 * 4); 285 highlightSize.height = ceil(highlightSize.width * [fsnodeRep highlightHeightFactor]); 286 if ((highlightSize.height - iconSize) < 4) { 287 highlightSize.height = iconSize + 4; 288 } 289 290 labelSize.height = myrintf([fsnodeRep heightOfFont: labelFont]); 291 gridSize.height = highlightSize.height + labelSize.height; 292} 293 294- (void)tile 295{ 296 NSClipView *clip = (NSClipView *)[self superview]; 297 float vwidth = [clip visibleRect].size.width; 298 int count = [icons count]; 299 int i; 300 301 if (ownScroller) { 302 NSRect fr = [self frame]; 303 float x = [clip bounds].origin.x; 304 float y = [clip bounds].origin.y; 305 float posx = 0.0; 306 307 gridSize.width = myrintf(vwidth / visibleIcons); 308 [(NSScrollView *)[clip superview] setLineScroll: gridSize.width]; 309 310 for (i = 0; i < count; i++) { 311 NSRect r = NSZeroRect; 312 313 r.size = gridSize; 314 r.origin.y = 0; 315 r.origin.x = posx; 316 317 [[icons objectAtIndex: i] setFrame: r]; 318 319 posx += gridSize.width; 320 } 321 322 if (posx != fr.size.width) { 323 [self setFrame: NSMakeRect(0, fr.origin.y, posx, fr.size.height)]; 324 } 325 326 if (count > visibleIcons) { 327 x += gridSize.width * count; 328 [clip scrollToPoint: NSMakePoint(x, y)]; 329 } 330 331 } else { 332 vwidth -= visibleIcons; 333 gridSize.width = myrintf(vwidth / visibleIcons); 334 335 for (i = 0; i < count; i++) { 336 int n = i - firstVisibleIcon; 337 NSRect r = NSZeroRect; 338 339 r.size = gridSize; 340 r.origin.y = 0; 341 342 if (i < firstVisibleIcon) { 343 r.origin.x = (n * gridSize.width) - 8; 344 } else { 345 if (i == firstVisibleIcon) { 346 r.origin.x = (n * gridSize.width); 347 } else if (i <= lastVisibleIcon) { 348 r.origin.x = (n * gridSize.width) + n; 349 } else { 350 r.origin.x = (n * gridSize.width) + n + 8; 351 } 352 } 353 354 if (i == lastVisibleIcon) { 355 r.size.width = [[self superview] visibleRect].size.width - r.origin.x; 356 } 357 358 [[icons objectAtIndex: i] setFrame: r]; 359 } 360 } 361 362 [self updateNameEditor]; 363 364 [self setNeedsDisplay: YES]; 365} 366 367- (void)resizeWithOldSuperviewSize:(NSSize)oldFrameSize 368{ 369 [self tile]; 370} 371 372- (NSMenu *)menuForEvent:(NSEvent *)theEvent 373{ 374 NSPoint location = [theEvent locationInWindow]; 375 NSPoint selfloc = [self convertPoint: location fromView: nil]; 376 377 if (editIcon && [self mouse: selfloc inRect: [editIcon frame]]) { 378 NSArray *selnodes; 379 NSMenu *menu; 380 NSMenuItem *menuItem; 381 NSString *firstext; 382 NSDictionary *apps; 383 NSEnumerator *app_enum; 384 id key; 385 int i; 386 387 if ([theEvent modifierFlags] == NSControlKeyMask) { 388 return [super menuForEvent: theEvent]; 389 } 390 391 selnodes = [self selectedNodes]; 392 393 if ([selnodes count]) { 394 NSAutoreleasePool *pool; 395 396 firstext = [[[selnodes objectAtIndex: 0] path] pathExtension]; 397 398 for (i = 0; i < [selnodes count]; i++) { 399 FSNode *snode = [selnodes objectAtIndex: i]; 400 NSString *selpath = [snode path]; 401 NSString *ext = [selpath pathExtension]; 402 403 if ([ext isEqual: firstext] == NO) { 404 return [super menuForEvent: theEvent]; 405 } 406 407 if ([snode isDirectory] == NO) { 408 if ([snode isPlain] == NO) { 409 return [super menuForEvent: theEvent]; 410 } 411 } else { 412 if (([snode isPackage] == NO) || [snode isApplication]) { 413 return [super menuForEvent: theEvent]; 414 } 415 } 416 } 417 418 menu = [[NSMenu alloc] initWithTitle: NSLocalizedString(@"Open with", @"")]; 419 apps = [[NSWorkspace sharedWorkspace] infoForExtension: firstext]; 420 app_enum = [[apps allKeys] objectEnumerator]; 421 422 pool = [NSAutoreleasePool new]; 423 424 while ((key = [app_enum nextObject])) { 425 menuItem = [NSMenuItem new]; 426 key = [key stringByDeletingPathExtension]; 427 [menuItem setTitle: key]; 428 [menuItem setTarget: [GWorkspace gworkspace]]; 429 [menuItem setAction: @selector(openSelectionWithApp:)]; 430 [menuItem setRepresentedObject: key]; 431 [menu addItem: menuItem]; 432 RELEASE (menuItem); 433 } 434 435 RELEASE (pool); 436 437 return [menu autorelease]; 438 } 439 } 440 441 return [super menuForEvent: theEvent]; 442} 443 444// 445// scrollview delegate 446// 447- (void)gwviewerPathsScroll:(GWViewerPathsScroll *)sender 448 scrollViewScrolled:(NSClipView *)clip 449 hitPart:(NSScrollerPart)hitpart 450{ 451 if (hitpart != NSScrollerNoPart) { 452 int x = (int)[clip bounds].origin.x; 453 int y = (int)[clip bounds].origin.y; 454 int rem = x % (int)(myrintf(gridSize.width)); 455 456 [self stopRepNameEditing]; 457 458 if (rem != 0) { 459 if (rem <= gridSize.width / 2) { 460 x -= rem; 461 } else { 462 x += myrintf(gridSize.width) - rem; 463 } 464 465 [clip scrollToPoint: NSMakePoint(x, y)]; 466 [self setNeedsDisplay: YES]; 467 } 468 469 editIcon = [self lastIcon]; 470 if (editIcon && NSContainsRect([editIcon visibleRect], [editIcon iconBounds])) { 471 [self updateNameEditor]; 472 } 473 } 474} 475 476@end 477 478 479@implementation GWViewerIconsPath (NodeRepContainer) 480 481- (FSNode *)baseNode 482{ 483 return [viewer baseNode]; 484} 485 486- (id)repOfSubnode:(FSNode *)anode 487{ 488 int i; 489 490 for (i = 0; i < [icons count]; i++) { 491 FSNIcon *icon = [icons objectAtIndex: i]; 492 493 if ([[icon node] isEqualToNode: anode]) { 494 return icon; 495 } 496 } 497 498 return nil; 499} 500 501- (id)repOfSubnodePath:(NSString *)apath 502{ 503 int i; 504 505 for (i = 0; i < [icons count]; i++) { 506 FSNIcon *icon = [icons objectAtIndex: i]; 507 508 if ([[[icon node] path] isEqual: apath]) { 509 return icon; 510 } 511 } 512 513 return nil; 514} 515 516- (id)addRepForSubnode:(FSNode *)anode 517{ 518 FSNIcon *icon = [[FSNIcon alloc] initForNode: anode 519 nodeInfoType: infoType 520 extendedType: extInfoType 521 iconSize: iconSize 522 iconPosition: iconPosition 523 labelFont: labelFont 524 textColor: textColor 525 gridIndex: -1 526 dndSource: YES 527 acceptDnd: YES 528 slideBack: YES]; 529 [icons addObject: icon]; 530 [self addSubview: icon]; 531 RELEASE (icon); 532 533 return icon; 534} 535 536- (id)addRepForSubnodePath:(NSString *)apath 537{ 538 FSNode *subnode = [FSNode nodeWithPath: apath]; 539 return [self addRepForSubnode: subnode]; 540} 541 542- (void)removeRep:(id)arep 543{ 544 if (arep == editIcon) { 545 editIcon = nil; 546 } 547 [arep removeFromSuperviewWithoutNeedingDisplay]; 548 [icons removeObject: arep]; 549} 550 551- (void)repSelected:(id)arep 552{ 553 if (([arep isShowingSelection] == NO) && ((arep == [self lastIcon]) == NO)) { 554 [viewer pathsViewDidSelectIcon: arep]; 555 } 556} 557 558- (void)unselectOtherReps:(id)arep 559{ 560 int i; 561 562 for (i = 0; i < [icons count]; i++) { 563 FSNIcon *icon = [icons objectAtIndex: i]; 564 565 if (icon != arep) { 566 [icon unselect]; 567 } 568 } 569} 570 571- (NSArray *)selectedNodes 572{ 573 NSMutableArray *selectedNodes = [NSMutableArray array]; 574 NSUInteger i; 575 576 for (i = 0; i < [icons count]; i++) { 577 FSNIcon *icon = [icons objectAtIndex: i]; 578 579 if ([icon isSelected]) { 580 NSArray *selection = [icon selection]; 581 582 if (selection) { 583 [selectedNodes addObjectsFromArray: selection]; 584 } else { 585 [selectedNodes addObject: [icon node]]; 586 } 587 } 588 } 589 590 return [selectedNodes makeImmutableCopyOnFail: NO]; 591} 592 593- (NSArray *)selectedPaths 594{ 595 NSMutableArray *selectedPaths = [NSMutableArray array]; 596 NSUInteger i, j; 597 598 for (i = 0; i < [icons count]; i++) { 599 FSNIcon *icon = [icons objectAtIndex: i]; 600 601 if ([icon isSelected]) { 602 NSArray *selection = [icon selection]; 603 604 if (selection) { 605 for (j = 0; j < [selection count]; j++) { 606 [selectedPaths addObject: [[selection objectAtIndex: j] path]]; 607 } 608 } else { 609 [selectedPaths addObject: [[icon node] path]]; 610 } 611 } 612 } 613 614 return [selectedPaths makeImmutableCopyOnFail: NO]; 615} 616 617- (void)checkLockedReps 618{ 619 NSUInteger i; 620 621 for (i = 0; i < [icons count]; i++) 622 { 623 [[icons objectAtIndex: i] checkLocked]; 624 } 625} 626 627- (FSNSelectionMask)selectionMask 628{ 629 return NSSingleSelectionMask; 630} 631 632- (void)openSelectionInNewViewer:(BOOL)newv 633{ 634 [viewer openSelectionInNewViewer: newv]; 635} 636 637- (void)restoreLastSelection 638{ 639 [[self lastIcon] select]; 640 [nameEditor setBackgroundColor: [NSColor selectedControlColor]]; 641} 642 643- (NSColor *)backgroundColor 644{ 645 return [NSColor windowBackgroundColor]; 646} 647 648- (NSColor *)textColor 649{ 650 return [NSColor controlTextColor]; 651} 652 653- (NSColor *)disabledTextColor 654{ 655 return [NSColor disabledControlTextColor]; 656} 657 658- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender 659{ 660 return NSDragOperationNone; 661} 662 663@end 664 665 666@implementation GWViewerIconsPath (IconNameEditing) 667 668- (void)updateNameEditor 669{ 670 [self stopRepNameEditing]; 671 672 editIcon = [self lastIcon]; 673 674 if (editIcon && NSContainsRect([editIcon visibleRect], [editIcon iconBounds])) { 675 FSNode *ednode = [editIcon node]; 676 NSString *nodeDescr = [editIcon shownInfo]; 677 NSRect icnr = [editIcon frame]; 678 CGFloat centerx = icnr.origin.x + (icnr.size.width / 2); 679 NSRect labr = [editIcon labelRect]; 680 int margin = [fsnodeRep labelMargin]; 681 CGFloat bw = [self bounds].size.width - EDIT_MARGIN; 682 CGFloat edwidth = 0.0; 683 NSRect edrect; 684 685 [editIcon setNameEdited: YES]; 686 687 edwidth = [[nameEditor font] widthOfString: nodeDescr]; 688 edwidth += margin; 689 690 if ((centerx + (edwidth / 2)) >= bw) { 691 centerx -= (centerx + (edwidth / 2) - bw); 692 } else if ((centerx - (edwidth / 2)) < margin) { 693 centerx += fabs(centerx - (edwidth / 2)) + margin; 694 } 695 696 edrect = [self convertRect: labr fromView: editIcon]; 697 edrect.origin.x = centerx - (edwidth / 2); 698 edrect.size.width = edwidth; 699 edrect = NSIntegralRect(edrect); 700 701 [nameEditor setFrame: edrect]; 702 [nameEditor setAlignment: NSCenterTextAlignment]; 703 704 [nameEditor setNode: ednode 705 stringValue: nodeDescr 706 index: 0]; 707 708 [nameEditor setBackgroundColor: [NSColor selectedControlColor]]; 709 710 [nameEditor setEditable: NO]; 711 [nameEditor setSelectable: NO]; 712 [self addSubview: nameEditor]; 713 } 714} 715 716- (void)setNameEditorForRep:(id)arep 717{ 718 [self updateNameEditor]; 719} 720 721- (void)stopRepNameEditing 722{ 723 int i; 724 725 if ([[self subviews] containsObject: nameEditor]) { 726 NSRect edrect = [nameEditor frame]; 727 [nameEditor abortEditing]; 728 [nameEditor setEditable: NO]; 729 [nameEditor setSelectable: NO]; 730 [nameEditor setNode: nil stringValue: @"" index: -1]; 731 [nameEditor removeFromSuperview]; 732 [self setNeedsDisplayInRect: edrect]; 733 } 734 735 for (i = 0; i < [icons count]; i++) { 736 [[icons objectAtIndex: i] setNameEdited: NO]; 737 } 738 739 editIcon = nil; 740} 741 742- (BOOL)canStartRepNameEditing 743{ 744 return (editIcon && ([editIcon isLocked] == NO) 745 && ([editIcon isShowingSelection] == NO) 746 && ([[editIcon node] isMountPoint] == NO) 747 && (infoType == FSNInfoNameType)); 748} 749 750- (void)controlTextDidChange:(NSNotification *)aNotification 751{ 752 NSRect icnr = [editIcon frame]; 753 float centerx = icnr.origin.x + (icnr.size.width / 2); 754 float edwidth = [[nameEditor font] widthOfString: [nameEditor stringValue]]; 755 int margin = [fsnodeRep labelMargin]; 756 float bw = [self bounds].size.width - EDIT_MARGIN; 757 NSRect edrect = [nameEditor frame]; 758 759 edwidth += margin; 760 761 while ((centerx + (edwidth / 2)) > bw) { 762 centerx --; 763 if (centerx < EDIT_MARGIN) { 764 break; 765 } 766 } 767 768 while ((centerx - (edwidth / 2)) < EDIT_MARGIN) { 769 centerx ++; 770 if (centerx >= bw) { 771 break; 772 } 773 } 774 775 edrect.origin.x = centerx - (edwidth / 2); 776 edrect.size.width = edwidth; 777 778 [self setNeedsDisplayInRect: [nameEditor frame]]; 779 [nameEditor setFrame: NSIntegralRect(edrect)]; 780} 781 782- (void)controlTextDidEndEditing:(NSNotification *)aNotification 783{ 784 FSNode *ednode = [nameEditor node]; 785 786 if ([ednode isParentWritable] == NO) 787 { 788 showAlertNoPermission([FSNode class], [ednode parentName]); 789 [self updateNameEditor]; 790 return; 791 } 792 if ([ednode isSubnodeOfPath: [[GWorkspace gworkspace] trashPath]]) 793 { 794 showAlertInRecycler([FSNode class]); 795 [self updateNameEditor]; 796 return; 797 } 798 else 799 { 800 NSString *newname = [nameEditor stringValue]; 801 NSString *newpath = [[ednode parentPath] stringByAppendingPathComponent: newname]; 802 NSString *extension = [newpath pathExtension]; 803 NSCharacterSet *notAllowSet = [NSCharacterSet characterSetWithCharactersInString: @"/\\*:?\33"]; 804 NSRange range = [newname rangeOfCharacterFromSet: notAllowSet]; 805 NSArray *dirContents = [ednode subNodeNamesOfParent]; 806 NSMutableDictionary *opinfo = [NSMutableDictionary dictionary]; 807 808 if (([newname length] == 0) || (range.length > 0)) 809 { 810 showAlertInvalidName([FSNode class]); 811 [self updateNameEditor]; 812 return; 813 } 814 815 if (([extension length] 816 && ([ednode isDirectory] && ([ednode isPackage] == NO)))) 817 { 818 if (showAlertExtensionChange([FSNode class], extension) == NSAlertDefaultReturn) 819 { 820 [self updateNameEditor]; 821 return; 822 } 823 } 824 825 if ([dirContents containsObject: newname]) 826 { 827 if ([newname isEqual: [ednode name]]) 828 { 829 [self updateNameEditor]; 830 return; 831 } 832 else 833 { 834 showAlertNameInUse([FSNode class], newname); 835 [self updateNameEditor]; 836 return; 837 } 838 } 839 840 [opinfo setObject: @"GWorkspaceRenameOperation" forKey: @"operation"]; 841 [opinfo setObject: [ednode path] forKey: @"source"]; 842 [opinfo setObject: newpath forKey: @"destination"]; 843 [opinfo setObject: [NSArray arrayWithObject: @""] forKey: @"files"]; 844 845 [self stopRepNameEditing]; 846 [[GWorkspace gworkspace] performFileOperation: opinfo]; 847 } 848} 849 850@end 851 852 853@implementation GWViewerPathsScroll 854 855- (void)setDelegate:(id)anObject 856{ 857 delegate = anObject; 858} 859 860- (id)delegate 861{ 862 return delegate; 863} 864 865- (void)reflectScrolledClipView:(NSClipView *)aClipView 866{ 867 [super reflectScrolledClipView: aClipView]; 868 869 if (delegate) { 870 NSScroller *scroller = [self horizontalScroller]; 871 NSScrollerPart hitPart = [scroller hitPart]; 872 873 [delegate gwviewerPathsScroll: self 874 scrollViewScrolled: aClipView 875 hitPart: hitPart]; 876 } 877} 878 879@end 880 881 882 883 884 885 886 887 888 889 890 891 892 893