mirror of
https://github.com/transmission/transmission.git
synced 2025-12-24 20:35:36 +00:00
First commit on my own 8-)
Sorting by progress, sorting no longer causes crashes. New look for the table. Info is now inspector: can set individual and multiple ratio limits, shows listing of files, more info in general, resizes when changing tabs, can change tabs with cmd-left and cmd-right. Menu items moved to "Transfers" menu. Sliding status bar in its own view. Prefs moved into their own nib. Toolbar items for pause and resume selected (many wanted this, but it needs better icons) New icons for Transfers and General. A lot of tweaking of main window to fix alignment etc. Sparkle used for updated (still needs to be added to website to work). And a lot more tweaking and changes that I'm too lazy to list. ...now let's hope I commit this right
This commit is contained in:
@@ -25,39 +25,65 @@
|
||||
#import "InfoWindowController.h"
|
||||
#import "StringAdditions.h"
|
||||
|
||||
#define RATIO_NO_CHECK_TAG 0
|
||||
#define RATIO_GLOBAL_TAG 1
|
||||
#define RATIO_CHECK_TAG 2
|
||||
|
||||
#define TAB_INFO_IDENT @"Info"
|
||||
#define TAB_STATUS_IDENT @"Status"
|
||||
#define TAB_OPTIONS_IDENT @"Options"
|
||||
#define TAB_FILES_IDENT @"Files"
|
||||
|
||||
#define TAB_INFO_HEIGHT 191.0
|
||||
#define TAB_STATUS_HEIGHT 241.0
|
||||
#define TAB_OPTIONS_HEIGHT 82.0
|
||||
#define TAB_FILES_HEIGHT 250.0
|
||||
|
||||
@implementation InfoWindowController
|
||||
|
||||
- (void) awakeFromNib
|
||||
{
|
||||
fAppIcon = [[NSApp applicationIconImage] copy];
|
||||
|
||||
fFiles = [[NSMutableArray alloc] initWithCapacity: 6];
|
||||
[fFileTable setDoubleAction: @selector(revealFile:)];
|
||||
|
||||
//window location and size
|
||||
NSWindow * window = [self window];
|
||||
[window setFrameAutosaveName: @"InspectorWindowFrame"];
|
||||
[window setFrameUsingName: @"InspectorWindowFrame" force: YES];
|
||||
|
||||
NSRect frame = [window frame];
|
||||
float difference = TAB_INFO_HEIGHT - [[[fTabView selectedTabViewItem]
|
||||
view] frame].size.height;
|
||||
frame.origin.y -= difference;
|
||||
frame.size.height += difference;
|
||||
[window setFrame: frame display: YES];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (fTorrents)
|
||||
[fTorrents release];
|
||||
[fFiles release];
|
||||
|
||||
[fAppIcon release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) updateInfoForTorrents: (NSArray *) torrents
|
||||
{
|
||||
int numberSelected = [torrents count];
|
||||
if (fTorrents)
|
||||
[fTorrents release];
|
||||
fTorrents = [torrents retain];
|
||||
|
||||
int numberSelected = [fTorrents count];
|
||||
if (numberSelected != 1)
|
||||
{
|
||||
[fImageView setImage: fAppIcon];
|
||||
|
||||
[fTracker setStringValue: @""];
|
||||
[fAnnounce setStringValue: @""];
|
||||
[fPieceSize setStringValue: @""];
|
||||
[fPieces setStringValue: @""];
|
||||
[fHash setStringValue: @""];
|
||||
|
||||
[fSeeders setStringValue: @""];
|
||||
[fLeechers setStringValue: @""];
|
||||
|
||||
if (numberSelected > 0)
|
||||
{
|
||||
[fName setStringValue: [[NSString stringWithInt: numberSelected]
|
||||
stringByAppendingString: @" Torrents Selected"]];
|
||||
[fNameField setStringValue: [NSString stringWithFormat:
|
||||
@"%d Torrents Selected", numberSelected]];
|
||||
|
||||
uint64_t size = 0;
|
||||
NSEnumerator * enumerator = [torrents objectEnumerator];
|
||||
@@ -65,63 +91,325 @@
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
size += [torrent size];
|
||||
|
||||
[fSize setStringValue: [[NSString
|
||||
stringForFileSize: size] stringByAppendingString: @" Total"]];
|
||||
[fSizeField setStringValue: [[NSString stringForFileSize: size]
|
||||
stringByAppendingString: @" Total"]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[fName setStringValue: @"No Torrents Selected"];
|
||||
|
||||
[fSize setStringValue: @""];
|
||||
[fDownloaded setStringValue: @""];
|
||||
[fUploaded setStringValue: @""];
|
||||
[fNameField setStringValue: @"No Torrents Selected"];
|
||||
[fSizeField setStringValue: @""];
|
||||
|
||||
[fDownloadRateField setStringValue: @""];
|
||||
[fUploadRateField setStringValue: @""];
|
||||
|
||||
[fDownloadedField setStringValue: @""];
|
||||
[fUploadedField setStringValue: @""];
|
||||
}
|
||||
|
||||
[fImageView setImage: fAppIcon];
|
||||
|
||||
[fNameField setToolTip: nil];
|
||||
|
||||
[fTrackerField setStringValue: @""];
|
||||
[fTrackerField setToolTip: nil];
|
||||
[fAnnounceField setStringValue: @""];
|
||||
[fAnnounceField setToolTip: nil];
|
||||
[fPieceSizeField setStringValue: @""];
|
||||
[fPiecesField setStringValue: @""];
|
||||
[fHashField setStringValue: @""];
|
||||
|
||||
[fTorrentLocationField setStringValue: @""];
|
||||
[fTorrentLocationField setToolTip: nil];
|
||||
[fDataLocationField setStringValue: @""];
|
||||
[fDataLocationField setToolTip: nil];
|
||||
[fDateStartedField setStringValue: @""];
|
||||
|
||||
[fStateField setStringValue: @""];
|
||||
[fPercentField setStringValue: @""];
|
||||
[fRatioField setStringValue: @""];
|
||||
|
||||
[fSeedersField setStringValue: @""];
|
||||
[fLeechersField setStringValue: @""];
|
||||
[fConnectedPeersField setStringValue: @""];
|
||||
[fDownloadingFromField setStringValue: @""];
|
||||
[fUploadingToField setStringValue: @""];
|
||||
}
|
||||
else
|
||||
{
|
||||
Torrent * torrent = [torrents objectAtIndex: 0];
|
||||
Torrent * torrent = [fTorrents objectAtIndex: 0];
|
||||
|
||||
[fImageView setImage: [torrent iconNonFlipped]];
|
||||
[fImageView setImage: [torrent icon]];
|
||||
|
||||
[fName setStringValue: [torrent name]];
|
||||
[fSize setStringValue: [NSString stringForFileSize: [torrent size]]];
|
||||
[fTracker setStringValue: [torrent tracker]];
|
||||
[fAnnounce setStringValue: [torrent announce]];
|
||||
[fPieceSize setStringValue: [NSString stringForFileSize: [torrent pieceSize]]];
|
||||
[fPieces setIntValue: [torrent pieceCount]];
|
||||
[fHash setStringValue: [torrent hash]];
|
||||
NSString * name = [torrent name];
|
||||
[fNameField setStringValue: name];
|
||||
[fNameField setToolTip: name];
|
||||
[fSizeField setStringValue: [NSString stringForFileSize: [torrent size]]];
|
||||
|
||||
NSString * tracker = [torrent tracker], * announce = [torrent announce];
|
||||
[fTrackerField setStringValue: tracker];
|
||||
[fTrackerField setToolTip: tracker];
|
||||
[fAnnounceField setStringValue: announce];
|
||||
[fAnnounceField setToolTip: announce];
|
||||
[fPieceSizeField setStringValue: [NSString stringForFileSize: [torrent pieceSize]]];
|
||||
[fPiecesField setIntValue: [torrent pieceCount]];
|
||||
[fHashField setStringValue: [torrent hashString]];
|
||||
|
||||
[fTorrentLocationField setStringValue: [[torrent torrentLocation]
|
||||
stringByAbbreviatingWithTildeInPath]];
|
||||
[fTorrentLocationField setToolTip: [torrent torrentLocation]];
|
||||
[fDataLocationField setStringValue: [[torrent dataLocation]
|
||||
stringByAbbreviatingWithTildeInPath]];
|
||||
[fDataLocationField setToolTip: [torrent dataLocation]];
|
||||
[fDateStartedField setObjectValue: [torrent date]];
|
||||
}
|
||||
[self updateInfoStats];
|
||||
|
||||
[self updateInfoStatsForTorrents: torrents];
|
||||
}
|
||||
|
||||
- (void) updateInfoStatsForTorrents: (NSArray *) torrents
|
||||
{
|
||||
int numberSelected = [torrents count];
|
||||
//set file table
|
||||
[fFiles removeAllObjects];
|
||||
|
||||
Torrent * torrent;
|
||||
NSEnumerator * enumerator = [fTorrents objectEnumerator];
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
[fFiles addObjectsFromArray: [torrent fileList]];
|
||||
|
||||
[fFileTable deselectAll: nil];
|
||||
[fFileTable reloadData];
|
||||
|
||||
//set ratio settings
|
||||
if (numberSelected > 0)
|
||||
{
|
||||
Torrent * torrent;
|
||||
if (numberSelected == 1)
|
||||
{
|
||||
torrent = [torrents objectAtIndex: 0];
|
||||
NSEnumerator * enumerator = [fTorrents objectEnumerator];
|
||||
Torrent * torrent = [enumerator nextObject]; //first torrent
|
||||
const int INVALID = -99;
|
||||
int ratioSetting = [torrent stopRatioSetting];
|
||||
float ratioLimit = [torrent ratioLimit];
|
||||
|
||||
while ((ratioSetting != INVALID || ratioLimit != INVALID)
|
||||
&& (torrent = [enumerator nextObject]))
|
||||
{
|
||||
if (ratioSetting != INVALID && ratioSetting != [torrent stopRatioSetting])
|
||||
ratioSetting = INVALID;
|
||||
|
||||
int seeders = [torrent seeders], leechers = [torrent leechers];
|
||||
[fSeeders setStringValue: seeders < 0 ?
|
||||
@"?" : [NSString stringWithInt: seeders]];
|
||||
[fLeechers setStringValue: leechers < 0 ?
|
||||
@"?" : [NSString stringWithInt: leechers]];
|
||||
if (ratioLimit != INVALID && ratioLimit != [torrent ratioLimit])
|
||||
ratioLimit = INVALID;
|
||||
}
|
||||
|
||||
|
||||
[fRatioMatrix setEnabled: YES];
|
||||
|
||||
if (ratioSetting == RATIO_CHECK)
|
||||
{
|
||||
[fRatioMatrix selectCellWithTag: RATIO_CHECK_TAG];
|
||||
[fRatioLimitField setEnabled: YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ratioSetting == RATIO_NO_CHECK)
|
||||
[fRatioMatrix selectCellWithTag: RATIO_NO_CHECK_TAG];
|
||||
else if (ratioSetting == RATIO_GLOBAL)
|
||||
[fRatioMatrix selectCellWithTag: RATIO_GLOBAL_TAG];
|
||||
else
|
||||
[fRatioMatrix deselectAllCells];
|
||||
|
||||
[fRatioLimitField setEnabled: NO];
|
||||
}
|
||||
|
||||
if (ratioLimit != INVALID)
|
||||
[fRatioLimitField setFloatValue: ratioLimit];
|
||||
else
|
||||
[fRatioLimitField setStringValue: @""];
|
||||
}
|
||||
else
|
||||
{
|
||||
[fRatioMatrix deselectAllCells];
|
||||
[fRatioMatrix setEnabled: NO];
|
||||
|
||||
[fRatioLimitField setEnabled: NO];
|
||||
[fRatioLimitField setStringValue: @""];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) updateInfoStats
|
||||
{
|
||||
int numberSelected = [fTorrents count];
|
||||
if (numberSelected > 0)
|
||||
{
|
||||
float downloadRate = 0, uploadRate = 0;
|
||||
uint64_t downloaded = 0, uploaded = 0;
|
||||
NSEnumerator * enumerator = [torrents objectEnumerator];
|
||||
Torrent * torrent;
|
||||
NSEnumerator * enumerator = [fTorrents objectEnumerator];
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
{
|
||||
downloadRate += [torrent downloadRate];
|
||||
uploadRate += [torrent uploadRate];
|
||||
|
||||
downloaded += [torrent downloaded];
|
||||
uploaded += [torrent uploaded];
|
||||
}
|
||||
|
||||
[fDownloaded setStringValue: [NSString stringForFileSize: downloaded]];
|
||||
[fUploaded setStringValue: [NSString stringForFileSize: uploaded]];
|
||||
[fDownloadRateField setStringValue: [NSString stringForSpeed: downloadRate]];
|
||||
[fUploadRateField setStringValue: [NSString stringForSpeed: uploadRate]];
|
||||
|
||||
[fDownloadedField setStringValue: [NSString stringForFileSize: downloaded]];
|
||||
[fUploadedField setStringValue: [NSString stringForFileSize: uploaded]];
|
||||
|
||||
if (numberSelected == 1)
|
||||
{
|
||||
torrent = [fTorrents objectAtIndex: 0];
|
||||
|
||||
[fStateField setStringValue: [torrent state]];
|
||||
[fPercentField setStringValue: [NSString stringWithFormat:
|
||||
@"%.2f%%", 100 * [torrent progress]]];
|
||||
|
||||
int seeders = [torrent seeders], leechers = [torrent leechers];
|
||||
[fSeedersField setStringValue: seeders < 0 ?
|
||||
@"N/A" : [NSString stringWithInt: seeders]];
|
||||
[fLeechersField setStringValue: leechers < 0 ?
|
||||
@"N/A" : [NSString stringWithInt: leechers]];
|
||||
|
||||
BOOL active = [torrent isActive];
|
||||
|
||||
[fConnectedPeersField setStringValue: active ? [NSString
|
||||
stringWithInt: [torrent totalPeers]] : @"N/A"];
|
||||
[fDownloadingFromField setStringValue: active ? [NSString
|
||||
stringWithInt: [torrent peersUploading]] : @"N/A"];
|
||||
[fUploadingToField setStringValue: active ? [NSString
|
||||
stringWithInt: [torrent peersDownloading]] : @"N/A"];
|
||||
|
||||
[fRatioField setStringValue: [NSString stringForRatioWithDownload:
|
||||
downloaded upload: uploaded]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
|
||||
{
|
||||
SEL action = [menuItem action];
|
||||
|
||||
if (action == @selector(revealFile:))
|
||||
return [fFileTable numberOfSelectedRows] > 0 &&
|
||||
[[[fTabView selectedTabViewItem] identifier] isEqualToString: TAB_FILES_IDENT];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) tabView: (NSTabView *) tabView didSelectTabViewItem: (NSTabViewItem *) tabViewItem
|
||||
{
|
||||
NSWindow * window = [self window];
|
||||
NSRect frame = [window frame];
|
||||
|
||||
float height;
|
||||
NSString * identifier = [tabViewItem identifier];
|
||||
if ([identifier isEqualToString: TAB_INFO_IDENT])
|
||||
height = TAB_INFO_HEIGHT;
|
||||
else if ([identifier isEqualToString: TAB_STATUS_IDENT])
|
||||
height = TAB_STATUS_HEIGHT;
|
||||
else if ([identifier isEqualToString: TAB_OPTIONS_IDENT])
|
||||
height = TAB_OPTIONS_HEIGHT;
|
||||
else
|
||||
height = TAB_FILES_HEIGHT;
|
||||
|
||||
NSView * view = [tabViewItem view];
|
||||
float difference = height - [view frame].size.height;
|
||||
frame.origin.y -= difference;
|
||||
frame.size.height += difference;
|
||||
|
||||
[view setHidden: YES];
|
||||
[window setFrame: frame display: YES animate: YES];
|
||||
[view setHidden: NO];
|
||||
}
|
||||
|
||||
- (void) setNextTab
|
||||
{
|
||||
if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]]
|
||||
== [fTabView numberOfTabViewItems] - 1)
|
||||
[fTabView selectFirstTabViewItem: nil];
|
||||
else
|
||||
[fTabView selectNextTabViewItem: nil];
|
||||
}
|
||||
|
||||
- (void) setPreviousTab
|
||||
{
|
||||
if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]] == 0)
|
||||
[fTabView selectLastTabViewItem: nil];
|
||||
else
|
||||
[fTabView selectPreviousTabViewItem: nil];
|
||||
}
|
||||
|
||||
- (int) numberOfRowsInTableView: (NSTableView *) tableView
|
||||
{
|
||||
return [fFiles count];
|
||||
}
|
||||
|
||||
- (id) tableView: (NSTableView *) tableView objectValueForTableColumn:
|
||||
(NSTableColumn *) column row: (int) row
|
||||
{
|
||||
NSString * file = [fFiles objectAtIndex: row];
|
||||
if ([[column identifier] isEqualToString: @"Icon"])
|
||||
return [[NSWorkspace sharedWorkspace] iconForFileType: [file pathExtension]];
|
||||
else
|
||||
return [file lastPathComponent];
|
||||
}
|
||||
|
||||
//only called on >= 10.4
|
||||
- (NSString *) tableView: (NSTableView *) tableView toolTipForCell: (NSCell *) cell
|
||||
rect: (NSRectPointer) rect tableColumn: (NSTableColumn *) column
|
||||
row: (int) row mouseLocation: (NSPoint) mouseLocation
|
||||
{
|
||||
return [fFiles objectAtIndex: row];
|
||||
}
|
||||
|
||||
- (void) revealFile: (id) sender
|
||||
{
|
||||
if ([fFileTable numberOfSelectedRows] > 0)
|
||||
[[NSWorkspace sharedWorkspace] selectFile: [fFiles objectAtIndex: [fFileTable selectedRow]]
|
||||
inFileViewerRootedAtPath: nil];
|
||||
}
|
||||
|
||||
- (void) setRatioCheck: (id) sender
|
||||
{
|
||||
NSButtonCell * selected = [fRatioMatrix selectedCell];
|
||||
int ratioSetting;
|
||||
if (selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG])
|
||||
ratioSetting = RATIO_CHECK;
|
||||
else if (selected == [fRatioMatrix cellWithTag: RATIO_NO_CHECK_TAG])
|
||||
ratioSetting = RATIO_NO_CHECK;
|
||||
else
|
||||
ratioSetting = RATIO_GLOBAL;
|
||||
|
||||
Torrent * torrent;
|
||||
NSEnumerator * enumerator = [fTorrents objectEnumerator];
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
[torrent setStopRatioSetting: ratioSetting];
|
||||
|
||||
[self setRatioLimit: fRatioLimitField];
|
||||
[fRatioLimitField setEnabled: selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG]];
|
||||
}
|
||||
|
||||
- (void) setRatioLimit: (id) sender
|
||||
{
|
||||
Torrent * torrent;
|
||||
NSEnumerator * enumerator = [fTorrents objectEnumerator];
|
||||
|
||||
float ratioLimit = [sender floatValue];
|
||||
if (![[sender stringValue] isEqualToString:
|
||||
[NSString stringWithFormat: @"%.2f", ratioLimit]]
|
||||
|| ratioLimit < 0)
|
||||
{
|
||||
NSBeep();
|
||||
float ratioLimit = [[enumerator nextObject] ratioLimit]; //use first torrent
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
if (ratioLimit != [torrent ratioLimit])
|
||||
{
|
||||
[sender setStringValue: @""];
|
||||
return;
|
||||
}
|
||||
|
||||
[sender setFloatValue: ratioLimit];
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((torrent = [enumerator nextObject]))
|
||||
[torrent setRatioLimit: ratioLimit];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user