first experimental commit: sorting by group will now add group dividers

This commit is contained in:
Mitchell Livingston 2008-01-23 02:51:58 +00:00
parent d0fb48121e
commit 1fa3e0d869
4 changed files with 159 additions and 56 deletions

View File

@ -190,7 +190,6 @@ typedef enum
- (void) updateTorrentHistory;
- (void) sortTorrents;
- (void) sortTorrentsIgnoreSelected;
- (void) setSort: (id) sender;
- (void) setSortByGroup: (id) sender;

View File

@ -323,7 +323,6 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
[fPrefsController setUpdater: fUpdater];
[fTableView setTorrents: fDisplayedTorrents];
[[fTableView tableColumnWithIdentifier: @"Torrent"] setDataCell: [[[TorrentCell alloc] init] autorelease]];
[fTableView registerForDraggedTypes: [NSArray arrayWithObject: TORRENT_TABLE_VIEW_DATA_TYPE]];
[fWindow registerForDraggedTypes: [NSArray arrayWithObjects: NSFilenamesPboardType, NSURLPboardType, nil]];
@ -1081,10 +1080,10 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
NSString * title, * message;
int selected = [fTableView numberOfSelectedRows];
int selected = [torrents count];
if (selected == 1)
{
NSString * torrentName = [[fDisplayedTorrents objectAtIndex: [fTableView selectedRow]] name];
NSString * torrentName = [[torrents objectAtIndex: 0] name];
if (!deleteData && !deleteTorrent)
title = [NSString stringWithFormat: NSLocalizedString(@"Confirm removal of \"%@\" from the transfer list.",
@ -1389,7 +1388,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
{
if ([fWindow isVisible])
{
[self sortTorrents];
[self applyFilter: nil];
//update status bar
if (![fStatusBar isHidden])
@ -1597,15 +1596,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
[history writeToFile: [NSHomeDirectory() stringByAppendingPathComponent: SUPPORT_FOLDER] atomically: YES];
}
- (void) sortTorrents
{
NSArray * selectedTorrents = [fTableView selectedTorrents];
[self sortTorrentsIgnoreSelected]; //actually sort
[fTableView selectTorrents: selectedTorrents];
}
#warning rename/change
//doesn't remember selected rows
- (void) sortTorrentsIgnoreSelected
{
@ -1617,6 +1608,8 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
* orderDescriptor = [[[NSSortDescriptor alloc] initWithKey: @"orderValue"
ascending: asc] autorelease];
BOOL group = NO;
NSArray * descriptors;
if ([sortType isEqualToString: SORT_ORDER])
descriptors = [[NSArray alloc] initWithObjects: orderDescriptor, nil];
@ -1671,7 +1664,8 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
descriptors = [[NSArray alloc] initWithObjects: dateDescriptor, orderDescriptor, nil];
}
if ([fDefaults boolForKey: @"SortByGroup"])
group = [fDefaults boolForKey: @"SortByGroup"];
if (group)
{
NSSortDescriptor * groupDescriptor = [[[NSSortDescriptor alloc] initWithKey: @"groupOrderValue"
ascending: asc] autorelease];
@ -1688,6 +1682,25 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
[fDisplayedTorrents sortUsingDescriptors: descriptors];
[descriptors release];
//add group divider if necessary
int total = [fDisplayedTorrents count];
if (group && total > 0)
{
int i, groupValue = [[fDisplayedTorrents objectAtIndex: total-1] groupValue], newGroupValue;
for (i = total-1; i >= 0; i--)
{
if (i > 0)
newGroupValue = [[fDisplayedTorrents objectAtIndex: i-1] groupValue];
if (groupValue != newGroupValue || i == 0)
{
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: groupValue], @"Group", nil];
[fDisplayedTorrents insertObject: dict atIndex: i];
groupValue = newGroupValue;
}
}
}
[fTableView reloadData];
}
@ -1724,26 +1737,26 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
}
[fDefaults setObject: sortType forKey: @"Sort"];
[self sortTorrents];
[self applyFilter: nil];
}
- (void) setSortByGroup: (id) sender
{
[fDefaults setBool: ![fDefaults boolForKey: @"SortByGroup"] forKey: @"SortByGroup"];
[self sortTorrents];
[self applyFilter: nil];
}
- (void) setSortReverse: (id) sender
{
[fDefaults setBool: ![fDefaults boolForKey: @"SortReverse"] forKey: @"SortReverse"];
[self sortTorrents];
[self applyFilter: nil];
}
- (void) applyFilter: (id) sender
{
NSMutableArray * previousTorrents = [fDisplayedTorrents mutableCopy];
NSArray * selectedTorrents = [fTableView selectedTorrents];
NSArray * selectedValues = [fTableView selectedValues];
int active = 0, downloading = 0, seeding = 0, paused = 0;
NSString * filterType = [fDefaults stringForKey: @"Filter"];
@ -1853,9 +1866,12 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
if ([previousTorrents count] > 0)
{
NSEnumerator * enumerator = [previousTorrents objectEnumerator];
Torrent * torrent;
id torrent;
while ((torrent = [enumerator nextObject]))
[torrent setPreviousAmountFinished: NULL];
{
if ([torrent isKindOfClass: [Torrent class]])
[torrent setPreviousAmountFinished: NULL];
}
}
[previousTorrents release];
@ -1869,7 +1885,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
[self sortTorrentsIgnoreSelected];
//set selected rows
[fTableView selectTorrents: selectedTorrents];
[fTableView selectValues: selectedValues];
//set status bar torrent count text
NSString * totalTorrentsString;
@ -2367,7 +2383,12 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
- (id) tableView: (NSTableView *) tableView objectValueForTableColumn: (NSTableColumn *) tableColumn row: (int) row
{
return nil;
id object = [fDisplayedTorrents objectAtIndex: row];
if ([object isKindOfClass: [Torrent class]])
return nil;
int group = [[object objectForKey: @"Group"] intValue];
return group != -1 ? [[GroupsWindowController groups] nameForIndex: group] : NSLocalizedString(@"No Group", "Group table row");
}
- (BOOL) tableView: (NSTableView *) tableView writeRowsWithIndexes: (NSIndexSet *) indexes toPasteboard: (NSPasteboard *) pasteboard
@ -2402,7 +2423,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
if ([[pasteboard types] containsObject: TORRENT_TABLE_VIEW_DATA_TYPE])
{
//remember selected rows if needed
NSArray * selectedTorrents = [fTableView selectedTorrents];
NSArray * selectedValues = [fTableView selectedValues];
NSIndexSet * indexes = [NSKeyedUnarchiver unarchiveObjectWithData:
[pasteboard dataForType: TORRENT_TABLE_VIEW_DATA_TYPE]];
@ -2442,7 +2463,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
[self applyFilter: nil];
//set selected rows
[fTableView selectTorrents: selectedTorrents];
[fTableView selectValues: selectedValues];
}
return YES;
@ -3585,8 +3606,15 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
- (NSRect) sizedWindowFrame
{
float heightChange = [fDisplayedTorrents count] * ([fTableView rowHeight] +
[fTableView intercellSpacing].height) - [fScrollView frame].size.height;
float heightChange = 0;
NSEnumerator * enumerator = [fDisplayedTorrents objectEnumerator];
id object;
while ((object = [enumerator nextObject]))
heightChange += ([object isKindOfClass: [Torrent class]] ? [fTableView rowHeight] : GROUP_SEPARATOR_HEIGHT)
+ [fTableView intercellSpacing].height;
heightChange -= [fScrollView frame].size.height;
return [self windowFrameByAddingHeight: heightChange checkLimits: YES];
}

View File

@ -26,6 +26,8 @@
#import <transmission.h>
#import <Controller.h>
#define GROUP_SEPARATOR_HEIGHT 20.0
@class TorrentCell;
@interface TorrentTableView : NSTableView
@ -38,7 +40,7 @@
IBOutlet NSMenu * fContextRow, * fContextNoRow;
int fMouseControlRow, fMouseRevealRow, fMouseActionRow, fActionPushedRow;
NSArray * fSelectedTorrents;
NSArray * fSelectedValues;
NSMutableArray * fKeyStrokes;
@ -56,7 +58,8 @@
- (void) setRevealButtonHover: (int) row;
- (void) setActionButtonHover: (int) row;
- (void) selectTorrents: (NSArray *) torrents;
- (void) selectValues: (NSArray *) values;
- (NSArray *) selectedValues;
- (NSArray *) selectedTorrents;
- (void) toggleControlForTorrent: (Torrent *) torrent;

View File

@ -71,11 +71,17 @@
return self;
}
- (void) awakeFromNib
{
if (![NSApp isOnLeopardOrBetter])
[[self tableColumnWithIdentifier: @"Torrent"] setDataCell: [[[TorrentCell alloc] init] autorelease]];
}
- (void) dealloc
{
[fPiecesBarTimer invalidate];
[fSelectedTorrents release];
[fSelectedValues release];
[fKeyStrokes release];
[fMenuTorrent release];
@ -88,8 +94,32 @@
fTorrents = torrents;
}
- (id) dataCellForRow: (NSInteger) row
{
return (row == -1 || [[fTorrents objectAtIndex: row] isKindOfClass: [Torrent class]]) ? [[[TorrentCell alloc] init] autorelease]
: [[[NSTextFieldCell alloc] init] autorelease];
}
- (BOOL) tableView: (NSTableView *) tableView isGroupRow: (NSInteger) row
{
return ![[fTorrents objectAtIndex: row] isKindOfClass: [Torrent class]];
}
- (CGFloat) tableView: (NSTableView *) tableView heightOfRow: (NSInteger) row
{
return [[fTorrents objectAtIndex: row] isKindOfClass: [Torrent class]] ? [self rowHeight] : GROUP_SEPARATOR_HEIGHT;
}
- (NSCell *) tableView: (NSTableView *) tableView dataCellForTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row
{
return [self dataCellForRow: row];
}
- (void) tableView: (NSTableView *) tableView willDisplayCell: (id) cell forTableColumn: (NSTableColumn *) tableColumn row: (int) row
{
if (![cell isKindOfClass: [TorrentCell class]])
return;
[cell setRepresentedObject: [fTorrents objectAtIndex: row]];
[cell setControlHover: row == fMouseControlRow];
@ -120,6 +150,8 @@
for (row = visibleRows.location; row < NSMaxRange(visibleRows); row++)
{
TorrentCell * cell = (TorrentCell *)[self preparedCellAtColumn: col row: row];
if (![cell isKindOfClass: [TorrentCell class]])
continue;
NSDictionary * userInfo = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: row] forKey: @"Row"];
[cell addTrackingAreasForView: self inRect: [self frameOfCellAtColumn: col row: row] withUserInfo: userInfo
@ -207,8 +239,8 @@
- (void) tableViewSelectionIsChanging: (NSNotification *) notification
{
if (fSelectedTorrents)
[self selectTorrents: fSelectedTorrents];
if (fSelectedValues)
[self selectValues: fSelectedValues];
}
- (void) mouseDown: (NSEvent *) event
@ -220,12 +252,12 @@
//if pushing a button, don't change the selected rows
if (pushed)
fSelectedTorrents = [[fTorrents objectsAtIndexes: [self selectedRowIndexes]] retain];
fSelectedValues = [[self selectedValues] retain];
[super mouseDown: event];
[fSelectedTorrents release];
fSelectedTorrents = nil;
[fSelectedValues release];
fSelectedValues = nil;
//avoid weird behavior when showing menu by doing this after mouse down
if ([self pointInActionRect: point])
@ -245,14 +277,35 @@
else;
}
- (void) selectTorrents: (NSArray *) torrents
#warning better way?
- (void) selectValues: (NSArray *) values
{
Torrent * torrent;
NSEnumerator * enumerator = [torrents objectEnumerator];
id object;
NSEnumerator * enumerator = [values objectEnumerator];
NSMutableIndexSet * indexSet = [[NSMutableIndexSet alloc] init];
while ((torrent = [enumerator nextObject]))
while ((object = [enumerator nextObject]))
{
unsigned int index = [fTorrents indexOfObject: torrent];
unsigned index = NSNotFound;
if ([object isKindOfClass: [Torrent class]])
index = [fTorrents indexOfObject: object];
else
{
int value = [[object objectForKey: @"Group"] intValue];
unsigned i;
for (i = 0; i < [fTorrents count]; i++)
{
id currentObject = [fTorrents objectAtIndex: i];
if ((![currentObject isKindOfClass: [Torrent class]]))
{
if (value == [[currentObject objectForKey: @"Group"] intValue])
{
index = i;
break;
}
}
}
}
if (index != NSNotFound)
[indexSet addIndex: index];
}
@ -261,9 +314,24 @@
[indexSet release];
}
- (NSArray *) selectedValues
{
return [fTorrents objectsAtIndexes: [self selectedRowIndexes]];
}
- (NSArray *) selectedTorrents
{
[fTorrents objectsAtIndexes: [self selectedRowIndexes]];
NSIndexSet * selectedIndexes = [self selectedRowIndexes];
NSMutableIndexSet * indexSet = [NSMutableIndexSet indexSet];
NSUInteger i;
for (i = [selectedIndexes firstIndex]; i != NSNotFound; i = [selectedIndexes indexGreaterThanIndex: i])
{
if ([[fTorrents objectAtIndex: i] isKindOfClass: [Torrent class]])
[indexSet addIndex: i];
}
[fTorrents objectsAtIndexes: indexSet];
}
- (NSMenu *) menuForEvent: (NSEvent *) event
@ -381,7 +449,7 @@
[fActionMenu appendItemsFromMenu: fileMenu atIndexes: [NSIndexSet indexSetWithIndexesInRange: range] atBottom: YES];
//place menu below button
NSRect rect = [[[self tableColumnWithIdentifier: @"Torrent"] dataCell] iconRectForBounds: [self frameOfCellAtColumn: 0 row: row]];
NSRect rect = [[self dataCellForRow: row] iconRectForBounds: [self frameOfCellAtColumn: 0 row: row]];
NSPoint location = rect.origin;
location.y += rect.size.height + 5.0;
location = [self convertPoint: location toView: nil];
@ -579,8 +647,9 @@
if (row < 0)
return NO;
TorrentCell * cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
return NSPointInRect(point, [cell controlButtonRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
NSCell * cell = [self dataCellForRow: row];
return [cell isKindOfClass: [TorrentCell class]]
&& NSPointInRect(point, [(TorrentCell*) cell controlButtonRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
}
- (BOOL) pointInRevealRect: (NSPoint) point
@ -589,8 +658,9 @@
if (row < 0)
return NO;
TorrentCell * cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
return NSPointInRect(point, [cell revealButtonRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
NSCell * cell = [self dataCellForRow: row];
return [cell isKindOfClass: [TorrentCell class]]
&& NSPointInRect(point, [(TorrentCell*)cell revealButtonRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
}
- (BOOL) pointInActionRect: (NSPoint) point
@ -599,8 +669,9 @@
if (row < 0)
return NO;
TorrentCell * cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
return NSPointInRect(point, [cell iconRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
NSCell * cell = [self dataCellForRow: row];
return [cell isKindOfClass: [TorrentCell class]]
&& NSPointInRect(point, [(TorrentCell*)cell iconRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
}
- (BOOL) pointInProgressRect: (NSPoint) point
@ -609,15 +680,16 @@
if (row < 0 || [fDefaults boolForKey: @"SmallView"])
return NO;
TorrentCell * cell;
NSCell * cell;
if ([NSApp isOnLeopardOrBetter])
cell = (TorrentCell * )[self preparedCellAtColumn: [self columnWithIdentifier: @"Torrent"] row: row];
cell = (TorrentCell *)[self preparedCellAtColumn: [self columnWithIdentifier: @"Torrent"] row: row];
else
{
cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
cell = [self dataCellForRow: row];
[cell setRepresentedObject: [fTorrents objectAtIndex: row]];
}
return NSPointInRect(point, [cell progressRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
return [cell isKindOfClass: [TorrentCell class]]
&& NSPointInRect(point, [(TorrentCell*)cell progressRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
}
- (BOOL) pointInMinimalStatusRect: (NSPoint) point
@ -626,15 +698,16 @@
if (row < 0 || ![fDefaults boolForKey: @"SmallView"])
return NO;
TorrentCell * cell;
NSCell * cell;
if ([NSApp isOnLeopardOrBetter])
cell = (TorrentCell * )[self preparedCellAtColumn: [self columnWithIdentifier: @"Torrent"] row: row];
cell = (TorrentCell *)[self preparedCellAtColumn: [self columnWithIdentifier: @"Torrent"] row: row];
else
{
cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
cell = [self dataCellForRow: row];
[cell setRepresentedObject: [fTorrents objectAtIndex: row]];
}
return NSPointInRect(point, [cell minimalStatusRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
return [cell isKindOfClass: [TorrentCell class]]
&& NSPointInRect(point, [(TorrentCell*)cell minimalStatusRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
}
- (void) updateFileMenu: (NSMenu *) menu forFiles: (NSArray *) files