First commit of collapsable groups. A lot more needs to still be done.
This commit is contained in:
parent
e372450e98
commit
a0061f43fb
|
@ -86,7 +86,6 @@
|
|||
A2265F420B5EF5F40093DDA5 /* FileNameCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A2265F400B5EF5F40093DDA5 /* FileNameCell.m */; };
|
||||
A226FDAC0D0CDF20005A7F71 /* libnatpmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C7A118D0D0B2EB800B5701F /* libnatpmp.a */; };
|
||||
A22A8D560AEEAFA5007E9CB9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A22A8D540AEEAFA5007E9CB9 /* Localizable.strings */; };
|
||||
A22B862D0D47D91300F9BAD9 /* NSMutableArrayAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A22B862C0D47D91300F9BAD9 /* NSMutableArrayAdditions.m */; };
|
||||
A22D3AA60D00D1790079CFED /* Turtle.png in Resources */ = {isa = PBXBuildFile; fileRef = A22D3AA30D00D1790079CFED /* Turtle.png */; };
|
||||
A22D3AA70D00D1790079CFED /* TurtleBlue.png in Resources */ = {isa = PBXBuildFile; fileRef = A22D3AA40D00D1790079CFED /* TurtleBlue.png */; };
|
||||
A231274C0D11D0B7003F9AFF /* AboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = A231274B0D11D0B7003F9AFF /* AboutWindow.xib */; };
|
||||
|
@ -460,8 +459,6 @@
|
|||
A223AABB0D22ECE800840069 /* it */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = it; path = macosx/it.lproj/StatsWindow.xib; sourceTree = "<group>"; };
|
||||
A2265F3F0B5EF5F40093DDA5 /* FileNameCell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FileNameCell.h; path = macosx/FileNameCell.h; sourceTree = "<group>"; };
|
||||
A2265F400B5EF5F40093DDA5 /* FileNameCell.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = FileNameCell.m; path = macosx/FileNameCell.m; sourceTree = "<group>"; };
|
||||
A22B862B0D47D91300F9BAD9 /* NSMutableArrayAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSMutableArrayAdditions.h; path = macosx/NSMutableArrayAdditions.h; sourceTree = "<group>"; };
|
||||
A22B862C0D47D91300F9BAD9 /* NSMutableArrayAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSMutableArrayAdditions.m; path = macosx/NSMutableArrayAdditions.m; sourceTree = "<group>"; };
|
||||
A22D3AA30D00D1790079CFED /* Turtle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Turtle.png; path = macosx/Images/Turtle.png; sourceTree = "<group>"; };
|
||||
A22D3AA40D00D1790079CFED /* TurtleBlue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = TurtleBlue.png; path = macosx/Images/TurtleBlue.png; sourceTree = "<group>"; };
|
||||
A231274B0D11D0B7003F9AFF /* AboutWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = AboutWindow.xib; path = macosx/AboutWindow.xib; sourceTree = "<group>"; };
|
||||
|
@ -1114,8 +1111,6 @@
|
|||
A21576090C0D449A0057A26A /* NSBezierPathAdditions.m */,
|
||||
A234D0CF0C79FB3600A82373 /* NSMenuAdditions.h */,
|
||||
A234D0D00C79FB3600A82373 /* NSMenuAdditions.m */,
|
||||
A22B862B0D47D91300F9BAD9 /* NSMutableArrayAdditions.h */,
|
||||
A22B862C0D47D91300F9BAD9 /* NSMutableArrayAdditions.m */,
|
||||
);
|
||||
name = Additions;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1798,7 +1793,6 @@
|
|||
A22180980D148A71007D09ED /* GroupsWindowController.m in Sources */,
|
||||
A26AF21A0D2DA35A00FF7140 /* FileOutlineController.m in Sources */,
|
||||
A26AF2840D2DC27C00FF7140 /* AddWindowController.m in Sources */,
|
||||
A22B862D0D47D91300F9BAD9 /* NSMutableArrayAdditions.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -52,7 +52,6 @@ typedef enum
|
|||
tr_handle * fLib;
|
||||
|
||||
NSMutableArray * fTorrents, * fDisplayedTorrents;
|
||||
NSMutableIndexSet * fDisplayedGroupIndexes;
|
||||
|
||||
PrefsController * fPrefsController;
|
||||
InfoWindowController * fInfoController;
|
||||
|
@ -63,7 +62,6 @@ typedef enum
|
|||
|
||||
IBOutlet NSWindow * fWindow;
|
||||
DragOverlayWindow * fOverlayWindow;
|
||||
IBOutlet NSScrollView * fScrollView;
|
||||
IBOutlet TorrentTableView * fTableView;
|
||||
|
||||
IBOutlet NSMenuItem * fOpenIgnoreDownloadFolder;
|
||||
|
@ -183,6 +181,8 @@ typedef enum
|
|||
|
||||
- (void) updateUI;
|
||||
|
||||
- (void) setBottomCountTextFiltering: (BOOL) filtering;
|
||||
|
||||
- (void) updateTorrentsInQueue;
|
||||
- (int) numToStartFromQueue: (BOOL) downloadQueue;
|
||||
|
||||
|
@ -247,6 +247,8 @@ typedef enum
|
|||
- (void) setWindowSizeToFit;
|
||||
- (NSRect) sizedWindowFrame;
|
||||
|
||||
- (void) updateForExpandCollape;
|
||||
|
||||
- (void) showMainWindow: (id) sender;
|
||||
|
||||
- (void) linkHomepage: (id) sender;
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#import "NSApplicationAdditions.h"
|
||||
#import "NSStringAdditions.h"
|
||||
#import "NSMenuAdditions.h"
|
||||
#import "NSMutableArrayAdditions.h"
|
||||
#import "UKKQueue.h"
|
||||
#import "ExpandedPathToPathTransformer.h"
|
||||
#import "ExpandedPathToIconTransformer.h"
|
||||
|
@ -212,7 +211,6 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
fTorrents = [[NSMutableArray alloc] init];
|
||||
fDisplayedTorrents = [[NSMutableArray alloc] init];
|
||||
fDisplayedGroupIndexes = [[NSMutableIndexSet alloc] init];
|
||||
|
||||
fMessageController = [[MessageWindowController alloc] init];
|
||||
fInfoController = [[InfoWindowController alloc] init];
|
||||
|
@ -252,7 +250,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
//window min height
|
||||
NSSize contentMinSize = [fWindow contentMinSize];
|
||||
contentMinSize.height = [[fWindow contentView] frame].size.height - [fScrollView frame].size.height
|
||||
contentMinSize.height = [[fWindow contentView] frame].size.height - [[fTableView enclosingScrollView] frame].size.height
|
||||
+ [fTableView rowHeight] + [fTableView intercellSpacing].height;
|
||||
[fWindow setContentMinSize: contentMinSize];
|
||||
|
||||
|
@ -324,10 +322,8 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
[fPrefsController setUpdater: fUpdater];
|
||||
|
||||
[fTableView setTorrents: fDisplayedTorrents];
|
||||
[fTableView setGroupIndexes: fDisplayedGroupIndexes];
|
||||
|
||||
[fTableView registerForDraggedTypes: [NSArray arrayWithObject: TORRENT_TABLE_VIEW_DATA_TYPE]];
|
||||
#warning fix
|
||||
//[fTableView registerForDraggedTypes: [NSArray arrayWithObject: TORRENT_TABLE_VIEW_DATA_TYPE]];
|
||||
[fWindow registerForDraggedTypes: [NSArray arrayWithObjects: NSFilenamesPboardType, NSURLPboardType, nil]];
|
||||
|
||||
//register for sleep notifications
|
||||
|
@ -415,7 +411,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
//avoids need of setting delegate
|
||||
[nc addObserver: self selector: @selector(torrentTableViewSelectionDidChange:)
|
||||
name: NSTableViewSelectionDidChangeNotification object: fTableView];
|
||||
name: NSOutlineViewSelectionDidChangeNotification object: fTableView];
|
||||
|
||||
[nc addObserver: self selector: @selector(prepareForUpdate:)
|
||||
name: SUUpdaterWillRestartNotification object: nil];
|
||||
|
@ -430,6 +426,9 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
[nc addObserver: self selector: @selector(setWindowSizeToFit)
|
||||
name: @"AutoSizeSettingChange" object: nil];
|
||||
|
||||
[nc addObserver: self selector: @selector(updateForExpandCollape)
|
||||
name: @"OutlineExpandCollapse" object: nil];
|
||||
|
||||
[nc addObserver: fWindow selector: @selector(makeKeyWindow)
|
||||
name: @"MakeWindowKey" object: nil];
|
||||
|
||||
|
@ -589,7 +588,6 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
[fTorrents release];
|
||||
[fDisplayedTorrents release];
|
||||
[fDisplayedGroupIndexes release];
|
||||
|
||||
[fOverlayWindow release];
|
||||
[fIPCController release];
|
||||
|
@ -1199,26 +1197,22 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
- (void) removeNoDelete: (id) sender
|
||||
{
|
||||
[self removeTorrents: [fTableView selectedTorrents]
|
||||
deleteData: NO deleteTorrent: NO];
|
||||
[self removeTorrents: [fTableView selectedTorrents] deleteData: NO deleteTorrent: NO];
|
||||
}
|
||||
|
||||
- (void) removeDeleteData: (id) sender
|
||||
{
|
||||
[self removeTorrents: [fTableView selectedTorrents]
|
||||
deleteData: YES deleteTorrent: NO];
|
||||
[self removeTorrents: [fTableView selectedTorrents] deleteData: YES deleteTorrent: NO];
|
||||
}
|
||||
|
||||
- (void) removeDeleteTorrent: (id) sender
|
||||
{
|
||||
[self removeTorrents: [fTableView selectedTorrents]
|
||||
deleteData: NO deleteTorrent: YES];
|
||||
[self removeTorrents: [fTableView selectedTorrents] deleteData: NO deleteTorrent: YES];
|
||||
}
|
||||
|
||||
- (void) removeDeleteDataAndTorrent: (id) sender
|
||||
{
|
||||
[self removeTorrents: [fTableView selectedTorrents]
|
||||
deleteData: YES deleteTorrent: YES];
|
||||
[self removeTorrents: [fTableView selectedTorrents] deleteData: YES deleteTorrent: YES];
|
||||
}
|
||||
|
||||
- (void) moveDataFiles: (id) sender
|
||||
|
@ -1258,8 +1252,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
- (void) copyTorrentFiles: (id) sender
|
||||
{
|
||||
[self copyTorrentFileForTorrents: [[NSMutableArray alloc] initWithArray:
|
||||
[fTableView selectedTorrents]]];
|
||||
[self copyTorrentFileForTorrents: [[NSMutableArray alloc] initWithArray: [fTableView selectedTorrents]]];
|
||||
}
|
||||
|
||||
- (void) copyTorrentFileForTorrents: (NSMutableArray *) torrents
|
||||
|
@ -1457,6 +1450,35 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
[fBadger updateBadge];
|
||||
}
|
||||
|
||||
- (void) setBottomCountTextFiltering: (BOOL) filtering
|
||||
{
|
||||
NSString * totalTorrentsString;
|
||||
int totalCount = [fTorrents count];
|
||||
if (totalCount != 1)
|
||||
totalTorrentsString = [NSString stringWithFormat: NSLocalizedString(@"%d transfers", "Status bar transfer count"), totalCount];
|
||||
else
|
||||
totalTorrentsString = NSLocalizedString(@"1 transfer", "Status bar transfer count");
|
||||
|
||||
if (filtering)
|
||||
{
|
||||
int count = 0, rows = [fTableView numberOfRows];
|
||||
if (rows > 0 && ![[fTableView itemAtRow: 0] isKindOfClass: [Torrent class]])
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < [fTableView numberOfRows]; i++)
|
||||
if ([[fTableView itemAtRow: i] isKindOfClass: [Torrent class]])
|
||||
count++;
|
||||
}
|
||||
else
|
||||
count = rows;
|
||||
|
||||
totalTorrentsString = [NSString stringWithFormat: NSLocalizedString(@"%d of %@", "Status bar transfer count"),
|
||||
count, totalTorrentsString];
|
||||
}
|
||||
|
||||
[fTotalTorrentsField setStringValue: totalTorrentsString];
|
||||
}
|
||||
|
||||
- (void) updateTorrentsInQueue
|
||||
{
|
||||
BOOL download = [fDefaults boolForKey: @"Queue"],
|
||||
|
@ -1738,15 +1760,10 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
//actually sort
|
||||
if ([fDefaults boolForKey: @"SortByGroup"] && [NSApp isOnLeopardOrBetter])
|
||||
{
|
||||
NSUInteger i, nextGroup;
|
||||
for (i = [fDisplayedGroupIndexes firstIndex]; i != NSNotFound; i = nextGroup)
|
||||
{
|
||||
nextGroup = [fDisplayedGroupIndexes indexGreaterThanIndex: i];
|
||||
NSUInteger count = (nextGroup != NSNotFound ? nextGroup : [fDisplayedTorrents count]) - i - 1;
|
||||
|
||||
[fDisplayedTorrents sortIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(i+1, count)]
|
||||
usingDescriptors: descriptors];
|
||||
}
|
||||
NSEnumerator * enumerator = [fDisplayedTorrents objectEnumerator];
|
||||
NSDictionary * dict;
|
||||
while ((dict = [enumerator nextObject]))
|
||||
[[dict objectForKey: @"Torrents"] sortUsingDescriptors: descriptors];
|
||||
}
|
||||
else
|
||||
[fDisplayedTorrents sortUsingDescriptors: descriptors];
|
||||
|
@ -1758,8 +1775,17 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
- (void) applyFilter: (id) sender
|
||||
{
|
||||
NSMutableArray * previousTorrents = [fDisplayedTorrents mutableCopy];
|
||||
[previousTorrents removeObjectsAtIndexes: fDisplayedGroupIndexes];
|
||||
//get all the torrents in the table
|
||||
NSMutableArray * previousTorrents = [NSMutableArray array];
|
||||
if ([fDisplayedTorrents count] > 0 && ![[fDisplayedTorrents objectAtIndex: 0] isKindOfClass: [Torrent class]])
|
||||
{
|
||||
NSEnumerator * enumerator = [fDisplayedTorrents objectEnumerator];
|
||||
NSDictionary * dict;
|
||||
while ((dict = [enumerator nextObject]))
|
||||
[previousTorrents addObjectsFromArray: [dict objectForKey: @"Torrents"]];
|
||||
}
|
||||
else
|
||||
[previousTorrents setArray: fDisplayedTorrents];
|
||||
|
||||
NSArray * selectedValues = [fTableView selectedValues];
|
||||
|
||||
|
@ -1790,7 +1816,6 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
NSEnumerator * enumerator = [fTorrents objectEnumerator];
|
||||
Torrent * torrent;
|
||||
int i = -1;
|
||||
BOOL isActive;
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
{
|
||||
i++;
|
||||
|
@ -1801,7 +1826,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
if ([torrent isSeeding])
|
||||
{
|
||||
seeding++;
|
||||
isActive = ![torrent isStalled];
|
||||
BOOL isActive = ![torrent isStalled];
|
||||
if (isActive)
|
||||
active++;
|
||||
|
||||
|
@ -1811,7 +1836,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
else
|
||||
{
|
||||
downloading++;
|
||||
isActive = ![torrent isStalled];
|
||||
BOOL isActive = ![torrent isStalled];
|
||||
if (isActive)
|
||||
active++;
|
||||
|
||||
|
@ -1874,53 +1899,45 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
[fPauseFilterButton setCount: paused];
|
||||
|
||||
//clear display cache for not-shown torrents
|
||||
[previousTorrents removeObjectsInArray: fDisplayedTorrents]; //neither array should currently have group items
|
||||
|
||||
[previousTorrents removeObjectsInArray: fDisplayedTorrents];
|
||||
enumerator = [previousTorrents objectEnumerator];
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
[torrent setPreviousAmountFinished: NULL];
|
||||
|
||||
[previousTorrents release];
|
||||
|
||||
//add group items
|
||||
[fDisplayedGroupIndexes removeAllIndexes];
|
||||
if ([fDefaults boolForKey: @"SortByGroup"] && [fDisplayedTorrents count] > 0 && [NSApp isOnLeopardOrBetter])
|
||||
//place torrents into groups
|
||||
BOOL groupRows = [fDefaults boolForKey: @"SortByGroup"];
|
||||
if (groupRows && [fDisplayedTorrents count] > 0 && [NSApp isOnLeopardOrBetter])
|
||||
{
|
||||
NSSortDescriptor * groupDescriptor = [[[NSSortDescriptor alloc] initWithKey: @"groupOrderValue" ascending: YES] autorelease];
|
||||
[fDisplayedTorrents sortUsingDescriptors: [NSArray arrayWithObject: groupDescriptor]];
|
||||
|
||||
NSMutableArray * groups = [NSMutableArray array], * groupTorrents;
|
||||
int i, oldGroupValue = -2;
|
||||
for (i = 0; i < [fDisplayedTorrents count]; i++)
|
||||
{
|
||||
int groupValue = [[fDisplayedTorrents objectAtIndex: i] groupValue];
|
||||
Torrent * torrent = [fDisplayedTorrents objectAtIndex: i];
|
||||
int groupValue = [torrent groupValue];
|
||||
if (groupValue != oldGroupValue)
|
||||
{
|
||||
[fDisplayedTorrents insertObject: [NSNumber numberWithInt: groupValue] atIndex: i];
|
||||
[fDisplayedGroupIndexes addIndex: i];
|
||||
groupTorrents = [NSMutableArray array];
|
||||
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: groupValue], @"Group",
|
||||
groupTorrents, @"Torrents", nil];
|
||||
[groups addObject: dict];
|
||||
|
||||
i++;
|
||||
oldGroupValue = groupValue;
|
||||
}
|
||||
|
||||
[groupTorrents addObject: torrent];
|
||||
}
|
||||
|
||||
[fDisplayedTorrents setArray: groups];
|
||||
}
|
||||
|
||||
//actually sort
|
||||
[self sortTorrentsIgnoreSelected];
|
||||
[fTableView selectValues: selectedValues];
|
||||
|
||||
//set status bar torrent count text
|
||||
NSString * totalTorrentsString;
|
||||
int totalCount = [fTorrents count];
|
||||
if (totalCount != 1)
|
||||
totalTorrentsString = [NSString stringWithFormat: NSLocalizedString(@"%d transfers", "Status bar transfer count"), totalCount];
|
||||
else
|
||||
totalTorrentsString = NSLocalizedString(@"1 transfer", "Status bar transfer count");
|
||||
|
||||
if (filterStatus || filterGroup || filterText)
|
||||
totalTorrentsString = [NSString stringWithFormat: NSLocalizedString(@"%d of %@", "Status bar transfer count"),
|
||||
[fDisplayedTorrents count] - [fDisplayedGroupIndexes count], totalTorrentsString];
|
||||
|
||||
[fTotalTorrentsField setStringValue: totalTorrentsString];
|
||||
[self setBottomCountTextFiltering: groupRows || filterStatus || filterGroup || filterText];
|
||||
|
||||
[self setWindowSizeToFit];
|
||||
}
|
||||
|
@ -2397,20 +2414,39 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
[fAutoImportedNames addObject: [location lastPathComponent]];
|
||||
}
|
||||
|
||||
- (int) numberOfRowsInTableView: (NSTableView *) tableview
|
||||
- (NSInteger) outlineView: (NSOutlineView *) outlineView numberOfChildrenOfItem: (id) item
|
||||
{
|
||||
return [fDisplayedTorrents count];
|
||||
if (item)
|
||||
return [[item objectForKey: @"Torrents"] count];
|
||||
else
|
||||
return [fDisplayedTorrents count];
|
||||
}
|
||||
|
||||
- (id) tableView: (NSTableView *) tableView objectValueForTableColumn: (NSTableColumn *) tableColumn row: (int) row
|
||||
- (id) outlineView: (NSOutlineView *) outlineView child: (NSInteger) index ofItem: (id) item
|
||||
{
|
||||
if (![fDisplayedGroupIndexes containsIndex: row])
|
||||
return nil;
|
||||
|
||||
int group = [[fDisplayedTorrents objectAtIndex: row] intValue];
|
||||
return group != -1 ? [[GroupsWindowController groups] nameForIndex: group] : NSLocalizedString(@"No Group", "Group table row");
|
||||
if (item)
|
||||
return [[item objectForKey: @"Torrents"] objectAtIndex: index];
|
||||
else
|
||||
return [fDisplayedTorrents objectAtIndex: index];
|
||||
}
|
||||
|
||||
- (BOOL) outlineView: (NSOutlineView *) outlineView isItemExpandable: (id) item
|
||||
{
|
||||
return ![item isKindOfClass: [Torrent class]];
|
||||
}
|
||||
|
||||
- (id) outlineView: (NSOutlineView *) outlineView objectValueForTableColumn: (NSTableColumn *) tableColumn byItem: (id) item
|
||||
{
|
||||
if (![item isKindOfClass: [Torrent class]])
|
||||
{
|
||||
int group = [[item objectForKey: @"Group"] intValue];
|
||||
return group != -1 ? [[GroupsWindowController groups] nameForIndex: group] : NSLocalizedString(@"No Group", "Group table row");
|
||||
}
|
||||
else
|
||||
return [item hashString];
|
||||
}
|
||||
|
||||
#warning fix
|
||||
- (BOOL) tableView: (NSTableView *) tableView writeRowsWithIndexes: (NSIndexSet *) indexes toPasteboard: (NSPasteboard *) pasteboard
|
||||
{
|
||||
//only allow reordering of rows if sorting by order
|
||||
|
@ -2626,15 +2662,12 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
[fTableView setRowHeight: makeSmall ? ROW_HEIGHT_SMALL : ROW_HEIGHT_REGULAR];
|
||||
|
||||
//non-group rows are being resized
|
||||
NSMutableIndexSet * indexes = [NSMutableIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTableView numberOfRows])];
|
||||
[indexes removeIndexes: fDisplayedGroupIndexes];
|
||||
[fTableView noteHeightOfRowsWithIndexesChanged: indexes];
|
||||
[fTableView noteHeightOfRowsWithIndexesChanged: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTableView numberOfRows])]];
|
||||
|
||||
//window min height
|
||||
NSSize contentMinSize = [fWindow contentMinSize],
|
||||
contentSize = [[fWindow contentView] frame].size;
|
||||
contentMinSize.height = contentSize.height - [fScrollView frame].size.height
|
||||
contentMinSize.height = contentSize.height - [[fTableView enclosingScrollView] frame].size.height
|
||||
+ [fTableView rowHeight] + [fTableView intercellSpacing].height;
|
||||
[fWindow setContentMinSize: contentMinSize];
|
||||
|
||||
|
@ -2675,20 +2708,22 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
- (NSRect) windowFrameByAddingHeight: (float) height checkLimits: (BOOL) check
|
||||
{
|
||||
NSScrollView * scrollView = [fTableView enclosingScrollView];
|
||||
|
||||
//convert pixels to points
|
||||
NSRect windowFrame = [fWindow frame];
|
||||
NSSize windowSize = [fScrollView convertSize: windowFrame.size fromView: nil];
|
||||
NSSize windowSize = [scrollView convertSize: windowFrame.size fromView: nil];
|
||||
windowSize.height += height;
|
||||
|
||||
if (check)
|
||||
{
|
||||
NSSize minSize = [fScrollView convertSize: [fWindow minSize] fromView: nil];
|
||||
NSSize minSize = [scrollView convertSize: [fWindow minSize] fromView: nil];
|
||||
|
||||
if (windowSize.height < minSize.height)
|
||||
windowSize.height = minSize.height;
|
||||
else
|
||||
{
|
||||
NSSize maxSize = [fScrollView convertSize: [[fWindow screen] visibleFrame].size fromView: nil];
|
||||
NSSize maxSize = [scrollView convertSize: [[fWindow screen] visibleFrame].size fromView: nil];
|
||||
if ([fStatusBar isHidden])
|
||||
maxSize.height -= [fStatusBar frame].size.height;
|
||||
if ([fFilterBar isHidden])
|
||||
|
@ -2699,7 +2734,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
}
|
||||
|
||||
//convert points to pixels
|
||||
windowSize = [fScrollView convertSize: windowSize toView: nil];
|
||||
windowSize = [scrollView convertSize: windowSize toView: nil];
|
||||
|
||||
windowFrame.origin.y -= (windowSize.height - windowFrame.size.height);
|
||||
windowFrame.size.height = windowSize.height;
|
||||
|
@ -2735,13 +2770,15 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
|
||||
[self updateUI];
|
||||
|
||||
NSScrollView * scrollView = [fTableView enclosingScrollView];
|
||||
|
||||
//set views to not autoresize
|
||||
unsigned int statsMask = [fStatusBar autoresizingMask];
|
||||
unsigned int filterMask = [fFilterBar autoresizingMask];
|
||||
unsigned int scrollMask = [fScrollView autoresizingMask];
|
||||
unsigned int scrollMask = [scrollView autoresizingMask];
|
||||
[fStatusBar setAutoresizingMask: NSViewNotSizable];
|
||||
[fFilterBar setAutoresizingMask: NSViewNotSizable];
|
||||
[fScrollView setAutoresizingMask: NSViewNotSizable];
|
||||
[scrollView setAutoresizingMask: NSViewNotSizable];
|
||||
|
||||
frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO];
|
||||
[fWindow setFrame: frame display: YES animate: animate];
|
||||
|
@ -2749,7 +2786,7 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
//re-enable autoresize
|
||||
[fStatusBar setAutoresizingMask: statsMask];
|
||||
[fFilterBar setAutoresizingMask: filterMask];
|
||||
[fScrollView setAutoresizingMask: scrollMask];
|
||||
[scrollView setAutoresizingMask: scrollMask];
|
||||
|
||||
//change min size
|
||||
NSSize minSize = [fWindow contentMinSize];
|
||||
|
@ -2800,19 +2837,21 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
[fWindow setFrame: frame display: NO animate: NO];
|
||||
}
|
||||
}
|
||||
|
||||
NSScrollView * scrollView = [fTableView enclosingScrollView];
|
||||
|
||||
//set views to not autoresize
|
||||
unsigned int filterMask = [fFilterBar autoresizingMask];
|
||||
unsigned int scrollMask = [fScrollView autoresizingMask];
|
||||
unsigned int scrollMask = [scrollView autoresizingMask];
|
||||
[fFilterBar setAutoresizingMask: NSViewNotSizable];
|
||||
[fScrollView setAutoresizingMask: NSViewNotSizable];
|
||||
[scrollView setAutoresizingMask: NSViewNotSizable];
|
||||
|
||||
frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO];
|
||||
[fWindow setFrame: frame display: YES animate: animate];
|
||||
|
||||
//re-enable autoresize
|
||||
[fFilterBar setAutoresizingMask: filterMask];
|
||||
[fScrollView setAutoresizingMask: scrollMask];
|
||||
[scrollView setAutoresizingMask: scrollMask];
|
||||
|
||||
//change min size
|
||||
NSSize minSize = [fWindow contentMinSize];
|
||||
|
@ -3622,21 +3661,32 @@ void sleepCallBack(void * controller, io_service_t y, natural_t messageType, voi
|
|||
{
|
||||
if ([fDefaults boolForKey: @"AutoSize"])
|
||||
{
|
||||
[fScrollView setHasVerticalScroller: NO];
|
||||
NSScrollView * scrollView = [fTableView enclosingScrollView];
|
||||
|
||||
[scrollView setHasVerticalScroller: NO];
|
||||
[fWindow setFrame: [self sizedWindowFrame] display: YES animate: YES];
|
||||
[fScrollView setHasVerticalScroller: YES];
|
||||
[scrollView setHasVerticalScroller: YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect) sizedWindowFrame
|
||||
{
|
||||
float heightChange = (GROUP_SEPARATOR_HEIGHT + [fTableView intercellSpacing].height) * [fDisplayedGroupIndexes count]
|
||||
+ ([fTableView rowHeight] + [fTableView intercellSpacing].height) * ([fDisplayedTorrents count]
|
||||
- [fDisplayedGroupIndexes count]) - [fScrollView frame].size.height;
|
||||
int groups = ([fDisplayedTorrents count] > 0 && ![[fDisplayedTorrents objectAtIndex: 0] isKindOfClass: [Torrent class]])
|
||||
? [fDisplayedTorrents count] : 0;
|
||||
|
||||
float heightChange = (GROUP_SEPARATOR_HEIGHT + [fTableView intercellSpacing].height) * groups
|
||||
+ ([fTableView rowHeight] + [fTableView intercellSpacing].height) * ([fTableView numberOfRows] - groups)
|
||||
- [[fTableView enclosingScrollView] frame].size.height;
|
||||
|
||||
return [self windowFrameByAddingHeight: heightChange checkLimits: YES];
|
||||
}
|
||||
|
||||
- (void) updateForExpandCollape
|
||||
{
|
||||
[self setWindowSizeToFit];
|
||||
[self setBottomCountTextFiltering: YES];
|
||||
}
|
||||
|
||||
- (void) showMainWindow: (id) sender
|
||||
{
|
||||
[fWindow makeKeyAndOrderFront: nil];
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -161,10 +161,7 @@ GroupsWindowController * fGroupsWindowInstance = nil;
|
|||
- (NSImage *) imageForIndex: (int) index isSmall: (BOOL) small
|
||||
{
|
||||
int orderIndex = [self orderValueForIndex: index];
|
||||
if (orderIndex == -1)
|
||||
return nil;
|
||||
|
||||
return [self imageForGroup: [fGroups objectAtIndex: orderIndex] isSmall: small];
|
||||
return orderIndex != -1 ? [self imageForGroup: [fGroups objectAtIndex: orderIndex] isSmall: small] : nil;
|
||||
}
|
||||
|
||||
- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableview
|
||||
|
@ -262,14 +259,13 @@ GroupsWindowController * fGroupsWindowInstance = nil;
|
|||
|
||||
if ([selectedGroups count] > 0)
|
||||
{
|
||||
NSMutableIndexSet * indexSet = [NSMutableIndexSet indexSet];
|
||||
NSEnumerator * enumerator = [selectedGroups objectEnumerator];
|
||||
NSMutableIndexSet * indexSet = [[NSMutableIndexSet alloc] init];
|
||||
NSDictionary * dict;
|
||||
while ((dict = [enumerator nextObject]))
|
||||
[indexSet addIndex: [fGroups indexOfObject: dict]];
|
||||
|
||||
[fTableView selectRowIndexes: indexSet byExtendingSelection: NO];
|
||||
[indexSet release];
|
||||
}
|
||||
|
||||
[fTableView reloadData];
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2008 Transmission authors and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
@interface NSMutableArray (NSMutableArrayAdditions)
|
||||
|
||||
- (void) sortIndexes: (NSIndexSet *) indexes usingDescriptors: (NSArray *) sortDescriptors;
|
||||
|
||||
@end
|
|
@ -1,39 +0,0 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2008 Transmission authors and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#import "NSMutableArrayAdditions.h"
|
||||
|
||||
@implementation NSMutableArray (NSMutableArrayAdditions)
|
||||
|
||||
- (void) sortIndexes: (NSIndexSet *) indexes usingDescriptors: (NSArray *) sortDescriptors
|
||||
{
|
||||
if ([indexes count] <= 1)
|
||||
return;
|
||||
|
||||
NSArray * items = [self objectsAtIndexes: indexes];
|
||||
items = [items sortedArrayUsingDescriptors: sortDescriptors];
|
||||
[self replaceObjectsAtIndexes: indexes withObjects: items];
|
||||
}
|
||||
|
||||
@end
|
|
@ -56,6 +56,8 @@ typedef enum
|
|||
|
||||
NSImage * fIcon;
|
||||
|
||||
NSString * fHashString;
|
||||
|
||||
tr_file_stat * fileStat;
|
||||
NSArray * fFileList;
|
||||
|
||||
|
|
|
@ -175,6 +175,8 @@ void completenessChangeCallback(tr_torrent * torrent, cp_status_t status, void *
|
|||
free(fPreviousFinishedPieces);
|
||||
[fFinishedPiecesDate release];
|
||||
|
||||
[fHashString release];
|
||||
|
||||
[fDownloadFolder release];
|
||||
[fIncompleteFolder release];
|
||||
|
||||
|
@ -732,7 +734,7 @@ void completenessChangeCallback(tr_torrent * torrent, cp_status_t status, void *
|
|||
|
||||
- (NSString *) hashString
|
||||
{
|
||||
return [NSString stringWithUTF8String: fInfo->hashString];
|
||||
return fHashString;
|
||||
}
|
||||
|
||||
- (BOOL) privateTorrent
|
||||
|
@ -1571,7 +1573,9 @@ void completenessChangeCallback(tr_torrent * torrent, cp_status_t status, void *
|
|||
tr_torrentSetStatusCallback(fHandle, completenessChangeCallback, self);
|
||||
|
||||
fInfo = tr_torrentInfo(fHandle);
|
||||
|
||||
|
||||
fHashString = [[NSString alloc] initWithUTF8String: fInfo->hashString];
|
||||
|
||||
fDateAdded = dateAdded ? [dateAdded retain] : [[NSDate alloc] init];
|
||||
if (dateCompleted)
|
||||
fDateCompleted = [dateCompleted retain];
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
- (NSRect) progressRectForBounds: (NSRect) bounds
|
||||
{
|
||||
return [self rectForProgressWithString: [self attributedStatusString: [[self representedObject] progressString] withColor: nil]
|
||||
inBounds: bounds];
|
||||
inBounds: bounds];
|
||||
}
|
||||
|
||||
- (NSRect) barRectForBounds: (NSRect) bounds
|
||||
|
@ -453,14 +453,14 @@
|
|||
fMouseDownActionButton = pushed;
|
||||
}
|
||||
|
||||
- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) controlView
|
||||
- (void) drawInteriorWithFrame: (NSRect) cellFrame inView: (NSView *) controlView
|
||||
{
|
||||
[super drawWithFrame: cellFrame inView: controlView];
|
||||
|
||||
Torrent * torrent = [self representedObject];
|
||||
|
||||
BOOL minimal = [fDefaults boolForKey: @"SmallView"];
|
||||
|
||||
#warning use inset instead of edges
|
||||
|
||||
//group coloring
|
||||
NSRect iconRect = [self iconRectForBounds: cellFrame];
|
||||
|
||||
|
|
|
@ -26,14 +26,13 @@
|
|||
#import <transmission.h>
|
||||
#import <Controller.h>
|
||||
|
||||
#define GROUP_SEPARATOR_HEIGHT 18.0
|
||||
|
||||
@class TorrentCell;
|
||||
|
||||
@interface TorrentTableView : NSTableView
|
||||
#define GROUP_SEPARATOR_HEIGHT 18.0
|
||||
|
||||
@interface TorrentTableView : NSOutlineView
|
||||
{
|
||||
IBOutlet Controller * fController;
|
||||
NSArray * fTorrents;
|
||||
NSIndexSet * fGroupIndexes;
|
||||
|
||||
TorrentCell * fTorrentCell;
|
||||
|
@ -45,8 +44,6 @@
|
|||
int fMouseControlRow, fMouseRevealRow, fMouseActionRow, fActionPushedRow;
|
||||
NSArray * fSelectedValues;
|
||||
|
||||
NSMutableArray * fKeyStrokes;
|
||||
|
||||
IBOutlet NSMenu * fActionMenu, * fUploadMenu, * fDownloadMenu, * fRatioMenu;
|
||||
Torrent * fMenuTorrent;
|
||||
|
||||
|
@ -54,9 +51,6 @@
|
|||
NSTimer * fPiecesBarTimer;
|
||||
}
|
||||
|
||||
- (void) setTorrents: (NSArray *) torrents;
|
||||
- (void) setGroupIndexes: (NSIndexSet *) indexes;
|
||||
|
||||
- (void) removeButtonTrackingAreas;
|
||||
- (void) setControlButtonHover: (int) row;
|
||||
- (void) setRevealButtonHover: (int) row;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#import "TorrentTableView.h"
|
||||
#import "TorrentCell.h"
|
||||
#import "Controller.h"
|
||||
#import "Torrent.h"
|
||||
#import "NSApplicationAdditions.h"
|
||||
#import "NSMenuAdditions.h"
|
||||
|
@ -75,90 +74,86 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) awakeFromNib
|
||||
{
|
||||
[self setGridStyleMask: NSTableViewSolidVerticalGridLineMask]; //weird redrawing issues if set to none
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[fPiecesBarTimer invalidate];
|
||||
[fMenuTorrent release];
|
||||
|
||||
[fSelectedValues release];
|
||||
|
||||
[fKeyStrokes release];
|
||||
[fMenuTorrent release];
|
||||
|
||||
[fTorrentCell release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setTorrents: (NSArray *) torrents
|
||||
- (BOOL) outlineView: (NSOutlineView *) outlineView isGroupItem: (id) item
|
||||
{
|
||||
fTorrents = torrents;
|
||||
return ![item isKindOfClass: [Torrent class]];
|
||||
}
|
||||
|
||||
- (void) setGroupIndexes: (NSIndexSet *) indexes
|
||||
- (CGFloat) outlineView: (NSOutlineView *) outlineView heightOfRowByItem: (id) item
|
||||
{
|
||||
fGroupIndexes = indexes;
|
||||
return [item isKindOfClass: [Torrent class]] ? [self rowHeight] : GROUP_SEPARATOR_HEIGHT;
|
||||
}
|
||||
|
||||
- (BOOL) tableView: (NSTableView *) tableView isGroupRow: (NSInteger) row
|
||||
- (NSCell *) outlineView: (NSOutlineView *) outlineView dataCellForTableColumn: (NSTableColumn *) tableColumn item: (id) item
|
||||
{
|
||||
return [fGroupIndexes containsIndex: row];
|
||||
if (!tableColumn)
|
||||
return nil;
|
||||
return [item isKindOfClass: [Torrent class]] ? fTorrentCell : nil;
|
||||
}
|
||||
|
||||
- (CGFloat) tableView: (NSTableView *) tableView heightOfRow: (NSInteger) row
|
||||
- (void) outlineView: (NSOutlineView *) outlineView willDisplayCell: (id) cell forTableColumn: (NSTableColumn *) tableColumn
|
||||
item: (id) item
|
||||
{
|
||||
return ![fGroupIndexes containsIndex: row] ? [self rowHeight] : GROUP_SEPARATOR_HEIGHT;
|
||||
}
|
||||
|
||||
- (NSCell *) tableView: (NSTableView *) tableView dataCellForTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row
|
||||
{
|
||||
return ![fGroupIndexes containsIndex: row] ? fTorrentCell : nil;
|
||||
}
|
||||
|
||||
- (void) tableView: (NSTableView *) tableView willDisplayCell: (id) cell forTableColumn: (NSTableColumn *) tableColumn row: (int) row
|
||||
{
|
||||
if ([fGroupIndexes containsIndex: row])
|
||||
if (![item isKindOfClass: [Torrent class]])
|
||||
return;
|
||||
|
||||
[cell setRepresentedObject: [fTorrents objectAtIndex: row]];
|
||||
[cell setRepresentedObject: item];
|
||||
|
||||
int row = [self rowForItem: item];
|
||||
[cell setControlHover: row == fMouseControlRow];
|
||||
[cell setRevealHover: row == fMouseRevealRow];
|
||||
[cell setActionHover: row == fMouseActionRow];
|
||||
[cell setActionPushed: row == fActionPushedRow];
|
||||
}
|
||||
|
||||
- (NSString *) tableView: (NSTableView *) tableView typeSelectStringForTableColumn: (NSTableColumn *) tableColumn row: (int) row
|
||||
- (NSRect) frameOfCellAtColumn: (NSInteger) column row: (NSInteger) row
|
||||
{
|
||||
return ![fGroupIndexes containsIndex: row] ? [[fTorrents objectAtIndex: row] name]
|
||||
: [[self preparedCellAtColumn: 0 row: row] stringValue];
|
||||
NSRect rect = [super frameOfCellAtColumn: column row: row];
|
||||
|
||||
if ([[self itemAtRow: row] isKindOfClass: [Torrent class]])
|
||||
{
|
||||
rect.size.width += rect.origin.x;
|
||||
rect.origin.x = 0.0;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (BOOL) tableView: (NSTableView *) tableView shouldEditTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row
|
||||
- (NSString *) outlineView: (NSOutlineView *) outlineView typeSelectStringForTableColumn: (NSTableColumn *) tableColumn item: (id) item
|
||||
{
|
||||
return NO;
|
||||
return [item isKindOfClass: [Torrent class]] ? [item name]
|
||||
: [[self preparedCellAtColumn: 0 row: [self rowForItem: item]] stringValue];
|
||||
}
|
||||
|
||||
- (void) updateTrackingAreas
|
||||
{
|
||||
[super updateTrackingAreas];
|
||||
|
||||
[self removeButtonTrackingAreas];
|
||||
|
||||
NSMutableIndexSet * indexes = [NSMutableIndexSet indexSetWithIndexesInRange: [self rowsInRect: [self visibleRect]]];
|
||||
[indexes removeIndexes: fGroupIndexes];
|
||||
if ([indexes count] == 0)
|
||||
NSRange rows = [self rowsInRect: [self visibleRect]];
|
||||
if (rows.length == 0)
|
||||
return;
|
||||
|
||||
NSPoint mouseLocation = [self convertPoint: [[self window] convertScreenToBase: [NSEvent mouseLocation]] fromView: nil];
|
||||
|
||||
NSUInteger row;
|
||||
for (row = [indexes firstIndex]; row != NSNotFound; row = [indexes indexGreaterThanIndex: row])
|
||||
for (row = rows.location; row < NSMaxRange(rows); row++)
|
||||
{
|
||||
if (![[self itemAtRow: row] isKindOfClass: [Torrent class]])
|
||||
continue;
|
||||
|
||||
NSDictionary * userInfo = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: row] forKey: @"Row"];
|
||||
TorrentCell * cell = (TorrentCell *)[self preparedCellAtColumn: 0 row: row];
|
||||
[cell addTrackingAreasForView: self inRect: [self frameOfCellAtColumn: 0 row: row] withUserInfo: userInfo
|
||||
|
@ -244,12 +239,22 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void) tableViewSelectionIsChanging: (NSNotification *) notification
|
||||
- (void) outlineViewSelectionIsChanging: (NSNotification *) notification
|
||||
{
|
||||
if (fSelectedValues)
|
||||
[self selectValues: fSelectedValues];
|
||||
}
|
||||
|
||||
- (void) outlineViewItemDidExpand: (NSNotification *) notification
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName: @"OutlineExpandCollapse" object: self];
|
||||
}
|
||||
|
||||
- (void) outlineViewItemDidCollapse: (NSNotification *) notification
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName: @"OutlineExpandCollapse" object: self];
|
||||
}
|
||||
|
||||
- (void) mouseDown: (NSEvent *) event
|
||||
{
|
||||
NSPoint point = [self convertPoint: [event locationInWindow] fromView: nil];
|
||||
|
@ -280,7 +285,19 @@
|
|||
[self setNeedsDisplayInRect: [self rectOfRow: row]];
|
||||
}
|
||||
else if (!pushed && [event clickCount] == 2) //double click
|
||||
[fController showInfo: nil];
|
||||
{
|
||||
id item = [self itemAtRow: [self rowAtPoint: point]];
|
||||
|
||||
if ([item isKindOfClass: [Torrent class]])
|
||||
[fController showInfo: nil];
|
||||
else
|
||||
{
|
||||
if ([self isItemExpanded: item])
|
||||
[self collapseItem: item];
|
||||
else
|
||||
[self expandItem: item];
|
||||
}
|
||||
}
|
||||
else;
|
||||
}
|
||||
|
||||
|
@ -289,12 +306,25 @@
|
|||
NSMutableIndexSet * indexSet = [NSMutableIndexSet indexSet];
|
||||
|
||||
NSEnumerator * enumerator = [values objectEnumerator];
|
||||
id object;
|
||||
while ((object = [enumerator nextObject]))
|
||||
id item;
|
||||
while ((item = [enumerator nextObject]))
|
||||
{
|
||||
unsigned index = [fTorrents indexOfObject: object]; //works with torrents and groups
|
||||
if (index != NSNotFound)
|
||||
[indexSet addIndex: index];
|
||||
if ([item isKindOfClass: [Torrent class]])
|
||||
{
|
||||
NSUInteger index = [self rowForItem: item];
|
||||
if (index != -1)
|
||||
[indexSet addIndex: index];
|
||||
}
|
||||
else
|
||||
{
|
||||
int group = [[item objectForKey: @"Group"] intValue], i;
|
||||
for (i = 0; i < [self numberOfRows]; i++)
|
||||
{
|
||||
id tableItem = [self itemAtRow: i];
|
||||
if (![tableItem isKindOfClass: [Torrent class]] && [[tableItem objectForKey: @"Group"] intValue] == group)
|
||||
[indexSet addIndex: i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[self selectRowIndexes: indexSet byExtendingSelection: NO];
|
||||
|
@ -302,31 +332,35 @@
|
|||
|
||||
- (NSArray *) selectedValues
|
||||
{
|
||||
return [fTorrents objectsAtIndexes: [self selectedRowIndexes]];
|
||||
NSIndexSet * selectedIndexes = [self selectedRowIndexes];
|
||||
NSMutableArray * values = [NSMutableArray arrayWithCapacity: [selectedIndexes count]];
|
||||
|
||||
NSUInteger i;
|
||||
for (i = [selectedIndexes firstIndex]; i != NSNotFound; i = [selectedIndexes indexGreaterThanIndex: i])
|
||||
[values addObject: [self itemAtRow: i]];
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
- (NSArray *) selectedTorrents
|
||||
{
|
||||
NSIndexSet * selectedIndexes = [self selectedRowIndexes];
|
||||
NSMutableIndexSet * indexSet = [NSMutableIndexSet indexSet];
|
||||
NSMutableArray * torrents = [NSMutableArray array];
|
||||
|
||||
NSUInteger i;
|
||||
for (i = [selectedIndexes firstIndex]; i != NSNotFound; i = [selectedIndexes indexGreaterThanIndex: i])
|
||||
{
|
||||
if (![fGroupIndexes containsIndex: i])
|
||||
[indexSet addIndex: i];
|
||||
else
|
||||
id item = [self itemAtRow: i];
|
||||
if ([item isKindOfClass: [Torrent class]])
|
||||
{
|
||||
NSUInteger nextGroup = [fGroupIndexes indexGreaterThanIndex: i];
|
||||
if (nextGroup == NSNotFound)
|
||||
nextGroup = [fTorrents count];
|
||||
|
||||
[indexSet addIndexesInRange: NSMakeRange(i+1, nextGroup - i - 1)];
|
||||
|
||||
i = nextGroup - 1;
|
||||
if (![torrents containsObject: item])
|
||||
[torrents addObject: item];
|
||||
}
|
||||
else
|
||||
[torrents addObjectsFromArray: [item objectForKey: @"Torrents"]];
|
||||
}
|
||||
[fTorrents objectsAtIndexes: indexSet];
|
||||
|
||||
return torrents;
|
||||
}
|
||||
|
||||
- (NSMenu *) menuForEvent: (NSEvent *) event
|
||||
|
@ -352,66 +386,6 @@
|
|||
[super flagsChanged: event];
|
||||
}
|
||||
|
||||
- (void) keyDown: (NSEvent *) event
|
||||
{
|
||||
//this is handled by the delegate in Leopard
|
||||
if ([NSApp isOnLeopardOrBetter])
|
||||
{
|
||||
[super keyDown: event];
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fKeyStrokes)
|
||||
fKeyStrokes = [[NSMutableArray alloc] init];
|
||||
|
||||
unichar newChar = [[event characters] characterAtIndex: 0];
|
||||
if (newChar == ' ' || [[NSCharacterSet alphanumericCharacterSet] characterIsMember: newChar]
|
||||
|| [[NSCharacterSet symbolCharacterSet] characterIsMember: newChar]
|
||||
|| [[NSCharacterSet punctuationCharacterSet] characterIsMember: newChar])
|
||||
{
|
||||
if ([fKeyStrokes count] > 0 && [event timestamp] - [[fKeyStrokes lastObject] timestamp] > 1.0)
|
||||
[fKeyStrokes removeAllObjects];
|
||||
[fKeyStrokes addObject: event];
|
||||
|
||||
[self interpretKeyEvents: fKeyStrokes];
|
||||
}
|
||||
else
|
||||
{
|
||||
[fKeyStrokes removeAllObjects];
|
||||
[super keyDown: event];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) insertText: (NSString *) text
|
||||
{
|
||||
//this is handled by the delegate in Leopard
|
||||
if ([NSApp isOnLeopardOrBetter])
|
||||
{
|
||||
[super insertText: text];
|
||||
return;
|
||||
}
|
||||
|
||||
//sort torrents by name before finding closest match
|
||||
NSSortDescriptor * nameDescriptor = [[[NSSortDescriptor alloc] initWithKey: @"name" ascending: YES
|
||||
selector: @selector(caseInsensitiveCompare:)] autorelease];
|
||||
|
||||
NSArray * tempTorrents = [fTorrents sortedArrayUsingDescriptors: [NSArray arrayWithObject: nameDescriptor]];
|
||||
|
||||
text = [text lowercaseString];
|
||||
|
||||
//select torrent closest to text that isn't before text alphabetically
|
||||
NSEnumerator * enumerator = [tempTorrents objectEnumerator];
|
||||
Torrent * torrent;
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
if ([[[torrent name] lowercaseString] hasPrefix: text])
|
||||
{
|
||||
int row = [fTorrents indexOfObject: torrent];
|
||||
[self selectRow: row byExtendingSelection: NO];
|
||||
[self scrollRowToVisible: row];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) toggleControlForTorrent: (Torrent *) torrent
|
||||
{
|
||||
if ([torrent isActive])
|
||||
|
@ -434,7 +408,7 @@
|
|||
return;
|
||||
|
||||
//get and update file menu
|
||||
fMenuTorrent = [[fTorrents objectAtIndex: row] retain];
|
||||
fMenuTorrent = [[self itemAtRow: row] retain];
|
||||
NSMenu * fileMenu = [fMenuTorrent fileMenu];
|
||||
[self updateFileMenu: fileMenu forFiles: [fMenuTorrent fileList]];
|
||||
|
||||
|
@ -494,7 +468,7 @@
|
|||
item = [menu itemWithTag: ACTION_MENU_LIMIT_TAG];
|
||||
[item setState: mode == TR_SPEEDLIMIT_SINGLE ? NSOnState : NSOffState];
|
||||
[item setTitle: [NSString stringWithFormat: NSLocalizedString(@"Limit (%d KB/s)",
|
||||
"torrent action menu -> upload/download limit"), [fMenuTorrent speedLimit: upload]]];
|
||||
"torrent action menu -> upload/download limit"), [fMenuTorrent speedLimit: upload]]];
|
||||
|
||||
item = [menu itemWithTag: ACTION_MENU_UNLIMITED_TAG];
|
||||
[item setState: mode == TR_SPEEDLIMIT_UNLIMITED ? NSOnState : NSOffState];
|
||||
|
@ -638,7 +612,7 @@
|
|||
- (BOOL) pointInControlRect: (NSPoint) point
|
||||
{
|
||||
int row = [self rowAtPoint: point];
|
||||
if (row < 0 || [fGroupIndexes containsIndex: row])
|
||||
if (row < 0 || ![[self itemAtRow: row] isKindOfClass: [Torrent class]])
|
||||
return NO;
|
||||
|
||||
return NSPointInRect(point, [fTorrentCell controlButtonRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
|
||||
|
@ -647,7 +621,7 @@
|
|||
- (BOOL) pointInRevealRect: (NSPoint) point
|
||||
{
|
||||
int row = [self rowAtPoint: point];
|
||||
if (row < 0 || [fGroupIndexes containsIndex: row])
|
||||
if (row < 0 || ![[self itemAtRow: row] isKindOfClass: [Torrent class]])
|
||||
return NO;
|
||||
|
||||
return NSPointInRect(point, [fTorrentCell revealButtonRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
|
||||
|
@ -656,7 +630,7 @@
|
|||
- (BOOL) pointInActionRect: (NSPoint) point
|
||||
{
|
||||
int row = [self rowAtPoint: point];
|
||||
if (row < 0 || [fGroupIndexes containsIndex: row])
|
||||
if (row < 0 || ![[self itemAtRow: row] isKindOfClass: [Torrent class]])
|
||||
return NO;
|
||||
|
||||
return NSPointInRect(point, [fTorrentCell iconRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
|
||||
|
@ -665,7 +639,7 @@
|
|||
- (BOOL) pointInProgressRect: (NSPoint) point
|
||||
{
|
||||
int row = [self rowAtPoint: point];
|
||||
if (row < 0 || [fGroupIndexes containsIndex: row] || [fDefaults boolForKey: @"SmallView"])
|
||||
if (row < 0 || ![[self itemAtRow: row] isKindOfClass: [Torrent class]] || [fDefaults boolForKey: @"SmallView"])
|
||||
return NO;
|
||||
|
||||
TorrentCell * cell;
|
||||
|
@ -674,7 +648,7 @@
|
|||
else
|
||||
{
|
||||
cell = fTorrentCell;
|
||||
[cell setRepresentedObject: [fTorrents objectAtIndex: row]];
|
||||
[cell setRepresentedObject: [self itemAtRow: row]];
|
||||
}
|
||||
return NSPointInRect(point, [cell progressRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
|
||||
}
|
||||
|
@ -682,7 +656,7 @@
|
|||
- (BOOL) pointInMinimalStatusRect: (NSPoint) point
|
||||
{
|
||||
int row = [self rowAtPoint: point];
|
||||
if (row < 0 || [fGroupIndexes containsIndex: row] || ![fDefaults boolForKey: @"SmallView"])
|
||||
if (row < 0 || ![[self itemAtRow: row] isKindOfClass: [Torrent class]] || ![fDefaults boolForKey: @"SmallView"])
|
||||
return NO;
|
||||
|
||||
TorrentCell * cell;
|
||||
|
@ -691,7 +665,7 @@
|
|||
else
|
||||
{
|
||||
cell = fTorrentCell;
|
||||
[cell setRepresentedObject: [fTorrents objectAtIndex: row]];
|
||||
[cell setRepresentedObject: [self itemAtRow: row]];
|
||||
}
|
||||
return NSPointInRect(point, [cell minimalStatusRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue