2001-10-19 19:41:13 +00:00
|
|
|
#import "OutlineViewDelegate.h"
|
2002-02-12 04:01:47 +00:00
|
|
|
#import "Resource.h"
|
2008-07-31 20:27:55 +00:00
|
|
|
#import "ResourceDocument.h"
|
2002-10-04 19:54:05 +00:00
|
|
|
#import "ResourceDataSource.h"
|
|
|
|
#import "ResourceNameCell.h"
|
2002-04-27 18:17:47 +00:00
|
|
|
#import "ApplicationDelegate.h"
|
2001-10-19 19:41:13 +00:00
|
|
|
|
|
|
|
@implementation OutlineViewDelegate
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
- (id)init
|
|
|
|
{
|
|
|
|
self = [super init];
|
|
|
|
if(!self) return nil;
|
|
|
|
if(NSAppKitVersionNumber >= 700.0) // darwin 7.0 == Mac OS 10.3, needed for -setPlaceholderString:
|
|
|
|
{
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePlaceholder:) name:ResourceNameDidChangeNotification object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePlaceholder:) name:ResourceTypeDidChangeNotification object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePlaceholder:) name:ResourceIDDidChangeNotification object:nil];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)updatePlaceholder:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
Resource *resource = [notification object];
|
|
|
|
ResourceNameCell *cell = (ResourceNameCell *) [[outlineView tableColumnWithIdentifier:@"name"] dataCellForRow:[outlineView rowForItem:resource]];
|
|
|
|
if([[resource name] isEqualToString:@""])
|
|
|
|
{
|
|
|
|
if([[resource resID] shortValue] == -16455)
|
|
|
|
[cell setPlaceholderString:NSLocalizedString(@"Custom Icon", nil)];
|
|
|
|
else [cell setPlaceholderString:NSLocalizedString(@"Untitled Resource", nil)];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@method tableView:didClickTableColumn:
|
|
|
|
@pending not needed in 10.3+, use existing sort functionality
|
|
|
|
*/
|
|
|
|
|
2002-03-31 12:00:02 +00:00
|
|
|
- (void)tableView:(NSTableView*)tableView didClickTableColumn:(NSTableColumn *)tableColumn
|
|
|
|
{
|
2002-10-04 19:54:05 +00:00
|
|
|
NSArray *newResources;
|
2002-11-15 15:12:42 +00:00
|
|
|
NSArray *oldResources = [(ResourceDataSource *)[tableView dataSource] resources];
|
2002-10-04 19:54:05 +00:00
|
|
|
|
|
|
|
// sort the array
|
2002-11-15 15:12:42 +00:00
|
|
|
NSImage *indicator = [tableView indicatorImageInTableColumn:tableColumn];
|
|
|
|
NSImage *upArrow = [NSTableView _defaultTableHeaderSortImage];
|
2008-07-31 20:27:55 +00:00
|
|
|
if(indicator == upArrow)
|
|
|
|
newResources = [oldResources sortedArrayUsingFunction:compareResourcesAscending context:[tableColumn identifier]];
|
|
|
|
else newResources = [oldResources sortedArrayUsingFunction:compareResourcesDescending context:[tableColumn identifier]];
|
2002-10-04 19:54:05 +00:00
|
|
|
|
|
|
|
// swap new array for old one
|
|
|
|
[(ResourceDataSource *)[tableView dataSource] setResources:[NSMutableArray arrayWithArray:newResources]];
|
|
|
|
[tableView reloadData];
|
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
/*!
|
|
|
|
@function compareResourcesAscending
|
|
|
|
@updated 2003-10-25 NGS: now uses KVC methods to obtain the strings to compare
|
|
|
|
*/
|
|
|
|
|
|
|
|
int compareResourcesAscending(Resource *r1, Resource *r2, void *context)
|
2002-10-04 19:54:05 +00:00
|
|
|
{
|
|
|
|
NSString *key = (NSString *)context;
|
2008-07-31 20:27:55 +00:00
|
|
|
// compare two NSStrings (case-insensitive)
|
|
|
|
if([key isEqualToString:@"name"] || [key isEqualToString:@"type"])
|
|
|
|
return [(NSString *)[r1 valueForKey:key] caseInsensitiveCompare:(NSString *)[r2 valueForKey:key]];
|
|
|
|
// compare two NSNumbers (or any other class)
|
|
|
|
else return [(NSNumber *)[r1 valueForKey:key] compare:(NSNumber *)[r2 valueForKey:key]];
|
2002-10-04 19:54:05 +00:00
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
/*!
|
|
|
|
@function compareResourcesDescending
|
|
|
|
@updated 2003-10-25 NGS: now uses KVC methods to obtain the strings to compare
|
|
|
|
*/
|
|
|
|
|
|
|
|
int compareResourcesDescending(Resource *r1, Resource *r2, void *context)
|
2002-10-04 19:54:05 +00:00
|
|
|
{
|
|
|
|
NSString *key = (NSString *)context;
|
2008-07-31 20:27:55 +00:00
|
|
|
// compare two NSStrings (case-insensitive)
|
|
|
|
if([key isEqualToString:@"name"] || [key isEqualToString:@"type"])
|
|
|
|
return -1 * [(NSString *)[r1 valueForKey:key] caseInsensitiveCompare: (NSString *)[r2 valueForKey:key]];
|
|
|
|
// compare two NSNumbers (or any other class)
|
|
|
|
else return -1 * [(NSNumber *)[r1 valueForKey:key] compare: (NSNumber *)[r2 valueForKey:key]];
|
2002-03-31 12:00:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
if([[tableColumn identifier] isEqualToString:@"size"] || [[tableColumn identifier] isEqualToString:@"attributes"])
|
|
|
|
return NO;
|
|
|
|
else return YES;
|
2002-03-31 12:00:02 +00:00
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
/*!
|
|
|
|
@method outlineView:willDisplayCell:forTableColumn:item:
|
|
|
|
@updated 2003-10-25 NGS: Moved functionality of NameFormatter into this method, removed NameFormatter class.
|
|
|
|
@updated 2003-10-24 NGS: Swapped row colours so first row is white (as per 10.3), conditionalised drawing line background colours to system versions < 10.3, since in 10.3 it is handled by the nib file.
|
|
|
|
@updated 2003-10-24 NGS: Added iconForResourceType method to app delegate instead of interrogating the cache here.
|
|
|
|
@pending remove setting of the cell formatter when that capability is in interface builder
|
|
|
|
*/
|
|
|
|
|
2001-10-19 19:41:13 +00:00
|
|
|
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
Resource *resource = (Resource *)item;
|
2002-02-23 03:40:24 +00:00
|
|
|
NSString *identifier = [tableColumn identifier];
|
2008-07-31 20:27:55 +00:00
|
|
|
|
|
|
|
// set formatters for cells (remove when IB can set a formatter for an entire table column)
|
|
|
|
if([identifier isEqualToString:@"size"]) [cell setFormatter:sizeFormatter];
|
|
|
|
else if([identifier isEqualToString:@"attributes"]) [cell setFormatter:attributesFormatter];
|
2002-02-07 03:45:43 +00:00
|
|
|
|
|
|
|
// set resource icon
|
2008-07-31 20:27:55 +00:00
|
|
|
if([identifier isEqualToString:@"name"])
|
2002-02-07 03:45:43 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
if(![resource representedFork])
|
|
|
|
[(ResourceNameCell *)cell setImage:[(ApplicationDelegate *)[NSApp delegate] iconForResourceType:[resource type]]];
|
|
|
|
else [(ResourceNameCell *)cell setImage:[(ApplicationDelegate *)[NSApp delegate] iconForResourceType:nil]];
|
|
|
|
|
|
|
|
if([[resource name] isEqualToString:@""])
|
|
|
|
{
|
|
|
|
if([cell respondsToSelector:@selector(setPlaceholderString:)]) // 10.3+
|
|
|
|
{
|
|
|
|
// 10.3+ uses placeholder strings
|
|
|
|
if([[resource resID] shortValue] == -16455) // don't bother checking type since there are too many icon types
|
|
|
|
[cell setPlaceholderString:NSLocalizedString(@"Custom Icon", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"carb"] && [[resource resID] shortValue] == 0)
|
|
|
|
[cell setPlaceholderString:NSLocalizedString(@"Carbon Identifier", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"pnot"] && [[resource resID] shortValue] == 0)
|
|
|
|
[cell setPlaceholderString:NSLocalizedString(@"File Preview", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"STR "] && [[resource resID] shortValue] == -16396)
|
|
|
|
[cell setPlaceholderString:NSLocalizedString(@"Creator Information", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"vers"] && [[resource resID] shortValue] == 1)
|
|
|
|
[cell setPlaceholderString:NSLocalizedString(@"File Version", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"vers"] && [[resource resID] shortValue] == 2)
|
|
|
|
[cell setPlaceholderString:NSLocalizedString(@"Package Version", nil)];
|
|
|
|
else [cell setPlaceholderString:NSLocalizedString(@"Untitled Resource", nil)];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// pre-10.3, set text colour to grey and set title accordingly
|
|
|
|
if([[resource resID] shortValue] == -16455)
|
|
|
|
[cell setTitle:NSLocalizedString(@"Custom Icon", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"carb"] && [[resource resID] shortValue] == 0)
|
|
|
|
[cell setTitle:NSLocalizedString(@"Carbon Identifier", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"pnot"] && [[resource resID] shortValue] == 0)
|
|
|
|
[cell setTitle:NSLocalizedString(@"File Preview", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"STR "] && [[resource resID] shortValue] == -16396)
|
|
|
|
[cell setTitle:NSLocalizedString(@"Creator Information", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"vers"] && [[resource resID] shortValue] == 1)
|
|
|
|
[cell setTitle:NSLocalizedString(@"File Version", nil)];
|
|
|
|
else if([[resource type] isEqualToString:@"vers"] && [[resource resID] shortValue] == 2)
|
|
|
|
[cell setTitle:NSLocalizedString(@"Package Version", nil)];
|
|
|
|
else [cell setTitle:NSLocalizedString(@"Untitled Resource", nil)];
|
|
|
|
|
|
|
|
// if([[outlineView selectedItems] containsObject:resource])
|
|
|
|
// [cell setTextColor:[NSColor whiteColor]];
|
|
|
|
// else [cell setTextColor:[NSColor grayColor]];
|
|
|
|
}
|
|
|
|
}
|
2002-02-07 03:45:43 +00:00
|
|
|
}
|
2002-04-27 18:17:47 +00:00
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
// draw alternating blue/white backgrounds (if pre-10.3)
|
|
|
|
if(NSAppKitVersionNumber < 700.0)
|
2002-05-31 00:17:53 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
int row = [outlineView rowForItem:item];
|
|
|
|
if(row % 2) [cell setBackgroundColor:[NSColor colorWithCalibratedRed:0.93 green:0.95 blue:1.0 alpha:1.0]];
|
|
|
|
else [cell setBackgroundColor:[NSColor whiteColor]];
|
|
|
|
[cell setDrawsBackground:YES];
|
2002-05-31 00:17:53 +00:00
|
|
|
}
|
2001-10-19 19:41:13 +00:00
|
|
|
}
|
|
|
|
|
2002-11-15 15:12:42 +00:00
|
|
|
@end
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
@implementation RKOutlineView
|
2002-11-15 15:12:42 +00:00
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
/*!
|
|
|
|
@method draggingSourceOperationMaskForLocal:
|
|
|
|
*/
|
|
|
|
- (unsigned int)draggingSourceOperationMaskForLocal:(BOOL)local
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
if(local) return NSDragOperationEvery;
|
|
|
|
else return NSDragOperationCopy;
|
2002-11-15 15:12:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)keyDown:(NSEvent *)event
|
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
int selectedRow = [self selectedRow];
|
|
|
|
if(selectedRow != -1 && [[event characters] isEqualToString:[NSString stringWithCString:"\r"]])
|
|
|
|
[self editColumn:0 row:selectedRow withEvent:nil select:YES];
|
|
|
|
else if(selectedRow != -1 && [[event characters] isEqualToString:[NSString stringWithCString:"\x7F"]])
|
|
|
|
[(ResourceDocument *)[[[self window] windowController] document] deleteSelectedResources];
|
2002-11-15 15:12:42 +00:00
|
|
|
else [super keyDown:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)selector
|
|
|
|
{
|
|
|
|
// pressed return, end editing
|
2008-07-31 20:27:55 +00:00
|
|
|
if(selector == @selector(insertNewline:))
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
|
|
|
[[self window] makeFirstResponder:self];
|
|
|
|
[self abortEditing];
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
// pressed tab, move to next editable field
|
2008-07-31 20:27:55 +00:00
|
|
|
else if(selector == @selector(insertTab:))
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
|
|
|
int newColumn = ([self editedColumn] +1) % [self numberOfColumns];
|
|
|
|
NSString *newColIdentifier = [[[self tableColumns] objectAtIndex:newColumn] identifier];
|
2008-07-31 20:27:55 +00:00
|
|
|
if([newColIdentifier isEqualToString:@"size"] || [newColIdentifier isEqualToString:@"attributes"])
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
|
|
|
newColumn = (newColumn +1) % [self numberOfColumns];
|
|
|
|
newColIdentifier = [[[self tableColumns] objectAtIndex:newColumn] identifier];
|
2008-07-31 20:27:55 +00:00
|
|
|
if([newColIdentifier isEqualToString:@"size"] || [newColIdentifier isEqualToString:@"attributes"])
|
2002-11-15 15:12:42 +00:00
|
|
|
newColumn = (newColumn +1) % [self numberOfColumns];
|
|
|
|
}
|
|
|
|
|
|
|
|
[self editColumn:newColumn row:[self selectedRow] withEvent:nil select:YES];
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
// pressed shift-tab, move to previous editable field
|
2008-07-31 20:27:55 +00:00
|
|
|
else if(selector == @selector(insertBacktab:))
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
|
|
|
int newColumn = ([self editedColumn] + [self numberOfColumns] -1) % [self numberOfColumns];
|
|
|
|
NSString *newColIdentifier = [[[self tableColumns] objectAtIndex:newColumn] identifier];
|
2008-07-31 20:27:55 +00:00
|
|
|
if([newColIdentifier isEqualToString:@"size"] || [newColIdentifier isEqualToString:@"attributes"])
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
|
|
|
newColumn = (newColumn + [self numberOfColumns] -1) % [self numberOfColumns];
|
|
|
|
newColIdentifier = [[[self tableColumns] objectAtIndex:newColumn] identifier];
|
2008-07-31 20:27:55 +00:00
|
|
|
if([newColIdentifier isEqualToString:@"size"] || [newColIdentifier isEqualToString:@"attributes"])
|
2002-11-15 15:12:42 +00:00
|
|
|
newColumn = (newColumn + [self numberOfColumns] -1) % [self numberOfColumns];
|
|
|
|
}
|
|
|
|
|
|
|
|
[self editColumn:newColumn row:[self selectedRow] withEvent:nil select:YES];
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
/*!
|
|
|
|
@method _sendDelegateDidClickColumn:
|
|
|
|
@pending not needed in 10.3+, use existing sort functionality
|
|
|
|
*/
|
|
|
|
|
2002-11-15 15:12:42 +00:00
|
|
|
//- (void)_sendDelegateDidMouseDownInHeader:(int)columnIndex
|
|
|
|
- (void)_sendDelegateDidClickColumn:(int)columnIndex
|
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
// if(NSAppKitVersionNumber < 700.0)
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
NSTableColumn *tableColumn = [[self tableColumns] objectAtIndex:columnIndex];
|
|
|
|
NSImage *indicator = [self indicatorImageInTableColumn:tableColumn];
|
|
|
|
NSImage *upArrow = [NSTableView _defaultTableHeaderSortImage];
|
|
|
|
NSImage *downArrow = [NSTableView _defaultTableHeaderReverseSortImage];
|
|
|
|
if(indicator)
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
// column already selected
|
|
|
|
if(indicator == upArrow)
|
|
|
|
[self setIndicatorImage:downArrow inTableColumn:tableColumn];
|
|
|
|
else [self setIndicatorImage:upArrow inTableColumn:tableColumn];
|
2002-11-15 15:12:42 +00:00
|
|
|
}
|
2008-07-31 20:27:55 +00:00
|
|
|
else // new column selected
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
// if there is an existing selection, clear it's image
|
|
|
|
if([self highlightedTableColumn] != nil)
|
|
|
|
[self setIndicatorImage:nil inTableColumn:[self highlightedTableColumn]];
|
|
|
|
|
2002-11-15 15:12:42 +00:00
|
|
|
// sort name and type columns ascending by default
|
2008-07-31 20:27:55 +00:00
|
|
|
if([[tableColumn identifier] isEqualToString:@"name"] || [[tableColumn identifier] isEqualToString:@"type"])
|
|
|
|
[self setIndicatorImage:upArrow inTableColumn:tableColumn];
|
2002-11-15 15:12:42 +00:00
|
|
|
// sort all other columns descending by default
|
2008-07-31 20:27:55 +00:00
|
|
|
else [self setIndicatorImage:downArrow inTableColumn:tableColumn];
|
|
|
|
[self setHighlightedTableColumn:tableColumn];
|
2002-11-15 15:12:42 +00:00
|
|
|
}
|
2008-07-31 20:27:55 +00:00
|
|
|
[[self delegate] tableView:self didClickTableColumn:tableColumn];
|
2002-11-15 15:12:42 +00:00
|
|
|
}
|
2008-07-31 20:27:55 +00:00
|
|
|
// else [super _sendDelegateDidClickColumn:columnIndex];
|
2002-11-15 15:12:42 +00:00
|
|
|
}
|
|
|
|
|
2002-02-23 03:40:24 +00:00
|
|
|
@end
|