From: Mike Gelfand Date: Tue, 24 Jan 2017 17:53:16 +0000 (+0300) Subject: Convert tabs to spaces, remove trailing whitespace (Mac client) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4160743738bbfe4c4ed9087dbef6acac8365034e;p=transmission Convert tabs to spaces, remove trailing whitespace (Mac client) --- diff --git a/macosx/AboutWindowController.h b/macosx/AboutWindowController.h index 45ed065ed..610be4b74 100644 --- a/macosx/AboutWindowController.h +++ b/macosx/AboutWindowController.h @@ -24,7 +24,7 @@ @interface AboutWindowController : NSWindowController { - IBOutlet NSTextView * fTextView, * fLicenseView; + IBOutlet NSTextView * fTextView, * fLicenseView; IBOutlet NSTextField * fVersionField, * fCopyrightField; IBOutlet NSButton * fLicenseButton, * fLicenseCloseButton; IBOutlet NSPanel * fLicenseSheet; diff --git a/macosx/AboutWindowController.m b/macosx/AboutWindowController.m index 1dd30d21d..d8db4420e 100644 --- a/macosx/AboutWindowController.m +++ b/macosx/AboutWindowController.m @@ -37,19 +37,19 @@ AboutWindowController * fAboutBoxInstance = nil; NSDictionary * info = [[NSBundle mainBundle] infoDictionary]; [fVersionField setStringValue: [NSString stringWithFormat: @"%@ (%@)", [info objectForKey: @"CFBundleShortVersionString"], [info objectForKey: (NSString *)kCFBundleVersionKey]]]; - + [fCopyrightField setStringValue: [[NSBundle mainBundle] localizedStringForKey: @"NSHumanReadableCopyright" value: nil table: @"InfoPlist"]]; - + [[fTextView textStorage] setAttributedString: [[[NSAttributedString alloc] initWithPath: [[NSBundle mainBundle] pathForResource: @"Credits" ofType: @"rtf"] documentAttributes: nil] autorelease]]; - + //size license button const CGFloat oldButtonWidth = NSWidth([fLicenseButton frame]); - + [fLicenseButton setTitle: NSLocalizedString(@"License", "About window -> license button")]; [fLicenseButton sizeToFit]; - + NSRect buttonFrame = [fLicenseButton frame]; buttonFrame.size.width += 10.0; buttonFrame.origin.x -= NSWidth(buttonFrame) - oldButtonWidth; @@ -63,7 +63,7 @@ AboutWindowController * fAboutBoxInstance = nil; - (void) windowWillClose: (id) sender { - [fAboutBoxInstance autorelease]; + [fAboutBoxInstance autorelease]; fAboutBoxInstance = nil; } @@ -73,8 +73,8 @@ AboutWindowController * fAboutBoxInstance = nil; usedEncoding: nil error: NULL]; [fLicenseView setString: licenseText]; [fLicenseCloseButton setTitle: NSLocalizedString(@"OK", "About window -> license close button")]; - - [NSApp beginSheet: fLicenseSheet modalForWindow: [self window] modalDelegate: nil didEndSelector: nil contextInfo: nil]; + + [NSApp beginSheet: fLicenseSheet modalForWindow: [self window] modalDelegate: nil didEndSelector: nil contextInfo: nil]; } - (IBAction) hideLicense: (id) sender diff --git a/macosx/AddMagnetWindowController.h b/macosx/AddMagnetWindowController.h index 8b2f6616a..eae943149 100644 --- a/macosx/AddMagnetWindowController.h +++ b/macosx/AddMagnetWindowController.h @@ -32,19 +32,19 @@ IBOutlet NSTextField * fNameField, * fLocationField; IBOutlet NSButton * fStartCheck; IBOutlet NSPopUpButton * fGroupPopUp, * fPriorityPopUp; - + //remove these when switching to auto layout IBOutlet NSTextField * fMagnetLinkLabel; IBOutlet NSTextField * fDownloadToLabel, * fGroupLabel, * fPriorityLabel; IBOutlet NSButton * fChangeDestinationButton; IBOutlet NSBox * fDownloadToBox; IBOutlet NSButton * fAddButton, * fCancelButton; - + Controller * fController; - + Torrent * fTorrent; NSString * fDestination; - + NSInteger fGroupValue; TorrentDeterminationType fGroupDeterminationType; } diff --git a/macosx/AddMagnetWindowController.m b/macosx/AddMagnetWindowController.m index d02b2eeea..fe7d5d5f6 100644 --- a/macosx/AddMagnetWindowController.m +++ b/macosx/AddMagnetWindowController.m @@ -52,9 +52,9 @@ { fTorrent = torrent; fDestination = [[path stringByExpandingTildeInPath] retain]; - + fController = controller; - + fGroupValue = [torrent groupValue]; fGroupDeterminationType = TorrentDeterminationAutomatic; } @@ -65,15 +65,15 @@ { [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateGroupMenu:) name: @"UpdateGroups" object: nil]; - + NSString * name = [fTorrent name]; [[self window] setTitle: name]; [fNameField setStringValue: name]; [fNameField setToolTip: name]; - + [self setGroupsMenu]; [fGroupPopUp selectItemWithTag: fGroupValue]; - + NSInteger priorityIndex; switch ([fTorrent priority]) { @@ -85,9 +85,9 @@ priorityIndex = POPUP_PRIORITY_NORMAL; } [fPriorityPopUp selectItemAtIndex: priorityIndex]; - + [fStartCheck setState: [[NSUserDefaults standardUserDefaults] boolForKey: @"AutoStartDownload"] ? NSOnState : NSOffState]; - + if (fDestination) [self setDestinationPath: fDestination determinationType: TorrentDeterminationAutomatic]; else @@ -95,10 +95,10 @@ [fLocationField setStringValue: @""]; [fLocationImageView setImage: nil]; } - + #warning when 10.7-only, switch to auto layout [fMagnetLinkLabel sizeToFit]; - + const CGFloat downloadToLabelOldWidth = [fDownloadToLabel frame].size.width; [fDownloadToLabel sizeToFit]; const CGFloat changeDestOldWidth = [fChangeDestinationButton frame].size.width; @@ -106,13 +106,13 @@ NSRect changeDestFrame = [fChangeDestinationButton frame]; changeDestFrame.origin.x -= changeDestFrame.size.width - changeDestOldWidth; [fChangeDestinationButton setFrame: changeDestFrame]; - + NSRect downloadToBoxFrame = [fDownloadToBox frame]; const CGFloat downloadToBoxSizeDiff = ([fDownloadToLabel frame].size.width - downloadToLabelOldWidth) + (changeDestFrame.size.width - changeDestOldWidth); downloadToBoxFrame.size.width -= downloadToBoxSizeDiff; downloadToBoxFrame.origin.x -= downloadToLabelOldWidth - [fDownloadToLabel frame].size.width; [fDownloadToBox setFrame: downloadToBoxFrame]; - + NSRect groupPopUpFrame = [fGroupPopUp frame]; NSRect priorityPopUpFrame = [fPriorityPopUp frame]; const CGFloat popUpOffset = groupPopUpFrame.origin.x - NSMaxX([fGroupLabel frame]); @@ -133,7 +133,7 @@ [fGroupPopUp setFrame: groupPopUpFrame]; [fPriorityLabel setFrame: priorityLabelFrame]; [fPriorityPopUp setFrame: priorityPopUpFrame]; - + const CGFloat minButtonWidth = 82.0; const CGFloat oldAddButtonWidth = [fAddButton bounds].size.width; const CGFloat oldCancelButtonWidth = [fCancelButton bounds].size.width; @@ -150,7 +150,7 @@ cancelButtonFrame.origin.x -= addButtonWidthIncrease + (buttonWidth - oldCancelButtonWidth); [fAddButton setFrame: addButtonFrame]; [fCancelButton setFrame: cancelButtonFrame]; - + [fStartCheck sizeToFit]; } @@ -164,9 +164,9 @@ - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fDestination release]; - + [super dealloc]; } @@ -184,10 +184,10 @@ [panel setCanChooseFiles: NO]; [panel setCanChooseDirectories: YES]; [panel setCanCreateDirectories: YES]; - + [panel setMessage: [NSString stringWithFormat: NSLocalizedString(@"Select the download folder for \"%@\"", "Add -> select destination folder"), [fTorrent name]]]; - + [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) [self setDestinationPath: [[[panel URLs] objectAtIndex: 0] path] determinationType:TorrentDeterminationUserSpecified]; @@ -213,7 +213,7 @@ [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Add torrent -> same name -> button")]; [alert addButtonWithTitle: NSLocalizedString(@"Add", "Add torrent -> same name -> button")]; [alert setShowsSuppressionButton: YES]; - + [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: @selector(sameNameAlertDidEnd:returnCode:contextInfo:) contextInfo: nil]; } @@ -254,7 +254,7 @@ if (![fGroupPopUp selectItemWithTag: fGroupValue]) { fGroupValue = -1; - fGroupDeterminationType = TorrentDeterminationAutomatic; + fGroupDeterminationType = TorrentDeterminationAutomatic; [fGroupPopUp selectItemWithTag: fGroupValue]; } } @@ -266,10 +266,10 @@ - (void) confirmAdd { [fTorrent setGroupValue: fGroupValue determinationType: fGroupDeterminationType]; - + if ([fStartCheck state] == NSOnState) [fTorrent startTransfer]; - + [self close]; [fController askOpenMagnetConfirmed: self add: YES]; //ensure last, since it releases this controller } @@ -278,16 +278,16 @@ { destination = [destination stringByExpandingTildeInPath]; if (!fDestination || ![fDestination isEqualToString: destination]) - { + { [fDestination release]; fDestination = [destination retain]; - + [fTorrent changeDownloadFolderBeforeUsing: fDestination determinationType: determinationType]; } - + [fLocationField setStringValue: [fDestination stringByAbbreviatingWithTildeInPath]]; [fLocationField setToolTip: fDestination]; - + ExpandedPathToIconTransformer * iconTransformer = [[ExpandedPathToIconTransformer alloc] init]; [fLocationImageView setImage: [iconTransformer transformedValue: fDestination]]; [iconTransformer release]; @@ -302,7 +302,7 @@ - (void) changeGroupValue: (id) sender { NSInteger previousGroup = fGroupValue; - fGroupValue = [sender tag]; + fGroupValue = [sender tag]; fGroupDeterminationType = TorrentDeterminationUserSpecified; if ([[GroupsController groups] usesCustomDownloadLocationForIndex: fGroupValue]) @@ -316,9 +316,9 @@ { if ([[alert suppressionButton] state] == NSOnState) [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningFolderDataSameName"]; - + [alert release]; - + if (returnCode == NSAlertSecondButtonReturn) [self performSelectorOnMainThread: @selector(confirmAdd) withObject: nil waitUntilDone: NO]; } diff --git a/macosx/AddWindowController.h b/macosx/AddWindowController.h index e11645c7b..128105fbf 100644 --- a/macosx/AddWindowController.h +++ b/macosx/AddWindowController.h @@ -34,24 +34,24 @@ IBOutlet NSButton * fStartCheck, * fDeleteCheck; IBOutlet NSPopUpButton * fGroupPopUp, * fPriorityPopUp; IBOutlet NSProgressIndicator * fVerifyIndicator; - + IBOutlet NSTextField * fFileFilterField; IBOutlet NSButton * fCheckAllButton, *fUncheckAllButton; - + IBOutlet FileOutlineController * fFileController; IBOutlet NSScrollView * fFileScrollView; - + Controller * fController; - + Torrent * fTorrent; NSString * fDestination, * fTorrentFile; BOOL fLockDestination; - + BOOL fDeleteTorrentEnableInitially, fCanToggleDelete; NSInteger fGroupValue; - + NSTimer * fTimer; - + TorrentDeterminationType fGroupValueDetermination; } diff --git a/macosx/AddWindowController.m b/macosx/AddWindowController.m index f698e209d..796ba7c99 100644 --- a/macosx/AddWindowController.m +++ b/macosx/AddWindowController.m @@ -60,14 +60,14 @@ fTorrent = torrent; fDestination = [[path stringByExpandingTildeInPath] retain]; fLockDestination = lockDestination; - + fController = controller; - + fTorrentFile = [[torrentFile stringByExpandingTildeInPath] retain]; - + fDeleteTorrentEnableInitially = deleteTorrent; fCanToggleDelete = canToggleDelete; - + fGroupValue = [torrent groupValue]; fGroupValueDetermination = TorrentDeterminationAutomatic; @@ -79,24 +79,24 @@ - (void) awakeFromNib { [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateCheckButtons:) name: @"TorrentFileCheckChange" object: fTorrent]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateGroupMenu:) name: @"UpdateGroups" object: nil]; - + [fFileController setTorrent: fTorrent]; - + NSString * name = [fTorrent name]; [[self window] setTitle: name]; [fNameField setStringValue: name]; [fNameField setToolTip: name]; - + [fIconView setImage: [fTorrent icon]]; - + if (![fTorrent isFolder]) { [fFileFilterField setHidden: YES]; [fCheckAllButton setHidden: YES]; [fUncheckAllButton setHidden: YES]; - + NSRect scrollFrame = [fFileScrollView frame]; const CGFloat diff = NSMinY([fFileScrollView frame]) - NSMinY([fFileFilterField frame]); scrollFrame.origin.y -= diff; @@ -105,10 +105,10 @@ } else [self updateCheckButtons: nil]; - + [self setGroupsMenu]; [fGroupPopUp selectItemWithTag: fGroupValue]; - + NSInteger priorityIndex; switch ([fTorrent priority]) { @@ -120,12 +120,12 @@ priorityIndex = POPUP_PRIORITY_NORMAL; } [fPriorityPopUp selectItemAtIndex: priorityIndex]; - + [fStartCheck setState: [[NSUserDefaults standardUserDefaults] boolForKey: @"AutoStartDownload"] ? NSOnState : NSOffState]; - + [fDeleteCheck setState: fDeleteTorrentEnableInitially ? NSOnState : NSOffState]; [fDeleteCheck setEnabled: fCanToggleDelete]; - + if (fDestination) [self setDestinationPath: fDestination determinationType: (fLockDestination ? TorrentDeterminationUserSpecified : TorrentDeterminationAutomatic)]; else @@ -133,7 +133,7 @@ [fLocationField setStringValue: @""]; [fLocationImageView setImage: nil]; } - + fTimer = [[NSTimer scheduledTimerWithTimeInterval: UPDATE_SECONDS target: self selector: @selector(updateFiles) userInfo: nil repeats: YES] retain]; [self updateFiles]; @@ -149,13 +149,13 @@ - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fTimer invalidate]; [fTimer release]; - + [fDestination release]; [fTorrentFile release]; - + [super dealloc]; } @@ -173,10 +173,10 @@ [panel setCanChooseFiles: NO]; [panel setCanChooseDirectories: YES]; [panel setCanCreateDirectories: YES]; - + [panel setMessage: [NSString stringWithFormat: NSLocalizedString(@"Select the download folder for \"%@\"", "Add -> select destination folder"), [fTorrent name]]]; - + [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) { @@ -205,7 +205,7 @@ [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Add torrent -> same name -> button")]; [alert addButtonWithTitle: NSLocalizedString(@"Add", "Add torrent -> same name -> button")]; [alert setShowsSuppressionButton: YES]; - + [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: @selector(sameNameAlertDidEnd:returnCode:contextInfo:) contextInfo: nil]; } @@ -224,9 +224,9 @@ [fTimer invalidate]; [fTimer release]; fTimer = nil; - + [fFileController setTorrent: nil]; //avoid a crash when window tries to update - + [fController askOpenConfirmed: self add: NO]; return YES; } @@ -277,7 +277,7 @@ const NSInteger filesCheckState = [fTorrent checkForFiles: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTorrent fileCount])]]; [fCheckAllButton setEnabled: filesCheckState != NSOnState]; //if anything is unchecked [fUncheckAllButton setEnabled: ![fTorrent allDownloaded]]; //if there are any checked files that aren't finished - + //status field NSString * fileString; NSInteger count = [fTorrent fileCount]; @@ -286,13 +286,13 @@ [NSString formattedUInteger: count]]; else fileString = NSLocalizedString(@"1 file", "Add torrent -> info"); - + NSString * selectedString = [NSString stringWithFormat: NSLocalizedString(@"%@ selected", "Add torrent -> info"), [NSString stringForFileSize: [fTorrent totalSizeSelected]]]; - + statusString = [NSString stringWithFormat: @"%@, %@ (%@)", fileString, statusString, selectedString]; } - + [fStatusField setStringValue: statusString]; } @@ -302,7 +302,7 @@ if (![fGroupPopUp selectItemWithTag: fGroupValue]) { fGroupValue = -1; - fGroupValueDetermination = TorrentDeterminationAutomatic; + fGroupValueDetermination = TorrentDeterminationAutomatic; [fGroupPopUp selectItemWithTag: fGroupValue]; } } @@ -314,11 +314,11 @@ - (void) updateFiles { [fTorrent update]; - + [fFileController refresh]; - + [self updateCheckButtons: nil]; //call in case button state changed by checking - + if ([fTorrent isChecking]) { const BOOL waiting = [fTorrent isCheckingWaiting]; @@ -343,12 +343,12 @@ if (fTorrentFile && fCanToggleDelete && [fDeleteCheck state] == NSOnState) [Torrent trashFile: fTorrentFile error: nil]; - + if ([fStartCheck state] == NSOnState) [fTorrent startTransfer]; - + [fFileController setTorrent: nil]; //avoid a crash when window tries to update - + [self close]; [fController askOpenConfirmed: self add: YES]; //ensure last, since it releases this controller } @@ -357,16 +357,16 @@ { destination = [destination stringByExpandingTildeInPath]; if (!fDestination || ![fDestination isEqualToString: destination]) - { + { [fDestination release]; fDestination = [destination retain]; - + [fTorrent changeDownloadFolderBeforeUsing: fDestination determinationType: determinationType]; } - + [fLocationField setStringValue: [fDestination stringByAbbreviatingWithTildeInPath]]; [fLocationField setToolTip: fDestination]; - + ExpandedPathToIconTransformer * iconTransformer = [[ExpandedPathToIconTransformer alloc] init]; [fLocationImageView setImage: [iconTransformer transformedValue: fDestination]]; [iconTransformer release]; @@ -398,9 +398,9 @@ { if ([[alert suppressionButton] state] == NSOnState) [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningFolderDataSameName"]; - + [alert release]; - + if (returnCode == NSAlertSecondButtonReturn) [self performSelectorOnMainThread: @selector(confirmAdd) withObject: nil waitUntilDone: NO]; } diff --git a/macosx/BadgeView.h b/macosx/BadgeView.h index b4bb260c7..450b54dff 100644 --- a/macosx/BadgeView.h +++ b/macosx/BadgeView.h @@ -26,9 +26,9 @@ @interface BadgeView : NSView { tr_session * fLib; - + NSMutableDictionary * fAttributes; - + CGFloat fDownloadRate, fUploadRate; BOOL fQuitting; } diff --git a/macosx/BadgeView.m b/macosx/BadgeView.m index 430f01539..a1d7426ee 100644 --- a/macosx/BadgeView.m +++ b/macosx/BadgeView.m @@ -38,7 +38,7 @@ if ((self = [super init])) { fLib = lib; - + fDownloadRate = 0.0; fUploadRate = 0.0; fQuitting = NO; @@ -57,7 +57,7 @@ //only needs update if the badges were displayed or are displayed now if (fDownloadRate == downloadRate && fUploadRate == uploadRate) return NO; - + fDownloadRate = downloadRate; fUploadRate = uploadRate; return YES; @@ -71,7 +71,7 @@ - (void) drawRect: (NSRect) rect { [[NSApp applicationIconImage] drawInRect: rect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0]; - + if (fQuitting) { NSImage * quitBadge = [NSImage imageNamed: @"QuitBadge"]; @@ -79,7 +79,7 @@ atHeight: (NSHeight(rect) - [quitBadge size].height) * 0.5 adjustForQuit: YES]; return; } - + const BOOL upload = fUploadRate >= 0.1, download = fDownloadRate >= 0.1; CGFloat bottom = 0.0; @@ -106,21 +106,21 @@ NSShadow * stringShadow = [[NSShadow alloc] init]; [stringShadow setShadowOffset: NSMakeSize(2.0, -2.0)]; [stringShadow setShadowBlurRadius: 4.0]; - + fAttributes = [[NSMutableDictionary alloc] initWithCapacity: 3]; [fAttributes setObject: [NSColor whiteColor] forKey: NSForegroundColorAttributeName]; [fAttributes setObject: stringShadow forKey: NSShadowAttributeName]; - + [stringShadow release]; } - + NSRect badgeRect; badgeRect.size = [badge size]; badgeRect.origin.x = 0.0; badgeRect.origin.y = height; - + [badge drawInRect: badgeRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0]; - + //make sure text fits on the badge CGFloat fontSize = 26.0; NSSize stringSize; @@ -130,13 +130,13 @@ stringSize = [string sizeWithAttributes: fAttributes]; fontSize -= 1.0; } while (NSWidth(badgeRect) < stringSize.width); - + //string is in center of image NSRect stringRect; stringRect.origin.x = NSMidX(badgeRect) - stringSize.width * 0.5; stringRect.origin.y = NSMidY(badgeRect) - stringSize.height * 0.5 + (quit ? 2.0 : 1.0); //adjust for shadow, extra for quit stringRect.size = stringSize; - + [string drawInRect: stringRect withAttributes: fAttributes]; } diff --git a/macosx/Badger.h b/macosx/Badger.h index 7db8a05ba..57aa74901 100644 --- a/macosx/Badger.h +++ b/macosx/Badger.h @@ -28,7 +28,7 @@ @interface Badger : NSObject { tr_session * fLib; - + NSMutableSet * fHashes; } diff --git a/macosx/Badger.m b/macosx/Badger.m index deb7a4e58..06784b127 100644 --- a/macosx/Badger.m +++ b/macosx/Badger.m @@ -32,14 +32,14 @@ if ((self = [super init])) { fLib = lib; - + BadgeView * view = [[BadgeView alloc] initWithLib: lib]; [[NSApp dockTile] setContentView: view]; [view release]; - + fHashes = [[NSMutableSet alloc] init]; } - + return self; } @@ -55,7 +55,7 @@ ? downloadRate : 0.0; const CGFloat displayUlRate = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeUploadRate"] ? uploadRate : 0.0; - + //only update if the badged values change if ([(BadgeView *)[[NSApp dockTile] contentView] setRatesWithDownload: displayDlRate upload: displayUlRate]) [[NSApp dockTile] display]; @@ -64,7 +64,7 @@ - (void) addCompletedTorrent: (Torrent *) torrent { NSParameterAssert(torrent != nil); - + [fHashes addObject: [torrent hashString]]; [[NSApp dockTile] setBadgeLabel: [NSString formattedUInteger: [fHashes count]]]; } diff --git a/macosx/BlocklistDownloader.h b/macosx/BlocklistDownloader.h index ad3e283e9..d739c9d30 100644 --- a/macosx/BlocklistDownloader.h +++ b/macosx/BlocklistDownloader.h @@ -34,13 +34,13 @@ typedef enum @interface BlocklistDownloader : NSObject { NSURLDownload * fDownload; - + BlocklistDownloaderViewController * fViewController; - + NSString * fDestination; NSUInteger fCurrentSize; long long fExpectedSize; - + blocklistDownloadState fState; } diff --git a/macosx/BlocklistDownloader.m b/macosx/BlocklistDownloader.m index e9396f139..d99db5c1b 100644 --- a/macosx/BlocklistDownloader.m +++ b/macosx/BlocklistDownloader.m @@ -42,7 +42,7 @@ BlocklistDownloader * fBLDownloader = nil; fBLDownloader = [[BlocklistDownloader alloc] init]; [fBLDownloader startDownload]; } - + return fBLDownloader; } @@ -81,11 +81,11 @@ BlocklistDownloader * fBLDownloader = nil; - (void) cancelDownload { [fViewController setFinished]; - + [fDownload cancel]; - + [[BlocklistScheduler scheduler] updateSchedule]; - + fBLDownloader = nil; [self release]; } @@ -105,10 +105,10 @@ BlocklistDownloader * fBLDownloader = nil; - (void) download: (NSURLDownload *) download didReceiveResponse: (NSURLResponse *) response { fState = BLOCKLIST_DL_DOWNLOADING; - + fCurrentSize = 0; fExpectedSize = [response expectedContentLength]; - + [fViewController setStatusProgressForCurrentSize: fCurrentSize expectedSize: fExpectedSize]; } @@ -121,10 +121,10 @@ BlocklistDownloader * fBLDownloader = nil; - (void) download: (NSURLDownload *) download didFailWithError: (NSError *) error { [fViewController setFailed: [error localizedDescription]]; - + [[NSUserDefaults standardUserDefaults] setObject: [NSDate date] forKey: @"BlocklistNewLastUpdate"]; [[BlocklistScheduler scheduler] updateSchedule]; - + fBLDownloader = nil; [self release]; } @@ -132,34 +132,34 @@ BlocklistDownloader * fBLDownloader = nil; - (void) downloadDidFinish: (NSURLDownload *) download { fState = BLOCKLIST_DL_PROCESSING; - + [fViewController setStatusProcessing]; - + NSAssert(fDestination != nil, @"the blocklist file destination has not been specified"); - + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self decompressBlocklist]; - + dispatch_async(dispatch_get_main_queue(), ^{ const int count = tr_blocklistSetContent([(Controller *)[NSApp delegate] sessionHandle], [fDestination UTF8String]); - + //delete downloaded file [[NSFileManager defaultManager] removeItemAtPath: fDestination error: NULL]; - + if (count > 0) [fViewController setFinished]; else [fViewController setFailed: NSLocalizedString(@"The specified blocklist file did not contain any valid rules.", "blocklist fail message")]; - + //update last updated date for schedule NSDate * date = [NSDate date]; [[NSUserDefaults standardUserDefaults] setObject: date forKey: @"BlocklistNewLastUpdate"]; [[NSUserDefaults standardUserDefaults] setObject: date forKey: @"BlocklistNewLastUpdateSuccess"]; [[BlocklistScheduler scheduler] updateSchedule]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"BlocklistUpdated" object: nil]; - + fBLDownloader = nil; [self release]; }); @@ -178,87 +178,87 @@ BlocklistDownloader * fBLDownloader = nil; - (void) startDownload { fState = BLOCKLIST_DL_START; - + [[BlocklistScheduler scheduler] cancelSchedule]; - + NSString * urlString = [[NSUserDefaults standardUserDefaults] stringForKey: @"BlocklistURL"]; if (!urlString) urlString = @""; else if (![urlString isEqualToString: @""] && [urlString rangeOfString: @"://"].location == NSNotFound) urlString = [@"http://" stringByAppendingString: urlString]; - + NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString]]; - + fDownload = [[NSURLDownload alloc] initWithRequest: request delegate: self]; } //.gz, .tar.gz, .tgz, and .bgz will be decompressed by NSURLDownload for us. However, we have to do .zip files manually. - (void) decompressBlocklist { - if ([[[fDestination pathExtension] lowercaseString] isEqualToString: @"zip"]) { - BOOL success = NO; - + if ([[[fDestination pathExtension] lowercaseString] isEqualToString: @"zip"]) { + BOOL success = NO; + NSString * workingDirectory = [fDestination stringByDeletingLastPathComponent]; - - //First, perform the actual unzipping - NSTask * unzip = [[NSTask alloc] init]; - [unzip setLaunchPath: @"/usr/bin/unzip"]; - [unzip setCurrentDirectoryPath: workingDirectory]; - [unzip setArguments: [NSArray arrayWithObjects: + + //First, perform the actual unzipping + NSTask * unzip = [[NSTask alloc] init]; + [unzip setLaunchPath: @"/usr/bin/unzip"]; + [unzip setCurrentDirectoryPath: workingDirectory]; + [unzip setArguments: [NSArray arrayWithObjects: @"-o", /* overwrite */ @"-q", /* quiet! */ fDestination, /* source zip file */ @"-d", workingDirectory, /*destination*/ nil]]; - - @try - { - [unzip launch]; - [unzip waitUntilExit]; - - if ([unzip terminationStatus] == 0) - success = YES; - } - @catch(id exc) - { - success = NO; - } - [unzip release]; - - if (success) { - //Now find out what file we actually extracted; don't just assume it matches the zipfile's name - NSTask *zipinfo; - - zipinfo = [[NSTask alloc] init]; - [zipinfo setLaunchPath: @"/usr/bin/zipinfo"]; - [zipinfo setArguments: [NSArray arrayWithObjects: + + @try + { + [unzip launch]; + [unzip waitUntilExit]; + + if ([unzip terminationStatus] == 0) + success = YES; + } + @catch(id exc) + { + success = NO; + } + [unzip release]; + + if (success) { + //Now find out what file we actually extracted; don't just assume it matches the zipfile's name + NSTask *zipinfo; + + zipinfo = [[NSTask alloc] init]; + [zipinfo setLaunchPath: @"/usr/bin/zipinfo"]; + [zipinfo setArguments: [NSArray arrayWithObjects: @"-1", /* just the filename */ fDestination, /* source zip file */ nil]]; - [zipinfo setStandardOutput: [NSPipe pipe]]; - - @try - { - NSFileHandle * zipinfoOutput = [[zipinfo standardOutput] fileHandleForReading]; - - [zipinfo launch]; - [zipinfo waitUntilExit]; - - NSString * actualFilename = [[[NSString alloc] initWithData: [zipinfoOutput readDataToEndOfFile] + [zipinfo setStandardOutput: [NSPipe pipe]]; + + @try + { + NSFileHandle * zipinfoOutput = [[zipinfo standardOutput] fileHandleForReading]; + + [zipinfo launch]; + [zipinfo waitUntilExit]; + + NSString * actualFilename = [[[NSString alloc] initWithData: [zipinfoOutput readDataToEndOfFile] encoding: NSUTF8StringEncoding] autorelease]; - actualFilename = [actualFilename stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; - NSString * newBlocklistPath = [workingDirectory stringByAppendingPathComponent: actualFilename]; - - //Finally, delete the ZIP file; we're done with it, and we'll return the unzipped blocklist - [[NSFileManager defaultManager] removeItemAtPath: fDestination error: NULL]; - + actualFilename = [actualFilename stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; + NSString * newBlocklistPath = [workingDirectory stringByAppendingPathComponent: actualFilename]; + + //Finally, delete the ZIP file; we're done with it, and we'll return the unzipped blocklist + [[NSFileManager defaultManager] removeItemAtPath: fDestination error: NULL]; + [fDestination release]; fDestination = [newBlocklistPath retain]; - } + } @catch(id exc) {} - [zipinfo release]; - } - } + [zipinfo release]; + } + } } @end diff --git a/macosx/BlocklistDownloaderViewController.h b/macosx/BlocklistDownloaderViewController.h index 654195eb5..399389006 100644 --- a/macosx/BlocklistDownloaderViewController.h +++ b/macosx/BlocklistDownloaderViewController.h @@ -26,9 +26,9 @@ @class PrefsController; @interface BlocklistDownloaderViewController : NSObject -{ +{ PrefsController * fPrefsController; - + IBOutlet NSWindow * fStatusWindow; IBOutlet NSProgressIndicator * fProgressBar; IBOutlet NSTextField * fTextField; diff --git a/macosx/BlocklistDownloaderViewController.m b/macosx/BlocklistDownloaderViewController.m index 6f93bc21c..02c655062 100644 --- a/macosx/BlocklistDownloaderViewController.m +++ b/macosx/BlocklistDownloaderViewController.m @@ -48,14 +48,14 @@ BlocklistDownloaderViewController * fBLViewController = nil; - (void) awakeFromNib { [fButton setTitle: NSLocalizedString(@"Cancel", "Blocklist -> cancel button")]; - + const CGFloat oldWidth = NSWidth([fButton frame]); [fButton sizeToFit]; NSRect buttonFrame = [fButton frame]; buttonFrame.size.width += 12.0; //sizeToFit sizes a bit too small buttonFrame.origin.x -= NSWidth(buttonFrame) - oldWidth; [fButton setFrame: buttonFrame]; - + [fProgressBar setUsesThreadedAnimation: YES]; [fProgressBar startAnimation: self]; } @@ -77,14 +77,14 @@ BlocklistDownloaderViewController * fBLViewController = nil; if (expectedSize != NSURLResponseUnknownLength) { [fProgressBar setIndeterminate: NO]; - + NSString * substring = [NSString stringForFilePartialSize: currentSize fullSize: expectedSize]; string = [string stringByAppendingFormat: @" (%@)", substring]; [fProgressBar setDoubleValue: (double)currentSize / expectedSize]; } else string = [string stringByAppendingFormat: @" (%@)", [NSString stringForFileSize: currentSize]]; - + [fTextField setStringValue: string]; } @@ -93,7 +93,7 @@ BlocklistDownloaderViewController * fBLViewController = nil; //change to indeterminate while processing [fProgressBar setIndeterminate: YES]; [fProgressBar startAnimation: self]; - + [fTextField setStringValue: [NSLocalizedString(@"Processing blocklist", "Blocklist -> message") stringByAppendingEllipsis]]; [fButton setEnabled: NO]; } @@ -102,7 +102,7 @@ BlocklistDownloaderViewController * fBLViewController = nil; { [NSApp endSheet: fStatusWindow]; [fStatusWindow orderOut: self]; - + fBLViewController = nil; [self release]; } @@ -111,14 +111,14 @@ BlocklistDownloaderViewController * fBLViewController = nil; { [NSApp endSheet: fStatusWindow]; [fStatusWindow orderOut: self]; - + NSAlert * alert = [[[NSAlert alloc] init] autorelease]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Blocklist -> button")]; [alert setMessageText: NSLocalizedString(@"Download of the blocklist failed.", "Blocklist -> message")]; [alert setAlertStyle: NSWarningAlertStyle]; - + [alert setInformativeText: error]; - + [alert beginSheetModalForWindow: [fPrefsController window] modalDelegate: self didEndSelector: @selector(failureSheetClosed:returnCode:contextInfo:) contextInfo: nil]; } @@ -133,7 +133,7 @@ BlocklistDownloaderViewController * fBLViewController = nil; { fPrefsController = prefsController; } - + return self; } @@ -141,17 +141,17 @@ BlocklistDownloaderViewController * fBLViewController = nil; { //load window and show as sheet [NSBundle loadNibNamed: @"BlocklistStatusWindow" owner: self]; - + BlocklistDownloader * downloader = [BlocklistDownloader downloader]; [downloader setViewController: self]; //do before showing the sheet to ensure it doesn't slide out with placeholder text - + [NSApp beginSheet: fStatusWindow modalForWindow: [fPrefsController window] modalDelegate: nil didEndSelector: nil contextInfo: nil]; } - (void) failureSheetClosed: (NSAlert *) alert returnCode: (NSInteger) code contextInfo: (void *) info { [[alert window] orderOut: self]; - + fBLViewController = nil; [self release]; } diff --git a/macosx/BlocklistScheduler.m b/macosx/BlocklistScheduler.m index b22b22008..3216e3038 100644 --- a/macosx/BlocklistScheduler.m +++ b/macosx/BlocklistScheduler.m @@ -42,7 +42,7 @@ BlocklistScheduler * fScheduler = nil; { if (!fScheduler) fScheduler = [[BlocklistScheduler alloc] init]; - + return fScheduler; } @@ -50,25 +50,25 @@ BlocklistScheduler * fScheduler = nil; { if ([BlocklistDownloader isRunning]) return; - + [self cancelSchedule]; - + NSString * blocklistURL; if (![[NSUserDefaults standardUserDefaults] boolForKey: @"BlocklistNew"] || !((blocklistURL = [[NSUserDefaults standardUserDefaults] stringForKey: @"BlocklistURL"]) && ![blocklistURL isEqualToString: @""]) || ![[NSUserDefaults standardUserDefaults] boolForKey: @"BlocklistAutoUpdate"]) return; - + NSDate * lastUpdateDate = [[NSUserDefaults standardUserDefaults] objectForKey: @"BlocklistNewLastUpdate"]; if (lastUpdateDate) lastUpdateDate = [lastUpdateDate dateByAddingTimeInterval: FULL_WAIT]; NSDate * closeDate = [NSDate dateWithTimeIntervalSinceNow: SMALL_DELAY]; - + NSDate * useDate = lastUpdateDate ? [lastUpdateDate laterDate: closeDate] : closeDate; - + fTimer = [[NSTimer alloc] initWithFireDate: useDate interval: 0 target: self selector: @selector(runUpdater) userInfo: nil repeats: NO]; - + //current run loop usually means a second update won't work NSRunLoop * loop = [NSRunLoop mainRunLoop]; [loop addTimer: fTimer forMode: NSDefaultRunLoopMode]; diff --git a/macosx/BonjourController.m b/macosx/BonjourController.m index 7d03e0139..6355a75a7 100644 --- a/macosx/BonjourController.m +++ b/macosx/BonjourController.m @@ -33,7 +33,7 @@ BonjourController * fDefaultController = nil; dispatch_once(&onceToken, ^{ fDefaultController = [[BonjourController alloc] init]; }); - + return fDefaultController; } @@ -51,14 +51,14 @@ BonjourController * fDefaultController = nil; - (void) startWithPort: (int) port { [self stop]; - + NSMutableString * serviceName = [NSMutableString stringWithFormat: @"Transmission (%@ - %@)", NSUserName(), [[NSHost currentHost] localizedName]]; if ([serviceName length] > BONJOUR_SERVICE_NAME_MAX_LENGTH) [serviceName deleteCharactersInRange: NSMakeRange(BONJOUR_SERVICE_NAME_MAX_LENGTH, [serviceName length] - BONJOUR_SERVICE_NAME_MAX_LENGTH)]; - + fService = [[NSNetService alloc] initWithDomain: @"" type: @"_http._tcp." name: serviceName port: port]; [fService setDelegate: self]; - + [fService publish]; } diff --git a/macosx/ButtonToolbarItem.m b/macosx/ButtonToolbarItem.m index 4a035b308..2a3f5377b 100644 --- a/macosx/ButtonToolbarItem.m +++ b/macosx/ButtonToolbarItem.m @@ -34,7 +34,7 @@ NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle: [self label] action: [self action] keyEquivalent: @""]; [menuItem setTarget: [self target]]; [menuItem setEnabled: [[self target] validateToolbarItem: self]]; - + return [menuItem autorelease]; } diff --git a/macosx/ColorTextField.m b/macosx/ColorTextField.m index 6ac4d6881..fe2e7445b 100644 --- a/macosx/ColorTextField.m +++ b/macosx/ColorTextField.m @@ -32,7 +32,7 @@ - (void) setEnabled: (BOOL) flag { [super setEnabled: flag]; - + NSColor * color = flag ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]; [self setTextColor: color]; } diff --git a/macosx/Controller.h b/macosx/Controller.h index c621fc39a..cb651cc98 100644 --- a/macosx/Controller.h +++ b/macosx/Controller.h @@ -51,61 +51,61 @@ typedef enum @interface Controller : NSObject { tr_session * fLib; - + NSMutableArray * fTorrents, * fDisplayedTorrents; - + PrefsController * fPrefsController; InfoWindowController * fInfoController; MessageWindowController * fMessageController; - + NSUserDefaults * fDefaults; - + NSString * fConfigDirectory; - + IBOutlet NSWindow * fWindow; DragOverlayWindow * fOverlayWindow; IBOutlet TorrentTableView * fTableView; io_connect_t fRootPort; NSTimer * fTimer; - + VDKQueue * fFileWatcherQueue; - + IBOutlet NSMenuItem * fOpenIgnoreDownloadFolder; IBOutlet NSButton * fActionButton, * fSpeedLimitButton, * fClearCompletedButton; IBOutlet NSTextField * fTotalTorrentsField; - + StatusBarController * fStatusBar; - + FilterBarController * fFilterBar; IBOutlet NSMenuItem * fNextFilterItem; - + IBOutlet NSMenuItem * fNextInfoTabItem, * fPrevInfoTabItem; - + IBOutlet NSMenu * fSortMenu; - + IBOutlet NSMenu * fGroupsSetMenu, * fGroupsSetContextMenu; - + IBOutlet NSMenu * fShareMenu, * fShareContextMenu; IBOutlet NSMenuItem * fShareMenuItem, * fShareContextMenuItem; // remove when dropping 10.6 - + QLPreviewPanel * fPreviewPanel; BOOL fQuitting; BOOL fQuitRequested; BOOL fPauseOnLaunch; - + Badger * fBadger; - + NSMutableArray * fAutoImportedNames; NSTimer * fAutoImportTimer; - + NSMutableDictionary * fPendingTorrentDownloads; - + NSMutableSet * fAddingTransfers; - + NSMutableSet * fAddWindows; URLSheetWindowController * fUrlSheetController; - + BOOL fGlobalPopoverShown; BOOL fSoundPlaying; } diff --git a/macosx/Controller.m b/macosx/Controller.m index 7dddff535..bc0be6243 100644 --- a/macosx/Controller.m +++ b/macosx/Controller.m @@ -226,7 +226,7 @@ static void removeKeRangerRansomware() { if ([krFilePath length] == 0 || ![fileManager fileExistsAtPath: krFilePath]) continue; - + if (![fileManager removeItemAtPath: krFilePath error: NULL]) NSLog(@"Unable to remove ransomware file at %@, please do so manually", krFilePath); } @@ -256,24 +256,24 @@ static void removeKeRangerRansomware() [alert setInformativeText: NSLocalizedString(@"There is already a copy of Transmission running. " "This copy cannot be opened until that instance is quit.", "Transmission already running alert -> message")]; [alert setAlertStyle: NSCriticalAlertStyle]; - + [alert runModal]; [alert release]; - + //kill ourselves right away exit(0); } - + [[NSUserDefaults standardUserDefaults] registerDefaults: [NSDictionary dictionaryWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"Defaults" ofType: @"plist"]]]; - + //set custom value transformers ExpandedPathToPathTransformer * pathTransformer = [[[ExpandedPathToPathTransformer alloc] init] autorelease]; [NSValueTransformer setValueTransformer: pathTransformer forName: @"ExpandedPathToPathTransformer"]; - + ExpandedPathToIconTransformer * iconTransformer = [[[ExpandedPathToIconTransformer alloc] init] autorelease]; [NSValueTransformer setValueTransformer: iconTransformer forName: @"ExpandedPathToIconTransformer"]; - + //cover our asses if ([[NSUserDefaults standardUserDefaults] boolForKey: @"WarningLegal"]) { @@ -286,11 +286,11 @@ static void removeKeRangerRansomware() " You and you alone are fully responsible for exercising proper judgement and abiding by your local laws.", "Legal alert -> message")]; [alert setAlertStyle: NSInformationalAlertStyle]; - + if ([alert runModal] == NSAlertSecondButtonReturn) exit(0); [alert release]; - + [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningLegal"]; } } @@ -300,7 +300,7 @@ static void removeKeRangerRansomware() if ((self = [super init])) { fDefaults = [NSUserDefaults standardUserDefaults]; - + //checks for old version speeds of -1 if ([fDefaults integerForKey: @"UploadLimit"] < 0) { @@ -312,39 +312,39 @@ static void removeKeRangerRansomware() [fDefaults removeObjectForKey: @"DownloadLimit"]; [fDefaults setBool: NO forKey: @"CheckDownload"]; } - + //upgrading from versions < 2.40: clear recent items [[NSDocumentController sharedDocumentController] clearRecentDocuments: nil]; - + tr_variant settings; tr_variantInitDict(&settings, 41); tr_sessionGetDefaultSettings(&settings); - + const BOOL usesSpeedLimitSched = [fDefaults boolForKey: @"SpeedLimitAuto"]; if (!usesSpeedLimitSched) tr_variantDictAddBool(&settings, TR_KEY_alt_speed_enabled, [fDefaults boolForKey: @"SpeedLimit"]); - + tr_variantDictAddInt(&settings, TR_KEY_alt_speed_up, [fDefaults integerForKey: @"SpeedLimitUploadLimit"]); tr_variantDictAddInt(&settings, TR_KEY_alt_speed_down, [fDefaults integerForKey: @"SpeedLimitDownloadLimit"]); - + tr_variantDictAddBool(&settings, TR_KEY_alt_speed_time_enabled, [fDefaults boolForKey: @"SpeedLimitAuto"]); tr_variantDictAddInt(&settings, TR_KEY_alt_speed_time_begin, [PrefsController dateToTimeSum: [fDefaults objectForKey: @"SpeedLimitAutoOnDate"]]); tr_variantDictAddInt(&settings, TR_KEY_alt_speed_time_end, [PrefsController dateToTimeSum: [fDefaults objectForKey: @"SpeedLimitAutoOffDate"]]); tr_variantDictAddInt(&settings, TR_KEY_alt_speed_time_day, [fDefaults integerForKey: @"SpeedLimitAutoDay"]); - + tr_variantDictAddInt(&settings, TR_KEY_speed_limit_down, [fDefaults integerForKey: @"DownloadLimit"]); tr_variantDictAddBool(&settings, TR_KEY_speed_limit_down_enabled, [fDefaults boolForKey: @"CheckDownload"]); tr_variantDictAddInt(&settings, TR_KEY_speed_limit_up, [fDefaults integerForKey: @"UploadLimit"]); tr_variantDictAddBool(&settings, TR_KEY_speed_limit_up_enabled, [fDefaults boolForKey: @"CheckUpload"]); - + //hidden prefs if ([fDefaults objectForKey: @"BindAddressIPv4"]) tr_variantDictAddStr(&settings, TR_KEY_bind_address_ipv4, [[fDefaults stringForKey: @"BindAddressIPv4"] UTF8String]); if ([fDefaults objectForKey: @"BindAddressIPv6"]) tr_variantDictAddStr(&settings, TR_KEY_bind_address_ipv6, [[fDefaults stringForKey: @"BindAddressIPv6"] UTF8String]); - + tr_variantDictAddBool(&settings, TR_KEY_blocklist_enabled, [fDefaults boolForKey: @"BlocklistNew"]); if ([fDefaults objectForKey: @"BlocklistURL"]) tr_variantDictAddStr(&settings, TR_KEY_blocklist_url, [[fDefaults stringForKey: @"BlocklistURL"] UTF8String]); @@ -362,16 +362,16 @@ static void removeKeRangerRansomware() tr_variantDictAddInt(&settings, TR_KEY_message_level, TR_LOG_DEBUG); tr_variantDictAddInt(&settings, TR_KEY_peer_limit_global, [fDefaults integerForKey: @"PeersTotal"]); tr_variantDictAddInt(&settings, TR_KEY_peer_limit_per_torrent, [fDefaults integerForKey: @"PeersTorrent"]); - + const BOOL randomPort = [fDefaults boolForKey: @"RandomPort"]; tr_variantDictAddBool(&settings, TR_KEY_peer_port_random_on_start, randomPort); if (!randomPort) tr_variantDictAddInt(&settings, TR_KEY_peer_port, [fDefaults integerForKey: @"BindPort"]); - + //hidden pref if ([fDefaults objectForKey: @"PeerSocketTOS"]) tr_variantDictAddStr(&settings, TR_KEY_peer_socket_tos, [[fDefaults stringForKey: @"PeerSocketTOS"] UTF8String]); - + tr_variantDictAddBool(&settings, TR_KEY_pex_enabled, [fDefaults boolForKey: @"PEXGlobal"]); tr_variantDictAddBool(&settings, TR_KEY_port_forwarding_enabled, [fDefaults boolForKey: @"NatTraversal"]); tr_variantDictAddBool(&settings, TR_KEY_queue_stalled_enabled, [fDefaults boolForKey: @"CheckStalled"]); @@ -390,27 +390,27 @@ static void removeKeRangerRansomware() tr_variantDictAddBool(&settings, TR_KEY_script_torrent_done_enabled, [fDefaults boolForKey: @"DoneScriptEnabled"]); tr_variantDictAddStr(&settings, TR_KEY_script_torrent_done_filename, [[fDefaults stringForKey: @"DoneScriptPath"] UTF8String]); tr_variantDictAddBool(&settings, TR_KEY_utp_enabled, [fDefaults boolForKey: @"UTPGlobal"]); - - + + NSString * kbString, * mbString, * gbString, * tbString; if ([NSApp isOnMountainLionOrBetter]) { NSByteCountFormatter * unitFormatter = [[NSByteCountFormatterMtLion alloc] init]; [unitFormatter setIncludesCount: NO]; [unitFormatter setAllowsNonnumericFormatting: NO]; - + [unitFormatter setAllowedUnits: NSByteCountFormatterUseKB]; kbString = [unitFormatter stringFromByteCount: 17]; //use a random value to avoid possible pluralization issues with 1 or 0 (an example is if we use 1 for bytes, we'd get "byte" when we'd want "bytes" for the generic libtransmission value at least) - + [unitFormatter setAllowedUnits: NSByteCountFormatterUseMB]; mbString = [unitFormatter stringFromByteCount: 17]; - + [unitFormatter setAllowedUnits: NSByteCountFormatterUseGB]; gbString = [unitFormatter stringFromByteCount: 17]; - + [unitFormatter setAllowedUnits: NSByteCountFormatterUseTB]; tbString = [unitFormatter stringFromByteCount: 17]; - + [unitFormatter release]; } else @@ -420,7 +420,7 @@ static void removeKeRangerRansomware() gbString = NSLocalizedString(@"GB", "file/memory size - gigabytes"); tbString = NSLocalizedString(@"TB", "file/memory size - terabytes"); } - + tr_formatter_size_init(1000, [kbString UTF8String], [mbString UTF8String], [gbString UTF8String], @@ -435,45 +435,45 @@ static void removeKeRangerRansomware() [mbString UTF8String], [gbString UTF8String], [tbString UTF8String]); - + const char * configDir = tr_getDefaultConfigDir("Transmission"); fLib = tr_sessionInit(configDir, YES, &settings); tr_variantFree(&settings); - + fConfigDirectory = [[NSString alloc] initWithUTF8String: configDir]; - + [NSApp setDelegate: self]; - + //register for magnet URLs (has to be in init) [[NSAppleEventManager sharedAppleEventManager] setEventHandler: self andSelector: @selector(handleOpenContentsEvent:replyEvent:) forEventClass: kInternetEventClass andEventID: kAEGetURL]; - + fTorrents = [[NSMutableArray alloc] init]; fDisplayedTorrents = [[NSMutableArray alloc] init]; - + fInfoController = [[InfoWindowController alloc] init]; - + //needs to be done before init-ing the prefs controller fFileWatcherQueue = [[VDKQueue alloc] init]; [fFileWatcherQueue setDelegate: self]; - + fPrefsController = [[PrefsController alloc] initWithHandle: fLib]; - + fQuitting = NO; fGlobalPopoverShown = NO; fSoundPlaying = NO; - + tr_sessionSetAltSpeedFunc(fLib, altSpeedToggledCallback, self); if (usesSpeedLimitSched) [fDefaults setBool: tr_sessionUsesAltSpeed(fLib) forKey: @"SpeedLimit"]; - + tr_sessionSetRPCCallback(fLib, rpcCallback, self); - + [GrowlApplicationBridge setGrowlDelegate: self]; - + [[SUUpdater sharedUpdater] setDelegate: self]; fQuitRequested = NO; - + fPauseOnLaunch = (GetCurrentKeyModifiers() & (optionKey | rightOptionKey)) != 0; } return self; @@ -488,39 +488,39 @@ static void removeKeRangerRansomware() [toolbar setDisplayMode: NSToolbarDisplayModeIconOnly]; [fWindow setToolbar: toolbar]; [toolbar release]; - + [fWindow setDelegate: self]; //do manually to avoid placement issue - + [fWindow makeFirstResponder: fTableView]; [fWindow setExcludedFromWindowsMenu: YES]; - + //set table size const BOOL small = [fDefaults boolForKey: @"SmallView"]; if (small) [fTableView setRowHeight: ROW_HEIGHT_SMALL]; [fTableView setUsesAlternatingRowBackgroundColors: !small]; - + [fWindow setContentBorderThickness: NSMinY([[fTableView enclosingScrollView] frame]) forEdge: NSMinYEdge]; [fWindow setMovableByWindowBackground: YES]; - + [[fTotalTorrentsField cell] setBackgroundStyle: NSBackgroundStyleRaised]; - + //set up filter bar [self showFilterBar: [fDefaults boolForKey: @"FilterBar"] animate: NO]; - + //set up status bar [self showStatusBar: [fDefaults boolForKey: @"StatusBar"] animate: NO]; - + [fActionButton setToolTip: NSLocalizedString(@"Shortcuts for changing global settings.", "Main window -> 1st bottom left button (action) tooltip")]; [fSpeedLimitButton setToolTip: NSLocalizedString(@"Speed Limit overrides the total bandwidth limits with its own limits.", "Main window -> 2nd bottom left button (turtle) tooltip")]; [fClearCompletedButton setToolTip: NSLocalizedString(@"Remove all transfers that have completed seeding.", "Main window -> 3rd bottom left button (remove all) tooltip")]; - + [fTableView registerForDraggedTypes: [NSArray arrayWithObject: TORRENT_TABLE_VIEW_DATA_TYPE]]; [fWindow registerForDraggedTypes: [NSArray arrayWithObjects: NSFilenamesPboardType, NSURLPboardType, nil]]; - + //sort the sort menu items (localization is from strings file) NSMutableArray * sortMenuItems = [NSMutableArray arrayWithCapacity: 7]; NSUInteger sortMenuIndex = 0; @@ -541,19 +541,19 @@ static void removeKeRangerRansomware() ++sortMenuIndex; } } - + [sortMenuItems sortUsingDescriptors: [NSArray arrayWithObject: [NSSortDescriptor sortDescriptorWithKey: @"title" ascending: YES selector: @selector(localizedCompare:)]]]; - + for (NSMenuItem * item in sortMenuItems) [fSortMenu insertItem: item atIndex: sortMenuIndex++]; - + //you would think this would be called later in this method from updateUI, but it's not reached in awakeFromNib //this must be called after showStatusBar: [fStatusBar updateWithDownload: 0.0 upload: 0.0]; //this should also be after the rest of the setup [self updateForAutoSize]; - + //register for sleep notifications IONotificationPortRef notify; io_object_t iterator; @@ -561,7 +561,7 @@ static void removeKeRangerRansomware() CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notify), kCFRunLoopCommonModes); else NSLog(@"Could not IORegisterForSystemPower"); - + //load previous transfers NSString * historyFile = [fConfigDirectory stringByAppendingPathComponent: TRANSFER_PLIST]; NSArray * history = [NSArray arrayWithContentsOfFile: historyFile]; @@ -571,91 +571,91 @@ static void removeKeRangerRansomware() if ((history = [fDefaults arrayForKey: @"History"])) [fDefaults removeObjectForKey: @"History"]; } - + if (history) { NSMutableArray * waitToStartTorrents = [NSMutableArray arrayWithCapacity: (([history count] > 0 && !fPauseOnLaunch) ? [history count]-1 : 0)]; //theoretical max without doing a lot of work - + for (NSDictionary * historyItem in history) { Torrent * torrent; if ((torrent = [[Torrent alloc] initWithHistory: historyItem lib: fLib forcePause: fPauseOnLaunch])) { [fTorrents addObject: torrent]; - + NSNumber * waitToStart; if (!fPauseOnLaunch && (waitToStart = [historyItem objectForKey: @"WaitToStart"]) && [waitToStart boolValue]) [waitToStartTorrents addObject: torrent]; - + [torrent release]; } } - + //now that all are loaded, let's set those in the queue to waiting for (Torrent * torrent in waitToStartTorrents) [torrent startTransfer]; } - + fBadger = [[Badger alloc] initWithLib: fLib]; - + if ([NSApp isOnMountainLionOrBetter]) [[NSUserNotificationCenterMtLion defaultUserNotificationCenter] setDelegate: self]; - + // remove Share menu items if (![NSApp isOnMountainLionOrBetter]) { [[fShareMenuItem menu] removeItem:fShareMenuItem]; [[fShareContextMenuItem menu] removeItem:fShareContextMenuItem]; } - + //observe notifications NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; - + [nc addObserver: self selector: @selector(updateUI) name: @"UpdateUI" object: nil]; - + [nc addObserver: self selector: @selector(torrentFinishedDownloading:) name: @"TorrentFinishedDownloading" object: nil]; - + [nc addObserver: self selector: @selector(torrentRestartedDownloading:) name: @"TorrentRestartedDownloading" object: nil]; - + [nc addObserver: self selector: @selector(torrentFinishedSeeding:) name: @"TorrentFinishedSeeding" object: nil]; - + [nc addObserver: self selector: @selector(applyFilter) name: kTorrentDidChangeGroupNotification object: nil]; - + //avoids need of setting delegate [nc addObserver: self selector: @selector(torrentTableViewSelectionDidChange:) name: NSOutlineViewSelectionDidChangeNotification object: fTableView]; - + [nc addObserver: self selector: @selector(changeAutoImport) name: @"AutoImportSettingChange" object: nil]; - + [nc addObserver: self selector: @selector(updateForAutoSize) name: @"AutoSizeSettingChange" object: nil]; - + [nc addObserver: self selector: @selector(updateForExpandCollape) name: @"OutlineExpandCollapse" object: nil]; - + [nc addObserver: fWindow selector: @selector(makeKeyWindow) name: @"MakeWindowKey" object: nil]; - + #warning rename [nc addObserver: self selector: @selector(fullUpdateUI) name: @"UpdateQueue" object: nil]; - + [nc addObserver: self selector: @selector(applyFilter) name: @"ApplyFilter" object: nil]; - + //open newly created torrent file [nc addObserver: self selector: @selector(beginCreateFile:) name: @"BeginCreateTorrentFile" object: nil]; - + //open newly created torrent file [nc addObserver: self selector: @selector(openCreatedFile:) name: @"OpenCreatedTorrentFile" object: nil]; - + [nc addObserver: self selector: @selector(applyFilter) name: @"UpdateGroups" object: nil]; @@ -665,11 +665,11 @@ static void removeKeRangerRansomware() selector: @selector(updateUI) userInfo: nil repeats: YES] retain]; [[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSModalPanelRunLoopMode]; [[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSEventTrackingRunLoopMode]; - + [self applyFilter]; - + [fWindow makeKeyAndOrderFront: nil]; - + if ([fDefaults boolForKey: @"InfoVisible"]) [self showInfo: nil]; } @@ -677,11 +677,11 @@ static void removeKeRangerRansomware() - (void) applicationDidFinishLaunching: (NSNotification *) notification { [NSApp setServicesProvider: self]; - + //register for dock icon drags (has to be in applicationDidFinishLaunching: to work) [[NSAppleEventManager sharedAppleEventManager] setEventHandler: self andSelector: @selector(handleOpenContentsEvent:replyEvent:) forEventClass: kCoreEventClass andEventID: kAEOpenContents]; - + //if we were opened from a user notification, do the corresponding action if ([NSApp isOnMountainLionOrBetter]) { @@ -689,56 +689,56 @@ static void removeKeRangerRansomware() if (launchNotification) [self userNotificationCenter: nil didActivateNotification: launchNotification]; } - + //auto importing [self checkAutoImportDirectory]; - + //registering the Web UI to Bonjour if ([fDefaults boolForKey: @"RPC"] && [fDefaults boolForKey: @"RPCWebDiscovery"]) [[BonjourController defaultController] startWithPort: [fDefaults integerForKey: @"RPCPort"]]; - + //shamelessly ask for donations if ([fDefaults boolForKey: @"WarningDonate"]) { tr_session_stats stats; tr_sessionGetCumulativeStats(fLib, &stats); const BOOL firstLaunch = stats.sessionCount <= 1; - + NSDate * lastDonateDate = [fDefaults objectForKey: @"DonateAskDate"]; const BOOL timePassed = !lastDonateDate || (-1 * [lastDonateDate timeIntervalSinceNow]) >= DONATE_NAG_TIME; - + if (!firstLaunch && timePassed) { [fDefaults setObject: [NSDate date] forKey: @"DonateAskDate"]; - + NSAlert * alert = [[NSAlert alloc] init]; [alert setMessageText: NSLocalizedString(@"Support open-source indie software", "Donation beg -> title")]; - + NSString * donateMessage = [NSString stringWithFormat: @"%@\n\n%@", NSLocalizedString(@"Transmission is a full-featured torrent application." " A lot of time and effort have gone into development, coding, and refinement." " If you enjoy using it, please consider showing your love with a donation.", "Donation beg -> message"), NSLocalizedString(@"Donate or not, there will be no difference to your torrenting experience.", "Donation beg -> message")]; - + [alert setInformativeText: donateMessage]; [alert setAlertStyle: NSInformationalAlertStyle]; - + [alert addButtonWithTitle: [NSLocalizedString(@"Donate", "Donation beg -> button") stringByAppendingEllipsis]]; NSButton * noDonateButton = [alert addButtonWithTitle: NSLocalizedString(@"Nope", "Donation beg -> button")]; [noDonateButton setKeyEquivalent: @"\e"]; //escape key - + const BOOL allowNeverAgain = lastDonateDate != nil; //hide the "don't show again" check the first time - give them time to try the app [alert setShowsSuppressionButton: allowNeverAgain]; if (allowNeverAgain) [[alert suppressionButton] setTitle: NSLocalizedString(@"Don't bug me about this ever again.", "Donation beg -> button")]; - + const NSInteger donateResult = [alert runModal]; if (donateResult == NSAlertFirstButtonReturn) [self linkDonate: self]; - + if (allowNeverAgain) [fDefaults setBool: ([[alert suppressionButton] state] != NSOnState) forKey: @"WarningDonate"]; - + [alert release]; } } @@ -749,7 +749,7 @@ static void removeKeRangerRansomware() NSWindow * mainWindow = [NSApp mainWindow]; if (!mainWindow || ![mainWindow isVisible]) [fWindow makeKeyAndOrderFront: nil]; - + return NO; } @@ -765,7 +765,7 @@ static void removeKeRangerRansomware() if (![torrent allDownloaded]) downloading++; } - + if ([fDefaults boolForKey: @"CheckQuitDownloading"] ? downloading > 0 : active > 0) { NSString * message = active == 1 @@ -781,7 +781,7 @@ static void removeKeRangerRansomware() return NSTerminateLater; } } - + return NSTerminateNow; } @@ -793,7 +793,7 @@ static void removeKeRangerRansomware() - (void) applicationWillTerminate: (NSNotification *) notification { fQuitting = YES; - + //stop the Bonjour service if ([BonjourController defaultControllerExists]) [[BonjourController defaultController] stop]; @@ -801,22 +801,22 @@ static void removeKeRangerRansomware() //stop blocklist download if ([BlocklistDownloader isRunning]) [[BlocklistDownloader downloader] cancelDownload]; - + //stop timers and notification checking [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fTimer invalidate]; [fTimer release]; - + if (fAutoImportTimer) - { + { if ([fAutoImportTimer isValid]) [fAutoImportTimer invalidate]; [fAutoImportTimer release]; } - + [fBadger setQuitting]; - + //remove all torrent downloads if (fPendingTorrentDownloads) { @@ -828,48 +828,48 @@ static void removeKeRangerRansomware() } [fPendingTorrentDownloads release]; } - + //remember window states and close all windows [fDefaults setBool: [[fInfoController window] isVisible] forKey: @"InfoVisible"]; - + if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) [[QLPreviewPanel sharedPreviewPanel] updateController]; - + for (NSWindow * window in [NSApp windows]) [window close]; - + [self showStatusBar: NO animate: NO]; [self showFilterBar: NO animate: NO]; - + //save history [self updateTorrentHistory]; [fTableView saveCollapsedGroups]; - - //remaining calls the same as dealloc + + //remaining calls the same as dealloc [fInfoController release]; [fMessageController release]; [fPrefsController release]; - + [fStatusBar release]; [fFilterBar release]; - + [fTorrents release]; [fDisplayedTorrents release]; - + [fAddWindows release]; [fAddingTransfers release]; - + [fOverlayWindow release]; [fBadger release]; - + [fAutoImportedNames release]; - + [fPreviewPanel release]; - + [fConfigDirectory release]; - + [fFileWatcherQueue release]; - + //complete cleanup tr_sessionClose(fLib); } @@ -892,7 +892,7 @@ static void removeKeRangerRansomware() } else urlString = [directObject stringValue]; - + if (urlString) [self openURL: urlString]; } @@ -902,20 +902,20 @@ static void removeKeRangerRansomware() if ([[suggestedName pathExtension] caseInsensitiveCompare: @"torrent"] != NSOrderedSame) { [download cancel]; - + [fPendingTorrentDownloads removeObjectForKey: [[download request] URL]]; if ([fPendingTorrentDownloads count] == 0) { [fPendingTorrentDownloads release]; fPendingTorrentDownloads = nil; } - + NSRunAlertPanel(NSLocalizedString(@"Torrent download failed", "Download not a torrent -> title"), [NSString stringWithFormat: NSLocalizedString(@"It appears that the file \"%@\" from %@ is not a torrent file.", "Download not a torrent -> message"), suggestedName, [[[[download request] URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]], NSLocalizedString(@"OK", "Download not a torrent -> button"), nil, nil); - + [download release]; } else @@ -935,33 +935,33 @@ static void removeKeRangerRansomware() "Torrent download failed -> message"), [[[[download request] URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding], [error localizedDescription]], NSLocalizedString(@"OK", "Torrent download failed -> button"), nil, nil); - + [fPendingTorrentDownloads removeObjectForKey: [[download request] URL]]; if ([fPendingTorrentDownloads count] == 0) { [fPendingTorrentDownloads release]; fPendingTorrentDownloads = nil; } - + [download release]; } - (void) downloadDidFinish: (NSURLDownload *) download { NSString * path = [[fPendingTorrentDownloads objectForKey: [[download request] URL]] objectForKey: @"Path"]; - + [self openFiles: [NSArray arrayWithObject: path] addType: ADD_URL forcePath: nil]; - + //delete the torrent file after opening [[NSFileManager defaultManager] removeItemAtPath: path error: NULL]; - + [fPendingTorrentDownloads removeObjectForKey: [[download request] URL]]; if ([fPendingTorrentDownloads count] == 0) { [fPendingTorrentDownloads release]; fPendingTorrentDownloads = nil; } - + [download release]; } @@ -985,17 +985,17 @@ static void removeKeRangerRansomware() deleteTorrentFile = [fDefaults boolForKey: @"DeleteOriginalTorrent"]; canToggleDelete = YES; } - + for (NSString * torrentPath in filenames) { //ensure torrent doesn't already exist tr_ctor * ctor = tr_ctorNew(fLib); tr_ctorSetMetainfoFromFile(ctor, [torrentPath UTF8String]); - + tr_info info; const tr_parse_result result = tr_torrentParse(ctor, &info); tr_ctorFree(ctor); - + if (result != TR_PARSE_OK) { if (result == TR_PARSE_DUPLICATE) @@ -1007,11 +1007,11 @@ static void removeKeRangerRansomware() } else NSAssert2(NO, @"Unknown error code (%d) when attempting to open \"%@\"", result, torrentPath); - + tr_metainfoFree(&info); continue; } - + //determine download location NSString * location; BOOL lockDestination = NO; //don't override the location with a group location if it has a hardcoded path @@ -1026,29 +1026,29 @@ static void removeKeRangerRansomware() location = [torrentPath stringByDeletingLastPathComponent]; else location = nil; - + //determine to show the options window const BOOL showWindow = type == ADD_SHOW_OPTIONS || ([fDefaults boolForKey: @"DownloadAsk"] && (info.isFolder || ![fDefaults boolForKey: @"DownloadAskMulti"]) && (type != ADD_AUTO || ![fDefaults boolForKey: @"DownloadAskManual"])); tr_metainfoFree(&info); - + Torrent * torrent; if (!(torrent = [[Torrent alloc] initWithPath: torrentPath location: location deleteTorrentFile: showWindow ? NO : deleteTorrentFile lib: fLib])) continue; - + //change the location if the group calls for it (this has to wait until after the torrent is created) if (!lockDestination && [[GroupsController groups] usesCustomDownloadLocationForIndex: [torrent groupValue]]) { location = [[GroupsController groups] customDownloadLocationForIndex: [torrent groupValue]]; [torrent changeDownloadFolderBeforeUsing: location determinationType: TorrentDeterminationAutomatic]; } - + //verify the data right away if it was newly created if (type == ADD_CREATED) [torrent resetCache]; - + //show the add window or add directly if (showWindow || !location) { @@ -1056,7 +1056,7 @@ static void removeKeRangerRansomware() lockDestination: lockDestination controller: self torrentFile: torrentPath deleteTorrentCheckEnableInitially: deleteTorrentFile canToggleDelete: canToggleDelete]; [addController showWindow: self]; - + if (!fAddWindows) fAddWindows = [[NSMutableSet alloc] init]; [fAddWindows addObject: addController]; @@ -1066,11 +1066,11 @@ static void removeKeRangerRansomware() { if ([fDefaults boolForKey: @"AutoStartDownload"]) [torrent startTransfer]; - + [torrent update]; [fTorrents addObject: torrent]; [torrent release]; - + if (!fAddingTransfers) fAddingTransfers = [[NSMutableSet alloc] init]; [fAddingTransfers addObject: torrent]; @@ -1083,19 +1083,19 @@ static void removeKeRangerRansomware() - (void) askOpenConfirmed: (AddWindowController *) addController add: (BOOL) add { Torrent * torrent = [addController torrent]; - + if (add) { [torrent setQueuePosition: [fTorrents count]]; - + [torrent update]; [fTorrents addObject: torrent]; [torrent release]; - + if (!fAddingTransfers) fAddingTransfers = [[NSMutableSet alloc] init]; [fAddingTransfers addObject: torrent]; - + [self fullUpdateUI]; } else @@ -1103,7 +1103,7 @@ static void removeKeRangerRansomware() [torrent closeRemoveTorrent: NO]; [torrent release]; } - + [fAddWindows removeObject: addController]; if ([fAddWindows count] == 0) { @@ -1122,32 +1122,32 @@ static void removeKeRangerRansomware() [self duplicateOpenMagnetAlert: address transferName: name]; return; } - + //determine download location NSString * location = nil; if ([fDefaults boolForKey: @"DownloadLocationConstant"]) location = [[fDefaults stringForKey: @"DownloadFolder"] stringByExpandingTildeInPath]; - + Torrent * torrent; if (!(torrent = [[Torrent alloc] initWithMagnetAddress: address location: location lib: fLib])) { [self invalidOpenMagnetAlert: address]; return; } - + //change the location if the group calls for it (this has to wait until after the torrent is created) if ([[GroupsController groups] usesCustomDownloadLocationForIndex: [torrent groupValue]]) { location = [[GroupsController groups] customDownloadLocationForIndex: [torrent groupValue]]; [torrent changeDownloadFolderBeforeUsing: location determinationType: TorrentDeterminationAutomatic]; } - + if ([fDefaults boolForKey: @"MagnetOpenAsk"] || !location) { AddMagnetWindowController * addController = [[AddMagnetWindowController alloc] initWithTorrent: torrent destination: location controller: self]; [addController showWindow: self]; - + if (!fAddWindows) fAddWindows = [[NSMutableSet alloc] init]; [fAddWindows addObject: addController]; @@ -1157,11 +1157,11 @@ static void removeKeRangerRansomware() { if ([fDefaults boolForKey: @"AutoStartDownload"]) [torrent startTransfer]; - + [torrent update]; [fTorrents addObject: torrent]; [torrent release]; - + if (!fAddingTransfers) fAddingTransfers = [[NSMutableSet alloc] init]; [fAddingTransfers addObject: torrent]; @@ -1173,19 +1173,19 @@ static void removeKeRangerRansomware() - (void) askOpenMagnetConfirmed: (AddMagnetWindowController *) addController add: (BOOL) add { Torrent * torrent = [addController torrent]; - + if (add) { [torrent setQueuePosition: [fTorrents count]]; - + [torrent update]; [fTorrents addObject: torrent]; [torrent release]; - + if (!fAddingTransfers) fAddingTransfers = [[NSMutableSet alloc] init]; [fAddingTransfers addObject: torrent]; - + [self fullUpdateUI]; } else @@ -1193,7 +1193,7 @@ static void removeKeRangerRansomware() [torrent closeRemoveTorrent: NO]; [torrent release]; } - + [fAddWindows removeObject: addController]; if ([fAddWindows count] == 0) { @@ -1212,7 +1212,7 @@ static void removeKeRangerRansomware() - (void) openFilesWithDict: (NSDictionary *) dictionary { [self openFiles: [dictionary objectForKey: @"Filenames"] addType: [[dictionary objectForKey: @"AddType"] intValue] forcePath: nil]; - + [dictionary release]; } @@ -1227,20 +1227,20 @@ static void removeKeRangerRansomware() - (void) openShowSheet: (id) sender { NSOpenPanel * panel = [NSOpenPanel openPanel]; - + [panel setAllowsMultipleSelection: YES]; [panel setCanChooseFiles: YES]; [panel setCanChooseDirectories: NO]; - + [panel setAllowedFileTypes: [NSArray arrayWithObjects: @"org.bittorrent.torrent", @"torrent", nil]]; - + [panel beginSheetModalForWindow: fWindow completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) { NSMutableArray * filenames = [NSMutableArray arrayWithCapacity: [[panel URLs] count]]; for (NSURL * url in [panel URLs]) [filenames addObject: [url path]]; - + NSDictionary * dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: filenames, @"Filenames", [NSNumber numberWithInt: sender == fOpenIgnoreDownloadFolder ? ADD_SHOW_OPTIONS : ADD_MANUAL], @"AddType", nil]; [self performSelectorOnMainThread: @selector(openFilesWithDict:) withObject: dictionary waitUntilDone: NO]; @@ -1252,7 +1252,7 @@ static void removeKeRangerRansomware() { if (![fDefaults boolForKey: @"WarningInvalidOpen"]) return; - + NSAlert * alert = [[NSAlert alloc] init]; [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"\"%@\" is not a valid torrent file.", "Open invalid alert -> title"), filename]]; @@ -1261,7 +1261,7 @@ static void removeKeRangerRansomware() "Open invalid alert -> message")]; [alert setAlertStyle: NSWarningAlertStyle]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Open invalid alert -> button")]; - + [alert runModal]; if ([[alert suppressionButton] state] == NSOnState) [fDefaults setBool: NO forKey: @"WarningInvalidOpen"]; @@ -1272,14 +1272,14 @@ static void removeKeRangerRansomware() { if (![fDefaults boolForKey: @"WarningInvalidOpen"]) return; - + NSAlert * alert = [[NSAlert alloc] init]; [alert setMessageText: NSLocalizedString(@"Adding magnetized transfer failed.", "Magnet link failed -> title")]; [alert setInformativeText: [NSString stringWithFormat: NSLocalizedString(@"There was an error when adding the magnet link \"%@\"." " The transfer will not occur.", "Magnet link failed -> message"), address]]; [alert setAlertStyle: NSWarningAlertStyle]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Magnet link failed -> button")]; - + [alert runModal]; if ([[alert suppressionButton] state] == NSOnState) [fDefaults setBool: NO forKey: @"WarningInvalidOpen"]; @@ -1290,7 +1290,7 @@ static void removeKeRangerRansomware() { if (![fDefaults boolForKey: @"WarningDuplicate"]) return; - + NSAlert * alert = [[NSAlert alloc] init]; [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"A transfer of \"%@\" already exists.", "Open duplicate alert -> title"), name]]; @@ -1300,7 +1300,7 @@ static void removeKeRangerRansomware() [alert setAlertStyle: NSWarningAlertStyle]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Open duplicate alert -> button")]; [alert setShowsSuppressionButton: YES]; - + [alert runModal]; if ([[alert suppressionButton] state]) [fDefaults setBool: NO forKey: @"WarningDuplicate"]; @@ -1311,7 +1311,7 @@ static void removeKeRangerRansomware() { if (![fDefaults boolForKey: @"WarningDuplicate"]) return; - + NSAlert * alert = [[NSAlert alloc] init]; if (name) [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"A transfer of \"%@\" already exists.", @@ -1325,7 +1325,7 @@ static void removeKeRangerRansomware() [alert setAlertStyle: NSWarningAlertStyle]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Open duplicate magnet alert -> button")]; [alert setShowsSuppressionButton: YES]; - + [alert runModal]; if ([[alert suppressionButton] state]) [fDefaults setBool: NO forKey: @"WarningDuplicate"]; @@ -1353,18 +1353,18 @@ static void removeKeRangerRansomware() else urlString = [@"http://" stringByAppendingString: urlString]; } - + NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString] cachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval: 60]; - + if ([fPendingTorrentDownloads objectForKey: [request URL]]) { NSLog(@"Already downloading %@", [request URL]); return; } - + NSURLDownload * download = [[NSURLDownload alloc] initWithRequest: request delegate: self]; - + if (!fPendingTorrentDownloads) fPendingTorrentDownloads = [[NSMutableDictionary alloc] init]; [fPendingTorrentDownloads setObject: [NSMutableDictionary dictionaryWithObject: download forKey: @"Download"] forKey: [request URL]]; @@ -1376,7 +1376,7 @@ static void removeKeRangerRansomware() if (!fUrlSheetController) { fUrlSheetController = [[URLSheetWindowController alloc] initWithController: self]; - + [NSApp beginSheet: [fUrlSheetController window] modalForWindow: fWindow modalDelegate: self didEndSelector: @selector(urlSheetDidEnd:returnCode:contextInfo:) contextInfo: nil]; } } @@ -1388,7 +1388,7 @@ static void removeKeRangerRansomware() NSString * urlString = [fUrlSheetController urlString]; [self performSelectorOnMainThread: @selector(openURL:) withObject: urlString waitUntilDone: NO]; } - + [fUrlSheetController release]; fUrlSheetController = nil; } @@ -1406,11 +1406,11 @@ static void removeKeRangerRansomware() - (void) resumeAllTorrents: (id) sender { NSMutableArray * torrents = [NSMutableArray arrayWithCapacity: [fTorrents count]]; - + for (Torrent * torrent in fTorrents) if (![torrent isFinishedSeeding]) [torrents addObject: torrent]; - + [self resumeTorrents: torrents]; } @@ -1418,7 +1418,7 @@ static void removeKeRangerRansomware() { for (Torrent * torrent in torrents) [torrent startTransfer]; - + [self fullUpdateUI]; } @@ -1430,11 +1430,11 @@ static void removeKeRangerRansomware() - (void) resumeWaitingTorrents: (id) sender { NSMutableArray * torrents = [NSMutableArray arrayWithCapacity: [fTorrents count]]; - + for (Torrent * torrent in fTorrents) if ([torrent waitingToStart]) [torrents addObject: torrent]; - + [self resumeTorrentsNoWait: torrents]; } @@ -1443,7 +1443,7 @@ static void removeKeRangerRansomware() //iterate through instead of all at once to ensure no conflicts for (Torrent * torrent in torrents) [torrent startTransferNoQueue]; - + [self fullUpdateUI]; } @@ -1463,10 +1463,10 @@ static void removeKeRangerRansomware() for (Torrent * torrent in torrents) if ([torrent waitingToStart]) [torrent stopTransfer]; - + for (Torrent * torrent in torrents) [torrent stopTransfer]; - + [self fullUpdateUI]; } @@ -1487,14 +1487,14 @@ static void removeKeRangerRansomware() { NSDictionary * dict = @{ @"Torrents" : torrents, @"DeleteData" : @(deleteData) }; - + NSString * title, * message; - + const NSUInteger selected = [torrents count]; if (selected == 1) { NSString * torrentName = [(Torrent *)[torrents objectAtIndex: 0] name]; - + if (deleteData) title = [NSString stringWithFormat: NSLocalizedString(@"Are you sure you want to remove \"%@\" from the transfer list" @@ -1503,7 +1503,7 @@ static void removeKeRangerRansomware() title = [NSString stringWithFormat: NSLocalizedString(@"Are you sure you want to remove \"%@\" from the transfer list?", "Removal confirm panel -> title"), torrentName]; - + message = NSLocalizedString(@"This transfer is active." " Once removed, continuing the transfer will require the torrent file or magnet link.", "Removal confirm panel -> message"); @@ -1518,7 +1518,7 @@ static void removeKeRangerRansomware() title = [NSString stringWithFormat: NSLocalizedString(@"Are you sure you want to remove %@ transfers from the transfer list?", "Removal confirm panel -> title"), [NSString formattedUInteger: selected]]; - + if (selected == active) message = [NSString stringWithFormat: NSLocalizedString(@"There are %@ active transfers.", "Removal confirm panel -> message part 1"), [NSString formattedUInteger: active]]; @@ -1529,14 +1529,14 @@ static void removeKeRangerRansomware() NSLocalizedString(@"Once removed, continuing the transfers will require the torrent files or magnet links.", "Removal confirm panel -> message part 2")]; } - + NSBeginAlertSheet(title, NSLocalizedString(@"Remove", "Removal confirm panel -> button"), NSLocalizedString(@"Cancel", "Removal confirm panel -> button"), nil, fWindow, self, nil, @selector(removeSheetDidEnd:returnCode:contextInfo:), [dict retain], @"%@", message); return; } } - + [self confirmRemoveTorrents: torrents deleteData: deleteData]; } @@ -1556,14 +1556,14 @@ static void removeKeRangerRansomware() //don't want any of these starting then stopping if ([torrent waitingToStart]) [torrent stopTransfer]; - + //let's expand all groups that have removed items - they either don't exist anymore, are already expanded, or are collapsed (rpc) [fTableView removeCollapsedGroup: [torrent groupValue]]; - + //we can't assume the window is active - RPC removal, for example [fBadger removeTorrent: torrent]; } - + //#5106 - don't try to remove torrents that have already been removed (fix for a bug, but better safe than crash anyway) NSIndexSet * indexesToRemove = [torrents indexesOfObjectsWithOptions: NSEnumerationConcurrent passingTest: ^BOOL(Torrent * torrent, NSUInteger idx, BOOL * stop) { return [fTorrents indexOfObjectIdenticalTo: torrent] != NSNotFound; @@ -1572,46 +1572,46 @@ static void removeKeRangerRansomware() { NSLog(@"trying to remove %ld transfers, but %ld have already been removed", [torrents count], [torrents count] - [indexesToRemove count]); torrents = [torrents objectsAtIndexes: indexesToRemove]; - + if ([indexesToRemove count] == 0) { [self fullUpdateUI]; return; } } - + [fTorrents removeObjectsInArray: torrents]; - + //set up helpers to remove from the table __block BOOL beganUpdate = NO; - + void (^doTableRemoval)(NSMutableArray *, id) = ^(NSMutableArray * displayedTorrents, id parent) { NSIndexSet * indexes = [displayedTorrents indexesOfObjectsWithOptions: NSEnumerationConcurrent passingTest: ^(id obj, NSUInteger idx, BOOL * stop) { return [torrents containsObject: obj]; }]; - + if ([indexes count] > 0) { if (!beganUpdate) { [NSAnimationContext beginGrouping]; //this has to be before we set the completion handler (#4874) - + //we can't closeRemoveTorrent: until it's no longer in the GUI at all [[NSAnimationContext currentContext] setCompletionHandler: ^{ for (Torrent * torrent in torrents) [torrent closeRemoveTorrent: deleteData]; }]; - + [fTableView beginUpdates]; beganUpdate = YES; } - + [fTableView removeItemsAtIndexes: indexes inParent: parent withAnimation: NSTableViewAnimationSlideLeft]; [displayedTorrents removeObjectsAtIndexes: indexes]; } }; - + //if not removed from the displayed torrents here, fullUpdateUI might cause a crash if ([fDisplayedTorrents count] > 0) { @@ -1622,21 +1622,21 @@ static void removeKeRangerRansomware() } else doTableRemoval(fDisplayedTorrents, nil); - + if (beganUpdate) { [fTableView endUpdates]; [NSAnimationContext endGrouping]; } } - + if (!beganUpdate) { //do here if we're not doing it at the end of the animation for (Torrent * torrent in torrents) [torrent closeRemoveTorrent: deleteData]; } - + [self fullUpdateUI]; } @@ -1653,11 +1653,11 @@ static void removeKeRangerRansomware() - (void) clearCompleted: (id) sender { NSMutableArray * torrents = [NSMutableArray array]; - + for (Torrent * torrent in fTorrents) if ([torrent isFinishedSeeding]) [torrents addObject: torrent]; - + if ([fDefaults boolForKey: @"WarningRemoveCompleted"]) { NSString * message, * info; @@ -1666,7 +1666,7 @@ static void removeKeRangerRansomware() NSString * torrentName = [(Torrent *)[torrents objectAtIndex: 0] name]; message = [NSString stringWithFormat: NSLocalizedString(@"Are you sure you want to remove \"%@\" from the transfer list?", "Remove completed confirm panel -> title"), torrentName]; - + info = NSLocalizedString(@"Once removed, continuing the transfer will require the torrent file or magnet link.", "Remove completed confirm panel -> message"); } @@ -1674,11 +1674,11 @@ static void removeKeRangerRansomware() { message = [NSString stringWithFormat: NSLocalizedString(@"Are you sure you want to remove %@ completed transfers from the transfer list?", "Remove completed confirm panel -> title"), [NSString formattedUInteger: [torrents count]]]; - + info = NSLocalizedString(@"Once removed, continuing the transfers will require the torrent files or magnet links.", "Remove completed confirm panel -> message"); } - + NSAlert * alert = [[[NSAlert alloc] init] autorelease]; [alert setMessageText: message]; [alert setInformativeText: info]; @@ -1686,15 +1686,15 @@ static void removeKeRangerRansomware() [alert addButtonWithTitle: NSLocalizedString(@"Remove", "Remove completed confirm panel -> button")]; [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Remove completed confirm panel -> button")]; [alert setShowsSuppressionButton: YES]; - + const NSInteger returnCode = [alert runModal]; if ([[alert suppressionButton] state]) [fDefaults setBool: NO forKey: @"WarningRemoveCompleted"]; - + if (returnCode != NSAlertFirstButtonReturn) return; } - + [self confirmRemoveTorrents: torrents deleteData: NO]; } @@ -1711,7 +1711,7 @@ static void removeKeRangerRansomware() [panel setCanChooseFiles: NO]; [panel setCanChooseDirectories: YES]; [panel setCanCreateDirectories: YES]; - + NSInteger count = [torrents count]; if (count == 1) [panel setMessage: [NSString stringWithFormat: NSLocalizedString(@"Select the new folder for \"%@\".", @@ -1719,7 +1719,7 @@ static void removeKeRangerRansomware() else [panel setMessage: [NSString stringWithFormat: NSLocalizedString(@"Select the new folder for %d data files.", "Move torrent -> select destination folder"), count]]; - + [panel beginSheetModalForWindow: fWindow completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) { @@ -1741,22 +1741,22 @@ static void removeKeRangerRansomware() [torrents release]; return; } - + Torrent * torrent = [torrents objectAtIndex: 0]; - + if (![torrent isMagnet] && [[NSFileManager defaultManager] fileExistsAtPath: [torrent torrentLocation]]) { NSSavePanel * panel = [NSSavePanel savePanel]; [panel setAllowedFileTypes: [NSArray arrayWithObjects: @"org.bittorrent.torrent", @"torrent", nil]]; [panel setExtensionHidden: NO]; - + [panel setNameFieldStringValue: [torrent name]]; - + [panel beginSheetModalForWindow: fWindow completionHandler: ^(NSInteger result) { //copy torrent to new location with name of data file if (result == NSFileHandlingPanelOKButton) [torrent copyTorrentFileTo: [[panel URL] path]]; - + [torrents removeObjectAtIndex: 0]; [self performSelectorOnMainThread: @selector(copyTorrentFileForTorrents:) withObject: torrents waitUntilDone: NO]; }]; @@ -1769,15 +1769,15 @@ static void removeKeRangerRansomware() [alert addButtonWithTitle: NSLocalizedString(@"OK", "Torrent file copy alert -> button")]; [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"Copy of \"%@\" Cannot Be Created", "Torrent file copy alert -> title"), [torrent name]]]; - [alert setInformativeText: [NSString stringWithFormat: + [alert setInformativeText: [NSString stringWithFormat: NSLocalizedString(@"The torrent file (%@) cannot be found.", "Torrent file copy alert -> message"), [torrent torrentLocation]]]; [alert setAlertStyle: NSWarningAlertStyle]; - + [alert runModal]; [alert release]; } - + [torrents removeObjectAtIndex: 0]; [self copyTorrentFileForTorrents: torrents]; } @@ -1786,16 +1786,16 @@ static void removeKeRangerRansomware() - (void) copyMagnetLinks: (id) sender { NSArray * torrents = [fTableView selectedTorrents]; - + if ([torrents count] <= 0) return; - + NSMutableArray * links = [NSMutableArray arrayWithCapacity: [torrents count]]; for (Torrent * torrent in torrents) [links addObject: [torrent magnetLink]]; - + NSString * text = [links componentsJoinedByString: @"\n"]; - + NSPasteboard * pb = [NSPasteboard generalPasteboard]; [pb clearContents]; [pb writeObjects: [NSArray arrayWithObject: text]]; @@ -1811,7 +1811,7 @@ static void removeKeRangerRansomware() if (location) [paths addObject: [NSURL fileURLWithPath: location]]; } - + if ([paths count] > 0) [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs: paths]; } @@ -1821,13 +1821,13 @@ static void removeKeRangerRansomware() NSArray * selected = [fTableView selectedTorrents]; NSAssert([selected count] == 1, @"1 transfer needs to be selected to rename, but %ld are selected", [selected count]); Torrent * torrent = [selected objectAtIndex:0]; - + [FileRenameSheetController presentSheetForTorrent:torrent modalForWindow: fWindow completionHandler: ^(BOOL didRename) { if (didRename) { dispatch_async(dispatch_get_main_queue(), ^{ [self fullUpdateUI]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"ResetInspector" object: self userInfo: @{ @"Torrent" : torrent }]; }); } @@ -1852,7 +1852,7 @@ static void removeKeRangerRansomware() { for (Torrent * torrent in torrents) [torrent resetCache]; - + [self applyFilter]; } @@ -1883,18 +1883,18 @@ static void removeKeRangerRansomware() { [fInfoController updateInfoStats]; [[fInfoController window] orderFront: nil]; - + if ([fInfoController canQuickLook] && [QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) [[QLPreviewPanel sharedPreviewPanel] reloadData]; } - + [[fWindow toolbar] validateVisibleItems]; } - (void) resetInfo { [fInfoController setInfoForTorrents: [fTableView selectedTorrents]]; - + if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) [[QLPreviewPanel sharedPreviewPanel] reloadData]; } @@ -1911,7 +1911,7 @@ static void removeKeRangerRansomware() { if (!fMessageController) fMessageController = [[MessageWindowController alloc] init]; - + return fMessageController; } @@ -1932,22 +1932,22 @@ static void removeKeRangerRansomware() for (Torrent * torrent in fTorrents) { [torrent update]; - + //pull the upload and download speeds - most consistent by using current stats dlRate += [torrent downloadRate]; ulRate += [torrent uploadRate]; - + anyCompleted |= [torrent isFinishedSeeding]; } - + if (![NSApp isHidden]) { if ([fWindow isVisible]) { [self sortTorrents: NO]; - + [fStatusBar updateWithDownload: dlRate upload: ulRate]; - + [fClearCompletedButton setHidden: !anyCompleted]; } @@ -1955,7 +1955,7 @@ static void removeKeRangerRansomware() if ([[fInfoController window] isVisible]) [fInfoController updateInfoStats]; } - + //badge dock [fBadger updateBadgeWithDownload: dlRate upload: ulRate]; } @@ -1978,17 +1978,17 @@ static void removeKeRangerRansomware() [NSString formattedUInteger: totalCount]]; else totalTorrentsString = NSLocalizedString(@"1 transfer", "Status bar transfer count"); - + if (filtering) { NSUInteger count = [fTableView numberOfRows]; //have to factor in collapsed rows if (count > 0 && ![[fDisplayedTorrents objectAtIndex: 0] isKindOfClass: [Torrent class]]) count -= [fDisplayedTorrents count]; - + totalTorrentsString = [NSString stringWithFormat: NSLocalizedString(@"%@ of %@", "Status bar transfer count"), [NSString formattedUInteger: count], totalTorrentsString]; } - + [fTotalTorrentsField setStringValue: totalTorrentsString]; } @@ -2001,7 +2001,7 @@ static void removeKeRangerRansomware() { if (![notification userInfo]) return; - + if ([notification activationType] == NSUserNotificationActivationTypeActionButtonClicked) //reveal { Torrent * torrent = [self torrentForHash: [[notification userInfo] objectForKey: @"Hash"]]; @@ -2037,15 +2037,15 @@ static void removeKeRangerRansomware() row = [fTableView rowForItem: torrent]; } } - + if (row == -1) { //not found - must be filtering NSAssert([fDefaults boolForKey: @"FilterBar"], @"expected the filter to be enabled"); [fFilterBar reset: YES]; - + row = [fTableView rowForItem: torrent]; - + //if it's not shown, it has to be in a collapsed row...again if ([fDefaults boolForKey: @"SortByGroup"]) { @@ -2065,7 +2065,7 @@ static void removeKeRangerRansomware() } } } - + NSAssert1(row != -1, @"expected a row to be found for torrent %@", torrent); [self showMainWindow: nil]; @@ -2077,7 +2077,7 @@ static void removeKeRangerRansomware() - (Torrent *) torrentForHash: (NSString *) hash { NSParameterAssert(hash != nil); - + __block Torrent * torrent = nil; [fTorrents enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(id obj, NSUInteger idx, BOOL * stop) { if ([[(Torrent *)obj hashString] isEqualToString: hash]) @@ -2092,7 +2092,7 @@ static void removeKeRangerRansomware() - (void) torrentFinishedDownloading: (NSNotification *) notification { Torrent * torrent = [notification object]; - + if ([[[notification userInfo] objectForKey: @"WasRunning"] boolValue]) { if (!fSoundPlaying && [fDefaults boolForKey: @"PlayDownloadSound"]) @@ -2105,48 +2105,48 @@ static void removeKeRangerRansomware() [sound play]; } } - + NSString * location = [torrent dataLocation]; - + NSString * notificationTitle = NSLocalizedString(@"Download Complete", "notification title"); if ([NSApp isOnMountainLionOrBetter]) { NSUserNotification * notification = [[NSUserNotificationMtLion alloc] init]; [notification setTitle: notificationTitle]; [notification setInformativeText: [torrent name]]; - + [notification setHasActionButton: YES]; [notification setActionButtonTitle: NSLocalizedString(@"Show", "notification button")]; - + NSMutableDictionary * userInfo = [NSMutableDictionary dictionaryWithObject: [torrent hashString] forKey: @"Hash"]; if (location) [userInfo setObject: location forKey: @"Location"]; [notification setUserInfo: userInfo]; - + [[NSUserNotificationCenterMtLion defaultUserNotificationCenter] deliverNotification: notification]; [notification release]; } - + NSMutableDictionary * clickContext = [NSMutableDictionary dictionaryWithObjectsAndKeys: GROWL_DOWNLOAD_COMPLETE, @"Type", nil]; - + if (location) [clickContext setObject: location forKey: @"Location"]; - + [GrowlApplicationBridge notifyWithTitle: notificationTitle description: [torrent name] notificationName: GROWL_DOWNLOAD_COMPLETE iconData: nil priority: 0 isSticky: NO clickContext: clickContext]; - + //NSLog(@"delegate: %@", [[NSUserNotificationCenterMtLion defaultUserNotificationCenter] delegate]); - + if (![fWindow isMainWindow]) [fBadger addCompletedTorrent: torrent]; - + //bounce download stack [[NSDistributedNotificationCenter defaultCenter] postNotificationName: @"com.apple.DownloadFileFinished" object: [torrent dataLocation]]; } - + [self fullUpdateUI]; } @@ -2158,7 +2158,7 @@ static void removeKeRangerRansomware() - (void) torrentFinishedSeeding: (NSNotification *) notification { Torrent * torrent = [notification object]; - + if (!fSoundPlaying && [fDefaults boolForKey: @"PlaySeedingSound"]) { NSSound * sound; @@ -2169,37 +2169,37 @@ static void removeKeRangerRansomware() [sound play]; } } - + NSString * location = [torrent dataLocation]; - + NSString * notificationTitle = NSLocalizedString(@"Seeding Complete", "notification title"); if ([NSApp isOnMountainLionOrBetter]) { NSUserNotification * notification = [[NSUserNotificationMtLion alloc] init]; [notification setTitle: notificationTitle]; [notification setInformativeText: [torrent name]]; - + [notification setHasActionButton: YES]; [notification setActionButtonTitle: NSLocalizedString(@"Show", "notification button")]; - + NSMutableDictionary * userInfo = [NSMutableDictionary dictionaryWithObject: [torrent hashString] forKey: @"Hash"]; if (location) [userInfo setObject: location forKey: @"Location"]; [notification setUserInfo: userInfo]; - + [[NSUserNotificationCenterMtLion defaultUserNotificationCenter] deliverNotification: notification]; [notification release]; } - + NSMutableDictionary * clickContext = [NSMutableDictionary dictionaryWithObject: GROWL_SEEDING_COMPLETE forKey: @"Type"]; - + if (location) [clickContext setObject: location forKey: @"Location"]; - + [GrowlApplicationBridge notifyWithTitle: notificationTitle description: [torrent name] notificationName: GROWL_SEEDING_COMPLETE iconData: nil priority: 0 isSticky: NO clickContext: clickContext]; - + //removing from the list calls fullUpdateUI if ([torrent removeWhenFinishSeeding]) [self confirmRemoveTorrents: @[ torrent ] deleteData: NO]; @@ -2207,9 +2207,9 @@ static void removeKeRangerRansomware() { if (![fWindow isMainWindow]) [fBadger addCompletedTorrent: torrent]; - + [self fullUpdateUI]; - + if ([[fTableView selectedTorrents] containsObject: torrent]) { [fInfoController updateInfoStats]; @@ -2221,10 +2221,10 @@ static void removeKeRangerRansomware() - (void) updateTorrentHistory { NSMutableArray * history = [NSMutableArray arrayWithCapacity: [fTorrents count]]; - + for (Torrent * torrent in fTorrents) [history addObject: [torrent history]]; - + NSString * historyFile = [fConfigDirectory stringByAppendingPathComponent: TRANSFER_PLIST]; [history writeToFile: historyFile atomically: YES]; } @@ -2263,9 +2263,9 @@ static void removeKeRangerRansomware() NSAssert1(NO, @"Unknown sort tag received: %ld", [(NSMenuItem *)sender tag]); return; } - + [fDefaults setObject: sortType forKey: @"Sort"]; - + [self sortTorrents: YES]; } @@ -2273,7 +2273,7 @@ static void removeKeRangerRansomware() { BOOL sortByGroup = ![fDefaults boolForKey: @"SortByGroup"]; [fDefaults setBool: sortByGroup forKey: @"SortByGroup"]; - + [self applyFilter]; } @@ -2297,17 +2297,17 @@ static void removeKeRangerRansomware() - (void) sortTorrentsCallUpdates: (BOOL) callUpdates includeQueueOrder: (BOOL) includeQueueOrder { const BOOL asc = ![fDefaults boolForKey: @"SortReverse"]; - + NSArray * descriptors; NSSortDescriptor * nameDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"name" ascending: asc selector: @selector(localizedStandardCompare:)]; - + NSString * sortType = [fDefaults stringForKey: @"Sort"]; if ([sortType isEqualToString: SORT_STATE]) { NSSortDescriptor * stateDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"stateSortKey" ascending: !asc], * progressDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"progress" ascending: !asc], * ratioDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"ratio" ascending: !asc]; - + descriptors = [NSArray arrayWithObjects: stateDescriptor, progressDescriptor, ratioDescriptor, nameDescriptor, nil]; } else if ([sortType isEqualToString: SORT_PROGRESS]) @@ -2315,32 +2315,32 @@ static void removeKeRangerRansomware() NSSortDescriptor * progressDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"progress" ascending: asc], * ratioProgressDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"progressStopRatio" ascending: asc], * ratioDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"ratio" ascending: asc]; - + descriptors = [NSArray arrayWithObjects: progressDescriptor, ratioProgressDescriptor, ratioDescriptor, nameDescriptor, nil]; } else if ([sortType isEqualToString: SORT_TRACKER]) { NSSortDescriptor * trackerDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"trackerSortKey" ascending: asc selector: @selector(localizedCaseInsensitiveCompare:)]; - + descriptors = [NSArray arrayWithObjects: trackerDescriptor, nameDescriptor, nil]; } else if ([sortType isEqualToString: SORT_ACTIVITY]) { NSSortDescriptor * rateDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"totalRate" ascending: !asc]; NSSortDescriptor * activityDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"dateActivityOrAdd" ascending: !asc]; - + descriptors = [NSArray arrayWithObjects: rateDescriptor, activityDescriptor, nameDescriptor, nil]; } else if ([sortType isEqualToString: SORT_DATE]) { NSSortDescriptor * dateDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"dateAdded" ascending: asc]; - + descriptors = [NSArray arrayWithObjects: dateDescriptor, nameDescriptor, nil]; } else if ([sortType isEqualToString: SORT_SIZE]) { NSSortDescriptor * sizeDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"size" ascending: asc]; - + descriptors = [NSArray arrayWithObjects: sizeDescriptor, nameDescriptor, nil]; } else if ([sortType isEqualToString: SORT_NAME]) @@ -2350,17 +2350,17 @@ static void removeKeRangerRansomware() else { NSAssert1([sortType isEqualToString: SORT_ORDER], @"Unknown sort type received: %@", sortType); - + if (!includeQueueOrder) return; - + NSSortDescriptor * orderDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"queuePosition" ascending: asc]; - + descriptors = [NSArray arrayWithObject: orderDescriptor]; } - + BOOL beganTableUpdate = !callUpdates; - + //actually sort if ([fDefaults boolForKey: @"SortByGroup"]) { @@ -2369,7 +2369,7 @@ static void removeKeRangerRansomware() } else [self rearrangeTorrentTableArray: fDisplayedTorrents forParent: nil withSortDescriptors: descriptors beganTableUpdate: &beganTableUpdate]; - + if (beganTableUpdate && callUpdates) { [fTableView endUpdates]; @@ -2389,10 +2389,10 @@ static void removeKeRangerRansomware() if (result != NSOrderedSame) return result; } - + return NSOrderedSame; }]; - + if (insertIndex != currentIndex) { if (!*beganTableUpdate) @@ -2400,12 +2400,12 @@ static void removeKeRangerRansomware() *beganTableUpdate = YES; [fTableView beginUpdates]; } - + [rearrangeArray moveObjectAtIndex: currentIndex toIndex: insertIndex]; [fTableView moveItemAtIndex: currentIndex inParent: parent toIndex: insertIndex inParent: parent]; } } - + NSAssert2([rearrangeArray isEqualToArray: [rearrangeArray sortedArrayUsingDescriptors: descriptors]], @"Torrent rearranging didn't work! %@ %@", rearrangeArray, [rearrangeArray sortedArrayUsingDescriptors: descriptors]); } @@ -2424,15 +2424,15 @@ static void removeKeRangerRansomware() filterPause = YES; else filterStatus = NO; - + const NSInteger groupFilterValue = [fDefaults integerForKey: @"FilterGroup"]; const BOOL filterGroup = groupFilterValue != GROUP_FILTER_ALL_TAG; - + NSArray * searchStrings = [fFilterBar searchStrings]; if (searchStrings && [searchStrings count] == 0) searchStrings = nil; const BOOL filterTracker = searchStrings && [[fDefaults stringForKey: @"FilterSearchType"] isEqualToString: FILTER_TYPE_TRACKER]; - + //filter & get counts of each type NSIndexSet * indexesOfNonFilteredTorrents = [fTorrents indexesOfObjectsWithOptions: NSEnumerationConcurrent passingTest: ^BOOL(Torrent * torrent, NSUInteger idx, BOOL * stop) { //check status @@ -2441,7 +2441,7 @@ static void removeKeRangerRansomware() const BOOL isActive = ![torrent isStalled]; if (isActive) OSAtomicIncrement32(&active); - + if ([torrent isSeeding]) { OSAtomicIncrement32(&seeding); @@ -2461,12 +2461,12 @@ static void removeKeRangerRansomware() if (filterStatus && !filterPause) return NO; } - + //checkGroup if (filterGroup) if ([torrent groupValue] != groupFilterValue) return NO; - + //check text field if (searchStrings) { @@ -2474,7 +2474,7 @@ static void removeKeRangerRansomware() if (filterTracker) { NSArray * trackers = [torrent allTrackersFlat]; - + //to count, we need each string in at least 1 tracker [searchStrings enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(id searchString, NSUInteger idx, BOOL * stop) { __block BOOL found = NO; @@ -2502,24 +2502,24 @@ static void removeKeRangerRansomware() } }]; } - + if (removeTextField) return NO; } - + return YES; }]; - + NSArray * allTorrents = [fTorrents objectsAtIndexes: indexesOfNonFilteredTorrents]; - + //set button tooltips if (fFilterBar) [fFilterBar setCountAll: [fTorrents count] active: active downloading: downloading seeding: seeding paused: paused]; - + //if either the previous or current lists are blank, set its value to the other const BOOL groupRows = [allTorrents count] > 0 ? [fDefaults boolForKey: @"SortByGroup"] : ([fDisplayedTorrents count] > 0 && [[fDisplayedTorrents objectAtIndex: 0] isKindOfClass: [TorrentGroup class]]); const BOOL wasGroupRows = [fDisplayedTorrents count] > 0 ? [[fDisplayedTorrents objectAtIndex: 0] isKindOfClass: [TorrentGroup class]] : groupRows; - + #warning could probably be merged with later code somehow //clear display cache for not-shown torrents if ([fDisplayedTorrents count] > 0) @@ -2530,7 +2530,7 @@ static void removeKeRangerRansomware() if (![allTorrents containsObject: torrent]) [torrent setPreviousFinishedPieces: nil]; }; - + if (wasGroupRows) [fDisplayedTorrents enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(id obj, NSUInteger idx, BOOL * stop) { [[(TorrentGroup *)obj torrents] enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: removePreviousFinishedPieces]; @@ -2538,7 +2538,7 @@ static void removeKeRangerRansomware() else [fDisplayedTorrents enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: removePreviousFinishedPieces]; } - + BOOL beganUpdates = NO; //don't animate torrents when first launching @@ -2547,13 +2547,13 @@ static void removeKeRangerRansomware() [[NSAnimationContext currentContext] setDuration: 0]; }); [NSAnimationContext beginGrouping]; - + //add/remove torrents (and rearrange for groups), one by one if (!groupRows && !wasGroupRows) { NSMutableIndexSet * addIndexes = [NSMutableIndexSet indexSet], * removePreviousIndexes = [NSMutableIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fDisplayedTorrents count])]; - + //for each of the torrents to add, find if it already exists (and keep track of those we've already added & those we need to remove) [allTorrents enumerateObjectsWithOptions: 0 usingBlock: ^(id objAll, NSUInteger previousIndex, BOOL * stop) { const NSUInteger currentIndex = [fDisplayedTorrents indexOfObjectAtIndexes: removePreviousIndexes options: NSEnumerationConcurrent passingTest: ^(id objDisplay, NSUInteger idx, BOOL *stop) { @@ -2564,19 +2564,19 @@ static void removeKeRangerRansomware() else [removePreviousIndexes removeIndex: currentIndex]; }]; - + if ([addIndexes count] > 0 || [removePreviousIndexes count] > 0) { beganUpdates = YES; [fTableView beginUpdates]; - + //remove torrents we didn't find if ([removePreviousIndexes count] > 0) { [fDisplayedTorrents removeObjectsAtIndexes: removePreviousIndexes]; [fTableView removeItemsAtIndexes: removePreviousIndexes inParent: nil withAnimation: NSTableViewAnimationSlideDown]; } - + //add new torrents if ([addIndexes count] > 0) { @@ -2586,13 +2586,13 @@ static void removeKeRangerRansomware() NSIndexSet * newAddIndexes = [allTorrents indexesOfObjectsAtIndexes: addIndexes options: NSEnumerationConcurrent passingTest: ^BOOL(id obj, NSUInteger idx, BOOL * stop) { return [fAddingTransfers containsObject: obj]; }]; - + [addIndexes removeIndexes: newAddIndexes]; - + [fDisplayedTorrents addObjectsFromArray: [allTorrents objectsAtIndexes: newAddIndexes]]; [fTableView insertItemsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange([fDisplayedTorrents count] - [newAddIndexes count], [newAddIndexes count])] inParent: nil withAnimation: NSTableViewAnimationSlideLeft]; } - + [fDisplayedTorrents addObjectsFromArray: [allTorrents objectsAtIndexes: addIndexes]]; [fTableView insertItemsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange([fDisplayedTorrents count] - [addIndexes count], [addIndexes count])] inParent: nil withAnimation: NSTableViewAnimationSlideDown]; } @@ -2601,24 +2601,24 @@ static void removeKeRangerRansomware() else if (groupRows && wasGroupRows) { NSAssert(groupRows && wasGroupRows, @"Should have had group rows and should remain with group rows"); - + #warning don't always do? beganUpdates = YES; [fTableView beginUpdates]; - + NSMutableIndexSet * unusedAllTorrentsIndexes = [NSMutableIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [allTorrents count])]; - + NSMutableDictionary * groupsByIndex = [NSMutableDictionary dictionaryWithCapacity: [fDisplayedTorrents count]]; for (TorrentGroup * group in fDisplayedTorrents) [groupsByIndex setObject: group forKey: [NSNumber numberWithInteger: [group groupIndex]]]; - + const NSUInteger originalGroupCount = [fDisplayedTorrents count]; for (NSUInteger index = 0; index < originalGroupCount; ++index) { TorrentGroup * group = [fDisplayedTorrents objectAtIndex: index]; - + NSMutableIndexSet * removeIndexes = [NSMutableIndexSet indexSet]; - + //needs to be a signed integer for (NSUInteger indexInGroup = 0; indexInGroup < [[group torrents] count]; ++indexInGroup) { @@ -2631,7 +2631,7 @@ static void removeKeRangerRansomware() else { BOOL markTorrentAsUsed = YES; - + const NSInteger groupValue = [torrent groupValue]; if (groupValue != [group groupIndex]) { @@ -2651,27 +2651,27 @@ static void removeKeRangerRansomware() if ([fDisplayedTorrents indexOfObject: newGroup inRange: NSMakeRange(index+1, originalGroupCount-(index+1))] != NSNotFound) markTorrentAsUsed = NO; } - + [[group torrents] removeObjectAtIndex: indexInGroup]; [[newGroup torrents] addObject: torrent]; [fTableView moveItemAtIndex: indexInGroup inParent: group toIndex: [[newGroup torrents] count]-1 inParent: newGroup]; - + --indexInGroup; } - + if (markTorrentAsUsed) [unusedAllTorrentsIndexes removeIndex: allIndex]; } } - + if ([removeIndexes count] > 0) { [[group torrents] removeObjectsAtIndexes: removeIndexes]; [fTableView removeItemsAtIndexes: removeIndexes inParent: group withAnimation: NSTableViewAnimationEffectFade]; } } - + //add remaining new torrents for (Torrent * torrent in [allTorrents objectsAtIndexes: unusedAllTorrentsIndexes]) { @@ -2686,24 +2686,24 @@ static void removeKeRangerRansomware() [fTableView insertItemsAtIndexes: [NSIndexSet indexSetWithIndex: [fDisplayedTorrents count]-1] inParent: nil withAnimation: NSTableViewAnimationEffectFade]; [fTableView isGroupCollapsed: groupValue] ? [fTableView collapseItem: group] : [fTableView expandItem: group]; } - + [[group torrents] addObject: torrent]; const BOOL newTorrent = fAddingTransfers && [fAddingTransfers containsObject: torrent]; [fTableView insertItemsAtIndexes: [NSIndexSet indexSetWithIndex: [[group torrents] count]-1] inParent: group withAnimation: newTorrent ? NSTableViewAnimationSlideLeft : NSTableViewAnimationSlideDown]; } - + //remove empty groups NSIndexSet * removeGroupIndexes = [fDisplayedTorrents indexesOfObjectsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, originalGroupCount)] options: NSEnumerationConcurrent passingTest: ^BOOL(id obj, NSUInteger idx, BOOL * stop) { return [[(TorrentGroup *)obj torrents] count] == 0; }]; - + if ([removeGroupIndexes count] > 0) { [fDisplayedTorrents removeObjectsAtIndexes: removeGroupIndexes]; [fTableView removeItemsAtIndexes: removeGroupIndexes inParent: nil withAnimation: NSTableViewAnimationEffectFade]; } - + //now that all groups are there, sort them - don't insert on the fly in case groups were reordered in prefs NSSortDescriptor * groupDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"groupOrderValue" ascending: YES]; [self rearrangeTorrentTableArray: fDisplayedTorrents forParent: nil withSortDescriptors: [NSArray arrayWithObject: groupDescriptor] beganTableUpdate: &beganUpdates]; @@ -2711,19 +2711,19 @@ static void removeKeRangerRansomware() else { NSAssert(groupRows != wasGroupRows, @"Trying toggling group-torrent reordering when we weren't expecting to."); - + //set all groups as expanded [fTableView removeAllCollapsedGroups]; - + //since we're not doing this the right way (boo buggy animation), we need to remember selected values #warning when Lion-only and using views instead of cells, this likely won't be needed NSArray * selectedValues = [fTableView selectedValues]; - + beganUpdates = YES; [fTableView beginUpdates]; [fTableView removeItemsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fDisplayedTorrents count])] inParent: nil withAnimation: NSTableViewAnimationSlideDown]; - + if (groupRows) { //a map for quickly finding groups @@ -2737,12 +2737,12 @@ static void removeKeRangerRansomware() group = [[[TorrentGroup alloc] initWithGroup: groupValue] autorelease]; [groupsByIndex setObject: group forKey: [NSNumber numberWithInteger: groupValue]]; } - + [[group torrents] addObject: torrent]; } - + [fDisplayedTorrents setArray: [groupsByIndex allValues]]; - + //we need the groups to be sorted, and we can do it without moving items in the table, too! NSSortDescriptor * groupDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"groupOrderValue" ascending: YES]; [fDisplayedTorrents sortUsingDescriptors: [NSArray arrayWithObject: groupDescriptor]]; @@ -2751,33 +2751,33 @@ static void removeKeRangerRansomware() [fDisplayedTorrents setArray: allTorrents]; [fTableView insertItemsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fDisplayedTorrents count])] inParent: nil withAnimation: NSTableViewAnimationEffectFade]; - - if (groupRows) - { - //actually expand group rows - for (TorrentGroup * group in fDisplayedTorrents) - [fTableView expandItem: group]; - } - + + if (groupRows) + { + //actually expand group rows + for (TorrentGroup * group in fDisplayedTorrents) + [fTableView expandItem: group]; + } + if (selectedValues) [fTableView selectValues: selectedValues]; } - + //sort the torrents (won't sort the groups, though) [self sortTorrentsCallUpdates: !beganUpdates includeQueueOrder: YES]; if (beganUpdates) [fTableView endUpdates]; [fTableView setNeedsDisplay: YES]; - + [NSAnimationContext endGrouping]; [self resetInfo]; //if group is already selected, but the torrents in it change - + [self setBottomCountText: groupRows || filterStatus || filterGroup || searchStrings]; - + [self setWindowSizeToFit]; - + if (fAddingTransfers) { [fAddingTransfers release]; @@ -2794,15 +2794,15 @@ static void removeKeRangerRansomware() { if (fGlobalPopoverShown) return; - + NSPopover * popover = [[NSPopover alloc] init]; [popover setBehavior: NSPopoverBehaviorTransient]; GlobalOptionsPopoverViewController * viewController = [[GlobalOptionsPopoverViewController alloc] initWithHandle: fLib]; [popover setContentViewController: viewController]; [popover setDelegate: self]; - + [popover showRelativeToRect: [sender frame] ofView: sender preferredEdge: NSMaxYEdge]; - + [viewController release]; [popover release]; } @@ -2824,9 +2824,9 @@ static void removeKeRangerRansomware() { for (NSInteger i = [menu numberOfItems]-1; i >= 0; i--) [menu removeItemAtIndex: i]; - + NSMenu * groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(setGroup:) isSmall: NO]; - + const NSInteger groupMenuCount = [groupMenu numberOfItems]; for (NSInteger i = 0; i < groupMenuCount; i++) { @@ -2838,7 +2838,7 @@ static void removeKeRangerRansomware() } else if (menu == fShareMenu || menu == fShareContextMenu) { [menu removeAllItems]; - + for (NSMenuItem * item in [[ShareTorrentFileHelper sharedHelper] menuItems]) { [menu addItem:item]; @@ -2852,10 +2852,10 @@ static void removeKeRangerRansomware() for (Torrent * torrent in [fTableView selectedTorrents]) { [fTableView removeCollapsedGroup: [torrent groupValue]]; //remove old collapsed group - + [torrent setGroupValue: [(NSMenuItem *)sender tag] determinationType: TorrentDeterminationUserSpecified]; } - + [self applyFilter]; [self updateUI]; [self updateTorrentHistory]; @@ -2880,7 +2880,7 @@ static void removeKeRangerRansomware() [fDefaults setBool: isLimited forKey: @"SpeedLimit"]; [fStatusBar updateSpeedFieldsToolTips]; - + if (![[dict objectForKey: @"ByUser"] boolValue]) [GrowlApplicationBridge notifyWithTitle: isLimited ? NSLocalizedString(@"Speed Limit Auto Enabled", "Growl notification title") : NSLocalizedString(@"Speed Limit Auto Disabled", "Growl notification title") description: NSLocalizedString(@"Bandwidth settings changed", "Growl notification description") @@ -2890,7 +2890,7 @@ static void removeKeRangerRansomware() isSticky: NO clickContext: nil identifier: GROWL_AUTO_SPEED_LIMIT]; - + [dict release]; } @@ -2902,18 +2902,18 @@ static void removeKeRangerRansomware() -(void) VDKQueue: (VDKQueue *) queue receivedNotification: (NSString*) notification forPath: (NSString*) fpath { //don't assume that just because we're watching for write notification, we'll only receive write notifications - + if (![fDefaults boolForKey: @"AutoImport"] || ![fDefaults stringForKey: @"AutoImportDirectory"]) return; - + if ([fAutoImportTimer isValid]) [fAutoImportTimer invalidate]; [fAutoImportTimer release]; - + //check again in 10 seconds in case torrent file wasn't complete - fAutoImportTimer = [[NSTimer scheduledTimerWithTimeInterval: 10.0 target: self + fAutoImportTimer = [[NSTimer scheduledTimerWithTimeInterval: 10.0 target: self selector: @selector(checkAutoImportDirectory) userInfo: nil repeats: NO] retain]; - + [self checkAutoImportDirectory]; } @@ -2923,10 +2923,10 @@ static void removeKeRangerRansomware() [fAutoImportTimer invalidate]; [fAutoImportTimer release]; fAutoImportTimer = nil; - + [fAutoImportedNames release]; fAutoImportedNames = nil; - + [self checkAutoImportDirectory]; } @@ -2935,70 +2935,70 @@ static void removeKeRangerRansomware() NSString * path; if (![fDefaults boolForKey: @"AutoImport"] || !(path = [fDefaults stringForKey: @"AutoImportDirectory"])) return; - + path = [path stringByExpandingTildeInPath]; - + NSArray * importedNames; if (!(importedNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: path error: NULL])) return; - + //only check files that have not been checked yet NSMutableArray * newNames = [importedNames mutableCopy]; - + if (fAutoImportedNames) [newNames removeObjectsInArray: fAutoImportedNames]; else fAutoImportedNames = [[NSMutableArray alloc] init]; [fAutoImportedNames setArray: importedNames]; - + for (NSString * file in newNames) { if ([file hasPrefix: @"."]) continue; - + NSString * fullFile = [path stringByAppendingPathComponent: file]; - + if (!([[[NSWorkspace sharedWorkspace] typeOfFile: fullFile error: NULL] isEqualToString: @"org.bittorrent.torrent"] || [[fullFile pathExtension] caseInsensitiveCompare: @"torrent"] == NSOrderedSame)) continue; - + tr_ctor * ctor = tr_ctorNew(fLib); tr_ctorSetMetainfoFromFile(ctor, [fullFile UTF8String]); - + switch (tr_torrentParse(ctor, NULL)) { case TR_PARSE_OK: [self openFiles: [NSArray arrayWithObject: fullFile] addType: ADD_AUTO forcePath: nil]; - + NSString * notificationTitle = NSLocalizedString(@"Torrent File Auto Added", "notification title"); if ([NSApp isOnMountainLionOrBetter]) { NSUserNotification* notification = [[NSUserNotificationMtLion alloc] init]; [notification setTitle: notificationTitle]; [notification setInformativeText: file]; - + [notification setHasActionButton: NO]; - + [[NSUserNotificationCenterMtLion defaultUserNotificationCenter] deliverNotification: notification]; [notification release]; } - + [GrowlApplicationBridge notifyWithTitle: notificationTitle description: file notificationName: GROWL_AUTO_ADD iconData: nil priority: 0 isSticky: NO clickContext: nil]; break; - + case TR_PARSE_ERR: [fAutoImportedNames removeObject: file]; break; - + case TR_PARSE_DUPLICATE: //let's ignore this (but silence a warning) break; } - + tr_ctorFree(ctor); } - + [newNames release]; } @@ -3006,10 +3006,10 @@ static void removeKeRangerRansomware() { if (![fDefaults boolForKey: @"AutoImport"]) return; - + NSString * location = [(NSURL *)[notification object] path], * path = [fDefaults stringForKey: @"AutoImportDirectory"]; - + if (location && path && [[[location stringByDeletingLastPathComponent] stringByExpandingTildeInPath] isEqualToString: [path stringByExpandingTildeInPath]]) [fAutoImportedNames addObject: [location lastPathComponent]]; @@ -3065,7 +3065,7 @@ static void removeKeRangerRansomware() else { TorrentGroup * group = (TorrentGroup *)item; - + if ([fDefaults boolForKey: @"DisplayGroupRowRatio"]) return [NSString stringForRatio: [group ratio]]; else @@ -3087,10 +3087,10 @@ static void removeKeRangerRansomware() { if (![torrent isKindOfClass: [Torrent class]]) return NO; - + [indexSet addIndex: [fTableView rowForItem: torrent]]; } - + [pasteboard declareTypes: [NSArray arrayWithObject: TORRENT_TABLE_VIEW_DATA_TYPE] owner: self]; [pasteboard setData: [NSKeyedArchiver archivedDataWithRootObject: indexSet] forType: TORRENT_TABLE_VIEW_DATA_TYPE]; return YES; @@ -3108,7 +3108,7 @@ static void removeKeRangerRansomware() { if (!item) return NSDragOperationNone; - + if ([[fDefaults stringForKey: @"Sort"] isEqualToString: SORT_ORDER]) { if ([item isKindOfClass: [Torrent class]]) @@ -3129,18 +3129,18 @@ static void removeKeRangerRansomware() { if (index == NSOutlineViewDropOnItemIndex) return NSDragOperationNone; - + if (item) { index = [fTableView rowForItem: item] + 1; item = nil; } } - + [fTableView setDropItem: item dropChildIndex: index]; return NSDragOperationGeneric; } - + return NSDragOperationNone; } @@ -3150,19 +3150,19 @@ static void removeKeRangerRansomware() if ([[pasteboard types] containsObject: TORRENT_TABLE_VIEW_DATA_TYPE]) { NSIndexSet * indexes = [NSKeyedUnarchiver unarchiveObjectWithData: [pasteboard dataForType: TORRENT_TABLE_VIEW_DATA_TYPE]]; - + //get the torrents to move NSMutableArray * movingTorrents = [NSMutableArray arrayWithCapacity: [indexes count]]; for (NSUInteger i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i]) { Torrent * torrent = [fTableView itemAtRow: i]; [movingTorrents addObject: torrent]; - + //change groups if (item) [torrent setGroupValue: [item groupIndex] determinationType: TorrentDeterminationUserSpecified]; } - + //reorder queue order if (newRow != NSOutlineViewDropOnItemIndex) { @@ -3178,15 +3178,15 @@ static void removeKeRangerRansomware() break; } } - + //remove objects to reinsert [fTorrents removeObjectsInArray: movingTorrents]; - + //insert objects at new location const NSUInteger insertIndex = topTorrent ? [fTorrents indexOfObject: topTorrent] + 1 : 0; NSIndexSet * insertIndexes = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(insertIndex, [movingTorrents count])]; [fTorrents insertObjects: movingTorrents atIndexes: insertIndexes]; - + //we need to make sure the queue order is updated in the Torrent object before we sort - safest to just reset all queue positions NSUInteger i = 0; for (Torrent * torrent in fTorrents) @@ -3194,18 +3194,18 @@ static void removeKeRangerRansomware() [torrent setQueuePosition: i++]; [torrent update]; } - + //do the drag animation here so that the dragged torrents are the ones that are animated as moving, and not the torrents around them [fTableView beginUpdates]; - + NSUInteger insertDisplayIndex = topTorrent ? [groupTorrents indexOfObject: topTorrent] + 1 : 0; - + for (Torrent * torrent in movingTorrents) { TorrentGroup * oldParent = item ? [fTableView parentForItem: torrent] : nil; NSMutableArray * oldTorrents = oldParent ? [oldParent torrents] : fDisplayedTorrents; const NSUInteger oldIndex = [oldTorrents indexOfObject: torrent]; - + if (item == oldParent) { if (oldIndex < insertDisplayIndex) @@ -3215,23 +3215,23 @@ static void removeKeRangerRansomware() else { NSAssert(item && oldParent, @"Expected to be dragging between group rows"); - + NSMutableArray * newTorrents = [(TorrentGroup *)item torrents]; [newTorrents insertObject: torrent atIndex: insertDisplayIndex]; [oldTorrents removeObjectAtIndex: oldIndex]; } [fTableView moveItemAtIndex: oldIndex inParent: oldParent toIndex: insertDisplayIndex inParent: item]; - + ++insertDisplayIndex; } [fTableView endUpdates]; } - + [self applyFilter]; } - + return YES; } @@ -3262,20 +3262,20 @@ static void removeKeRangerRansomware() if (!fOverlayWindow) fOverlayWindow = [[DragOverlayWindow alloc] initWithLib: fLib forWindow: fWindow]; [fOverlayWindow setTorrents: files]; - + return NSDragOperationCopy; } tr_ctorFree(ctor); } } - + //create a torrent file if a single file if (!torrent && [files count] == 1) { if (!fOverlayWindow) fOverlayWindow = [[DragOverlayWindow alloc] initWithLib: fLib forWindow: fWindow]; [fOverlayWindow setFile: [[files objectAtIndex: 0] lastPathComponent]]; - + return NSDragOperationCopy; } } @@ -3284,11 +3284,11 @@ static void removeKeRangerRansomware() if (!fOverlayWindow) fOverlayWindow = [[DragOverlayWindow alloc] initWithLib: fLib forWindow: fWindow]; [fOverlayWindow setURL: [[NSURL URLFromPasteboard: pasteboard] relativeString]]; - + return NSDragOperationCopy; } else; - + return NSDragOperationNone; } @@ -3302,12 +3302,12 @@ static void removeKeRangerRansomware() { if (fOverlayWindow) [fOverlayWindow fadeOut]; - + NSPasteboard * pasteboard = [info draggingPasteboard]; if ([[pasteboard types] containsObject: NSFilenamesPboardType]) { BOOL torrent = NO, accept = YES; - + //create an array of files that can be opened NSArray * files = [pasteboard propertyListForType: NSFilenamesPboardType]; NSMutableArray * filesToOpen = [NSMutableArray arrayWithCapacity: [files count]]; @@ -3324,7 +3324,7 @@ static void removeKeRangerRansomware() tr_ctorFree(ctor); } } - + if ([filesToOpen count] > 0) [self application: NSApp openFiles: filesToOpen]; else @@ -3334,7 +3334,7 @@ static void removeKeRangerRansomware() else accept = NO; } - + return accept; } else if ([[pasteboard types] containsObject: NSURLPboardType]) @@ -3347,7 +3347,7 @@ static void removeKeRangerRansomware() } } else; - + return NO; } @@ -3355,24 +3355,24 @@ static void removeKeRangerRansomware() { BOOL makeSmall = ![fDefaults boolForKey: @"SmallView"]; [fDefaults setBool: makeSmall forKey: @"SmallView"]; - + [fTableView setUsesAlternatingRowBackgroundColors: !makeSmall]; - + [fTableView setRowHeight: makeSmall ? ROW_HEIGHT_SMALL : ROW_HEIGHT_REGULAR]; [fTableView beginUpdates]; [fTableView noteHeightOfRowsWithIndexesChanged: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTableView numberOfRows])]]; [fTableView endUpdates]; - + //resize for larger min height if not set to auto size if (![fDefaults boolForKey: @"AutoSize"]) { const NSSize contentSize = [[fWindow contentView] frame].size; - + NSSize contentMinSize = [fWindow contentMinSize]; contentMinSize.height = [self minWindowContentSizeAllowed]; [fWindow setContentMinSize: contentMinSize]; - + //make sure the window already isn't too small if (!makeSmall && contentSize.height < contentMinSize.height) { @@ -3380,7 +3380,7 @@ static void removeKeRangerRansomware() CGFloat heightChange = contentMinSize.height - contentSize.height; frame.size.height += heightChange; frame.origin.y -= heightChange; - + [fWindow setFrame: frame display: YES]; } } @@ -3403,18 +3403,18 @@ static void removeKeRangerRansomware() - (NSRect) windowFrameByAddingHeight: (CGFloat) height checkLimits: (BOOL) check { NSScrollView * scrollView = [fTableView enclosingScrollView]; - + //convert pixels to points NSRect windowFrame = [fWindow frame]; NSSize windowSize = [scrollView convertSize: windowFrame.size fromView: nil]; windowSize.height += height; - + if (check) { //we can't call minSize, since it might be set to the current size (auto size) const CGFloat minHeight = [self minWindowContentSizeAllowed] + (NSHeight([fWindow frame]) - NSHeight([[fWindow contentView] frame])); //contentView to window - + if (windowSize.height <= minHeight) windowSize.height = minHeight; else @@ -3454,31 +3454,31 @@ static void removeKeRangerRansomware() const BOOL prevShown = fStatusBar != nil; if (show == prevShown) return; - + if (show) { fStatusBar = [[StatusBarController alloc] initWithLib: fLib]; - + NSView * contentView = [fWindow contentView]; const NSSize windowSize = [contentView convertSize: [fWindow frame].size fromView: nil]; - + NSRect statusBarFrame = [[fStatusBar view] frame]; statusBarFrame.size.width = windowSize.width; [[fStatusBar view] setFrame: statusBarFrame]; - + [contentView addSubview: [fStatusBar view]]; [[fStatusBar view] setFrameOrigin: NSMakePoint(0.0, NSMaxY([contentView frame]))]; } - + CGFloat heightChange = [[fStatusBar view] frame].size.height; if (!show) heightChange *= -1; - + //allow bar to show even if not enough room if (show && ![fDefaults boolForKey: @"AutoSize"]) { NSRect frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO]; - + NSScreen * screen = [fWindow screen]; if (screen) { @@ -3492,11 +3492,11 @@ static void removeKeRangerRansomware() } } } - + [self updateUI]; - + NSScrollView * scrollView = [fTableView enclosingScrollView]; - + //set views to not autoresize const NSUInteger statsMask = [[fStatusBar view] autoresizingMask]; [[fStatusBar view] setAutoresizingMask: NSViewNotSizable]; @@ -3508,23 +3508,23 @@ static void removeKeRangerRansomware() } const NSUInteger scrollMask = [scrollView autoresizingMask]; [scrollView setAutoresizingMask: NSViewNotSizable]; - + NSRect frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO]; - [fWindow setFrame: frame display: YES animate: animate]; - + [fWindow setFrame: frame display: YES animate: animate]; + //re-enable autoresize [[fStatusBar view] setAutoresizingMask: statsMask]; if (fFilterBar) [[fFilterBar view] setAutoresizingMask: filterMask]; [scrollView setAutoresizingMask: scrollMask]; - + if (!show) { [[fStatusBar view] removeFromSuperviewWithoutNeedingDisplay]; [fStatusBar release]; fStatusBar = nil; } - + if ([fDefaults boolForKey: @"AutoSize"]) [self setWindowMinMaxToCurrent]; else @@ -3539,15 +3539,15 @@ static void removeKeRangerRansomware() - (void) toggleFilterBar: (id) sender { const BOOL show = fFilterBar == nil; - + //disable filtering when hiding (have to do before showFilterBar:animate:) if (!show) [fFilterBar reset: NO]; - + [self showFilterBar: show animate: YES]; [fDefaults setBool: show forKey: @"FilterBar"]; [[fWindow toolbar] validateVisibleItems]; - + [self applyFilter]; //do even if showing to ensure tooltips are updated } @@ -3557,18 +3557,18 @@ static void removeKeRangerRansomware() const BOOL prevShown = fFilterBar != nil; if (show == prevShown) return; - + if (show) { fFilterBar = [[FilterBarController alloc] init]; - + NSView * contentView = [fWindow contentView]; const NSSize windowSize = [contentView convertSize: [fWindow frame].size fromView: nil]; - + NSRect filterBarFrame = [[fFilterBar view] frame]; filterBarFrame.size.width = windowSize.width; [[fFilterBar view] setFrame: filterBarFrame]; - + if (fStatusBar) [contentView addSubview: [fFilterBar view] positioned: NSWindowBelow relativeTo: [fStatusBar view]]; else @@ -3578,16 +3578,16 @@ static void removeKeRangerRansomware() } else [fWindow makeFirstResponder: fTableView]; - + CGFloat heightChange = NSHeight([[fFilterBar view] frame]); if (!show) heightChange *= -1; - + //allow bar to show even if not enough room if (show && ![fDefaults boolForKey: @"AutoSize"]) { NSRect frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO]; - + NSScreen * screen = [fWindow screen]; if (screen) { @@ -3601,7 +3601,7 @@ static void removeKeRangerRansomware() } } } - + NSScrollView * scrollView = [fTableView enclosingScrollView]; //set views to not autoresize @@ -3609,21 +3609,21 @@ static void removeKeRangerRansomware() const NSUInteger scrollMask = [scrollView autoresizingMask]; [[fFilterBar view] setAutoresizingMask: NSViewNotSizable]; [scrollView setAutoresizingMask: NSViewNotSizable]; - + const NSRect frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO]; [fWindow setFrame: frame display: YES animate: animate]; - + //re-enable autoresize [[fFilterBar view] setAutoresizingMask: filterMask]; [scrollView setAutoresizingMask: scrollMask]; - + if (!show) { [[fFilterBar view] removeFromSuperviewWithoutNeedingDisplay]; [fFilterBar release]; fFilterBar = nil; } - + if ([fDefaults boolForKey: @"AutoSize"]) [self setWindowMinMaxToCurrent]; else @@ -3664,11 +3664,11 @@ static void removeKeRangerRansomware() { NSArray * selectedTorrents = [fTableView selectedTorrents]; NSMutableArray * qlArray = [NSMutableArray arrayWithCapacity: [selectedTorrents count]]; - + for (Torrent * torrent in selectedTorrents) if (([torrent isFolder] || [torrent isComplete]) && [torrent dataLocation]) [qlArray addObject: torrent]; - + return qlArray; } @@ -3695,7 +3695,7 @@ static void removeKeRangerRansomware() [super keyDown: event]; return YES; }*/ - + return NO; } @@ -3707,16 +3707,16 @@ static void removeKeRangerRansomware() { if (![fWindow isVisible]) return NSZeroRect; - + const NSInteger row = [fTableView rowForItem: item]; if (row == -1) return NSZeroRect; - + NSRect frame = [fTableView iconRectForRow: row]; - + if (!NSIntersectsRect([fTableView visibleRect], frame)) return NSZeroRect; - + frame.origin = [fTableView convertPoint: frame.origin toView: nil]; frame = [fWindow convertRectToScreen: frame]; frame.origin.y -= frame.size.height; @@ -3727,10 +3727,10 @@ static void removeKeRangerRansomware() - (void) showToolbarShare: (id) sender { NSParameterAssert([sender isKindOfClass:[NSButton class]]); - + NSSharingServicePicker * picker = [[NSSharingServicePicker alloc] initWithItems: [[ShareTorrentFileHelper sharedHelper] shareTorrentURLs]]; picker.delegate = self; - + [picker showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinYEdge]; } @@ -3752,18 +3752,18 @@ static void removeKeRangerRansomware() - (id) toolbarButtonWithIdentifier: (NSString *) ident forToolbarButtonClass:(Class)class { ButtonToolbarItem * item = [[class alloc] initWithItemIdentifier: ident]; - + NSButton * button = [[NSButton alloc] init]; [button setBezelStyle: NSTexturedRoundedBezelStyle]; [button setStringValue: @""]; - + [item setView: button]; [button release]; - + const NSSize buttonSize = NSMakeSize(36.0, 25.0); [item setMinSize: buttonSize]; [item setMaxSize: buttonSize]; - + return [item autorelease]; } @@ -3772,7 +3772,7 @@ static void removeKeRangerRansomware() if ([ident isEqualToString: TOOLBAR_CREATE]) { ButtonToolbarItem * item = [self standardToolbarButtonWithIdentifier: ident]; - + [item setLabel: NSLocalizedString(@"Create", "Create toolbar item -> label")]; [item setPaletteLabel: NSLocalizedString(@"Create Torrent File", "Create toolbar item -> palette label")]; [item setToolTip: NSLocalizedString(@"Create torrent file", "Create toolbar item -> tooltip")]; @@ -3780,13 +3780,13 @@ static void removeKeRangerRansomware() [item setTarget: self]; [item setAction: @selector(createFile:)]; [item setAutovalidates: NO]; - + return item; } else if ([ident isEqualToString: TOOLBAR_OPEN_FILE]) { ButtonToolbarItem * item = [self standardToolbarButtonWithIdentifier: ident]; - + [item setLabel: NSLocalizedString(@"Open", "Open toolbar item -> label")]; [item setPaletteLabel: NSLocalizedString(@"Open Torrent Files", "Open toolbar item -> palette label")]; [item setToolTip: NSLocalizedString(@"Open torrent files", "Open toolbar item -> tooltip")]; @@ -3794,13 +3794,13 @@ static void removeKeRangerRansomware() [item setTarget: self]; [item setAction: @selector(openShowSheet:)]; [item setAutovalidates: NO]; - + return item; } else if ([ident isEqualToString: TOOLBAR_OPEN_WEB]) { ButtonToolbarItem * item = [self standardToolbarButtonWithIdentifier: ident]; - + [item setLabel: NSLocalizedString(@"Open Address", "Open address toolbar item -> label")]; [item setPaletteLabel: NSLocalizedString(@"Open Torrent Address", "Open address toolbar item -> palette label")]; [item setToolTip: NSLocalizedString(@"Open torrent web address", "Open address toolbar item -> tooltip")]; @@ -3808,13 +3808,13 @@ static void removeKeRangerRansomware() [item setTarget: self]; [item setAction: @selector(openURLShowSheet:)]; [item setAutovalidates: NO]; - + return item; } else if ([ident isEqualToString: TOOLBAR_REMOVE]) { ButtonToolbarItem * item = [self standardToolbarButtonWithIdentifier: ident]; - + [item setLabel: NSLocalizedString(@"Remove", "Remove toolbar item -> label")]; [item setPaletteLabel: NSLocalizedString(@"Remove Selected", "Remove toolbar item -> palette label")]; [item setToolTip: NSLocalizedString(@"Remove selected transfers", "Remove toolbar item -> tooltip")]; @@ -3822,134 +3822,134 @@ static void removeKeRangerRansomware() [item setTarget: self]; [item setAction: @selector(removeNoDelete:)]; [item setVisibilityPriority: NSToolbarItemVisibilityPriorityHigh]; - + return item; } else if ([ident isEqualToString: TOOLBAR_INFO]) { ButtonToolbarItem * item = [self standardToolbarButtonWithIdentifier: ident]; [[(NSButton *)[item view] cell] setShowsStateBy: NSContentsCellMask]; //blue when enabled - + [item setLabel: NSLocalizedString(@"Inspector", "Inspector toolbar item -> label")]; [item setPaletteLabel: NSLocalizedString(@"Toggle Inspector", "Inspector toolbar item -> palette label")]; [item setToolTip: NSLocalizedString(@"Toggle the torrent inspector", "Inspector toolbar item -> tooltip")]; [item setImage: [NSImage imageNamed: @"ToolbarInfoTemplate"]]; [item setTarget: self]; [item setAction: @selector(showInfo:)]; - + return item; } else if ([ident isEqualToString: TOOLBAR_PAUSE_RESUME_ALL]) { GroupToolbarItem * groupItem = [[GroupToolbarItem alloc] initWithItemIdentifier: ident]; - + NSSegmentedControl * segmentedControl = [[NSSegmentedControl alloc] initWithFrame: NSZeroRect]; [segmentedControl setCell: [[[ToolbarSegmentedCell alloc] init] autorelease]]; [groupItem setView: segmentedControl]; NSSegmentedCell * segmentedCell = (NSSegmentedCell *)[segmentedControl cell]; - + if ([NSApp isOnYosemiteOrBetter]) { segmentedControl.segmentStyle = NSSegmentStyleSeparated; } - + [segmentedControl setSegmentCount: 2]; [segmentedCell setTrackingMode: NSSegmentSwitchTrackingMomentary]; - + const NSSize groupSize = NSMakeSize(72.0, 25.0); [groupItem setMinSize: groupSize]; [groupItem setMaxSize: groupSize]; - + [groupItem setLabel: NSLocalizedString(@"Apply All", "All toolbar item -> label")]; [groupItem setPaletteLabel: NSLocalizedString(@"Pause / Resume All", "All toolbar item -> palette label")]; [groupItem setTarget: self]; [groupItem setAction: @selector(allToolbarClicked:)]; - + [groupItem setIdentifiers: [NSArray arrayWithObjects: TOOLBAR_PAUSE_ALL, TOOLBAR_RESUME_ALL, nil]]; - + [segmentedCell setTag: TOOLBAR_PAUSE_TAG forSegment: TOOLBAR_PAUSE_TAG]; [segmentedControl setImage: [NSImage imageNamed: @"ToolbarPauseAllTemplate"] forSegment: TOOLBAR_PAUSE_TAG]; [segmentedCell setToolTip: NSLocalizedString(@"Pause all transfers", "All toolbar item -> tooltip") forSegment: TOOLBAR_PAUSE_TAG]; - + [segmentedCell setTag: TOOLBAR_RESUME_TAG forSegment: TOOLBAR_RESUME_TAG]; [segmentedControl setImage: [NSImage imageNamed: @"ToolbarResumeAllTemplate"] forSegment: TOOLBAR_RESUME_TAG]; [segmentedCell setToolTip: NSLocalizedString(@"Resume all transfers", "All toolbar item -> tooltip") forSegment: TOOLBAR_RESUME_TAG]; - + [groupItem createMenu: [NSArray arrayWithObjects: NSLocalizedString(@"Pause All", "All toolbar item -> label"), NSLocalizedString(@"Resume All", "All toolbar item -> label"), nil]]; - + [segmentedControl release]; - + [groupItem setVisibilityPriority: NSToolbarItemVisibilityPriorityHigh]; - + return [groupItem autorelease]; } else if ([ident isEqualToString: TOOLBAR_PAUSE_RESUME_SELECTED]) { GroupToolbarItem * groupItem = [[GroupToolbarItem alloc] initWithItemIdentifier: ident]; - + NSSegmentedControl * segmentedControl = [[NSSegmentedControl alloc] initWithFrame: NSZeroRect]; [segmentedControl setCell: [[[ToolbarSegmentedCell alloc] init] autorelease]]; [groupItem setView: segmentedControl]; NSSegmentedCell * segmentedCell = (NSSegmentedCell *)[segmentedControl cell]; - + if ([NSApp isOnYosemiteOrBetter]) { segmentedControl.segmentStyle = NSSegmentStyleSeparated; } - + [segmentedControl setSegmentCount: 2]; [segmentedCell setTrackingMode: NSSegmentSwitchTrackingMomentary]; - + const NSSize groupSize = NSMakeSize(72.0, 25.0); [groupItem setMinSize: groupSize]; [groupItem setMaxSize: groupSize]; - + [groupItem setLabel: NSLocalizedString(@"Apply Selected", "Selected toolbar item -> label")]; [groupItem setPaletteLabel: NSLocalizedString(@"Pause / Resume Selected", "Selected toolbar item -> palette label")]; [groupItem setTarget: self]; [groupItem setAction: @selector(selectedToolbarClicked:)]; - + [groupItem setIdentifiers: [NSArray arrayWithObjects: TOOLBAR_PAUSE_SELECTED, TOOLBAR_RESUME_SELECTED, nil]]; - + [segmentedCell setTag: TOOLBAR_PAUSE_TAG forSegment: TOOLBAR_PAUSE_TAG]; [segmentedControl setImage: [NSImage imageNamed: @"ToolbarPauseSelectedTemplate"] forSegment: TOOLBAR_PAUSE_TAG]; [segmentedCell setToolTip: NSLocalizedString(@"Pause selected transfers", "Selected toolbar item -> tooltip") forSegment: TOOLBAR_PAUSE_TAG]; - + [segmentedCell setTag: TOOLBAR_RESUME_TAG forSegment: TOOLBAR_RESUME_TAG]; [segmentedControl setImage: [NSImage imageNamed: @"ToolbarResumeSelectedTemplate"] forSegment: TOOLBAR_RESUME_TAG]; [segmentedCell setToolTip: NSLocalizedString(@"Resume selected transfers", "Selected toolbar item -> tooltip") forSegment: TOOLBAR_RESUME_TAG]; - + [groupItem createMenu: [NSArray arrayWithObjects: NSLocalizedString(@"Pause Selected", "Selected toolbar item -> label"), NSLocalizedString(@"Resume Selected", "Selected toolbar item -> label"), nil]]; - + [segmentedControl release]; - + [groupItem setVisibilityPriority: NSToolbarItemVisibilityPriorityHigh]; - + return [groupItem autorelease]; } else if ([ident isEqualToString: TOOLBAR_FILTER]) { ButtonToolbarItem * item = [self standardToolbarButtonWithIdentifier: ident]; [[(NSButton *)[item view] cell] setShowsStateBy: NSContentsCellMask]; //blue when enabled - + [item setLabel: NSLocalizedString(@"Filter", "Filter toolbar item -> label")]; [item setPaletteLabel: NSLocalizedString(@"Toggle Filter", "Filter toolbar item -> palette label")]; [item setToolTip: NSLocalizedString(@"Toggle the filter bar", "Filter toolbar item -> tooltip")]; [item setImage: [NSImage imageNamed: @"ToolbarFilterTemplate"]]; [item setTarget: self]; [item setAction: @selector(toggleFilterBar:)]; - + return item; } else if ([ident isEqualToString: TOOLBAR_QUICKLOOK]) { ButtonToolbarItem * item = [self standardToolbarButtonWithIdentifier: ident]; [[(NSButton *)[item view] cell] setShowsStateBy: NSContentsCellMask]; //blue when enabled - + [item setLabel: NSLocalizedString(@"Quick Look", "QuickLook toolbar item -> label")]; [item setPaletteLabel: NSLocalizedString(@"Quick Look", "QuickLook toolbar item -> palette label")]; [item setToolTip: NSLocalizedString(@"Quick Look", "QuickLook toolbar item -> tooltip")]; @@ -3957,24 +3957,24 @@ static void removeKeRangerRansomware() [item setTarget: self]; [item setAction: @selector(toggleQuickLook:)]; [item setVisibilityPriority: NSToolbarItemVisibilityPriorityLow]; - + return item; } else if ([ident isEqualToString: TOOLBAR_SHARE]) { ShareToolbarItem * item = [self toolbarButtonWithIdentifier: ident forToolbarButtonClass: [ShareToolbarItem class]]; - + [item setLabel: NSLocalizedString(@"Share", "Share toolbar item -> label")]; [item setPaletteLabel: NSLocalizedString(@"Share", "Share toolbar item -> palette label")]; [item setToolTip: NSLocalizedString(@"Share torrent file", "Share toolbar item -> tooltip")]; [item setImage: [NSImage imageNamed: NSImageNameShareTemplate]]; [item setVisibilityPriority: NSToolbarItemVisibilityPriorityLow]; - + NSButton *itemButton = (NSButton *)[item view]; [itemButton setTarget: self]; [itemButton setAction: @selector(showToolbarShare:)]; [itemButton sendActionOn:NSLeftMouseDownMask]; - + return item; } else @@ -4042,7 +4042,7 @@ static void removeKeRangerRansomware() - (BOOL) validateToolbarItem: (NSToolbarItem *) toolbarItem { NSString * ident = [toolbarItem itemIdentifier]; - + //enable remove item if ([ident isEqualToString: TOOLBAR_REMOVE]) return [fTableView numberOfSelectedRows] > 0; @@ -4073,7 +4073,7 @@ static void removeKeRangerRansomware() return YES; return NO; } - + //enable resume item if ([ident isEqualToString: TOOLBAR_RESUME_SELECTED]) { @@ -4082,52 +4082,52 @@ static void removeKeRangerRansomware() return YES; return NO; } - + //set info item if ([ident isEqualToString: TOOLBAR_INFO]) { [(NSButton *)[toolbarItem view] setState: [[fInfoController window] isVisible]]; return YES; } - + //set filter item if ([ident isEqualToString: TOOLBAR_FILTER]) { [(NSButton *)[toolbarItem view] setState: fFilterBar != nil]; return YES; } - + //set quick look item if ([ident isEqualToString: TOOLBAR_QUICKLOOK]) { [(NSButton *)[toolbarItem view] setState: [QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]]; return YES; } - + //enable share item if ([ident isEqualToString: TOOLBAR_SHARE]) return [fTableView numberOfSelectedRows] > 0; - + return YES; } - (BOOL) validateMenuItem: (NSMenuItem *) menuItem { SEL action = [menuItem action]; - + if (action == @selector(toggleSpeedLimit:)) { [menuItem setState: [fDefaults boolForKey: @"SpeedLimit"] ? NSOnState : NSOffState]; return YES; } - + //only enable some items if it is in a context menu or the window is useable BOOL canUseTable = [fWindow isKeyWindow] || [[menuItem menu] supermenu] != [NSApp mainMenu]; //enable open items if (action == @selector(openShowSheet:) || action == @selector(openURLShowSheet:)) return [fWindow attachedSheet] == nil; - + //enable sort options if (action == @selector(setSort:)) { @@ -4162,15 +4162,15 @@ static void removeKeRangerRansomware() NSAssert1(NO, @"Unknown sort tag received: %ld", [menuItem tag]); sortType = SORT_ORDER; } - + [menuItem setState: [sortType isEqualToString: [fDefaults stringForKey: @"Sort"]] ? NSOnState : NSOffState]; return [fWindow isVisible]; } - + if (action == @selector(setGroup:)) { BOOL checked = NO; - + NSInteger index = [menuItem tag]; for (Torrent * torrent in [fTableView selectedTorrents]) if (index == [torrent groupValue]) @@ -4178,29 +4178,29 @@ static void removeKeRangerRansomware() checked = YES; break; } - + [menuItem setState: checked ? NSOnState : NSOffState]; return canUseTable && [fTableView numberOfSelectedRows] > 0; } - + if (action == @selector(toggleSmallView:)) { [menuItem setState: [fDefaults boolForKey: @"SmallView"] ? NSOnState : NSOffState]; return [fWindow isVisible]; } - + if (action == @selector(togglePiecesBar:)) { [menuItem setState: [fDefaults boolForKey: @"PiecesBar"] ? NSOnState : NSOffState]; return [fWindow isVisible]; } - + if (action == @selector(toggleAvailabilityBar:)) { [menuItem setState: [fDefaults boolForKey: @"DisplayProgressBarAvailable"] ? NSOnState : NSOffState]; return [fWindow isVisible]; } - + //enable show info if (action == @selector(showInfo:)) { @@ -4210,11 +4210,11 @@ static void removeKeRangerRansomware() return YES; } - + //enable prev/next inspector tab if (action == @selector(setInfoTab:)) return [[fInfoController window] isVisible]; - + //enable toggle status bar if (action == @selector(toggleStatusBar:)) { @@ -4224,7 +4224,7 @@ static void removeKeRangerRansomware() return [fWindow isVisible]; } - + //enable toggle filter bar if (action == @selector(toggleFilterBar:)) { @@ -4234,15 +4234,15 @@ static void removeKeRangerRansomware() return [fWindow isVisible]; } - + //enable prev/next filter button if (action == @selector(switchFilter:)) return [fWindow isVisible] && fFilterBar; - + //enable reveal in finder if (action == @selector(revealFile:)) return canUseTable && [fTableView numberOfSelectedRows] > 0; - + //enable renaming file/folder if (action == @selector(renameSelected:)) return canUseTable && [fTableView numberOfSelectedRows] == 1; @@ -4251,7 +4251,7 @@ static void removeKeRangerRansomware() if (action == @selector(removeNoDelete:) || action == @selector(removeDeleteData:)) { BOOL warning = NO; - + for (Torrent * torrent in [fTableView selectedTorrents]) { if ([torrent isActive]) @@ -4263,7 +4263,7 @@ static void removeKeRangerRansomware() } } } - + //append or remove ellipsis when needed NSString * title = [menuItem title], * ellipsis = [NSString ellipsis]; if (warning && [fDefaults boolForKey: @"CheckRemove"]) @@ -4276,10 +4276,10 @@ static void removeKeRangerRansomware() if ([title hasSuffix: ellipsis]) [menuItem setTitle: [title substringToIndex: [title rangeOfString: ellipsis].location]]; } - + return canUseTable && [fTableView numberOfSelectedRows] > 0; } - + //remove all completed transfers item if (action == @selector(clearCompleted:)) { @@ -4295,7 +4295,7 @@ static void removeKeRangerRansomware() if ([title hasSuffix: ellipsis]) [menuItem setTitle: [title substringToIndex: [title rangeOfString: ellipsis].location]]; } - + for (Torrent * torrent in fTorrents) if ([torrent isFinishedSeeding]) return YES; @@ -4310,7 +4310,7 @@ static void removeKeRangerRansomware() return YES; return NO; } - + //enable resume all item if (action == @selector(resumeAllTorrents:)) { @@ -4319,25 +4319,25 @@ static void removeKeRangerRansomware() return YES; return NO; } - + //enable resume all waiting item if (action == @selector(resumeWaitingTorrents:)) { if (![fDefaults boolForKey: @"Queue"] && ![fDefaults boolForKey: @"QueueSeed"]) return NO; - + for (Torrent * torrent in fTorrents) if ([torrent waitingToStart]) return YES; return NO; } - + //enable resume selected waiting item if (action == @selector(resumeSelectedTorrentsNoWait:)) { if (!canUseTable) return NO; - + for (Torrent * torrent in [fTableView selectedTorrents]) if (![torrent isActive]) return YES; @@ -4349,69 +4349,69 @@ static void removeKeRangerRansomware() { if (!canUseTable) return NO; - + for (Torrent * torrent in [fTableView selectedTorrents]) if ([torrent isActive] || [torrent waitingToStart]) return YES; return NO; } - + //enable resume item if (action == @selector(resumeSelectedTorrents:)) { if (!canUseTable) return NO; - + for (Torrent * torrent in [fTableView selectedTorrents]) if (![torrent isActive] && ![torrent waitingToStart]) return YES; return NO; } - + //enable manual announce item if (action == @selector(announceSelectedTorrents:)) { if (!canUseTable) return NO; - + for (Torrent * torrent in [fTableView selectedTorrents]) if ([torrent canManualAnnounce]) return YES; return NO; } - + //enable reset cache item if (action == @selector(verifySelectedTorrents:)) { if (!canUseTable) return NO; - + for (Torrent * torrent in [fTableView selectedTorrents]) if (![torrent isMagnet]) return YES; return NO; } - + //enable move torrent file item if (action == @selector(moveDataFilesSelected:)) return canUseTable && [fTableView numberOfSelectedRows] > 0; - + //enable copy torrent file item if (action == @selector(copyTorrentFiles:)) { if (!canUseTable) return NO; - + for (Torrent * torrent in [fTableView selectedTorrents]) if (![torrent isMagnet]) return YES; return NO; } - + //enable copy torrent file item if (action == @selector(copyMagnetLinks:)) return canUseTable && [fTableView numberOfSelectedRows] > 0; - + //enable reverse sort item if (action == @selector(setSortReverse:)) { @@ -4419,14 +4419,14 @@ static void removeKeRangerRansomware() [menuItem setState: (isReverse == [fDefaults boolForKey: @"SortReverse"]) ? NSOnState : NSOffState]; return ![[fDefaults stringForKey: @"Sort"] isEqualToString: SORT_ORDER]; } - + //enable group sort item if (action == @selector(setSortByGroup:)) { [menuItem setState: [fDefaults boolForKey: @"SortByGroup"] ? NSOnState : NSOffState]; return YES; } - + if (action == @selector(toggleQuickLook:)) { const BOOL visible =[QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]; @@ -4434,10 +4434,10 @@ static void removeKeRangerRansomware() NSString * title = !visible ? NSLocalizedString(@"Quick Look", "View menu -> Quick Look") : NSLocalizedString(@"Close Quick Look", "View menu -> Quick Look"); [menuItem setTitle: title]; - + return YES; } - + return YES; } @@ -4455,13 +4455,13 @@ static void removeKeRangerRansomware() anyActive = YES; [torrent sleep]; //have to call on all, regardless if they are active } - + //if there are any running transfers, wait 15 seconds for them to stop if (anyActive) { sleep(15); } - + IOAllowPowerChange(fRootPort, (long) messageArgument); break; } @@ -4477,7 +4477,7 @@ static void removeKeRangerRansomware() return; } } - + IOAllowPowerChange(fRootPort, (long) messageArgument); break; @@ -4493,7 +4493,7 @@ static void removeKeRangerRansomware() { if (fQuitting) return nil; - + NSUInteger seeding = 0, downloading = 0; for (Torrent * torrent in fTorrents) { @@ -4503,29 +4503,29 @@ static void removeKeRangerRansomware() downloading++; else; } - + NSMenu * menu = [[NSMenu alloc] init]; - + if (seeding > 0) { NSString * title = [NSString stringWithFormat: NSLocalizedString(@"%d Seeding", "Dock item - Seeding"), seeding]; [menu addItemWithTitle: title action: nil keyEquivalent: @""]; } - + if (downloading > 0) { NSString * title = [NSString stringWithFormat: NSLocalizedString(@"%d Downloading", "Dock item - Downloading"), downloading]; [menu addItemWithTitle: title action: nil keyEquivalent: @""]; } - + if (seeding > 0 || downloading > 0) [menu addItem: [NSMenuItem separatorItem]]; - + [menu addItemWithTitle: NSLocalizedString(@"Pause All", "Dock item") action: @selector(stopAllTorrents:) keyEquivalent: @""]; [menu addItemWithTitle: NSLocalizedString(@"Resume All", "Dock item") action: @selector(resumeAllTorrents:) keyEquivalent: @""]; [menu addItem: [NSMenuItem separatorItem]]; [menu addItemWithTitle: NSLocalizedString(@"Speed Limit", "Dock item") action: @selector(toggleSpeedLimit:) keyEquivalent: @""]; - + return [menu autorelease]; } @@ -4533,7 +4533,7 @@ static void removeKeRangerRansomware() { //if auto size is enabled, the current frame shouldn't need to change NSRect frame = [fDefaults boolForKey: @"AutoSize"] ? [window frame] : [self sizedWindowFrame]; - + frame.size.width = [fDefaults boolForKey: @"SmallView"] ? [fWindow minSize].width : WINDOW_REGULAR_WIDTH; return frame; } @@ -4543,11 +4543,11 @@ static void removeKeRangerRansomware() if ([fDefaults boolForKey: @"AutoSize"]) { NSScrollView * scrollView = [fTableView enclosingScrollView]; - + [scrollView setHasVerticalScroller: NO]; [fWindow setFrame: [self sizedWindowFrame] display: YES animate: YES]; [scrollView setHasVerticalScroller: YES]; - + [self setWindowMinMaxToCurrent]; } } @@ -4556,11 +4556,11 @@ static void removeKeRangerRansomware() { NSUInteger groups = ([fDisplayedTorrents count] > 0 && ![[fDisplayedTorrents objectAtIndex: 0] isKindOfClass: [Torrent class]]) ? [fDisplayedTorrents count] : 0; - + CGFloat heightChange = (GROUP_SEPARATOR_HEIGHT + [fTableView intercellSpacing].height) * groups + ([fTableView rowHeight] + [fTableView intercellSpacing].height) * ([fTableView numberOfRows] - groups) - NSHeight([[fTableView enclosingScrollView] frame]); - + return [self windowFrameByAddingHeight: heightChange checkLimits: YES]; } @@ -4572,9 +4572,9 @@ static void removeKeRangerRansomware() { NSSize contentMinSize = [fWindow contentMinSize]; contentMinSize.height = [self minWindowContentSizeAllowed]; - + [fWindow setContentMinSize: contentMinSize]; - + NSSize contentMaxSize = [fWindow contentMaxSize]; contentMaxSize.height = FLT_MAX; [fWindow setContentMaxSize: contentMaxSize]; @@ -4584,12 +4584,12 @@ static void removeKeRangerRansomware() - (void) setWindowMinMaxToCurrent { const CGFloat height = NSHeight([[fWindow contentView] frame]); - + NSSize minSize = [fWindow contentMinSize], maxSize = [fWindow contentMaxSize]; minSize.height = height; maxSize.height = height; - + [fWindow setContentMinSize: minSize]; [fWindow setContentMaxSize: maxSize]; } @@ -4659,7 +4659,7 @@ static void removeKeRangerRansomware() - (NSDictionary *) registrationDictionaryForGrowl { NSArray * notifications = @[GROWL_DOWNLOAD_COMPLETE, GROWL_SEEDING_COMPLETE, GROWL_AUTO_ADD, GROWL_AUTO_SPEED_LIMIT]; - + return @{GROWL_NOTIFICATIONS_ALL : notifications, GROWL_NOTIFICATIONS_DEFAULT : notifications }; } @@ -4668,7 +4668,7 @@ static void removeKeRangerRansomware() { if (![clickContext isKindOfClass: [NSDictionary class]]) return; - + NSString * type = [clickContext objectForKey: @"Type"], * location; if (([type isEqualToString: GROWL_DOWNLOAD_COMPLETE] || [type isEqualToString: GROWL_SEEDING_COMPLETE]) && (location = [clickContext objectForKey: @"Location"])) @@ -4693,55 +4693,55 @@ static void removeKeRangerRansomware() *stop = YES; } }]; - + if (!torrent) { NSLog(@"No torrent found matching the given torrent struct from the RPC callback!"); return; } } - + dispatch_async(dispatch_get_main_queue(), ^{ switch (type) { case TR_RPC_TORRENT_ADDED: [self rpcAddTorrentStruct: torrentStruct]; break; - + case TR_RPC_TORRENT_STARTED: case TR_RPC_TORRENT_STOPPED: [self rpcStartedStoppedTorrent: torrent]; break; - + case TR_RPC_TORRENT_REMOVING: [self rpcRemoveTorrent: torrent deleteData: NO]; break; - + case TR_RPC_TORRENT_TRASHING: [self rpcRemoveTorrent: torrent deleteData: YES]; break; - + case TR_RPC_TORRENT_CHANGED: [self rpcChangedTorrent: torrent]; break; - + case TR_RPC_TORRENT_MOVED: [self rpcMovedTorrent: torrent]; break; - + case TR_RPC_SESSION_QUEUE_POSITIONS_CHANGED: [self rpcUpdateQueue]; break; - + case TR_RPC_SESSION_CHANGED: [fPrefsController rpcUpdatePrefs]; break; - + case TR_RPC_SESSION_CLOSE: fQuitRequested = YES; [NSApp terminate: self]; break; - + default: NSAssert1(NO, @"Unknown RPC command received: %d", type); } @@ -4754,24 +4754,24 @@ static void removeKeRangerRansomware() NSString * location = nil; if (tr_torrentGetDownloadDir(torrentStruct) != NULL) location = [NSString stringWithUTF8String: tr_torrentGetDownloadDir(torrentStruct)]; - + Torrent * torrent = [[Torrent alloc] initWithTorrentStruct: torrentStruct location: location lib: fLib]; - + //change the location if the group calls for it (this has to wait until after the torrent is created) if ([[GroupsController groups] usesCustomDownloadLocationForIndex: [torrent groupValue]]) { location = [[GroupsController groups] customDownloadLocationForIndex: [torrent groupValue]]; [torrent changeDownloadFolderBeforeUsing: location determinationType: TorrentDeterminationAutomatic]; } - + [torrent update]; [fTorrents addObject: torrent]; [torrent release]; - + if (!fAddingTransfers) fAddingTransfers = [[NSMutableSet alloc] init]; [fAddingTransfers addObject: torrent]; - + [self fullUpdateUI]; } @@ -4783,7 +4783,7 @@ static void removeKeRangerRansomware() - (void) rpcStartedStoppedTorrent: (Torrent *) torrent { [torrent update]; - + [self updateUI]; [self applyFilter]; [self updateTorrentHistory]; @@ -4792,7 +4792,7 @@ static void removeKeRangerRansomware() - (void) rpcChangedTorrent: (Torrent *) torrent { [torrent update]; - + if ([[fTableView selectedTorrents] containsObject: torrent]) { [fInfoController updateInfoStats]; //this will reload the file table @@ -4804,7 +4804,7 @@ static void removeKeRangerRansomware() { [torrent update]; [torrent updateTimeMachineExclude]; - + if ([[fTableView selectedTorrents] containsObject: torrent]) [fInfoController updateInfoStats]; } @@ -4813,11 +4813,11 @@ static void removeKeRangerRansomware() { for (Torrent * torrent in fTorrents) [torrent update]; - + NSSortDescriptor * descriptor = [NSSortDescriptor sortDescriptorWithKey: @"queuePosition" ascending: YES]; NSArray * descriptors = [NSArray arrayWithObject: descriptor]; [fTorrents sortUsingDescriptors: descriptors]; - + [self sortTorrents: YES]; } diff --git a/macosx/CreatorWindowController.h b/macosx/CreatorWindowController.h index a5c03da6c..73fa66b21 100644 --- a/macosx/CreatorWindowController.h +++ b/macosx/CreatorWindowController.h @@ -32,17 +32,17 @@ IBOutlet NSSegmentedControl * fTrackerAddRemoveControl; IBOutlet NSTextView * fCommentView; IBOutlet NSButton * fPrivateCheck, * fOpenCheck; - + IBOutlet NSView * fProgressView; IBOutlet NSProgressIndicator * fProgressIndicator; - + tr_metainfo_builder * fInfo; NSURL * fPath, * fLocation; NSMutableArray * fTrackers; - + NSTimer * fTimer; BOOL fStarted, fOpenWhenCreated; - + NSUserDefaults * fDefaults; } diff --git a/macosx/CreatorWindowController.m b/macosx/CreatorWindowController.m index 13975fd38..4a86248e8 100644 --- a/macosx/CreatorWindowController.m +++ b/macosx/CreatorWindowController.m @@ -51,7 +51,7 @@ NSURL * path; if (!(path = [CreatorWindowController chooseFile])) return nil; - + CreatorWindowController * creator = [[self alloc] initWithHandle: handle path: path]; [creator showWindow: nil]; return creator; @@ -69,10 +69,10 @@ if ((self = [super initWithWindowNibName: @"Creator"])) { fStarted = NO; - + fPath = [path retain]; fInfo = tr_metaInfoBuilderCreate([[fPath path] UTF8String]); - + if (fInfo->fileCount == 0) { NSAlert * alert = [[NSAlert alloc] init]; @@ -82,10 +82,10 @@ [alert setInformativeText: NSLocalizedString(@"There must be at least one file in a folder to create a torrent file.", "Create torrent -> no files -> warning")]; [alert setAlertStyle: NSWarningAlertStyle]; - + [alert runModal]; [alert release]; - + [self release]; return nil; } @@ -98,21 +98,21 @@ [alert setInformativeText: NSLocalizedString(@"A torrent file cannot be created for files with no size.", "Create torrent -> zero size -> warning")]; [alert setAlertStyle: NSWarningAlertStyle]; - + [alert runModal]; [alert release]; - + [self release]; return nil; } - + fDefaults = [NSUserDefaults standardUserDefaults]; - + //get list of trackers if (!(fTrackers = [[fDefaults arrayForKey: @"CreatorTrackers"] mutableCopy])) { fTrackers = [[NSMutableArray alloc] init]; - + //check for single tracker from versions before 1.3 NSString * tracker; if ((tracker = [fDefaults stringForKey: @"CreatorTracker"])) @@ -125,7 +125,7 @@ } } } - + //remove potentially invalid addresses for (NSInteger i = [fTrackers count]-1; i >= 0; i--) { @@ -139,21 +139,21 @@ - (void) awakeFromNib { [[self window] setRestorationClass: [self class]]; - + NSString * name = [fPath lastPathComponent]; - + [[self window] setTitle: name]; - + [fNameField setStringValue: name]; [fNameField setToolTip: [fPath path]]; - + const BOOL multifile = fInfo->isFolder; - + NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFileType: multifile ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [fPath pathExtension]]; [icon setSize: [fIconView frame].size]; [fIconView setImage: icon]; - + NSString * statusString = [NSString stringForFileSize: fInfo->totalSize]; if (multifile) { @@ -167,14 +167,14 @@ statusString = [NSString stringWithFormat: @"%@, %@", fileString, statusString]; } [fStatusField setStringValue: statusString]; - + if (fInfo->pieceCount == 1) [fPiecesField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"1 piece, %@", "Create torrent -> info"), [NSString stringForFileSize: fInfo->pieceSize]]]; else [fPiecesField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%d pieces, %@ each", "Create torrent -> info"), fInfo->pieceCount, [NSString stringForFileSize: fInfo->pieceSize]]]; - + fLocation = [[[fDefaults URLForKey: @"CreatorLocationURL"] URLByAppendingPathComponent: [name stringByAppendingPathExtension: @"torrent"]] retain]; if (!fLocation) { @@ -184,11 +184,11 @@ fLocation = [[NSURL alloc] initFileURLWithPath: [[location stringByExpandingTildeInPath] stringByAppendingPathComponent: [name stringByAppendingPathExtension: @"torrent"]]]; } [self updateLocationField]; - + //set previously saved values if ([fDefaults objectForKey: @"CreatorPrivate"]) [fPrivateCheck setState: [fDefaults boolForKey: @"CreatorPrivate"] ? NSOnState : NSOffState]; - + [fOpenCheck setState: [fDefaults boolForKey: @"CreatorOpen"] ? NSOnState : NSOffState]; } @@ -196,15 +196,15 @@ { [fPath release]; [fLocation release]; - + [fTrackers release]; - + if (fInfo) tr_metaInfoBuilderFree(fInfo); - + [fTimer invalidate]; [fTimer release]; - + [super dealloc]; } @@ -216,7 +216,7 @@ completionHandler(nil, [NSError errorWithDomain: NSURLErrorDomain code: NSURLErrorCannotOpenFile userInfo: nil]); return; } - + NSWindow * window = [[self createTorrentFile: [(Controller *)[NSApp delegate] sessionHandle] forFile: path] window]; completionHandler(window, nil); } @@ -236,11 +236,11 @@ [fLocation release]; fLocation = [[coder decodeObjectForKey: @"TRCreatorLocation"] retain]; [self updateLocationField]; - + [fTrackers release]; fTrackers = [[coder decodeObjectForKey: @"TRCreatorTrackers"] retain]; [fTrackerTable reloadData]; - + [fOpenCheck setState: [coder decodeIntegerForKey: @"TRCreatorOpenCheck"]]; [fPrivateCheck setState: [coder decodeIntegerForKey: @"TRCreatorPrivateCheck"]]; [fCommentView setString: [coder decodeObjectForKey: @"TRCreatorPrivateComment"]]; @@ -252,14 +252,14 @@ [panel setPrompt: NSLocalizedString(@"Select", "Create torrent -> location sheet -> button")]; [panel setMessage: NSLocalizedString(@"Select the name and location for the torrent file.", - "Create torrent -> location sheet -> message")]; - + "Create torrent -> location sheet -> message")]; + [panel setAllowedFileTypes: [NSArray arrayWithObjects: @"org.bittorrent.torrent", @"torrent", nil]]; [panel setCanSelectHiddenExtension: YES]; - + [panel setDirectoryURL: [fLocation URLByDeletingLastPathComponent]]; [panel setNameFieldStringValue: [fLocation lastPathComponent]]; - + [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) { @@ -275,14 +275,14 @@ //make sure the trackers are no longer being verified if ([fTrackerTable editedRow] != -1) [[self window] endEditingFor: fTrackerTable]; - + const BOOL isPrivate = [fPrivateCheck state] == NSOnState; if ([fTrackers count] == 0 && [fDefaults boolForKey: isPrivate ? @"WarningCreatorPrivateBlankAddress" : @"WarningCreatorBlankAddress"]) { NSAlert * alert = [[NSAlert alloc] init]; [alert setMessageText: NSLocalizedString(@"There are no tracker addresses.", "Create torrent -> blank address -> title")]; - + NSString * infoString = isPrivate ? NSLocalizedString(@"A transfer marked as private with no tracker addresses will be unable to connect to peers." " The torrent file will only be useful if you plan to upload the file to a tracker website" @@ -290,7 +290,7 @@ : NSLocalizedString(@"The transfer will not contact trackers for peers, and will have to rely solely on" " non-tracker peer discovery methods such as PEX and DHT to download and seed.", "Create torrent -> blank address -> message"); - + [alert setInformativeText: infoString]; [alert addButtonWithTitle: NSLocalizedString(@"Create", "Create torrent -> blank address -> button")]; [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Create torrent -> blank address -> button")]; @@ -334,11 +334,11 @@ //don't allow add/remove when currently adding - it leads to weird results if ([fTrackerTable editedRow] != -1) return; - + if ([[sender cell] tagForSegment: [sender selectedSegment]] == TRACKER_REMOVE_TAG) { [fTrackers removeObjectsAtIndexes: [fTrackerTable selectedRowIndexes]]; - + [fTrackerTable deselectAll: self]; [fTrackerTable reloadData]; } @@ -346,7 +346,7 @@ { [fTrackers addObject: @""]; [fTrackerTable reloadData]; - + const NSInteger row = [fTrackers count] - 1; [fTrackerTable selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO]; [fTrackerTable editColumn: 0 row: row withEvent: nil select: YES]; @@ -357,12 +357,12 @@ row: (NSInteger) row { NSString * tracker = (NSString *)object; - + tracker = [tracker stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; - + if ([tracker rangeOfString: @"://"].location == NSNotFound) tracker = [@"http://" stringByAppendingString: tracker]; - + if (!tr_urlIsValidTracker([tracker UTF8String])) { NSBeep(); @@ -370,7 +370,7 @@ } else [fTrackers replaceObjectAtIndex: row withObject: tracker]; - + [fTrackerTable deselectAll: self]; [fTrackerTable reloadData]; } @@ -384,7 +384,7 @@ { NSArray * addresses = [fTrackers objectsAtIndexes: [fTrackerTable selectedRowIndexes]]; NSString * text = [addresses componentsJoinedByString: @"\n"]; - + NSPasteboard * pb = [NSPasteboard generalPasteboard]; [pb clearContents]; [pb writeObjects: [NSArray arrayWithObject: text]]; @@ -393,46 +393,46 @@ - (BOOL) validateMenuItem: (NSMenuItem *) menuItem { const SEL action = [menuItem action]; - + if (action == @selector(copy:)) return [[self window] firstResponder] == fTrackerTable && [fTrackerTable numberOfSelectedRows] > 0; - + if (action == @selector(paste:)) return [[self window] firstResponder] == fTrackerTable && [[NSPasteboard generalPasteboard] canReadObjectForClasses: [NSArray arrayWithObject: [NSString class]] options: nil]; - + return YES; } - (void) paste: (id) sender { NSMutableArray * tempTrackers = [NSMutableArray array]; - + NSArray * items = [[NSPasteboard generalPasteboard] readObjectsForClasses: [NSArray arrayWithObject: [NSString class]] options: nil]; NSAssert(items != nil, @"no string items to paste; should not be able to call this method"); - + for (NSString * pbItem in items) { for (NSString * tracker in [pbItem componentsSeparatedByString: @"\n"]) [tempTrackers addObject: tracker]; } - + BOOL added = NO; - + for (NSString * tracker in tempTrackers) { tracker = [tracker stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; - + if ([tracker rangeOfString: @"://"].location == NSNotFound) tracker = [@"http://" stringByAppendingString: tracker]; - + if (tr_urlIsValidTracker([tracker UTF8String])) { [fTrackers addObject: tracker]; added = YES; } } - + if (added) { [fTrackerTable deselectAll: self]; @@ -456,7 +456,7 @@ + (NSURL *) chooseFile { NSOpenPanel * panel = [NSOpenPanel openPanel]; - + [panel setTitle: NSLocalizedString(@"Create Torrent File", "Create torrent -> select file")]; [panel setPrompt: NSLocalizedString(@"Select", "Create torrent -> select file")]; [panel setAllowsMultipleSelection: NO]; @@ -465,7 +465,7 @@ [panel setCanCreateDirectories: NO]; [panel setMessage: NSLocalizedString(@"Select a file or folder for the torrent file.", "Create torrent -> select file")]; - + BOOL success = [panel runModal] == NSOKButton; return success ? [[panel URLs] objectAtIndex: 0] : nil; } @@ -478,9 +478,9 @@ if ([fPrivateCheck state] == NSOnState) [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningCreatorPrivateBlankAddress"]; } - + [alert release]; - + if (returnCode == NSAlertFirstButtonReturn) [self performSelectorOnMainThread: @selector(createReal) withObject: nil waitUntilDone: NO]; } @@ -500,17 +500,17 @@ "Create torrent -> directory doesn't exist warning -> warning"), [[fLocation URLByDeletingLastPathComponent] path]]]; [alert setAlertStyle: NSWarningAlertStyle]; - + [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: nil contextInfo: nil]; return; } - + //check if a file with the same name and location already exists if ([fLocation checkResourceIsReachableAndReturnError: NULL]) { NSArray * pathComponents = [fLocation pathComponents]; NSInteger count = [pathComponents count]; - + NSAlert * alert = [[[NSAlert alloc] init] autorelease]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> file already exists warning -> button")]; [alert setMessageText: NSLocalizedString(@"A torrent file with this name and directory cannot be created.", @@ -521,20 +521,20 @@ "Create torrent -> file already exists warning -> warning"), [pathComponents objectAtIndex: count-1], [pathComponents objectAtIndex: count-2]]]; [alert setAlertStyle: NSWarningAlertStyle]; - + [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: nil contextInfo: nil]; return; } - + //parse non-empty tracker strings tr_tracker_info * trackerInfo = tr_new0(tr_tracker_info, [fTrackers count]); - + for (NSUInteger i = 0; i < [fTrackers count]; i++) { trackerInfo[i].announce = (char *)[[fTrackers objectAtIndex: i] UTF8String]; trackerInfo[i].tier = i; } - + //store values [fDefaults setObject: fTrackers forKey: @"CreatorTrackers"]; [fDefaults setBool: [fPrivateCheck state] == NSOnState forKey: @"CreatorPrivate"]; @@ -543,11 +543,11 @@ [fDefaults setURL: [fLocation URLByDeletingLastPathComponent] forKey: @"CreatorLocationURL"]; [[self window] setRestorable: NO]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"BeginCreateTorrentFile" object: fLocation userInfo: nil]; tr_makeMetaInfo(fInfo, [[fLocation path] UTF8String], trackerInfo, [fTrackers count], [[fCommentView string] UTF8String], [fPrivateCheck state] == NSOnState); tr_free(trackerInfo); - + fTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: @selector(checkProgress) userInfo: nil repeats: YES] retain]; } @@ -558,7 +558,7 @@ [fTimer invalidate]; [fTimer release]; fTimer = nil; - + NSAlert * alert; switch (fInfo->result) { @@ -569,21 +569,21 @@ [[fPath URLByDeletingLastPathComponent] path], @"Path", nil]; [[NSNotificationCenter defaultCenter] postNotificationName: @"OpenCreatedTorrentFile" object: self userInfo: dict]; } - + [[self window] close]; break; - + case TR_MAKEMETA_CANCELLED: [[self window] close]; break; - + default: alert = [[[NSAlert alloc] init] autorelease]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> failed -> button")]; [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"Creation of \"%@\" failed.", "Create torrent -> failed -> title"), [fLocation lastPathComponent]]]; [alert setAlertStyle: NSWarningAlertStyle]; - + if (fInfo->result == TR_MAKEMETA_IO_READ) [alert setInformativeText: [NSString stringWithFormat: NSLocalizedString(@"Could not read \"%s\": %s.", "Create torrent -> failed -> warning"), fInfo->errfile, strerror(fInfo->my_errno)]]; @@ -593,7 +593,7 @@ else //invalid url should have been caught before creating [alert setInformativeText: [NSString stringWithFormat: @"%@ (%d)", NSLocalizedString(@"An unknown error has occurred.", "Create torrent -> failed -> warning"), fInfo->result]]; - + [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: @selector(failureSheetClosed:returnCode:contextInfo:) contextInfo: nil]; } @@ -601,30 +601,30 @@ else { [fProgressIndicator setDoubleValue: (double)fInfo->pieceIndex / fInfo->pieceCount]; - + if (!fStarted) { fStarted = YES; - + [fProgressView setHidden: YES]; - + NSWindow * window = [self window]; [window setFrameAutosaveName: @""]; - + NSRect windowRect = [window frame]; CGFloat difference = [fProgressView frame].size.height - [[window contentView] frame].size.height; windowRect.origin.y -= difference; windowRect.size.height += difference; - + //don't allow vertical resizing CGFloat height = windowRect.size.height; [window setMinSize: NSMakeSize([window minSize].width, height)]; [window setMaxSize: NSMakeSize([window maxSize].width, height)]; - + [window setContentView: fProgressView]; [window setFrame: windowRect display: YES animate: YES]; [fProgressView setHidden: NO]; - + [[window standardWindowButton: NSWindowCloseButton] setEnabled: NO]; } } diff --git a/macosx/DragOverlayView.h b/macosx/DragOverlayView.h index 43294bc5c..1f9b3ec4a 100644 --- a/macosx/DragOverlayView.h +++ b/macosx/DragOverlayView.h @@ -25,7 +25,7 @@ @interface DragOverlayView : NSView { NSImage * fBadge; - + NSDictionary * fMainLineAttributes, * fSubLineAttributes; } diff --git a/macosx/DragOverlayView.m b/macosx/DragOverlayView.m index c1686612c..c21a08290 100644 --- a/macosx/DragOverlayView.m +++ b/macosx/DragOverlayView.m @@ -35,23 +35,23 @@ NSShadow * stringShadow = [[NSShadow alloc] init]; [stringShadow setShadowOffset: NSMakeSize(2.0, -2.0)]; [stringShadow setShadowBlurRadius: 4.0]; - + NSFont * bigFont = [NSFont boldSystemFontOfSize: 18.0], * smallFont = [NSFont systemFontOfSize: 14.0]; - + NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [paragraphStyle setLineBreakMode: NSLineBreakByTruncatingMiddle]; - + fMainLineAttributes = [[NSDictionary alloc] initWithObjectsAndKeys: [NSColor whiteColor], NSForegroundColorAttributeName, bigFont, NSFontAttributeName, stringShadow, NSShadowAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; - + fSubLineAttributes = [[NSDictionary alloc] initWithObjectsAndKeys: [NSColor whiteColor], NSForegroundColorAttributeName, smallFont, NSFontAttributeName, stringShadow, NSShadowAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; - + [stringShadow release]; [paragraphStyle release]; } @@ -61,47 +61,47 @@ - (void) dealloc { [fBadge release]; - + [fMainLineAttributes release]; [fSubLineAttributes release]; - + [super dealloc]; } - (void) setOverlay: (NSImage *) icon mainLine: (NSString *) mainLine subLine: (NSString *) subLine { [fBadge release]; - + //create badge const NSRect badgeRect = NSMakeRect(0.0, 0.0, 325.0, 84.0); - + fBadge = [[NSImage alloc] initWithSize: badgeRect.size]; [fBadge lockFocus]; - + NSBezierPath * bp = [NSBezierPath bezierPathWithRoundedRect: badgeRect xRadius: 15.0 yRadius: 15.0]; [[NSColor colorWithCalibratedWhite: 0.0 alpha: 0.75] set]; [bp fill]; - + //place icon [icon drawInRect: NSMakeRect(PADDING, (NSHeight(badgeRect) - ICON_WIDTH) * 0.5, ICON_WIDTH, ICON_WIDTH) fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0]; - + //place main text const NSSize mainLineSize = [mainLine sizeWithAttributes: fMainLineAttributes]; const NSSize subLineSize = [subLine sizeWithAttributes: fSubLineAttributes]; - + NSRect lineRect = NSMakeRect(PADDING + ICON_WIDTH + 5.0, (NSHeight(badgeRect) + (subLineSize.height + 2.0 - mainLineSize.height)) * 0.5, NSWidth(badgeRect) - (PADDING + ICON_WIDTH + 2.0) - PADDING, mainLineSize.height); [mainLine drawInRect: lineRect withAttributes: fMainLineAttributes]; - + //place sub text lineRect.origin.y -= subLineSize.height + 2.0; lineRect.size.height = subLineSize.height; [subLine drawInRect: lineRect withAttributes: fSubLineAttributes]; - + [fBadge unlockFocus]; - + [self setNeedsDisplay: YES]; } diff --git a/macosx/DragOverlayWindow.h b/macosx/DragOverlayWindow.h index 3d50ae44f..71a4b8ee9 100644 --- a/macosx/DragOverlayWindow.h +++ b/macosx/DragOverlayWindow.h @@ -26,7 +26,7 @@ @interface DragOverlayWindow : NSWindow { tr_session * fLib; - + NSViewAnimation * fFadeInAnimation, * fFadeOutAnimation; } diff --git a/macosx/DragOverlayWindow.m b/macosx/DragOverlayWindow.m index 092203248..98efe9d5c 100644 --- a/macosx/DragOverlayWindow.m +++ b/macosx/DragOverlayWindow.m @@ -38,33 +38,33 @@ backing: NSBackingStoreBuffered defer: NO]))) { fLib = lib; - + [self setBackgroundColor: [NSColor colorWithCalibratedWhite: 0.0 alpha: 0.5]]; [self setAlphaValue: 0.0]; [self setOpaque: NO]; [self setHasShadow: NO]; - + DragOverlayView * view = [[DragOverlayView alloc] initWithFrame: [self frame]]; [self setContentView: view]; [view release]; - + [self setReleasedWhenClosed: NO]; [self setIgnoresMouseEvents: YES]; - + fFadeInAnimation = [[NSViewAnimation alloc] initWithViewAnimations: [NSArray arrayWithObject: [NSDictionary dictionaryWithObjectsAndKeys: self, NSViewAnimationTargetKey, NSViewAnimationFadeInEffect, NSViewAnimationEffectKey, nil]]]; [fFadeInAnimation setDuration: 0.15]; [fFadeInAnimation setAnimationBlockingMode: NSAnimationNonblockingThreaded]; - + fFadeOutAnimation = [[NSViewAnimation alloc] initWithViewAnimations: [NSArray arrayWithObject: [NSDictionary dictionaryWithObjectsAndKeys: self, NSViewAnimationTargetKey, NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey, nil]]]; [fFadeOutAnimation setDuration: 0.5]; [fFadeOutAnimation setAnimationBlockingMode: NSAnimationNonblockingThreaded]; - + [window addChildWindow: self ordered: NSWindowAbove]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resizeWindow) name: NSWindowDidResizeNotification object: window]; } @@ -74,10 +74,10 @@ - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fFadeInAnimation release]; [fFadeOutAnimation release]; - + [super dealloc]; } @@ -85,11 +85,11 @@ { uint64_t size = 0; NSInteger count = 0; - + NSString * name; BOOL folder; NSInteger fileCount = 0; - + for (NSString * file in files) { if ([[[NSWorkspace sharedWorkspace] typeOfFile: file error: NULL] isEqualToString: @"org.bittorrent.torrent"] @@ -103,7 +103,7 @@ count++; size += info.totalSize; fileCount += info.fileCount; - + //only useful when one torrent if (count == 1) { @@ -115,10 +115,10 @@ tr_ctorFree(ctor); } } - + if (count <= 0) return; - + //set strings and icon NSString * secondString = [NSString stringForFileSize: size]; if (count > 1 || folder) @@ -131,7 +131,7 @@ [NSString formattedUInteger: fileCount]]; secondString = [NSString stringWithFormat: @"%@, %@", fileString, secondString]; } - + NSImage * icon; if (count == 1) icon = [[NSWorkspace sharedWorkspace] iconForFileType: folder ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [name pathExtension]]; @@ -142,7 +142,7 @@ secondString = [secondString stringByAppendingString: @" total"]; icon = [NSImage imageNamed: @"TransmissionDocument.icns"]; } - + [[self contentView] setOverlay: icon mainLine: name subLine: secondString]; [self fadeIn]; } diff --git a/macosx/ExpandedPathToIconTransformer.m b/macosx/ExpandedPathToIconTransformer.m index e2030ffd7..3dff06aa2 100644 --- a/macosx/ExpandedPathToIconTransformer.m +++ b/macosx/ExpandedPathToIconTransformer.m @@ -40,7 +40,7 @@ { if (!value) return nil; - + NSString * path = [value stringByExpandingTildeInPath]; NSImage * icon; //show a folder icon if the folder doesn't exist @@ -48,9 +48,9 @@ icon = [[NSWorkspace sharedWorkspace] iconForFileType: NSFileTypeForHFSTypeCode(kGenericFolderIcon)]; else icon = [[NSWorkspace sharedWorkspace] iconForFile: path]; - + [icon setSize: NSMakeSize(16.0, 16.0)]; - + return icon; } diff --git a/macosx/FileListNode.h b/macosx/FileListNode.h index 26345d89d..bec03331d 100644 --- a/macosx/FileListNode.h +++ b/macosx/FileListNode.h @@ -27,7 +27,7 @@ @interface FileListNode : NSObject { NSMutableIndexSet * fIndexes; - + NSString * fName; NSString * fPath; Torrent * fTorrent; diff --git a/macosx/FileListNode.m b/macosx/FileListNode.m index 2ab55b243..5b33b1e08 100644 --- a/macosx/FileListNode.m +++ b/macosx/FileListNode.m @@ -47,7 +47,7 @@ fChildren = [[NSMutableArray alloc] init]; fSize = 0; } - + return self; } @@ -58,21 +58,21 @@ fSize = size; [fIndexes addIndex: index]; } - + return self; } - (void) insertChild: (FileListNode *) child { NSAssert(fIsFolder, @"method can only be invoked on folders"); - + [fChildren addObject: child]; } - (void) insertIndex: (NSUInteger) index withSize: (uint64_t) size { NSAssert(fIsFolder, @"method can only be invoked on folders"); - + [fIndexes addIndex: index]; fSize += size; } @@ -112,7 +112,7 @@ - (NSMutableArray *) children { NSAssert(fIsFolder, @"method can only be invoked on folders"); - + return fChildren; } @@ -121,10 +121,10 @@ NSParameterAssert(oldName != nil); NSParameterAssert(newName != nil); NSParameterAssert(path != nil); - + NSArray * lookupPathComponents = [path pathComponents]; NSArray * thesePathComponents = [self.path pathComponents]; - + if ([lookupPathComponents isEqualToArray: thesePathComponents]) //this node represents what's being renamed { if ([oldName isEqualToString: self.name]) @@ -140,18 +140,18 @@ const BOOL allSame = NSNotFound == [lookupPathComponents indexOfObjectWithOptions: NSEnumerationConcurrent passingTest: ^BOOL(NSString * name, NSUInteger idx, BOOL * stop) { return ![name isEqualToString: [thesePathComponents objectAtIndex: idx]]; }]; - + if (allSame) { NSString * oldPathPrefix = [path stringByAppendingPathComponent: oldName]; NSString * newPathPrefix = [path stringByAppendingPathComponent: newName]; - + [fPath autorelease]; fPath = [[fPath stringByReplacingCharactersInRange: NSMakeRange(0, [oldPathPrefix length]) withString: newPathPrefix] retain]; return YES; } } - + return NO; } @@ -166,12 +166,12 @@ fIsFolder = isFolder; fName = [name copy]; fPath = [path copy]; - + fIndexes = [[NSMutableIndexSet alloc] init]; - + fTorrent = torrent; } - + return self; } diff --git a/macosx/FileNameCell.m b/macosx/FileNameCell.m index 86adde543..604eb17d7 100644 --- a/macosx/FileNameCell.m +++ b/macosx/FileNameCell.m @@ -56,18 +56,18 @@ { NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [paragraphStyle setLineBreakMode: NSLineBreakByTruncatingMiddle]; - + fTitleAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys: [NSFont messageFontOfSize: 12.0], NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; - + NSMutableParagraphStyle * statusParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [statusParagraphStyle setLineBreakMode: NSLineBreakByTruncatingTail]; - + fStatusAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys: [NSFont messageFontOfSize: 9.0], NSFontAttributeName, statusParagraphStyle, NSParagraphStyleAttributeName, nil]; - + [paragraphStyle release]; [statusParagraphStyle release]; } @@ -78,17 +78,17 @@ { [fTitleAttributes release]; [fStatusAttributes release]; - + [super dealloc]; } - (id) copyWithZone: (NSZone *) zone { FileNameCell * copy = [super copyWithZone: zone]; - + copy->fTitleAttributes = [fTitleAttributes retain]; copy->fStatusAttributes = [fStatusAttributes retain]; - + return copy; } @@ -101,13 +101,13 @@ - (NSRect) imageRectForBounds: (NSRect) bounds { NSRect result = bounds; - + result.origin.x += PADDING_HORIZONAL; - + const CGFloat IMAGE_SIZE = [(FileListNode *)[self objectValue] isFolder] ? IMAGE_FOLDER_SIZE : IMAGE_ICON_SIZE; result.origin.y += (result.size.height - IMAGE_SIZE) * 0.5; result.size = NSMakeSize(IMAGE_SIZE, IMAGE_SIZE); - + return result; } @@ -115,7 +115,7 @@ { //icon [[self image] drawInRect: [self imageRectForBounds: cellFrame] fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; - + NSColor * titleColor, * statusColor; if ([self backgroundStyle] == NSBackgroundStyleDark) titleColor = statusColor = [NSColor whiteColor]; @@ -126,15 +126,15 @@ titleColor = [NSColor controlTextColor]; statusColor = [NSColor darkGrayColor]; } - + [fTitleAttributes setObject: titleColor forKey: NSForegroundColorAttributeName]; [fStatusAttributes setObject: statusColor forKey: NSForegroundColorAttributeName]; - + //title NSAttributedString * titleString = [self attributedTitle]; NSRect titleRect = [self rectForTitleWithString: titleString inBounds: cellFrame]; [titleString drawInRect: titleRect]; - + //status NSAttributedString * statusString = [self attributedStatus]; NSRect statusRect = [self rectForStatusWithString: statusString withTitleRect: titleRect inBounds: cellFrame]; @@ -145,14 +145,14 @@ { NSAttributedString * titleString = [self attributedTitle]; NSRect realRect = [self rectForTitleWithString: titleString inBounds: cellFrame]; - + if ([titleString size].width > NSWidth(realRect) && NSMouseInRect([view convertPoint: [[view window] mouseLocationOutsideOfEventStream] fromView: nil], realRect, [view isFlipped])) { realRect.size.width = [titleString size].width; return NSInsetRect(realRect, -PADDING_EXPANSION_FRAME, -PADDING_EXPANSION_FRAME); } - + return NSZeroRect; } @@ -160,7 +160,7 @@ { cellFrame.origin.x += PADDING_EXPANSION_FRAME; cellFrame.origin.y += PADDING_EXPANSION_FRAME; - + [fTitleAttributes setObject: [NSColor controlTextColor] forKey: NSForegroundColorAttributeName]; NSAttributedString * titleString = [self attributedTitle]; [titleString drawInRect: cellFrame]; @@ -173,7 +173,7 @@ - (NSRect) rectForTitleWithString: (NSAttributedString *) string inBounds: (NSRect) bounds { const NSSize titleSize = [string size]; - + //no right padding, so that there's not too much space between this and the priority image NSRect result; if (![(FileListNode *)[self objectValue] isFolder]) @@ -189,14 +189,14 @@ result.size.width = MIN(titleSize.width, NSMaxX(bounds) - NSMinX(result)); } result.size.height = titleSize.height; - + return result; } - (NSRect) rectForStatusWithString: (NSAttributedString *) string withTitleRect: (NSRect) titleRect inBounds: (NSRect) bounds { const NSSize statusSize = [string size]; - + NSRect result; if (![(FileListNode *)[self objectValue] isFolder]) { @@ -211,7 +211,7 @@ result.size.width = NSMaxX(bounds) - NSMaxX(titleRect); } result.size.height = statusSize.height; - + return result; } @@ -225,13 +225,13 @@ { FileListNode * node = (FileListNode *)[self objectValue]; Torrent * torrent = [node torrent]; - + const CGFloat progress = [torrent fileProgress: node]; NSString * percentString = [NSString percentString: progress longDecimals: YES]; - + NSString * status = [NSString stringWithFormat: NSLocalizedString(@"%@ of %@", "Inspector -> Files tab -> file status string"), percentString, [NSString stringForFileSize: [node size]]]; - + return [[[NSAttributedString alloc] initWithString: status attributes: fStatusAttributes] autorelease]; } diff --git a/macosx/FileOutlineController.h b/macosx/FileOutlineController.h index 8191c76ce..f8882b45a 100644 --- a/macosx/FileOutlineController.h +++ b/macosx/FileOutlineController.h @@ -29,9 +29,9 @@ { Torrent * fTorrent; NSMutableArray * fFileList; - + IBOutlet FileOutlineView * fOutline; - + NSString * fFilterText; } diff --git a/macosx/FileOutlineController.m b/macosx/FileOutlineController.m index ab1cdb7b2..a0b8c3700 100644 --- a/macosx/FileOutlineController.m +++ b/macosx/FileOutlineController.m @@ -59,16 +59,16 @@ typedef enum - (void) awakeFromNib { fFileList = [[NSMutableArray alloc] init]; - + [fOutline setDoubleAction: @selector(revealFile:)]; [fOutline setTarget: self]; - + //set table header tool tips [[fOutline tableColumnWithIdentifier: @"Check"] setHeaderToolTip: NSLocalizedString(@"Download", "file table -> header tool tip")]; [[fOutline tableColumnWithIdentifier: @"Priority"] setHeaderToolTip: NSLocalizedString(@"Priority", "file table -> header tool tip")]; - + [fOutline setMenu: [self menu]]; - + [self setTorrent: nil]; } @@ -76,7 +76,7 @@ typedef enum { [fFileList release]; [fFilterText release]; - + [super dealloc]; } @@ -88,12 +88,12 @@ typedef enum - (void) setTorrent: (Torrent *) torrent { fTorrent = torrent; - + [fFileList setArray: [fTorrent fileList]]; - + [fFilterText release]; fFilterText = nil; - + [fOutline reloadData]; [fOutline deselectAll: nil]; //do this after reloading the data #4575 } @@ -106,18 +106,18 @@ typedef enum text = nil; components = nil; } - + if ((!text && !fFilterText) || (text && fFilterText && [text isEqualToString: fFilterText])) return; [fOutline beginUpdates]; - + NSUInteger currentIndex = 0, totalCount = 0; NSMutableArray * itemsToAdd = [NSMutableArray array]; NSMutableIndexSet * itemsToAddIndexes = [NSMutableIndexSet indexSet]; - + NSMutableDictionary * removedIndexesForParents = nil; //ugly, but we can't modify the actual file nodes - + NSArray * tempList = !text ? [fTorrent fileList] : [fTorrent flatFileList]; for (FileListNode * item in tempList) { @@ -132,12 +132,12 @@ typedef enum } }]; } - + if (!filter) { FileListNode * parent = nil; NSUInteger previousIndex = ![item isFolder] ? [self findFileNode: item inList: fFileList atIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(currentIndex, [fFileList count]-currentIndex)] currentParent: nil finalParent: &parent] : NSNotFound; - + if (previousIndex == NSNotFound) { [itemsToAdd addObject: item]; @@ -156,11 +156,11 @@ typedef enum else { [fFileList insertObject: item atIndex: currentIndex]; - + //figure out the index within the semi-edited table - UGLY if (!removedIndexesForParents) removedIndexesForParents = [NSMutableDictionary dictionary]; - + NSMutableIndexSet * removedIndexes = [removedIndexesForParents objectForKey: parent]; if (!removedIndexes) { @@ -173,17 +173,17 @@ typedef enum previousIndex -= [removedIndexes countOfIndexesInRange: NSMakeRange(0, previousIndex)]; } } - + if (move) [fOutline moveItemAtIndex: previousIndex inParent: parent toIndex: currentIndex inParent: nil]; - + ++currentIndex; } - + ++totalCount; } } - + //remove trailing items - those are the unused if (currentIndex < [fFileList count]) { @@ -191,13 +191,13 @@ typedef enum [fFileList removeObjectsInRange: removeRange]; [fOutline removeItemsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: removeRange] inParent: nil withAnimation: NSTableViewAnimationSlideDown]; } - + //add new items [fFileList insertObjects: itemsToAdd atIndexes: itemsToAddIndexes]; [fOutline insertItemsAtIndexes: itemsToAddIndexes inParent: nil withAnimation: NSTableViewAnimationSlideUp]; [fOutline endUpdates]; - + [fFilterText release]; fFilterText = [text retain]; } @@ -205,7 +205,7 @@ typedef enum - (void) refresh { [fTorrent updateFileStat]; - + [fOutline setNeedsDisplay: YES]; } @@ -226,7 +226,7 @@ typedef enum } } -- (BOOL) outlineView: (NSOutlineView *) outlineView isItemExpandable: (id) item +- (BOOL) outlineView: (NSOutlineView *) outlineView isItemExpandable: (id) item { return [(FileListNode *)item isFolder]; } @@ -252,7 +252,7 @@ typedef enum else if ([identifier isEqualToString: @"Priority"]) { [cell setRepresentedObject: item]; - + NSInteger hoveredRow = [fOutline hoveredRow]; [(FilePriorityCell *)cell setHovered: hoveredRow != -1 && hoveredRow == [fOutline rowForItem: item]]; } @@ -269,10 +269,10 @@ typedef enum indexSet = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTorrent fileCount])]; else indexSet = [(FileListNode *)item indexes]; - + [fTorrent setFileCheckState: [object intValue] != NSOffState ? NSOnState : NSOffState forIndexes: indexSet]; [fOutline setNeedsDisplay: YES]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; } } @@ -328,7 +328,7 @@ typedef enum } } else; - + return nil; } @@ -343,12 +343,12 @@ typedef enum - (void) setCheck: (id) sender { NSInteger state = [sender tag] == FILE_UNCHECK_TAG ? NSOffState : NSOnState; - + NSIndexSet * indexSet = [fOutline selectedRowIndexes]; NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet]; for (NSInteger i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i]) [itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]]; - + [fTorrent setFileCheckState: state forIndexes: itemIndexes]; [fOutline setNeedsDisplay: YES]; } @@ -359,13 +359,13 @@ typedef enum NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet]; for (NSInteger i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i]) [itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]]; - + [fTorrent setFileCheckState: NSOnState forIndexes: itemIndexes]; - + NSMutableIndexSet * remainingItemIndexes = [NSMutableIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTorrent fileCount])]; [remainingItemIndexes removeIndexes: itemIndexes]; [fTorrent setFileCheckState: NSOffState forIndexes: remainingItemIndexes]; - + [fOutline setNeedsDisplay: YES]; } @@ -397,12 +397,12 @@ typedef enum case FILE_PRIORITY_LOW_TAG: priority = TR_PRI_LOW; } - + NSIndexSet * indexSet = [fOutline selectedRowIndexes]; NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet]; for (NSInteger i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i]) [itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]]; - + [fTorrent setFilePriority: priority forIndexes: itemIndexes]; [fOutline setNeedsDisplay: YES]; } @@ -417,7 +417,7 @@ typedef enum if (path) [paths addObject: [NSURL fileURLWithPath: path]]; } - + if ([paths count] > 0) [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs: paths]; } @@ -426,7 +426,7 @@ typedef enum { NSIndexSet * indexes = [fOutline selectedRowIndexes]; NSAssert([indexes count] == 1, @"1 file needs to be selected to rename, but %ld are selected", [indexes count]); - + FileListNode * node = [fOutline itemAtRow: [indexes firstIndex]]; Torrent * torrent = [node torrent]; if (![torrent isFolder]) @@ -454,9 +454,9 @@ typedef enum { if (!fTorrent) return NO; - + SEL action = [menuItem action]; - + if (action == @selector(revealFile:)) { NSIndexSet * indexSet = [fOutline selectedRowIndexes]; @@ -465,34 +465,34 @@ typedef enum return YES; return NO; } - + if (action == @selector(setCheck:)) { if ([fOutline numberOfSelectedRows] == 0) return NO; - + NSIndexSet * indexSet = [fOutline selectedRowIndexes]; NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet]; for (NSInteger i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i]) [itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]]; - + NSInteger state = ([menuItem tag] == FILE_CHECK_TAG) ? NSOnState : NSOffState; return [fTorrent checkForFiles: itemIndexes] != state && [fTorrent canChangeDownloadCheckForFiles: itemIndexes]; } - + if (action == @selector(setOnlySelectedCheck:)) { if ([fOutline numberOfSelectedRows] == 0) return NO; - + NSIndexSet * indexSet = [fOutline selectedRowIndexes]; NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet]; for (NSInteger i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i]) [itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]]; - + return [fTorrent canChangeDownloadCheckForFiles: itemIndexes]; } - + if (action == @selector(setPriority:)) { if ([fOutline numberOfSelectedRows] == 0) @@ -500,7 +500,7 @@ typedef enum [menuItem setState: NSOffState]; return NO; } - + //determine which priorities are checked NSIndexSet * indexSet = [fOutline selectedRowIndexes]; tr_priority_t priority; @@ -516,14 +516,14 @@ typedef enum priority = TR_PRI_LOW; break; } - + BOOL current = NO, canChange = NO; for (NSInteger i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i]) { NSIndexSet * fileIndexSet = [[fOutline itemAtRow: i] indexes]; if (![fTorrent canChangeDownloadCheckForFiles: fileIndexSet]) continue; - + canChange = YES; if ([fTorrent hasFilePriority: priority forIndexes: fileIndexSet]) { @@ -531,16 +531,16 @@ typedef enum break; } } - + [menuItem setState: current ? NSOnState : NSOffState]; return canChange; } - + if (action == @selector(renameSelected:)) { return [fOutline numberOfSelectedRows] == 1; } - + return YES; } @@ -551,7 +551,7 @@ typedef enum - (NSMenu *) menu { NSMenu * menu = [[NSMenu alloc] initWithTitle: @"File Outline Menu"]; - + //check and uncheck NSMenuItem * item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Check Selected", "File Outline -> Menu") action: @selector(setCheck:) keyEquivalent: @""]; @@ -559,30 +559,30 @@ typedef enum [item setTag: FILE_CHECK_TAG]; [menu addItem: item]; [item release]; - + item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Uncheck Selected", "File Outline -> Menu") action: @selector(setCheck:) keyEquivalent: @""]; [item setTarget: self]; [item setTag: FILE_UNCHECK_TAG]; [menu addItem: item]; [item release]; - + //only check selected item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Only Check Selected", "File Outline -> Menu") action: @selector(setOnlySelectedCheck:) keyEquivalent: @""]; [item setTarget: self]; [menu addItem: item]; [item release]; - + [menu addItem: [NSMenuItem separatorItem]]; - + //priority item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Priority", "File Outline -> Menu") action: NULL keyEquivalent: @""]; NSMenu * priorityMenu = [[NSMenu alloc] initWithTitle: @"File Priority Menu"]; [item setSubmenu: priorityMenu]; [menu addItem: item]; [item release]; - + item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"High", "File Outline -> Priority Menu") action: @selector(setPriority:) keyEquivalent: @""]; [item setTarget: self]; @@ -590,7 +590,7 @@ typedef enum [item setImage: [NSImage imageNamed: @"PriorityHighTemplate"]]; [priorityMenu addItem: item]; [item release]; - + item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Normal", "File Outline -> Priority Menu") action: @selector(setPriority:) keyEquivalent: @""]; [item setTarget: self]; @@ -598,7 +598,7 @@ typedef enum [item setImage: [NSImage imageNamed: @"PriorityNormalTemplate"]]; [priorityMenu addItem: item]; [item release]; - + item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Low", "File Outline -> Priority Menu") action: @selector(setPriority:) keyEquivalent: @""]; [item setTarget: self]; @@ -606,43 +606,43 @@ typedef enum [item setImage: [NSImage imageNamed: @"PriorityLowTemplate"]]; [priorityMenu addItem: item]; [item release]; - + [priorityMenu release]; - + [menu addItem: [NSMenuItem separatorItem]]; - + //reveal in finder item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Show in Finder", "File Outline -> Menu") action: @selector(revealFile:) keyEquivalent: @""]; [item setTarget: self]; [menu addItem: item]; [item release]; - + [menu addItem: [NSMenuItem separatorItem]]; - + //rename item = [[NSMenuItem alloc] initWithTitle: [NSLocalizedString(@"Rename File", "File Outline -> Menu") stringByAppendingEllipsis] action: @selector(renameSelected:) keyEquivalent: @""]; [item setTarget: self]; [menu addItem: item]; [item release]; - + return [menu autorelease]; } - (NSUInteger) findFileNode: (FileListNode *) node inList: (NSArray *) list atIndexes: (NSIndexSet *) indexes currentParent: (FileListNode *) currentParent finalParent: (FileListNode **) parent { NSAssert(![node isFolder], @"Looking up folder node!"); - + __block NSUInteger retIndex = NSNotFound; - + [list enumerateObjectsAtIndexes: indexes options: NSEnumerationConcurrent usingBlock: ^(id checkNode, NSUInteger index, BOOL * stop) { if ([[checkNode indexes] containsIndex: [[node indexes] firstIndex]]) { if (![checkNode isFolder]) { NSAssert2([checkNode isEqualTo: node], @"Expected file nodes to be equal: %@ %@", checkNode, node); - + *parent = currentParent; retIndex = index; } @@ -652,11 +652,11 @@ typedef enum NSAssert(subIndex != NSNotFound, @"We didn't find an expected file node."); retIndex = subIndex; } - + *stop = YES; } }]; - + return retIndex; } diff --git a/macosx/FileOutlineView.m b/macosx/FileOutlineView.m index a66d61404..e7fd03373 100644 --- a/macosx/FileOutlineView.m +++ b/macosx/FileOutlineView.m @@ -34,14 +34,14 @@ FileNameCell * nameCell = [[FileNameCell alloc] init]; [[self tableColumnWithIdentifier: @"Name"] setDataCell: nameCell]; [nameCell release]; - + FilePriorityCell * priorityCell = [[FilePriorityCell alloc] init]; [[self tableColumnWithIdentifier: @"Priority"] setDataCell: priorityCell]; [priorityCell release]; - + [self setAutoresizesOutlineColumn: NO]; [self setIndentationPerLevel: 14.0]; - + fMouseRow = -1; } @@ -59,7 +59,7 @@ - (NSMenu *) menuForEvent: (NSEvent *) event { const NSInteger row = [self rowAtPoint: [self convertPoint: [event locationInWindow] fromView: nil]]; - + if (row >= 0) { if (![self isRowSelected: row]) @@ -67,7 +67,7 @@ } else [self deselectAll: self]; - + return [self menu]; } @@ -75,7 +75,7 @@ { FileNameCell * cell = (FileNameCell *)[self preparedCellAtColumn: [self columnWithIdentifier: @"Name"] row: row]; NSRect iconRect = [cell imageRectForBounds: [self rectOfRow: row]]; - + iconRect.origin.x += [self indentationPerLevel] * (CGFloat)([self levelForRow: row] + 1); return iconRect; } @@ -83,23 +83,23 @@ - (void) updateTrackingAreas { [super updateTrackingAreas]; - + for (NSTrackingArea * area in [self trackingAreas]) { if ([area owner] == self && [[area userInfo] objectForKey: @"Row"]) [self removeTrackingArea: area]; } - + NSRange visibleRows = [self rowsInRect: [self visibleRect]]; if (visibleRows.length == 0) return; - + NSPoint mouseLocation = [self convertPoint: [[self window] mouseLocationOutsideOfEventStream] fromView: nil]; - + for (NSInteger row = visibleRows.location, col = [self columnWithIdentifier: @"Priority"]; (NSUInteger)row < NSMaxRange(visibleRows); row++) { FilePriorityCell * cell = (FilePriorityCell *)[self preparedCellAtColumn: col row: row]; - + NSDictionary * userInfo = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: row] forKey: @"Row"]; [cell addTrackingAreasForView: self inRect: [self frameOfCellAtColumn: col row: row] withUserInfo: userInfo mouseLocation: mouseLocation]; diff --git a/macosx/FilePriorityCell.m b/macosx/FilePriorityCell.m index 713c7b94f..b1a9f7c95 100644 --- a/macosx/FilePriorityCell.m +++ b/macosx/FilePriorityCell.m @@ -37,17 +37,17 @@ [self setTrackingMode: NSSegmentSwitchTrackingSelectAny]; [self setControlSize: NSMiniControlSize]; [self setSegmentCount: 3]; - + for (NSInteger i = 0; i < [self segmentCount]; i++) { [self setLabel: @"" forSegment: i]; [self setWidth: 9.0f forSegment: i]; //9 is minimum size to get proper look } - + [self setImage: [NSImage imageNamed: @"PriorityControlLow"] forSegment: 0]; [self setImage: [NSImage imageNamed: @"PriorityControlNormal"] forSegment: 1]; [self setImage: [NSImage imageNamed: @"PriorityControlHigh"] forSegment: 2]; - + fHoverRow = NO; } return self; @@ -63,7 +63,7 @@ - (void) setSelected: (BOOL) flag forSegment: (NSInteger) segment { [super setSelected: flag forSegment: segment]; - + //only for when clicking manually NSInteger priority; switch (segment) @@ -78,10 +78,10 @@ priority = TR_PRI_HIGH; break; } - + Torrent * torrent = [(FileListNode *)[self representedObject] torrent]; [torrent setFilePriority: priority forIndexes: [(FileListNode *)[self representedObject] indexes]]; - + FileOutlineView * controlView = (FileOutlineView *)[self controlView]; [controlView setNeedsDisplay: YES]; } @@ -90,13 +90,13 @@ mouseLocation: (NSPoint) mouseLocation { NSTrackingAreaOptions options = NSTrackingEnabledDuringMouseDrag | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways; - + if (NSMouseInRect(mouseLocation, cellFrame, [controlView isFlipped])) { options |= NSTrackingAssumeInside; [controlView setNeedsDisplayInRect: cellFrame]; } - + NSTrackingArea * area = [[NSTrackingArea alloc] initWithRect: cellFrame options: options owner: controlView userInfo: userInfo]; [controlView addTrackingArea: area]; [area release]; @@ -112,21 +112,21 @@ FileListNode * node = [self representedObject]; Torrent * torrent = [node torrent]; NSSet * priorities = [torrent filePrioritiesForIndexes: [node indexes]]; - + const NSUInteger count = [priorities count]; if (fHoverRow && count > 0) { [super setSelected: [priorities containsObject: [NSNumber numberWithInteger: TR_PRI_LOW]] forSegment: 0]; [super setSelected: [priorities containsObject: [NSNumber numberWithInteger: TR_PRI_NORMAL]] forSegment: 1]; [super setSelected: [priorities containsObject: [NSNumber numberWithInteger: TR_PRI_HIGH]] forSegment: 2]; - + [super drawWithFrame: cellFrame inView: controlView]; } else { NSMutableArray * images = [NSMutableArray arrayWithCapacity: MAX(count, 1u)]; CGFloat totalWidth; - + if (count == 0) { //if ([self backgroundStyle] != NSBackgroundStyleDark) @@ -139,7 +139,7 @@ else { NSColor * priorityColor = [self backgroundStyle] == NSBackgroundStyleDark ? [NSColor whiteColor] : [NSColor darkGrayColor]; - + totalWidth = 0.0; if ([priorities containsObject: [NSNumber numberWithInteger: TR_PRI_LOW]]) { @@ -160,19 +160,19 @@ totalWidth += [image size].width; } } - + if (count > 1) totalWidth -= IMAGE_OVERLAP * (count-1); - + CGFloat currentWidth = floor(NSMidX(cellFrame) - totalWidth * 0.5); - + for (NSImage * image in images) { const NSSize imageSize = [image size]; const NSRect imageRect = NSMakeRect(currentWidth, floor(NSMidY(cellFrame) - imageSize.height * 0.5), imageSize.width, imageSize.height); - + [image drawInRect: imageRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; - + currentWidth += imageSize.width - IMAGE_OVERLAP; } } diff --git a/macosx/FileRenameSheetController.h b/macosx/FileRenameSheetController.h index fbd1dc99d..3bbf0166c 100644 --- a/macosx/FileRenameSheetController.h +++ b/macosx/FileRenameSheetController.h @@ -17,7 +17,7 @@ FileListNode * _node; void (^_completionHandler)(BOOL); NSString * _originalName; - + IBOutlet NSTextField * _labelField; IBOutlet NSTextField * _inputField; IBOutlet NSButton * _renameButton; diff --git a/macosx/FileRenameSheetController.m b/macosx/FileRenameSheetController.m index 04eafb791..19e71ee5a 100644 --- a/macosx/FileRenameSheetController.m +++ b/macosx/FileRenameSheetController.m @@ -38,12 +38,12 @@ typedef void (^CompletionBlock)(BOOL); { NSParameterAssert(torrent != nil); NSParameterAssert(window != nil); - + FileRenameSheetController * renamer = [[FileRenameSheetController alloc] initWithWindowNibName: @"FileRenameSheetController"]; - + renamer.torrent = torrent; renamer.completionHandler = completionHandler; - + [NSApp beginSheet: [renamer window] modalForWindow: window modalDelegate: self didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) contextInfo: renamer]; } @@ -51,13 +51,13 @@ typedef void (^CompletionBlock)(BOOL); { NSParameterAssert(node != nil); NSParameterAssert(window != nil); - + FileRenameSheetController * renamer = [[FileRenameSheetController alloc] initWithWindowNibName: @"FileRenameSheetController"]; - + renamer.torrent = [node torrent]; renamer.node = node; renamer.completionHandler = completionHandler; - + [NSApp beginSheet: [renamer window] modalForWindow: window modalDelegate: self didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) contextInfo: renamer]; } @@ -65,9 +65,9 @@ typedef void (^CompletionBlock)(BOOL); { FileRenameSheetController * renamer = contextInfo; NSParameterAssert([renamer isKindOfClass:[FileRenameSheetController class]]); - + renamer.completionHandler(returnCode == NSOKButton); - + //TODO: retain/release logic needs to be figured out for ARC (when ARC is enabled) [renamer release]; [sheet orderOut: self]; @@ -85,36 +85,36 @@ typedef void (^CompletionBlock)(BOOL); - (void) windowDidLoad { [super windowDidLoad]; - + self.originalName = [self.node name] ?: [self.torrent name]; NSString * label = [NSString stringWithFormat: NSLocalizedString(@"Rename the file \"%@\":", "rename sheet label"), self.originalName]; [self.labelField setStringValue: label]; - + [self.inputField setStringValue: self.originalName]; [self.renameButton setEnabled: NO]; - + //resize the buttons so that they're long enough and the same width const NSRect oldRenameFrame = [self.renameButton frame]; const NSRect oldCancelFrame = [self.cancelButton frame]; - + //get the extra width of the rename button from the English xib - the width from sizeToFit is too squished [self.renameButton sizeToFit]; const CGFloat extra = NSWidth(oldRenameFrame) - NSWidth([self.renameButton frame]); - + [self.renameButton setTitle: NSLocalizedString(@"Rename", "rename sheet button")]; [self.cancelButton setTitle: NSLocalizedString(@"Cancel", "rename sheet button")]; - + [self.renameButton sizeToFit]; [self.cancelButton sizeToFit]; NSRect newRenameFrame = [self.renameButton frame]; NSRect newCancelFrame = [self.cancelButton frame]; newRenameFrame.size.width = MAX(NSWidth(newRenameFrame), NSWidth(newCancelFrame)) + extra; newCancelFrame.size.width = MAX(NSWidth(newRenameFrame), NSWidth(newCancelFrame)) + extra; - + const CGFloat renameWidthIncrease = NSWidth(newRenameFrame) - NSWidth(oldRenameFrame); newRenameFrame.origin.x -= renameWidthIncrease; [self.renameButton setFrame:newRenameFrame]; - + const CGFloat cancelWidthIncrease = NSWidth(newCancelFrame) - NSWidth(oldCancelFrame); newCancelFrame.origin.x -= renameWidthIncrease + cancelWidthIncrease; [self.cancelButton setFrame:newCancelFrame]; @@ -131,7 +131,7 @@ typedef void (^CompletionBlock)(BOOL); NSBeep(); } }; - + if (self.node) [self.torrent renameFileNode: self.node withName: [self.inputField stringValue] completionHandler: completionHandler]; else diff --git a/macosx/FilterBarController.h b/macosx/FilterBarController.h index 3a8b20824..e2bc232b8 100644 --- a/macosx/FilterBarController.h +++ b/macosx/FilterBarController.h @@ -39,9 +39,9 @@ { IBOutlet FilterButton * fNoFilterButton, * fActiveFilterButton, * fDownloadFilterButton, * fSeedFilterButton, * fPauseFilterButton; - + IBOutlet NSSearchField * fSearchField; - + IBOutlet NSPopUpButton * fGroupsButton; } diff --git a/macosx/FilterBarController.m b/macosx/FilterBarController.m index e925cbce3..4dd292d16 100644 --- a/macosx/FilterBarController.m +++ b/macosx/FilterBarController.m @@ -54,26 +54,26 @@ [fDownloadFilterButton setTitle: NSLocalizedString(@"Downloading", "Filter Bar -> filter button")]; [fSeedFilterButton setTitle: NSLocalizedString(@"Seeding", "Filter Bar -> filter button")]; [fPauseFilterButton setTitle: NSLocalizedString(@"Paused", "Filter Bar -> filter button")]; - + [[fNoFilterButton cell] setBackgroundStyle: NSBackgroundStyleRaised]; [[fActiveFilterButton cell] setBackgroundStyle: NSBackgroundStyleRaised]; [[fDownloadFilterButton cell] setBackgroundStyle: NSBackgroundStyleRaised]; [[fSeedFilterButton cell] setBackgroundStyle: NSBackgroundStyleRaised]; [[fPauseFilterButton cell] setBackgroundStyle: NSBackgroundStyleRaised]; - + [[[[fSearchField cell] searchMenuTemplate] itemWithTag: FILTER_TYPE_TAG_NAME] setTitle: NSLocalizedString(@"Name", "Filter Bar -> filter menu")]; [[[[fSearchField cell] searchMenuTemplate] itemWithTag: FILTER_TYPE_TAG_TRACKER] setTitle: NSLocalizedString(@"Tracker", "Filter Bar -> filter menu")]; - + [[[fGroupsButton menu] itemWithTag: GROUP_FILTER_ALL_TAG] setTitle: NSLocalizedString(@"All Groups", "Filter Bar -> group filter menu")]; - + [self resizeBar]; - + //set current filter NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"]; - + NSButton * currentFilterButton; if ([filterType isEqualToString: FILTER_ACTIVE]) currentFilterButton = fActiveFilterButton; @@ -91,10 +91,10 @@ currentFilterButton = fNoFilterButton; } [currentFilterButton setState: NSOnState]; - + //set filter search type NSString * filterSearchType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"]; - + NSMenu * filterSearchMenu = [[fSearchField cell] searchMenuTemplate]; NSString * filterSearchTypeTitle; if ([filterSearchType isEqualToString: FILTER_TYPE_TRACKER]) @@ -107,16 +107,16 @@ filterSearchTypeTitle = [[filterSearchMenu itemWithTag: FILTER_TYPE_TAG_NAME] title]; } [[fSearchField cell] setPlaceholderString: filterSearchTypeTitle]; - + NSString * searchString; if ((searchString = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchString"])) [fSearchField setStringValue: searchString]; - + [self updateGroupsButton]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resizeBar) name: NSWindowDidResizeNotification object: [[self view] window]]; - + //update when groups change [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateGroups:) name: @"UpdateGroups" object: nil]; @@ -125,14 +125,14 @@ - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [super dealloc]; } - (void) setFilter: (id) sender { NSString * oldFilterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"]; - + NSButton * prevFilterButton; if ([oldFilterType isEqualToString: FILTER_PAUSE]) prevFilterButton = fPauseFilterButton; @@ -144,7 +144,7 @@ prevFilterButton = fDownloadFilterButton; else prevFilterButton = fNoFilterButton; - + if (sender != prevFilterButton) { [prevFilterButton setState: NSOffState]; @@ -166,14 +166,14 @@ } else [sender setState: NSOnState]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil]; } - (void) switchFilter: (BOOL) right { NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"]; - + NSButton * button; if ([filterType isEqualToString: FILTER_NONE]) button = right ? fActiveFilterButton : fPauseFilterButton; @@ -187,7 +187,7 @@ button = right ? fNoFilterButton : fSeedFilterButton; else button = fNoFilterButton; - + [self setFilter: button]; } @@ -205,13 +205,13 @@ - (void) setSearchType: (id) sender { NSString * oldFilterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"]; - + NSInteger prevTag, currentTag = [sender tag]; if ([oldFilterType isEqualToString: FILTER_TYPE_TRACKER]) prevTag = FILTER_TYPE_TAG_TRACKER; else prevTag = FILTER_TYPE_TAG_NAME; - + if (currentTag != prevTag) { NSString * filterType; @@ -219,12 +219,12 @@ filterType = FILTER_TYPE_TRACKER; else filterType = FILTER_TYPE_NAME; - + [[NSUserDefaults standardUserDefaults] setObject: filterType forKey: @"FilterSearchType"]; - + [[fSearchField cell] setPlaceholderString: [sender title]]; } - + [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil]; } @@ -232,20 +232,20 @@ { [[NSUserDefaults standardUserDefaults] setInteger: [sender tag] forKey: @"FilterGroup"]; [self updateGroupsButton]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil]; } - (void) reset: (BOOL) updateUI { [[NSUserDefaults standardUserDefaults] setInteger: GROUP_FILTER_ALL_TAG forKey: @"FilterGroup"]; - + if (updateUI) - { + { [self updateGroupsButton]; - + [self setFilter: fNoFilterButton]; - + [fSearchField setStringValue: @""]; [self setSearchText: fSearchField]; } @@ -277,9 +277,9 @@ { for (NSInteger i = [menu numberOfItems]-1; i >= 3; i--) [menu removeItemAtIndex: i]; - + NSMenu * groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(setGroupFilter:) isSmall: YES]; - + const NSInteger groupMenuCount = [groupMenu numberOfItems]; for (NSInteger i = 0; i < groupMenuCount; i++) { @@ -294,29 +294,29 @@ - (BOOL) validateMenuItem: (NSMenuItem *) menuItem { const SEL action = [menuItem action]; - + //check proper filter search item if (action == @selector(setSearchType:)) { NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"]; - + BOOL state; if ([menuItem tag] == FILTER_TYPE_TAG_TRACKER) state = [filterType isEqualToString: FILTER_TYPE_TRACKER]; else state = [filterType isEqualToString: FILTER_TYPE_NAME]; - + [menuItem setState: state ? NSOnState : NSOffState]; return YES; } - + if (action == @selector(setGroupFilter:)) { [menuItem setState: [menuItem tag] == [[NSUserDefaults standardUserDefaults] integerForKey: @"FilterGroup"] ? NSOnState : NSOffState]; return YES; } - + return YES; } @@ -332,18 +332,18 @@ [fDownloadFilterButton sizeToFit]; [fSeedFilterButton sizeToFit]; [fPauseFilterButton sizeToFit]; - + NSRect allRect = [fNoFilterButton frame]; NSRect activeRect = [fActiveFilterButton frame]; NSRect downloadRect = [fDownloadFilterButton frame]; NSRect seedRect = [fSeedFilterButton frame]; NSRect pauseRect = [fPauseFilterButton frame]; - + //size search filter to not overlap buttons NSRect searchFrame = [fSearchField frame]; searchFrame.origin.x = NSMaxX(pauseRect) + 5.0; searchFrame.size.width = NSWidth([[self view] frame]) - searchFrame.origin.x - 5.0; - + //make sure it is not too long if (NSWidth(searchFrame) > SEARCH_MAX_WIDTH) { @@ -354,13 +354,13 @@ { searchFrame.origin.x += NSWidth(searchFrame) - SEARCH_MIN_WIDTH; searchFrame.size.width = SEARCH_MIN_WIDTH; - + //calculate width the buttons can take up const CGFloat allowedWidth = (searchFrame.origin.x - 5.0) - allRect.origin.x; const CGFloat currentWidth = NSWidth(allRect) + NSWidth(activeRect) + NSWidth(downloadRect) + NSWidth(seedRect) + NSWidth(pauseRect) + 4.0; //add 4 for space between buttons const CGFloat ratio = allowedWidth / currentWidth; - + //decrease button widths proportionally allRect.size.width = NSWidth(allRect) * ratio; activeRect.size.width = NSWidth(activeRect) * ratio; @@ -369,25 +369,25 @@ pauseRect.size.width = NSWidth(pauseRect) * ratio; } else; - + activeRect.origin.x = NSMaxX(allRect) + 1.0; downloadRect.origin.x = NSMaxX(activeRect) + 1.0; seedRect.origin.x = NSMaxX(downloadRect) + 1.0; pauseRect.origin.x = NSMaxX(seedRect) + 1.0; - + [fNoFilterButton setFrame: allRect]; [fActiveFilterButton setFrame: activeRect]; [fDownloadFilterButton setFrame: downloadRect]; [fSeedFilterButton setFrame: seedRect]; [fPauseFilterButton setFrame: pauseRect]; - + [fSearchField setFrame: searchFrame]; } - (void) updateGroupsButton { const NSInteger groupIndex = [[NSUserDefaults standardUserDefaults] integerForKey: @"FilterGroup"]; - + NSImage * icon; NSString * toolTip; if (groupIndex == GROUP_FILTER_ALL_TAG) @@ -402,7 +402,7 @@ : NSLocalizedString(@"None", "Groups -> Button"); toolTip = [NSLocalizedString(@"Group", "Groups -> Button") stringByAppendingFormat: @": %@", groupName]; } - + [[[fGroupsButton menu] itemAtIndex: 0] setImage: icon]; [fGroupsButton setToolTip: toolTip]; } diff --git a/macosx/FilterBarView.m b/macosx/FilterBarView.m index 4264c4ebc..94d2e53da 100644 --- a/macosx/FilterBarView.m +++ b/macosx/FilterBarView.m @@ -59,7 +59,7 @@ if ([NSApp isOnYosemiteOrBetter]) { [[NSColor windowBackgroundColor] setFill]; NSRectFill(rect); - + const NSRect lineBorderRect = NSMakeRect(NSMinX(rect), 0.0, NSWidth(rect), 1.0); if (NSIntersectsRect(lineBorderRect, rect)) { @@ -71,34 +71,34 @@ NSInteger count = 0; NSRect gridRects[2]; NSColor * colorRects[2]; - + NSRect lineBorderRect = NSMakeRect(NSMinX(rect), NSHeight([self bounds]) - 1.0, NSWidth(rect), 1.0); if (NSIntersectsRect(lineBorderRect, rect)) { gridRects[count] = lineBorderRect; colorRects[count] = [NSColor whiteColor]; ++count; - + rect.size.height -= 1.0; } - + lineBorderRect.origin.y = 0.0; if (NSIntersectsRect(lineBorderRect, rect)) { gridRects[count] = lineBorderRect; colorRects[count] = [NSColor colorWithCalibratedWhite: 0.65 alpha: 1.0]; ++count; - + rect.origin.y += 1.0; rect.size.height -= 1.0; } - + if (!NSIsEmptyRect(rect)) { const NSRect gradientRect = NSMakeRect(NSMinX(rect), 1.0, NSWidth(rect), NSHeight([self bounds]) - 1.0 - 1.0); //proper gradient requires the full height of the bar [fGradient drawInRect: gradientRect angle: 270.0]; } - + NSRectFillListWithColors(gridRects, colorRects, count); } } diff --git a/macosx/FilterButton.m b/macosx/FilterButton.m index 0a51d49ae..1a0c6e5a3 100644 --- a/macosx/FilterButton.m +++ b/macosx/FilterButton.m @@ -38,9 +38,9 @@ { if (count == fCount) return; - + fCount = count; - + [self setToolTip: fCount == 1 ? NSLocalizedString(@"1 transfer", "Filter Button -> tool tip") : [NSString stringWithFormat: NSLocalizedString(@"%@ transfers", "Filter Bar Button -> tool tip"), [NSString formattedUInteger: fCount]]]; diff --git a/macosx/GlobalOptionsPopoverViewController.h b/macosx/GlobalOptionsPopoverViewController.h index 88284e204..e5fd881ab 100644 --- a/macosx/GlobalOptionsPopoverViewController.h +++ b/macosx/GlobalOptionsPopoverViewController.h @@ -28,11 +28,11 @@ { tr_session * fHandle; NSUserDefaults * fDefaults; - + IBOutlet NSTextField * fUploadLimitField, * fDownloadLimitField; - + IBOutlet NSTextField * fRatioStopField, * fIdleStopField; - + NSString * fInitialString; } diff --git a/macosx/GlobalOptionsPopoverViewController.m b/macosx/GlobalOptionsPopoverViewController.m index 950db6865..412a270df 100644 --- a/macosx/GlobalOptionsPopoverViewController.m +++ b/macosx/GlobalOptionsPopoverViewController.m @@ -29,10 +29,10 @@ if ((self = [super initWithNibName: @"GlobalOptionsPopover" bundle: nil])) { fHandle = handle; - + fDefaults = [NSUserDefaults standardUserDefaults]; } - + return self; } @@ -40,7 +40,7 @@ { [fUploadLimitField setIntValue: [fDefaults integerForKey: @"UploadLimit"]]; [fDownloadLimitField setIntValue: [fDefaults integerForKey: @"DownloadLimit"]]; - + [fRatioStopField setFloatValue: [fDefaults floatForKey: @"RatioLimit"]]; [fIdleStopField setIntegerValue: [fDefaults integerForKey: @"IdleLimitMinutes"]]; @@ -55,7 +55,7 @@ - (IBAction) setDownSpeedSetting: (id) sender { tr_sessionLimitSpeed(fHandle, TR_DOWN, [fDefaults boolForKey: @"CheckDownload"]); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"SpeedLimitUpdate" object: nil]; } @@ -64,7 +64,7 @@ const NSInteger limit = [sender integerValue]; [fDefaults setInteger: limit forKey: @"DownloadLimit"]; tr_sessionSetSpeedLimit_KBps(fHandle, TR_DOWN, limit); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateSpeedLimitValuesOutsidePrefs" object: nil]; [[NSNotificationCenter defaultCenter] postNotificationName: @"SpeedLimitUpdate" object: nil]; } @@ -72,7 +72,7 @@ - (IBAction) setUpSpeedSetting: (id) sender { tr_sessionLimitSpeed(fHandle, TR_UP, [fDefaults boolForKey: @"CheckUpload"]); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateSpeedLimitValuesOutsidePrefs" object: nil]; [[NSNotificationCenter defaultCenter] postNotificationName: @"SpeedLimitUpdate" object: nil]; } @@ -82,17 +82,17 @@ const NSInteger limit = [sender integerValue]; [fDefaults setInteger: limit forKey: @"UploadLimit"]; tr_sessionSetSpeedLimit_KBps(fHandle, TR_UP, limit); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"SpeedLimitUpdate" object: nil]; } - (IBAction) setRatioStopSetting: (id) sender { tr_sessionSetRatioLimited(fHandle, [fDefaults boolForKey: @"RatioCheck"]); - + //reload main table for seeding progress [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; - + //reload global settings in inspector [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGlobalOptions" object: nil]; } @@ -102,12 +102,12 @@ const CGFloat value = [sender floatValue]; [fDefaults setFloat: value forKey: @"RatioLimit"]; tr_sessionSetRatioLimit(fHandle, value); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateRatioStopValueOutsidePrefs" object: nil]; - + //reload main table for seeding progress [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; - + //reload global settings in inspector [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGlobalOptions" object: nil]; } @@ -115,10 +115,10 @@ - (IBAction) setIdleStopSetting: (id) sender { tr_sessionSetIdleLimited(fHandle, [fDefaults boolForKey: @"IdleLimitCheck"]); - + //reload main table for remaining seeding time [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; - + //reload global settings in inspector [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGlobalOptions" object: nil]; } @@ -128,12 +128,12 @@ const NSInteger value = [sender integerValue]; [fDefaults setInteger: value forKey: @"IdleLimitMinutes"]; tr_sessionSetIdleLimit(fHandle, value); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateIdleStopValueOutsidePrefs" object: nil]; - + //reload main table for remaining seeding time [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; - + //reload global settings in inspector [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGlobalOptions" object: nil]; } @@ -142,7 +142,7 @@ { [fInitialString release]; fInitialString = [[control stringValue] retain]; - + return YES; } diff --git a/macosx/GroupToolbarItem.m b/macosx/GroupToolbarItem.m index 902331f74..e02983336 100644 --- a/macosx/GroupToolbarItem.m +++ b/macosx/GroupToolbarItem.m @@ -39,7 +39,7 @@ - (void) validate { NSSegmentedControl * control = (NSSegmentedControl *)[self view]; - + for (NSInteger i = 0; i < [control segmentCount]; i++) [control setEnabled: [[self target] validateToolbarItem: [[[NSToolbarItem alloc] initWithItemIdentifier: [fIdentifiers objectAtIndex: i]] autorelease]] forSegment: i]; @@ -50,20 +50,20 @@ NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle: [self label] action: NULL keyEquivalent: @""]; NSMenu * menu = [[NSMenu alloc] initWithTitle: [self label]]; [menuItem setSubmenu: menu]; - + [menu setAutoenablesItems: NO]; - + const NSInteger count = [(NSSegmentedControl *)[self view] segmentCount]; for (NSInteger i = 0; i < count; i++) { NSMenuItem * addItem = [[NSMenuItem alloc] initWithTitle: [labels objectAtIndex: i] action: [self action] keyEquivalent: @""]; [addItem setTarget: [self target]]; [addItem setTag: i]; - + [menu addItem: addItem]; [addItem release]; } - + [menu release]; [self setMenuFormRepresentation: menuItem]; [menuItem release]; @@ -72,12 +72,12 @@ - (NSMenuItem *) menuFormRepresentation { NSMenuItem * menuItem = [super menuFormRepresentation]; - + const NSInteger count = [(NSSegmentedControl *)[self view] segmentCount]; for (NSInteger i = 0; i < count; i++) [[[menuItem submenu] itemAtIndex: i] setEnabled: [[self target] validateToolbarItem: [[[NSToolbarItem alloc] initWithItemIdentifier: [fIdentifiers objectAtIndex: i]] autorelease]]]; - + return menuItem; } diff --git a/macosx/GroupsController.m b/macosx/GroupsController.m index f3b29ffcf..ca0136c4f 100644 --- a/macosx/GroupsController.m +++ b/macosx/GroupsController.m @@ -66,42 +66,42 @@ GroupsController * fGroupsInstance = nil; [NSColor redColor], @"Color", NSLocalizedString(@"Red", "Groups -> Name"), @"Name", [NSNumber numberWithInteger: 0], @"Index", nil]; - + NSMutableDictionary * orange = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSColor orangeColor], @"Color", NSLocalizedString(@"Orange", "Groups -> Name"), @"Name", [NSNumber numberWithInteger: 1], @"Index", nil]; - + NSMutableDictionary * yellow = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSColor yellowColor], @"Color", NSLocalizedString(@"Yellow", "Groups -> Name"), @"Name", [NSNumber numberWithInteger: 2], @"Index", nil]; - + NSMutableDictionary * green = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSColor greenColor], @"Color", NSLocalizedString(@"Green", "Groups -> Name"), @"Name", [NSNumber numberWithInteger: 3], @"Index", nil]; - + NSMutableDictionary * blue = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSColor blueColor], @"Color", NSLocalizedString(@"Blue", "Groups -> Name"), @"Name", [NSNumber numberWithInteger: 4], @"Index", nil]; - + NSMutableDictionary * purple = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSColor purpleColor], @"Color", NSLocalizedString(@"Purple", "Groups -> Name"), @"Name", [NSNumber numberWithInteger: 5], @"Index", nil]; - + NSMutableDictionary * gray = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSColor grayColor], @"Color", NSLocalizedString(@"Gray", "Groups -> Name"), @"Name", [NSNumber numberWithInteger: 6], @"Index", nil]; - + fGroups = [[NSMutableArray alloc] initWithObjects: red, orange, yellow, green, blue, purple, gray, nil]; [self saveGroups]; //make sure this is saved right away } } - + return self; } @@ -143,7 +143,7 @@ GroupsController * fGroupsInstance = nil; NSInteger orderIndex = [self rowValueForIndex: index]; [[fGroups objectAtIndex: orderIndex] setObject: name forKey: @"Name"]; [self saveGroups]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self]; } @@ -164,9 +164,9 @@ GroupsController * fGroupsInstance = nil; { NSMutableDictionary * dict = [fGroups objectAtIndex: [self rowValueForIndex: index]]; [dict removeObjectForKey: @"Icon"]; - + [dict setObject: color forKey: @"Color"]; - + [[GroupsController groups] saveGroups]; [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self]; } @@ -183,9 +183,9 @@ GroupsController * fGroupsInstance = nil; - (void) setUsesCustomDownloadLocation: (BOOL) useCustomLocation forIndex: (NSInteger) index { NSMutableDictionary * dict = [fGroups objectAtIndex: [self rowValueForIndex: index]]; - + [dict setObject: [NSNumber numberWithBool: useCustomLocation] forKey: @"UsesCustomDownloadLocation"]; - + [[GroupsController groups] saveGroups]; } @@ -199,7 +199,7 @@ GroupsController * fGroupsInstance = nil; { NSMutableDictionary * dict = [fGroups objectAtIndex: [self rowValueForIndex: index]]; [dict setObject: location forKey: @"CustomDownloadLocation"]; - + [[GroupsController groups] saveGroups]; } @@ -208,7 +208,7 @@ GroupsController * fGroupsInstance = nil; NSInteger orderIndex = [self rowValueForIndex: index]; if (orderIndex == -1) return NO; - + NSNumber * assignRules = [[fGroups objectAtIndex: orderIndex] objectForKey: @"UsesAutoGroupRules"]; return assignRules && [assignRules boolValue]; } @@ -216,9 +216,9 @@ GroupsController * fGroupsInstance = nil; - (void) setUsesAutoAssignRules: (BOOL) useAutoAssignRules forIndex: (NSInteger) index { NSMutableDictionary * dict = [fGroups objectAtIndex: [self rowValueForIndex: index]]; - + [dict setObject: [NSNumber numberWithBool: useAutoAssignRules] forKey: @"UsesAutoGroupRules"]; - + [[GroupsController groups] saveGroups]; } @@ -226,15 +226,15 @@ GroupsController * fGroupsInstance = nil; { NSInteger orderIndex = [self rowValueForIndex: index]; if (orderIndex == -1) - return nil; - - return [[fGroups objectAtIndex: orderIndex] objectForKey: @"AutoGroupRules"]; + return nil; + + return [[fGroups objectAtIndex: orderIndex] objectForKey: @"AutoGroupRules"]; } - (void) setAutoAssignRules: (NSPredicate *) predicate forIndex: (NSInteger) index { NSMutableDictionary * dict = [fGroups objectAtIndex: [self rowValueForIndex: index]]; - + if (predicate) { [dict setObject: predicate forKey: @"AutoGroupRules"]; @@ -253,12 +253,12 @@ GroupsController * fGroupsInstance = nil; NSMutableIndexSet * candidates = [NSMutableIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fGroups count]+1)]; for (NSDictionary * dict in fGroups) [candidates removeIndex: [[dict objectForKey: @"Index"] integerValue]]; - + const NSInteger index = [candidates firstIndex]; - + [fGroups addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInteger: index], @"Index", [NSColor colorWithCalibratedRed: 0.0 green: 0.65 blue: 1.0 alpha: 1.0], @"Color", @"", @"Name", nil]]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self]; [self saveGroups]; } @@ -267,13 +267,13 @@ GroupsController * fGroupsInstance = nil; { NSInteger index = [[[fGroups objectAtIndex: row] objectForKey: @"Index"] integerValue]; [fGroups removeObjectAtIndex: row]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"GroupValueRemoved" object: self userInfo: [NSDictionary dictionaryWithObject: [NSNumber numberWithInteger: index] forKey: @"Index"]]; - + if (index == [[NSUserDefaults standardUserDefaults] integerForKey: @"FilterGroup"]) [[NSUserDefaults standardUserDefaults] setInteger: -2 forKey: @"FilterGroup"]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self]; [self saveGroups]; } @@ -281,7 +281,7 @@ GroupsController * fGroupsInstance = nil; - (void) moveGroupAtRow: (NSInteger) oldRow toRow: (NSInteger) newRow { [fGroups moveObjectAtIndex: oldRow toIndex: newRow]; - + [self saveGroups]; [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self]; } @@ -289,50 +289,50 @@ GroupsController * fGroupsInstance = nil; - (NSMenu *) groupMenuWithTarget: (id) target action: (SEL) action isSmall: (BOOL) small { NSMenu * menu = [[NSMenu alloc] initWithTitle: @"Groups"]; - + NSMenuItem * item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"None", "Groups -> Menu") action: action keyEquivalent: @""]; [item setTarget: target]; [item setTag: -1]; - + NSImage * icon = [NSImage imageNamed: @"GroupsNoneTemplate"]; if (small) { icon = [icon copy]; [icon setSize: NSMakeSize(ICON_WIDTH_SMALL, ICON_WIDTH_SMALL)]; - + [item setImage: icon]; [icon release]; } else [item setImage: icon]; - + [menu addItem: item]; [item release]; - + for (NSMutableDictionary * dict in fGroups) { item = [[NSMenuItem alloc] initWithTitle: [dict objectForKey: @"Name"] action: action keyEquivalent: @""]; [item setTarget: target]; - + [item setTag: [[dict objectForKey: @"Index"] integerValue]]; - + NSImage * icon = [self imageForGroup: dict]; if (small) { icon = [icon copy]; [icon setSize: NSMakeSize(ICON_WIDTH_SMALL, ICON_WIDTH_SMALL)]; - + [item setImage: icon]; [icon release]; } else [item setImage: icon]; - + [menu addItem: item]; [item release]; } - + return [menu autorelease]; } @@ -362,7 +362,7 @@ GroupsController * fGroupsInstance = nil; [groups addObject: tempDict]; [tempDict release]; } - + [[NSUserDefaults standardUserDefaults] setObject: [NSKeyedArchiver archivedDataWithRootObject: groups] forKey: @"GroupDicts"]; } @@ -371,34 +371,34 @@ GroupsController * fGroupsInstance = nil; NSImage * image; if ((image = [dict objectForKey: @"Icon"])) return image; - + NSRect rect = NSMakeRect(0.0, 0.0, ICON_WIDTH, ICON_WIDTH); - + NSBezierPath * bp = [NSBezierPath bezierPathWithRoundedRect: rect xRadius: 3.0 yRadius: 3.0]; NSImage * icon = [[NSImage alloc] initWithSize: rect.size]; - + NSColor * color = [dict objectForKey: @"Color"]; - + [icon lockFocus]; - + //border NSGradient * gradient = [[NSGradient alloc] initWithStartingColor: [color blendedColorWithFraction: 0.45 ofColor: [NSColor whiteColor]] endingColor: color]; [gradient drawInBezierPath: bp angle: 270.0]; [gradient release]; - + //inside bp = [NSBezierPath bezierPathWithRoundedRect: NSInsetRect(rect, 1.0, 1.0) xRadius: 3.0 yRadius: 3.0]; gradient = [[NSGradient alloc] initWithStartingColor: [color blendedColorWithFraction: 0.75 ofColor: [NSColor whiteColor]] endingColor: [color blendedColorWithFraction: 0.2 ofColor: [NSColor whiteColor]]]; [gradient drawInBezierPath: bp angle: 270.0]; [gradient release]; - + [icon unlockFocus]; - + [dict setObject: icon forKey: @"Icon"]; [icon release]; - + return icon; } @@ -406,7 +406,7 @@ GroupsController * fGroupsInstance = nil; { if (![self usesAutoAssignRulesForIndex: index]) return NO; - + NSPredicate * predicate = [self autoAssignRulesForIndex: index]; BOOL eval = NO; @try diff --git a/macosx/GroupsPrefsController.h b/macosx/GroupsPrefsController.h index a457dadf6..9a8f0e317 100644 --- a/macosx/GroupsPrefsController.h +++ b/macosx/GroupsPrefsController.h @@ -26,15 +26,15 @@ { IBOutlet NSTableView * fTableView; IBOutlet NSSegmentedControl * fAddRemoveControl; - + IBOutlet NSColorWell * fSelectedColorView; IBOutlet NSTextField * fSelectedColorNameField; IBOutlet NSButton * fCustomLocationEnableCheck; IBOutlet NSPopUpButton * fCustomLocationPopUp; - + IBOutlet NSButton * fAutoAssignRulesEnableCheck; IBOutlet NSButton * fAutoAssignRulesEditButton; - + IBOutlet NSWindow * fGroupRulesSheetWindow; IBOutlet NSPredicateEditor * fRuleEditor; diff --git a/macosx/GroupsPrefsController.m b/macosx/GroupsPrefsController.m index d2b7ce778..21d0d8ae4 100644 --- a/macosx/GroupsPrefsController.m +++ b/macosx/GroupsPrefsController.m @@ -43,9 +43,9 @@ - (void) awakeFromNib { [fTableView registerForDraggedTypes: [NSArray arrayWithObject: GROUP_TABLE_VIEW_DATA_TYPE]]; - + [fSelectedColorView addObserver: self forKeyPath: @"color" options: 0 context: NULL]; - + [self updateSelectedGroup]; } @@ -58,7 +58,7 @@ { GroupsController * groupsController = [GroupsController groups]; NSInteger groupsIndex = [groupsController indexForRow: row]; - + NSString * identifier = [tableColumn identifier]; if ([identifier isEqualToString: @"Color"]) return [groupsController imageForIndex: groupsIndex]; @@ -107,7 +107,7 @@ [fTableView setDropRow: row dropOperation: NSTableViewDropAbove]; return NSDragOperationGeneric; } - + return NSDragOperationNone; } @@ -119,18 +119,18 @@ { NSIndexSet * indexes = [NSKeyedUnarchiver unarchiveObjectWithData: [pasteboard dataForType: GROUP_TABLE_VIEW_DATA_TYPE]]; NSInteger oldRow = [indexes firstIndex]; - + if (oldRow < newRow) newRow--; [fTableView beginUpdates]; - + [[GroupsController groups] moveGroupAtRow: oldRow toRow: newRow]; [fTableView moveRowAtIndex: oldRow toIndex: newRow]; [fTableView endUpdates]; } - + return YES; } @@ -140,37 +140,37 @@ [[NSColorPanel sharedColorPanel] close]; NSInteger row; - + switch ([[sender cell] tagForSegment: [sender selectedSegment]]) { case ADD_TAG: [fTableView beginUpdates]; - + [[GroupsController groups] addNewGroup]; - + row = [fTableView numberOfRows]; [fTableView insertRowsAtIndexes: [NSIndexSet indexSetWithIndex: row] withAnimation: NSTableViewAnimationSlideUp]; [fTableView endUpdates]; - + [fTableView selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO]; [fTableView scrollRowToVisible: row]; - + [[fSelectedColorNameField window] makeFirstResponder: fSelectedColorNameField]; - + break; - + case REMOVE_TAG: row = [fTableView selectedRow]; - + [fTableView beginUpdates]; - - [[GroupsController groups] removeGroupWithRowIndex: row]; + + [[GroupsController groups] removeGroupWithRowIndex: row]; [fTableView removeRowsAtIndexes: [NSIndexSet indexSetWithIndex: row] withAnimation: NSTableViewAnimationSlideUp]; [fTableView endUpdates]; - + if ([fTableView numberOfRows] > 0) { if (row == [fTableView numberOfRows]) @@ -178,10 +178,10 @@ [fTableView selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO]; [fTableView scrollRowToVisible: row]; } - + break; } - + [self updateSelectedGroup]; } @@ -194,7 +194,7 @@ [panel setCanChooseFiles: NO]; [panel setCanChooseDirectories: YES]; [panel setCanCreateDirectories: YES]; - + [panel beginSheetModalForWindow: [fCustomLocationPopUp window] completionHandler: ^(NSInteger result) { const NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]]; if (result == NSFileHandlingPanelOKButton) @@ -208,9 +208,9 @@ if (![[GroupsController groups] customDownloadLocationForIndex: index]) [[GroupsController groups] setUsesCustomDownloadLocation: NO forIndex: index]; } - + [self refreshCustomLocationWithSingleGroup]; - + [fCustomLocationPopUp selectItemAtIndex: 0]; }]; } @@ -256,12 +256,12 @@ [NSBundle loadNibNamed: @"GroupRules" owner: self]; NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]]; - NSPredicate *predicate = [[GroupsController groups] autoAssignRulesForIndex: index]; - [fRuleEditor setObjectValue: predicate]; - + NSPredicate *predicate = [[GroupsController groups] autoAssignRulesForIndex: index]; + [fRuleEditor setObjectValue: predicate]; + if ([fRuleEditor numberOfRows] == 0) [fRuleEditor addRow: nil]; - + [NSApp beginSheet: fGroupRulesSheetWindow modalForWindow: [fTableView window] modalDelegate: nil didEndSelector: NULL contextInfo: NULL]; } @@ -270,7 +270,7 @@ { [fGroupRulesSheetWindow orderOut: nil]; [NSApp endSheet: fGroupRulesSheetWindow]; - + NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]]; if (![[GroupsController groups] autoAssignRulesForIndex: index]) { @@ -284,13 +284,13 @@ { [fGroupRulesSheetWindow orderOut: nil]; [NSApp endSheet: fGroupRulesSheetWindow]; - + NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]]; [[GroupsController groups] setUsesAutoAssignRules: YES forIndex: index]; - + NSPredicate * predicate = [fRuleEditor objectValue]; [[GroupsController groups] setAutoAssignRules: predicate forIndex: index]; - + [fAutoAssignRulesEnableCheck setState: [[GroupsController groups] usesAutoAssignRulesForIndex: index]]; [fAutoAssignRulesEditButton setEnabled: [fAutoAssignRulesEnableCheck state] == NSOnState]; } @@ -298,13 +298,13 @@ - (void) ruleEditorRowsDidChange: (NSNotification *) notification { NSScrollView * ruleEditorScrollView = [fRuleEditor enclosingScrollView]; - + const CGFloat rowHeight = [fRuleEditor rowHeight]; const CGFloat bordersHeight = [ruleEditorScrollView frame].size.height - [ruleEditorScrollView contentSize].height; const CGFloat requiredRowCount = [fRuleEditor numberOfRows]; const CGFloat maxVisibleRowCount = (long)((NSHeight([[[fRuleEditor window] screen] visibleFrame]) * 2 / 3) / rowHeight); - + [fRuleEditorHeightConstraint setConstant: MIN(requiredRowCount, maxVisibleRowCount) * rowHeight + bordersHeight]; [ruleEditorScrollView setHasVerticalScroller: requiredRowCount > maxVisibleRowCount]; } @@ -323,7 +323,7 @@ [fSelectedColorView setEnabled: YES]; [fSelectedColorNameField setStringValue: [[GroupsController groups] nameForIndex: index]]; [fSelectedColorNameField setEnabled: YES]; - + [self refreshCustomLocationWithSingleGroup]; [fAutoAssignRulesEnableCheck setState: [[GroupsController groups] usesAutoAssignRulesForIndex: index]]; @@ -346,12 +346,12 @@ - (void) refreshCustomLocationWithSingleGroup { const NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]]; - + const BOOL hasCustomLocation = [[GroupsController groups] usesCustomDownloadLocationForIndex: index]; [fCustomLocationEnableCheck setState: hasCustomLocation]; [fCustomLocationEnableCheck setEnabled: YES]; [fCustomLocationPopUp setEnabled: hasCustomLocation]; - + NSString * location = [[GroupsController groups] customDownloadLocationForIndex: index]; if (location) { diff --git a/macosx/InfoActivityViewController.h b/macosx/InfoActivityViewController.h index a282db836..d09bec31d 100644 --- a/macosx/InfoActivityViewController.h +++ b/macosx/InfoActivityViewController.h @@ -29,19 +29,19 @@ @interface InfoActivityViewController : NSViewController { NSArray * fTorrents; - + BOOL fSet; - + IBOutlet NSTextField * fDateAddedField, * fDateCompletedField, * fDateActivityField, * fStateField, * fProgressField, * fHaveField, * fDownloadedTotalField, * fUploadedTotalField, * fFailedHashField, * fRatioField, * fDownloadTimeField, * fSeedTimeField; IBOutlet NSTextView * fErrorMessageView; - + IBOutlet PiecesView * fPiecesView; IBOutlet NSSegmentedControl * fPiecesControl; - + //remove when we switch to auto layout on 10.7 IBOutlet NSTextField * fTransferSectionLabel, * fDatesSectionLabel, * fTimeSectionLabel; IBOutlet NSTextField * fStateLabel, * fProgressLabel, * fHaveLabel, * fDownloadedLabel, * fUploadedLabel, diff --git a/macosx/InfoActivityViewController.m b/macosx/InfoActivityViewController.m index e426150ca..8d192363e 100644 --- a/macosx/InfoActivityViewController.m +++ b/macosx/InfoActivityViewController.m @@ -46,7 +46,7 @@ { [self setTitle: NSLocalizedString(@"Activity", "Inspector view -> title")]; } - + return self; } @@ -55,9 +55,9 @@ [fTransferSectionLabel sizeToFit]; [fDatesSectionLabel sizeToFit]; [fTimeSectionLabel sizeToFit]; - + NSArray * labels = @[ fStateLabel, fProgressLabel, fHaveLabel, fDownloadedLabel, fUploadedLabel, fFailedDLLabel, fRatioLabel, fErrorLabel, fDateAddedLabel, fDateCompletedLabel, fDateActivityLabel, fDownloadTimeLabel, fSeedTimeLabel ]; - + CGFloat oldMaxWidth = 0.0, originX, newMaxWidth = 0.0; for (NSTextField * label in labels) { @@ -67,22 +67,22 @@ oldMaxWidth = oldFrame.size.width; originX = oldFrame.origin.x; } - + [label sizeToFit]; const CGFloat newWidth = [label bounds].size.width; if (newWidth > newMaxWidth) newMaxWidth = newWidth; } - + for (NSTextField * label in labels) { NSRect frame = [label frame]; frame.origin.x = originX + (newMaxWidth - frame.size.width); [label setFrame: frame]; } - + NSArray * fields = @[ fDateAddedField, fDateCompletedField, fDateActivityField, fStateField, fProgressField, fHaveField, fDownloadedTotalField, fUploadedTotalField, fFailedHashField, fRatioField, fDownloadTimeField, fSeedTimeField, fErrorScrollView ]; - + const CGFloat widthIncrease = newMaxWidth - oldMaxWidth; for (NSView * field in fields) { NSRect frame = [field frame]; @@ -90,7 +90,7 @@ frame.size.width -= widthIncrease; [field setFrame: frame]; } - + //set the click action of the pieces view #warning after 2.8 just hook this up in the xib [fPiecesView setAction:@selector(updatePiecesView:)]; @@ -100,9 +100,9 @@ - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fTorrents release]; - + [super dealloc]; } @@ -111,7 +111,7 @@ //don't check if it's the same in case the metadata changed [fTorrents release]; fTorrents = [torrents retain]; - + fSet = NO; } @@ -119,11 +119,11 @@ { if (!fSet) [self setupInfo]; - + const NSInteger numberSelected = [fTorrents count]; if (numberSelected == 0) return; - + uint64_t have = 0, haveVerified = 0, downloadedTotal = 0, uploadedTotal = 0, failedHash = 0; NSDate * lastActivity = nil; for (Torrent * torrent in fTorrents) @@ -133,12 +133,12 @@ downloadedTotal += [torrent downloadedTotal]; uploadedTotal += [torrent uploadedTotal]; failedHash += [torrent failedHash]; - + NSDate * nextLastActivity; if ((nextLastActivity = [torrent dateActivity])) lastActivity = lastActivity ? [lastActivity laterDate: nextLastActivity] : nextLastActivity; } - + if (have == 0) [fHaveField setStringValue: [NSString stringForFileSize: 0]]; else @@ -150,19 +150,19 @@ else [fHaveField setStringValue: [NSString stringWithFormat: @"%@ (%@)", [NSString stringForFileSize: have], verifiedString]]; } - + [fDownloadedTotalField setStringValue: [NSString stringForFileSize: downloadedTotal]]; [fUploadedTotalField setStringValue: [NSString stringForFileSize: uploadedTotal]]; [fFailedHashField setStringValue: [NSString stringForFileSize: failedHash]]; - + [fDateActivityField setObjectValue: lastActivity]; - + if (numberSelected == 1) { Torrent * torrent = [fTorrents objectAtIndex: 0]; - + [fStateField setStringValue: [torrent stateString]]; - + NSString * progressString = [NSString percentString: [torrent progress] longDecimals: YES]; if ([torrent isFolder]) { @@ -172,18 +172,18 @@ progressString = [progressString stringByAppendingFormat: @" (%@)", progressSelectedString]; } [fProgressField setStringValue: progressString]; - + [fRatioField setStringValue: [NSString stringForRatio: [torrent ratio]]]; - + NSString * errorMessage = [torrent errorMessage]; if (![errorMessage isEqualToString: [fErrorMessageView string]]) [fErrorMessageView setString: errorMessage]; - + [fDateCompletedField setObjectValue: [torrent dateCompleted]]; - + //uses a relative date, so can't be set once [fDateAddedField setObjectValue: [torrent dateAdded]]; - + if ([NSApp isOnYosemiteOrBetter]) { static NSDateComponentsFormatter *timeFormatter; static dispatch_once_t onceToken; @@ -193,7 +193,7 @@ timeFormatter.allowedUnits = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; timeFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDropLeading; }); - + [fDownloadTimeField setStringValue: [timeFormatter stringFromTimeInterval:[torrent secondsDownloading]]]; [fSeedTimeField setStringValue: [timeFormatter stringFromTimeInterval:[torrent secondsSeeding]]]; } @@ -201,7 +201,7 @@ [fDownloadTimeField setStringValue: [NSString timeString: [torrent secondsDownloading] includesTimeRemainingPhrase:NO showSeconds: YES]]; [fSeedTimeField setStringValue: [NSString timeString: [torrent secondsSeeding] includesTimeRemainingPhrase:NO showSeconds: YES]]; } - + [fPiecesView updateView]; } else if (numberSelected > 1) @@ -222,10 +222,10 @@ - (void) updatePiecesView: (id) sender { const BOOL piecesAvailableSegment = [[NSUserDefaults standardUserDefaults] boolForKey: @"PiecesViewShowAvailability"]; - + [fPiecesControl setSelected: piecesAvailableSegment forSegment: PIECES_CONTROL_AVAILABLE]; [fPiecesControl setSelected: !piecesAvailableSegment forSegment: PIECES_CONTROL_PROGRESS]; - + [fPiecesView updateView]; } @@ -252,19 +252,19 @@ [fDateActivityField setObjectValue: @""]; //using [field setStringValue: @""] causes "December 31, 1969 7:00 PM" to be displayed, at least on 10.7.3 [fRatioField setStringValue: @""]; } - + [fStateField setStringValue: @""]; [fProgressField setStringValue: @""]; - + [fErrorMessageView setString: @""]; - + //using [field setStringValue: @""] causes "December 31, 1969 7:00 PM" to be displayed, at least on 10.7.3 [fDateAddedField setObjectValue: @""]; [fDateCompletedField setObjectValue: @""]; - + [fDownloadTimeField setStringValue: @""]; [fSeedTimeField setStringValue: @""]; - + [fPiecesControl setSelected: NO forSegment: PIECES_CONTROL_AVAILABLE]; [fPiecesControl setSelected: NO forSegment: PIECES_CONTROL_PROGRESS]; [fPiecesControl setEnabled: NO]; @@ -273,15 +273,15 @@ else { Torrent * torrent = [fTorrents objectAtIndex: 0]; - + const BOOL piecesAvailableSegment = [[NSUserDefaults standardUserDefaults] boolForKey: @"PiecesViewShowAvailability"]; [fPiecesControl setSelected: piecesAvailableSegment forSegment: PIECES_CONTROL_AVAILABLE]; [fPiecesControl setSelected: !piecesAvailableSegment forSegment: PIECES_CONTROL_PROGRESS]; [fPiecesControl setEnabled: YES]; - + [fPiecesView setTorrent: torrent]; } - + fSet = YES; } diff --git a/macosx/InfoFileViewController.h b/macosx/InfoFileViewController.h index 2b80af1a8..97ec63eb9 100644 --- a/macosx/InfoFileViewController.h +++ b/macosx/InfoFileViewController.h @@ -29,11 +29,11 @@ @interface InfoFileViewController : NSViewController { NSArray * fTorrents; - + BOOL fSet; - + IBOutlet FileOutlineController * fFileController; - + IBOutlet NSSearchField * fFileFilterField; IBOutlet NSButton * fCheckAllButton, *fUncheckAllButton; } diff --git a/macosx/InfoFileViewController.m b/macosx/InfoFileViewController.m index c2dbcfdfc..872629f6e 100644 --- a/macosx/InfoFileViewController.m +++ b/macosx/InfoFileViewController.m @@ -42,7 +42,7 @@ { [self setTitle: NSLocalizedString(@"Files", "Inspector view -> title")]; } - + return self; } @@ -55,27 +55,27 @@ viewRect.size.height = height; [[self view] setFrame: viewRect]; } - + [[fFileFilterField cell] setPlaceholderString: NSLocalizedString(@"Filter", "inspector -> file filter")]; - + //localize and place all and none buttons [fCheckAllButton setTitle: NSLocalizedString(@"All", "inspector -> check all")]; [fUncheckAllButton setTitle: NSLocalizedString(@"None", "inspector -> check all")]; - + NSRect checkAllFrame = [fCheckAllButton frame]; NSRect uncheckAllFrame = [fUncheckAllButton frame]; const CGFloat oldAllWidth = checkAllFrame.size.width; const CGFloat oldNoneWidth = uncheckAllFrame.size.width; - + [fCheckAllButton sizeToFit]; [fUncheckAllButton sizeToFit]; const CGFloat newWidth = MAX([fCheckAllButton bounds].size.width, [fUncheckAllButton bounds].size.width); - + const CGFloat uncheckAllChange = newWidth - oldNoneWidth; uncheckAllFrame.size.width = newWidth; uncheckAllFrame.origin.x -= uncheckAllChange; [fUncheckAllButton setFrame: uncheckAllFrame]; - + const CGFloat checkAllChange = newWidth - oldAllWidth; checkAllFrame.size.width = newWidth; checkAllFrame.origin.x -= (checkAllChange + uncheckAllChange); @@ -85,7 +85,7 @@ - (void) dealloc { [fTorrents release]; - + [super dealloc]; } @@ -94,7 +94,7 @@ //don't check if it's the same in case the metadata changed [fTorrents release]; fTorrents = [torrents retain]; - + fSet = NO; } @@ -102,11 +102,11 @@ { if (!fSet) [self setupInfo]; - + if ([fTorrents count] == 1) { [fFileController refresh]; - + #warning use TorrentFileCheckChange notification as well Torrent * torrent = [fTorrents objectAtIndex: 0]; if ([torrent isFolder]) @@ -144,14 +144,14 @@ Torrent * torrent = [fTorrents objectAtIndex: 0]; NSIndexSet * indexes = [fileOutlineView selectedRowIndexes]; NSMutableArray * urlArray = [NSMutableArray arrayWithCapacity: [indexes count]]; - + for (NSUInteger i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i]) { FileListNode * item = [fileOutlineView itemAtRow: i]; if ([self canQuickLookFile: item]) [urlArray addObject: [NSURL fileURLWithPath: [torrent fileLocation: item]]]; } - + return urlArray; } @@ -159,46 +159,46 @@ { if ([fTorrents count] != 1) return NO; - + Torrent * torrent = [fTorrents objectAtIndex: 0]; if (![torrent isFolder]) return NO; - + FileOutlineView * fileOutlineView = [fFileController outlineView]; NSIndexSet * indexes = [fileOutlineView selectedRowIndexes]; - + for (NSUInteger i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i]) if ([self canQuickLookFile: [fileOutlineView itemAtRow: i]]) return YES; - + return NO; } - (NSRect) quickLookSourceFrameForPreviewItem: (id ) item { FileOutlineView * fileOutlineView = [fFileController outlineView]; - + NSString * fullPath = [(NSURL *)item path]; Torrent * torrent = [fTorrents objectAtIndex: 0]; NSRange visibleRows = [fileOutlineView rowsInRect: [fileOutlineView bounds]]; - + for (NSUInteger row = visibleRows.location; row < NSMaxRange(visibleRows); row++) { FileListNode * rowItem = [fileOutlineView itemAtRow: row]; if ([[torrent fileLocation: rowItem] isEqualToString: fullPath]) { NSRect frame = [fileOutlineView iconRectForRow: row]; - + if (!NSIntersectsRect([fileOutlineView visibleRect], frame)) return NSZeroRect; - + frame.origin = [fileOutlineView convertPoint: frame.origin toView: nil]; frame = [[[self view] window] convertRectToScreen: frame]; frame.origin.y -= frame.size.height; return frame; } } - + return NSZeroRect; } @@ -209,16 +209,16 @@ - (void) setupInfo { [fFileFilterField setStringValue: @""]; - + if ([fTorrents count] == 1) { Torrent * torrent = [fTorrents objectAtIndex: 0]; - + [fFileController setTorrent: torrent]; - + const BOOL isFolder = [torrent isFolder]; [fFileFilterField setEnabled: isFolder]; - + if (!isFolder) { [fCheckAllButton setEnabled: NO]; @@ -228,13 +228,13 @@ else { [fFileController setTorrent: nil]; - + [fFileFilterField setEnabled: NO]; - + [fCheckAllButton setEnabled: NO]; [fUncheckAllButton setEnabled: NO]; } - + fSet = YES; } diff --git a/macosx/InfoGeneralViewController.h b/macosx/InfoGeneralViewController.h index 530bce4b2..9d6824df8 100644 --- a/macosx/InfoGeneralViewController.h +++ b/macosx/InfoGeneralViewController.h @@ -26,17 +26,17 @@ @interface InfoGeneralViewController : NSViewController { NSArray * fTorrents; - + BOOL fSet; - + IBOutlet NSTextField * fPiecesField, * fHashField, * fSecureField, * fDataLocationField, * fCreatorField, * fDateCreatedField; - + IBOutlet NSTextView * fCommentView; - + IBOutlet NSButton * fRevealDataButton; - + //remove when we switch to auto layout on 10.7 IBOutlet NSTextField * fPiecesLabel, * fHashLabel, * fSecureLabel, * fCreatorLabel, * fDateCreatedLabel, diff --git a/macosx/InfoGeneralViewController.m b/macosx/InfoGeneralViewController.m index 40d7d82cc..01b5e3291 100644 --- a/macosx/InfoGeneralViewController.m +++ b/macosx/InfoGeneralViewController.m @@ -38,14 +38,14 @@ { [self setTitle: NSLocalizedString(@"General Info", "Inspector view -> title")]; } - + return self; } - (void) dealloc { [fTorrents release]; - + [super dealloc]; } @@ -54,9 +54,9 @@ #warning remove when 10.7-only with auto layout [fInfoSectionLabel sizeToFit]; [fWhereSectionLabel sizeToFit]; - + NSArray * labels = @[ fPiecesLabel, fHashLabel, fSecureLabel, fCreatorLabel, fDateCreatedLabel, fCommentLabel, fDataLocationLabel ]; - + CGFloat oldMaxWidth = 0.0, originX, newMaxWidth = 0.0; for (NSTextField * label in labels) { @@ -66,22 +66,22 @@ oldMaxWidth = oldFrame.size.width; originX = oldFrame.origin.x; } - + [label sizeToFit]; const CGFloat newWidth = [label bounds].size.width; if (newWidth > newMaxWidth) newMaxWidth = newWidth; } - + for (NSTextField * label in labels) { NSRect frame = [label frame]; frame.origin.x = originX + (newMaxWidth - frame.size.width); [label setFrame: frame]; } - + NSArray * fields = @[ fPiecesField, fHashField, fSecureField, fCreatorField, fDateCreatedField, fCommentScrollView, fDataLocationField ]; - + const CGFloat widthIncrease = newMaxWidth - oldMaxWidth; for (NSView * field in fields) { NSRect frame = [field frame]; @@ -96,7 +96,7 @@ //don't check if it's the same in case the metadata changed [fTorrents release]; fTorrents = [torrents retain]; - + fSet = NO; } @@ -104,16 +104,16 @@ { if (!fSet) [self setupInfo]; - + if ([fTorrents count] != 1) return; - + Torrent * torrent = [fTorrents objectAtIndex: 0]; - + NSString * location = [torrent dataLocation]; [fDataLocationField setStringValue: location ? [location stringByAbbreviatingWithTildeInPath] : @""]; [fDataLocationField setToolTip: location ? location : @""]; - + [fRevealDataButton setHidden: !location]; } @@ -123,7 +123,7 @@ NSString * location = [torrent dataLocation]; if (!location) return; - + NSURL * file = [NSURL fileURLWithPath: location]; [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs: [NSArray arrayWithObject: file]]; } @@ -137,22 +137,22 @@ if ([fTorrents count] == 1) { Torrent * torrent = [fTorrents objectAtIndex: 0]; - + #warning candidate for localizedStringWithFormat (although then we'll get two commas) NSString * piecesString = ![torrent isMagnet] ? [NSString stringWithFormat: @"%ld, %@", [torrent pieceCount], [NSString stringForFileSize: [torrent pieceSize]]] : @""; [fPiecesField setStringValue: piecesString]; - + NSString * hashString = [torrent hashString]; [fHashField setStringValue: hashString]; [fHashField setToolTip: hashString]; [fSecureField setStringValue: [torrent privateTorrent] ? NSLocalizedString(@"Private Torrent, non-tracker peer discovery disabled", "Inspector -> private torrent") : NSLocalizedString(@"Public Torrent", "Inspector -> private torrent")]; - + NSString * commentString = [torrent comment]; [fCommentView setString: commentString]; - + NSString * creatorString = [torrent creator]; [fCreatorField setStringValue: creatorString]; [fDateCreatedField setObjectValue: [torrent dateCreated]]; @@ -164,16 +164,16 @@ [fHashField setToolTip: nil]; [fSecureField setStringValue: @""]; [fCommentView setString: @""]; - + [fCreatorField setStringValue: @""]; [fDateCreatedField setStringValue: @""]; - + [fDataLocationField setStringValue: @""]; [fDataLocationField setToolTip: nil]; - + [fRevealDataButton setHidden: YES]; } - + fSet = YES; } diff --git a/macosx/InfoOptionsViewController.h b/macosx/InfoOptionsViewController.h index 03dac7213..9a91d7403 100644 --- a/macosx/InfoOptionsViewController.h +++ b/macosx/InfoOptionsViewController.h @@ -26,21 +26,21 @@ @interface InfoOptionsViewController : NSViewController { NSArray * fTorrents; - + BOOL fSet; - + IBOutlet NSPopUpButton * fPriorityPopUp, * fRatioPopUp, * fIdlePopUp; IBOutlet NSButton * fUploadLimitCheck, * fDownloadLimitCheck, * fGlobalLimitCheck, * fRemoveSeedingCompleteCheck; IBOutlet NSTextField * fUploadLimitField, * fDownloadLimitField, * fRatioLimitField, * fIdleLimitField, * fUploadLimitLabel, * fDownloadLimitLabel, * fIdleLimitLabel, * fRatioLimitGlobalLabel, * fIdleLimitGlobalLabel, * fPeersConnectLabel, * fPeersConnectField; - + //remove when we switch to auto layout on 10.7 IBOutlet NSTextField * fTransferBandwidthSectionLabel, * fPrioritySectionLabel, * fPriorityLabel; IBOutlet NSTextField * fSeedingLimitsSectionLabel, * fRatioLabel, * fInactivityLabel; IBOutlet NSTextField * fAdvancedSectionLabel, * fMaxConnectionsLabel; - + NSString * fInitialString; } diff --git a/macosx/InfoOptionsViewController.m b/macosx/InfoOptionsViewController.m index e8ce3c5c0..202d4b604 100644 --- a/macosx/InfoOptionsViewController.m +++ b/macosx/InfoOptionsViewController.m @@ -50,14 +50,14 @@ { [self setTitle: NSLocalizedString(@"Options", "Inspector view -> title")]; } - + return self; } - (void) awakeFromNib { [self setGlobalLabels]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(setGlobalLabels) name: @"UpdateGlobalOptions" object: nil]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateOptionsNotification:) name: @"UpdateOptionsNotification" object: nil]; } @@ -65,9 +65,9 @@ - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fTorrents release]; - + [super dealloc]; } @@ -76,7 +76,7 @@ //don't check if it's the same in case the metadata changed [fTorrents release]; fTorrents = [torrents retain]; - + fSet = NO; } @@ -84,7 +84,7 @@ { if (!fSet) [self setupInfo]; - + fSet = YES; } @@ -92,17 +92,17 @@ { if ([fTorrents count] == 0) return; - + //get bandwidth info NSEnumerator * enumerator = [fTorrents objectEnumerator]; Torrent * torrent = [enumerator nextObject]; //first torrent - + NSInteger uploadUseSpeedLimit = [torrent usesSpeedLimit: YES] ? NSOnState : NSOffState, uploadSpeedLimit = [torrent speedLimit: YES], downloadUseSpeedLimit = [torrent usesSpeedLimit: NO] ? NSOnState : NSOffState, downloadSpeedLimit = [torrent speedLimit: NO], globalUseSpeedLimit = [torrent usesGlobalSpeedLimit] ? NSOnState : NSOffState; - + while ((torrent = [enumerator nextObject]) && (uploadUseSpeedLimit != NSMixedState || uploadSpeedLimit != INVALID || downloadUseSpeedLimit != NSMixedState || downloadSpeedLimit != INVALID @@ -110,74 +110,74 @@ { if (uploadUseSpeedLimit != NSMixedState && uploadUseSpeedLimit != ([torrent usesSpeedLimit: YES] ? NSOnState : NSOffState)) uploadUseSpeedLimit = NSMixedState; - + if (uploadSpeedLimit != INVALID && uploadSpeedLimit != [torrent speedLimit: YES]) uploadSpeedLimit = INVALID; - + if (downloadUseSpeedLimit != NSMixedState && downloadUseSpeedLimit != ([torrent usesSpeedLimit: NO] ? NSOnState : NSOffState)) downloadUseSpeedLimit = NSMixedState; - + if (downloadSpeedLimit != INVALID && downloadSpeedLimit != [torrent speedLimit: NO]) downloadSpeedLimit = INVALID; - + if (globalUseSpeedLimit != NSMixedState && globalUseSpeedLimit != ([torrent usesGlobalSpeedLimit] ? NSOnState : NSOffState)) globalUseSpeedLimit = NSMixedState; } - + //set upload view [fUploadLimitCheck setState: uploadUseSpeedLimit]; [fUploadLimitCheck setEnabled: YES]; - + [fUploadLimitLabel setEnabled: uploadUseSpeedLimit == NSOnState]; [fUploadLimitField setEnabled: uploadUseSpeedLimit == NSOnState]; if (uploadSpeedLimit != INVALID) [fUploadLimitField setIntValue: uploadSpeedLimit]; else [fUploadLimitField setStringValue: @""]; - + //set download view [fDownloadLimitCheck setState: downloadUseSpeedLimit]; [fDownloadLimitCheck setEnabled: YES]; - + [fDownloadLimitLabel setEnabled: downloadUseSpeedLimit == NSOnState]; [fDownloadLimitField setEnabled: downloadUseSpeedLimit == NSOnState]; if (downloadSpeedLimit != INVALID) [fDownloadLimitField setIntValue: downloadSpeedLimit]; else [fDownloadLimitField setStringValue: @""]; - + //set global check [fGlobalLimitCheck setState: globalUseSpeedLimit]; [fGlobalLimitCheck setEnabled: YES]; - + //get ratio and idle info enumerator = [fTorrents objectEnumerator]; torrent = [enumerator nextObject]; //first torrent - + NSInteger checkRatio = [torrent ratioSetting], checkIdle = [torrent idleSetting], removeWhenFinishSeeding = [torrent removeWhenFinishSeeding] ? NSOnState : NSOffState; CGFloat ratioLimit = [torrent ratioLimit]; NSUInteger idleLimit = [torrent idleLimitMinutes]; - + while ((torrent = [enumerator nextObject]) && (checkRatio != INVALID || ratioLimit != INVALID || checkIdle != INVALID || idleLimit != INVALID)) { if (checkRatio != INVALID && checkRatio != [torrent ratioSetting]) checkRatio = INVALID; - + if (ratioLimit != INVALID && ratioLimit != [torrent ratioLimit]) ratioLimit = INVALID; - + if (checkIdle != INVALID && checkIdle != [torrent idleSetting]) checkIdle = INVALID; - + if (idleLimit != INVALID && idleLimit != [torrent idleLimitMinutes]) idleLimit = INVALID; - + if (removeWhenFinishSeeding != NSMixedState && removeWhenFinishSeeding != ([torrent removeWhenFinishSeeding] ? NSOnState : NSOffState)) removeWhenFinishSeeding = NSMixedState; } - + //set ratio view NSInteger index; if (checkRatio == TR_RATIOLIMIT_SINGLE) @@ -190,15 +190,15 @@ index = -1; [fRatioPopUp selectItemAtIndex: index]; [fRatioPopUp setEnabled: YES]; - + [fRatioLimitField setHidden: checkRatio != TR_RATIOLIMIT_SINGLE]; if (ratioLimit != INVALID) [fRatioLimitField setFloatValue: ratioLimit]; else [fRatioLimitField setStringValue: @""]; - + [fRatioLimitGlobalLabel setHidden: checkRatio != TR_RATIOLIMIT_GLOBAL]; - + //set idle view if (checkIdle == TR_IDLELIMIT_SINGLE) index = OPTION_POPUP_LIMIT; @@ -210,32 +210,32 @@ index = -1; [fIdlePopUp selectItemAtIndex: index]; [fIdlePopUp setEnabled: YES]; - + [fIdleLimitField setHidden: checkIdle != TR_IDLELIMIT_SINGLE]; if (idleLimit != INVALID) [fIdleLimitField setIntegerValue: idleLimit]; else [fIdleLimitField setStringValue: @""]; [fIdleLimitLabel setHidden: checkIdle != TR_IDLELIMIT_SINGLE]; - + [fIdleLimitGlobalLabel setHidden: checkIdle != TR_IDLELIMIT_GLOBAL]; - + //set remove transfer when seeding finishes [fRemoveSeedingCompleteCheck setState: removeWhenFinishSeeding]; [fRemoveSeedingCompleteCheck setEnabled: YES]; - + //get priority info enumerator = [fTorrents objectEnumerator]; torrent = [enumerator nextObject]; //first torrent - + NSInteger priority = [torrent priority]; - + while ((torrent = [enumerator nextObject]) && priority != INVALID) { if (priority != INVALID && priority != [torrent priority]) priority = INVALID; } - + //set priority view if (priority == TR_PRI_HIGH) index = OPTION_POPUP_PRIORITY_HIGH; @@ -247,13 +247,13 @@ index = -1; [fPriorityPopUp selectItemAtIndex: index]; [fPriorityPopUp setEnabled: YES]; - + //get peer info enumerator = [fTorrents objectEnumerator]; torrent = [enumerator nextObject]; //first torrent - + NSInteger maxPeers = [torrent maxPeerConnect]; - + while ((torrent = [enumerator nextObject])) { if (maxPeers != [torrent maxPeerConnect]) @@ -262,7 +262,7 @@ break; } } - + //set peer view [fPeersConnectField setEnabled: YES]; [fPeersConnectLabel setEnabled: YES]; @@ -275,14 +275,14 @@ - (void) setUseSpeedLimit: (id) sender { const BOOL upload = sender == fUploadLimitCheck; - + if ([(NSButton *)sender state] == NSMixedState) [sender setState: NSOnState]; const BOOL limit = [(NSButton *)sender state] == NSOnState; - + for (Torrent * torrent in fTorrents) [torrent setUseSpeedLimit: limit upload: upload]; - + NSTextField * field = upload ? fUploadLimitField : fDownloadLimitField; [field setEnabled: limit]; if (limit) @@ -290,10 +290,10 @@ [field selectText: self]; [[[self view] window] makeKeyAndOrderFront: self]; } - + NSTextField * label = upload ? fUploadLimitLabel : fDownloadLimitLabel; [label setEnabled: limit]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } @@ -302,10 +302,10 @@ if ([(NSButton *)sender state] == NSMixedState) [sender setState: NSOnState]; const BOOL limit = [(NSButton *)sender state] == NSOnState; - + for (Torrent * torrent in fTorrents) [torrent setUseGlobalSpeedLimit: limit]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } @@ -313,10 +313,10 @@ { const BOOL upload = sender == fUploadLimitField; const NSInteger limit = [sender intValue]; - + for (Torrent * torrent in fTorrents) [torrent setSpeedLimit: limit upload: upload]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } @@ -340,29 +340,29 @@ NSAssert1(NO, @"Unknown option selected in ratio popup: %ld", [sender indexOfSelectedItem]); return; } - + for (Torrent * torrent in fTorrents) [torrent setRatioSetting: setting]; - + [fRatioLimitField setHidden: !single]; if (single) { [fRatioLimitField selectText: self]; [[[self view] window] makeKeyAndOrderFront: self]; } - + [fRatioLimitGlobalLabel setHidden: setting != TR_RATIOLIMIT_GLOBAL]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } - (void) setRatioLimit: (id) sender { const CGFloat limit = [sender floatValue]; - + for (Torrent * torrent in fTorrents) [torrent setRatioLimit: limit]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } @@ -386,10 +386,10 @@ NSAssert1(NO, @"Unknown option selected in idle popup: %ld", [sender indexOfSelectedItem]); return; } - + for (Torrent * torrent in fTorrents) [torrent setIdleSetting: setting]; - + [fIdleLimitField setHidden: !single]; [fIdleLimitLabel setHidden: !single]; if (single) @@ -397,19 +397,19 @@ [fIdleLimitField selectText: self]; [[[self view] window] makeKeyAndOrderFront: self]; } - + [fIdleLimitGlobalLabel setHidden: setting != TR_IDLELIMIT_GLOBAL]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } - (void) setIdleLimit: (id) sender { const NSUInteger limit = [sender integerValue]; - + for (Torrent * torrent in fTorrents) [torrent setIdleLimitMinutes: limit]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } @@ -418,10 +418,10 @@ if ([(NSButton *)sender state] == NSMixedState) [sender setState: NSOnState]; const BOOL enable = [(NSButton *)sender state] == NSOnState; - + for (Torrent * torrent in fTorrents) [torrent setRemoveWhenFinishSeeding: enable]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } @@ -443,22 +443,22 @@ NSAssert1(NO, @"Unknown option selected in priority popup: %ld", [sender indexOfSelectedItem]); return; } - + for (Torrent * torrent in fTorrents) [torrent setPriority: priority]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } - (void) setPeersConnectLimit: (id) sender { NSInteger limit = [sender intValue]; - + for (Torrent * torrent in fTorrents) [torrent setMaxPeerConnect: limit]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self]; } @@ -466,7 +466,7 @@ { [fInitialString release]; fInitialString = [[control stringValue] retain]; - + return YES; } @@ -495,35 +495,35 @@ [fUploadLimitField setEnabled: NO]; [fUploadLimitLabel setEnabled: NO]; [fUploadLimitField setStringValue: @""]; - + [fDownloadLimitCheck setEnabled: NO]; [fDownloadLimitCheck setState: NSOffState]; [fDownloadLimitField setEnabled: NO]; [fDownloadLimitLabel setEnabled: NO]; [fDownloadLimitField setStringValue: @""]; - + [fGlobalLimitCheck setEnabled: NO]; [fGlobalLimitCheck setState: NSOffState]; - + [fPriorityPopUp setEnabled: NO]; [fPriorityPopUp selectItemAtIndex: -1]; - + [fRatioPopUp setEnabled: NO]; [fRatioPopUp selectItemAtIndex: -1]; [fRatioLimitField setHidden: YES]; [fRatioLimitField setStringValue: @""]; [fRatioLimitGlobalLabel setHidden: YES]; - + [fIdlePopUp setEnabled: NO]; [fIdlePopUp selectItemAtIndex: -1]; [fIdleLimitField setHidden: YES]; [fIdleLimitField setStringValue: @""]; [fIdleLimitLabel setHidden: YES]; [fIdleLimitGlobalLabel setHidden: YES]; - + [fRemoveSeedingCompleteCheck setEnabled: NO]; [fRemoveSeedingCompleteCheck setState: NSOffState]; - + [fPeersConnectField setEnabled: NO]; [fPeersConnectField setStringValue: @""]; [fPeersConnectLabel setEnabled: NO]; @@ -538,7 +538,7 @@ ? [NSString stringForRatio: [[NSUserDefaults standardUserDefaults] floatForKey: @"RatioLimit"]] : NSLocalizedString(@"disabled", "Info options -> global setting"); [fRatioLimitGlobalLabel setStringValue: global]; - + //idle field NSString * globalIdle; if ([[NSUserDefaults standardUserDefaults] boolForKey: @"IdleLimitCheck"]) diff --git a/macosx/InfoPeersViewController.h b/macosx/InfoPeersViewController.h index 1237d83f9..af7daf7c2 100644 --- a/macosx/InfoPeersViewController.h +++ b/macosx/InfoPeersViewController.h @@ -28,14 +28,14 @@ @interface InfoPeersViewController : NSViewController { NSArray * fTorrents; - + BOOL fSet; - + NSMutableArray * fPeers, * fWebSeeds; - + IBOutlet NSTableView * fPeerTable; IBOutlet WebSeedTableView * fWebSeedTable; - + IBOutlet NSTextField * fConnectedPeersField; CGFloat fViewTopMargin; diff --git a/macosx/InfoPeersViewController.m b/macosx/InfoPeersViewController.m index 5493b36f4..224c5fbc7 100644 --- a/macosx/InfoPeersViewController.m +++ b/macosx/InfoPeersViewController.m @@ -50,7 +50,7 @@ { [self setTitle: NSLocalizedString(@"Peers", "Inspector view -> title")]; } - + return self; } @@ -63,7 +63,7 @@ viewRect.size.height = height; [[self view] setFrame: viewRect]; } - + //set table header text [[[fPeerTable tableColumnWithIdentifier: @"IP"] headerCell] setStringValue: NSLocalizedString(@"IP Address", "inspector -> peer table -> header")]; @@ -73,12 +73,12 @@ "inspector -> peer table -> header")]; [[[fPeerTable tableColumnWithIdentifier: @"UL To"] headerCell] setStringValue: NSLocalizedString(@"UL", "inspector -> peer table -> header")]; - + [[[fWebSeedTable tableColumnWithIdentifier: @"Address"] headerCell] setStringValue: NSLocalizedString(@"Web Seeds", "inspector -> web seed table -> header")]; [[[fWebSeedTable tableColumnWithIdentifier: @"DL From"] headerCell] setStringValue: NSLocalizedString(@"DL", "inspector -> web seed table -> header")]; - + //set table header tool tips [[fPeerTable tableColumnWithIdentifier: @"Encryption"] setHeaderToolTip: NSLocalizedString(@"Encrypted Connection", "inspector -> peer table -> header tool tip")]; @@ -88,30 +88,30 @@ "inspector -> peer table -> header tool tip")]; [[fPeerTable tableColumnWithIdentifier: @"UL To"] setHeaderToolTip: NSLocalizedString(@"Uploading To Peer", "inspector -> peer table -> header tool tip")]; - + [[fWebSeedTable tableColumnWithIdentifier: @"DL From"] setHeaderToolTip: NSLocalizedString(@"Downloading From Web Seed", "inspector -> web seed table -> header tool tip")]; - + //prepare for animating peer table and web seed table fViewTopMargin = fWebSeedTableTopConstraint.constant; - + CABasicAnimation * webSeedTableAnimation = [CABasicAnimation animation]; [webSeedTableAnimation setTimingFunction: [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear]]; [webSeedTableAnimation setDuration: 0.125]; [webSeedTableAnimation setDelegate: self]; [webSeedTableAnimation setValue: WEB_SEED_ANIMATION_ID forKey: ANIMATION_ID_KEY]; [fWebSeedTableTopConstraint setAnimations: @{ @"constant": webSeedTableAnimation }]; - + [self setWebSeedTableHidden: YES animate: NO]; } - (void) dealloc { [fTorrents release]; - + [fPeers release]; [fWebSeeds release]; - + [super dealloc]; } @@ -121,7 +121,7 @@ //don't check if it's the same in case the metadata changed [fTorrents release]; fTorrents = [torrents retain]; - + fSet = NO; } @@ -129,20 +129,20 @@ { if (!fSet) [self setupInfo]; - + if ([fTorrents count] == 0) return; - + if (!fPeers) fPeers = [[NSMutableArray alloc] init]; else [fPeers removeAllObjects]; - + if (!fWebSeeds) fWebSeeds = [[NSMutableArray alloc] init]; else [fWebSeeds removeAllObjects]; - + NSUInteger connected = 0, tracker = 0, incoming = 0, cache = 0, lpd = 0, pex = 0, dht = 0, ltep = 0, toUs = 0, fromUs = 0; BOOL anyActive = false; @@ -150,12 +150,12 @@ { if ([torrent webSeedCount] > 0) [fWebSeeds addObjectsFromArray: [torrent webSeeds]]; - + if ([torrent isActive]) { anyActive = YES; [fPeers addObjectsFromArray: [torrent peers]]; - + const NSUInteger connectedThis = [torrent totalPeersConnected]; if (connectedThis > 0) { @@ -167,25 +167,25 @@ pex += [torrent totalPeersPex]; dht += [torrent totalPeersDHT]; ltep += [torrent totalPeersLTEP]; - + toUs += [torrent peersSendingToUs]; fromUs += [torrent peersGettingFromUs]; } } } - + [fPeers sortUsingDescriptors: [self peerSortDescriptors]]; [fPeerTable reloadData]; - + [fWebSeeds sortUsingDescriptors: [fWebSeedTable sortDescriptors]]; [fWebSeedTable reloadData]; [fWebSeedTable setWebSeeds: fWebSeeds]; - + if (anyActive) { NSString * connectedText = [NSString stringWithFormat: NSLocalizedString(@"%d Connected", "Inspector -> Peers tab -> peers"), connected]; - + if (connected > 0) { NSMutableArray * upDownComponents = [NSMutableArray arrayWithCapacity: 2]; @@ -197,7 +197,7 @@ NSLocalizedString(@"UL to %d", "Inspector -> Peers tab -> peers"), fromUs]]; if ([upDownComponents count] > 0) connectedText = [connectedText stringByAppendingFormat: @": %@", [upDownComponents componentsJoinedByString: @", "]]; - + NSMutableArray * fromComponents = [NSMutableArray arrayWithCapacity: 7]; if (tracker > 0) [fromComponents addObject: [NSString stringWithFormat: @@ -220,10 +220,10 @@ if (ltep > 0) [fromComponents addObject: [NSString stringWithFormat: NSLocalizedString(@"%d LTEP", "Inspector -> Peers tab -> peers"), ltep]]; - + connectedText = [connectedText stringByAppendingFormat: @"\n%@", [fromComponents componentsJoinedByString: @", "]]; } - + [fConnectedPeersField setStringValue: connectedText]; } else @@ -233,7 +233,7 @@ notActiveString = NSLocalizedString(@"Transfer Not Active", "Inspector -> Peers tab -> peers"); else notActiveString = NSLocalizedString(@"Transfers Not Active", "Inspector -> Peers tab -> peers"); - + [fConnectedPeersField setStringValue: notActiveString]; } } @@ -265,7 +265,7 @@ { NSString * ident = [column identifier]; NSDictionary * webSeed = [fWebSeeds objectAtIndex: row]; - + if ([ident isEqualToString: @"DL From"]) { NSNumber * rate; @@ -278,7 +278,7 @@ { NSString * ident = [column identifier]; NSDictionary * peer = [fPeers objectAtIndex: row]; - + if ([ident isEqualToString: @"Encryption"]) return [[peer objectForKey: @"Encryption"] boolValue] ? [NSImage imageNamed: @"Lock"] : nil; else if ([ident isEqualToString: @"Client"]) @@ -306,7 +306,7 @@ if (tableView == fPeerTable) { NSString * ident = [tableColumn identifier]; - + if ([ident isEqualToString: @"Progress"]) { NSDictionary * peer = [fPeers objectAtIndex: row]; @@ -346,13 +346,13 @@ if (tableView == fPeerTable) { const BOOL multiple = [fTorrents count] > 1; - + NSDictionary * peer = [fPeers objectAtIndex: row]; NSMutableArray * components = [NSMutableArray arrayWithCapacity: multiple ? 6 : 5]; - + if (multiple) [components addObject: [peer objectForKey: @"Name"]]; - + const CGFloat progress = [[peer objectForKey: @"Progress"] floatValue]; NSString * progressString = [NSString stringWithFormat: NSLocalizedString(@"Progress: %@", "Inspector -> Peers tab -> table row tooltip"), @@ -361,7 +361,7 @@ progressString = [progressString stringByAppendingFormat: @" (%@)", NSLocalizedString(@"Partial Seed", "Inspector -> Peers tab -> table row tooltip")]; [components addObject: progressString]; - + NSString * protocolString = [[peer objectForKey: @"uTP"] boolValue] ? @"\u00b5TP" : @"TCP"; if ([[peer objectForKey: @"Encryption"] boolValue]) protocolString = [protocolString stringByAppendingFormat: @" (%@)", @@ -369,7 +369,7 @@ [components addObject: [NSString stringWithFormat: NSLocalizedString(@"Protocol: %@", "Inspector -> Peers tab -> table row tooltip"), protocolString]]; - + NSString * portString; NSInteger port; if ((port = [[peer objectForKey: @"Port"] intValue]) > 0) @@ -378,7 +378,7 @@ portString = NSLocalizedString(@"N/A", "Inspector -> Peers tab -> table row tooltip"); [components addObject: [NSString stringWithFormat: @"%@: %@", NSLocalizedString(@"Port", "Inspector -> Peers tab -> table row tooltip"), portString]]; - + const NSInteger peerFrom = [[peer objectForKey: @"From"] integerValue]; switch (peerFrom) { @@ -407,11 +407,11 @@ default: NSAssert1(NO, @"Peer from unknown source: %ld", peerFrom); } - + //determing status strings from flags NSMutableArray * statusArray = [NSMutableArray arrayWithCapacity: 6]; NSString * flags = [peer objectForKey: @"Flags"]; - + if ([flags rangeOfString: @"D"].location != NSNotFound) [statusArray addObject: NSLocalizedString(@"Currently downloading (interested and not choked)", "Inspector -> peer -> status")]; @@ -430,13 +430,13 @@ if ([flags rangeOfString: @"?"].location != NSNotFound) [statusArray addObject: NSLocalizedString(@"You unchoked the peer, but the peer is not interested", "Inspector -> peer -> status")]; - + if ([statusArray count] > 0) { NSString * statusStrings = [statusArray componentsJoinedByString: @"\n\n"]; [components addObject: [@"\n" stringByAppendingString: statusStrings]]; } - + return [components componentsJoinedByString: @"\n"]; } else @@ -444,7 +444,7 @@ if ([fTorrents count] > 1) return [[fWebSeeds objectAtIndex: row] objectForKey: @"Name"]; } - + return nil; } @@ -471,13 +471,13 @@ - (void) setupInfo { __block BOOL hasWebSeeds = NO; - + if ([fTorrents count] == 0) { [fPeers release]; fPeers = nil; [fPeerTable reloadData]; - + [fConnectedPeersField setStringValue: @""]; } else @@ -490,7 +490,7 @@ } }]; } - + if (!hasWebSeeds) { [fWebSeeds release]; @@ -500,7 +500,7 @@ else [fWebSeedTable deselectAll: self]; [self setWebSeedTableHidden: !hasWebSeeds animate: YES]; - + fSet = YES; } @@ -510,32 +510,32 @@ animate = NO; const CGFloat webSeedTableTopMargin = hide ? -NSHeight([[fWebSeedTable enclosingScrollView] frame]) : fViewTopMargin; - + [(animate ? [fWebSeedTableTopConstraint animator] : fWebSeedTableTopConstraint) setConstant: webSeedTableTopMargin]; } - (NSArray *) peerSortDescriptors { NSMutableArray * descriptors = [NSMutableArray arrayWithCapacity: 2]; - + NSArray * oldDescriptors = [fPeerTable sortDescriptors]; BOOL useSecond = YES, asc = YES; if ([oldDescriptors count] > 0) { NSSortDescriptor * descriptor = [oldDescriptors objectAtIndex: 0]; [descriptors addObject: descriptor]; - + if ((useSecond = ![[descriptor key] isEqualToString: @"IP"])) asc = [descriptor ascending]; } - + //sort by IP after primary sort if (useSecond) { NSSortDescriptor * secondDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"IP" ascending: asc selector: @selector(compareNumeric:)]; [descriptors addObject: secondDescriptor]; } - + return descriptors; } diff --git a/macosx/InfoTabButtonBack.m b/macosx/InfoTabButtonBack.m index 8c6aae96a..9a585ffd6 100644 --- a/macosx/InfoTabButtonBack.m +++ b/macosx/InfoTabButtonBack.m @@ -46,30 +46,30 @@ NSInteger count = 0; NSRect gridRects[2]; NSColor * colorRects[2]; - + NSRect lineBorderRect = NSMakeRect(NSMinX(rect), NSHeight([self bounds]) - 1.0, NSWidth(rect), 1.0); if (NSIntersectsRect(lineBorderRect, rect)) { gridRects[count] = lineBorderRect; colorRects[count] = [NSColor grayColor]; ++count; - + rect.size.height -= 1.0; } - + lineBorderRect.origin.y = 0.0; if (NSIntersectsRect(lineBorderRect, rect)) { gridRects[count] = lineBorderRect; colorRects[count] = [NSColor grayColor]; ++count; - + rect.origin.y += 1.0; rect.size.height -= 1.0; } - + NSRectFillListWithColors(gridRects, colorRects, count); - + [fGradient drawInRect: rect angle: 270.0]; } diff --git a/macosx/InfoTabButtonCell.h b/macosx/InfoTabButtonCell.h index a76b1ea07..46bce2935 100644 --- a/macosx/InfoTabButtonCell.h +++ b/macosx/InfoTabButtonCell.h @@ -25,7 +25,7 @@ @interface InfoTabButtonCell : NSButtonCell { NSImage * fIcon; - + BOOL fSelected; } diff --git a/macosx/InfoTabButtonCell.m b/macosx/InfoTabButtonCell.m index 28d83ef92..0229e9af3 100644 --- a/macosx/InfoTabButtonCell.m +++ b/macosx/InfoTabButtonCell.m @@ -29,9 +29,9 @@ NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; [nc addObserver: self selector: @selector(updateControlTint:) name: NSControlTintDidChangeNotification object: NSApp]; - + fSelected = NO; - + //expects the icon to currently be set as the image fIcon = [[self image] retain]; } @@ -39,7 +39,7 @@ - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fIcon release]; [super dealloc]; } @@ -60,7 +60,7 @@ - (void) setSelectedTab: (BOOL) selected { fSelected = selected; - + if ([self controlView] == nil) return; @@ -69,11 +69,11 @@ NSRect tabRect = [(NSMatrix *)[self controlView] cellFrameAtRow: row column: col]; tabRect.origin.x = 0.0; tabRect.origin.y = 0.0; - + NSImage * tabImage = [[NSImage alloc] initWithSize: tabRect.size]; - + [tabImage lockFocus]; - + NSGradient * gradient; if (fSelected) { @@ -87,30 +87,30 @@ NSColor * darkColor = [NSColor colorWithCalibratedRed: 215.0/255.0 green: 215.0/255.0 blue: 215.0/255.0 alpha: 1.0]; gradient = [[NSGradient alloc] initWithStartingColor: lightColor endingColor: darkColor]; } - + [[NSColor grayColor] set]; NSRectFill(NSMakeRect(0.0, 0.0, NSWidth(tabRect), 1.0)); NSRectFill(NSMakeRect(0.0, NSHeight(tabRect) - 1.0, NSWidth(tabRect), 1.0)); NSRectFill(NSMakeRect(NSWidth(tabRect) - 1.0, 1.0, NSWidth(tabRect) - 1.0, NSHeight(tabRect) - 2.0)); - + tabRect = NSMakeRect(0.0, 1.0, NSWidth(tabRect) - 1.0, NSHeight(tabRect) - 2.0); - + [gradient drawInRect: tabRect angle: 270.0]; [gradient release]; - + if (fIcon) { const NSSize iconSize = [fIcon size]; - + const NSRect iconRect = NSMakeRect(NSMinX(tabRect) + floor((NSWidth(tabRect) - iconSize.width) * 0.5), NSMinY(tabRect) + floor((NSHeight(tabRect) - iconSize.height) * 0.5), iconSize.width, iconSize.height); - + [fIcon drawInRect: iconRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0]; } - + [tabImage unlockFocus]; - + [self setImage: tabImage]; [tabImage release]; } diff --git a/macosx/InfoTextField.m b/macosx/InfoTextField.m index fce490b56..d4ee82930 100644 --- a/macosx/InfoTextField.m +++ b/macosx/InfoTextField.m @@ -27,14 +27,14 @@ - (void) setStringValue: (NSString *) string { [super setStringValue: string]; - + [self setSelectable: ![[self stringValue] isEqualToString: @""]]; } - (void) setObjectValue: (id ) object { [super setObjectValue: object]; - + [self setSelectable: ![[self stringValue] isEqualToString: @""]]; } diff --git a/macosx/InfoTrackersViewController.h b/macosx/InfoTrackersViewController.h index b3ad8fb45..2785fe31f 100644 --- a/macosx/InfoTrackersViewController.h +++ b/macosx/InfoTrackersViewController.h @@ -30,14 +30,14 @@ @interface InfoTrackersViewController : NSViewController { NSArray * fTorrents; - + BOOL fSet; - + NSMutableArray * fTrackers; - + IBOutlet TrackerTableView * fTrackerTable; TrackerCell * fTrackerCell; - + IBOutlet NSSegmentedControl * fTrackerAddRemoveControl; } diff --git a/macosx/InfoTrackersViewController.m b/macosx/InfoTrackersViewController.m index 3facf6bdb..78d8438d2 100644 --- a/macosx/InfoTrackersViewController.m +++ b/macosx/InfoTrackersViewController.m @@ -49,10 +49,10 @@ if ((self = [super initWithNibName: @"InfoTrackersView" bundle: nil])) { [self setTitle: NSLocalizedString(@"Trackers", "Inspector view -> title")]; - + fTrackerCell = [[TrackerCell alloc] init]; } - + return self; } @@ -62,7 +62,7 @@ forSegment: TRACKER_ADD_TAG]; [[fTrackerAddRemoveControl cell] setToolTip: NSLocalizedString(@"Remove selected trackers", "Inspector view -> tracker buttons") forSegment: TRACKER_REMOVE_TAG]; - + const CGFloat height = [[NSUserDefaults standardUserDefaults] floatForKey: @"InspectorContentHeightTracker"]; if (height != 0.0) { @@ -77,7 +77,7 @@ [fTorrents release]; [fTrackers release]; [fTrackerCell release]; - + [super dealloc]; } @@ -86,7 +86,7 @@ //don't check if it's the same in case the metadata changed [fTorrents release]; fTorrents = [torrents retain]; - + fSet = NO; } @@ -94,15 +94,15 @@ { if (!fSet) [self setupInfo]; - + if ([fTorrents count] == 0) return; - + //get updated tracker stats if ([fTrackerTable editedRow] == -1) { NSArray * oldTrackers = fTrackers; - + if ([fTorrents count] == 1) fTrackers = [[[fTorrents objectAtIndex: 0] allTrackerStats] retain]; else @@ -111,29 +111,29 @@ for (Torrent * torrent in fTorrents) [fTrackers addObjectsFromArray: [torrent allTrackerStats]]; } - + [fTrackerTable setTrackers: fTrackers]; - + if (oldTrackers && [fTrackers isEqualToArray: oldTrackers]) [fTrackerTable setNeedsDisplay: YES]; else [fTrackerTable reloadData]; - + [oldTrackers release]; } else { NSAssert1([fTorrents count] == 1, @"Attempting to add tracker with %ld transfers selected", [fTorrents count]); - + NSIndexSet * addedIndexes = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange([fTrackers count]-2, 2)]; NSArray * tierAndTrackerBeingAdded = [fTrackers objectsAtIndexes: addedIndexes]; - + [fTrackers release]; fTrackers = [[[fTorrents objectAtIndex: 0] allTrackerStats] retain]; [fTrackers addObjectsFromArray: tierAndTrackerBeingAdded]; - + [fTrackerTable setTrackers: fTrackers]; - + NSIndexSet * updateIndexes = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTrackers count]-2)], * columnIndexes = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [[fTrackerTable tableColumns] count])]; [fTrackerTable reloadDataForRowIndexes: updateIndexes columnIndexes: columnIndexes]; @@ -158,14 +158,14 @@ - (id) tableView: (NSTableView *) tableView objectValueForTableColumn: (NSTableColumn *) column row: (NSInteger) row { - id item = [fTrackers objectAtIndex: row]; - + id item = [fTrackers objectAtIndex: row]; + if ([item isKindOfClass: [NSDictionary class]]) { const NSInteger tier = [[item objectForKey: @"Tier"] integerValue]; NSString * tierString = tier == -1 ? NSLocalizedString(@"New Tier", "Inspector -> tracker table") : [NSString stringWithFormat: NSLocalizedString(@"Tier %d", "Inspector -> tracker table"), tier]; - + if ([fTorrents count] > 1) tierString = [tierString stringByAppendingFormat: @" - %@", [item objectForKey: @"Name"]]; return tierString; @@ -219,23 +219,23 @@ row: (NSInteger) row { Torrent * torrent= [fTorrents objectAtIndex: 0]; - + BOOL added = NO; for (NSString * tracker in [object componentsSeparatedByString: @"\n"]) if ([torrent addTrackerToNewTier: tracker]) added = YES; - + if (!added) NSBeep(); - + //reset table with either new or old value [fTrackers release]; fTrackers = [[torrent allTrackerStats] retain]; - + [fTrackerTable setTrackers: fTrackers]; [fTrackerTable reloadData]; [fTrackerTable deselectAll: self]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; //incase sort by tracker } @@ -244,9 +244,9 @@ //don't allow add/remove when currently adding - it leads to weird results if ([fTrackerTable editedRow] != -1) return; - + [self updateInfo]; - + if ([[sender cell] tagForSegment: [sender selectedSegment]] == TRACKER_REMOVE_TAG) [self removeTrackers]; else @@ -266,26 +266,26 @@ { [fTrackers release]; fTrackers = nil; - + [fTrackerTable setTrackers: nil]; [fTrackerTable reloadData]; } - + [fTrackerTable setTorrent: nil]; - + [fTrackerAddRemoveControl setEnabled: NO forSegment: TRACKER_ADD_TAG]; [fTrackerAddRemoveControl setEnabled: NO forSegment: TRACKER_REMOVE_TAG]; } else { [fTrackerTable setTorrent: [fTorrents objectAtIndex: 0]]; - + [fTrackerAddRemoveControl setEnabled: YES forSegment: TRACKER_ADD_TAG]; [fTrackerAddRemoveControl setEnabled: NO forSegment: TRACKER_REMOVE_TAG]; } - + [fTrackerTable deselectAll: self]; - + fSet = YES; } @@ -293,12 +293,12 @@ - (void) addTrackers { [[[self view] window] makeKeyWindow]; - + NSAssert1([fTorrents count] == 1, @"Attempting to add tracker with %ld transfers selected", [fTorrents count]); - + [fTrackers addObject: [NSDictionary dictionaryWithObject: [NSNumber numberWithInteger: -1] forKey: @"Tier"]]; [fTrackers addObject: @""]; - + [fTrackerTable setTrackers: fTrackers]; [fTrackerTable reloadData]; [fTrackerTable selectRowIndexes: [NSIndexSet indexSetWithIndex: [fTrackers count]-1] byExtendingSelection: NO]; @@ -309,7 +309,7 @@ { NSMutableDictionary * removeIdentifiers = [NSMutableDictionary dictionaryWithCapacity: [fTorrents count]]; NSUInteger removeTrackerCount = 0; - + NSIndexSet * selectedIndexes = [fTrackerTable selectedRowIndexes]; BOOL groupSelected = NO; NSUInteger groupRowIndex = NSNotFound; @@ -328,10 +328,10 @@ removeSet = [NSMutableSet set]; [removeIdentifiers setObject: removeSet forKey: torrent]; } - + [removeSet addObject: [(TrackerNode *)object fullAnnounceAddress]]; ++removeTrackerCount; - + [removeIndexes addIndex: i]; } else @@ -342,33 +342,33 @@ //mark the previous group row for removal, if necessary if (groupRowIndex != NSNotFound) [removeIndexes addIndex: groupRowIndex]; - + groupSelected = [selectedIndexes containsIndex: i]; if (!groupSelected && i > [selectedIndexes lastIndex]) { groupRowIndex = NSNotFound; break; } - + groupRowIndex = i; } } - + //mark the last group for removal, too if (groupRowIndex != NSNotFound) [removeIndexes addIndex: groupRowIndex]; - + NSAssert2(removeTrackerCount <= [removeIndexes count], @"Marked %ld trackers to remove, but only removing %ld rows", removeTrackerCount, [removeIndexes count]); - + //we might have no trackers if remove right after a failed add (race condition ftw) #warning look into having a failed add apply right away, so that this can become an assert if (removeTrackerCount == 0) return; - + if ([[NSUserDefaults standardUserDefaults] boolForKey: @"WarningRemoveTrackers"]) { NSAlert * alert = [[NSAlert alloc] init]; - + if (removeTrackerCount > 1) { [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"Are you sure you want to remove %d trackers?", @@ -382,27 +382,27 @@ [alert setInformativeText: NSLocalizedString(@"Once removed, Transmission will no longer attempt to contact it." " This cannot be undone.", "Remove trackers alert -> message")]; } - + [alert addButtonWithTitle: NSLocalizedString(@"Remove", "Remove trackers alert -> button")]; [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Remove trackers alert -> button")]; - + [alert setShowsSuppressionButton: YES]; NSInteger result = [alert runModal]; if ([[alert suppressionButton] state] == NSOnState) [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningRemoveTrackers"]; [alert release]; - + if (result != NSAlertFirstButtonReturn) return; } - + [fTrackerTable beginUpdates]; - + for (Torrent * torrent in removeIdentifiers) [torrent removeTrackers: [removeIdentifiers objectForKey: torrent]]; - + //reset table with either new or old value [fTrackers release]; fTrackers = [[NSMutableArray alloc] init]; @@ -410,11 +410,11 @@ [fTrackers addObjectsFromArray: [torrent allTrackerStats]]; [fTrackerTable removeRowsAtIndexes: removeIndexes withAnimation: NSTableViewAnimationSlideLeft]; - + [fTrackerTable setTrackers: fTrackers]; - + [fTrackerTable endUpdates]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; //incase sort by tracker } diff --git a/macosx/InfoWindowController.h b/macosx/InfoWindowController.h index 426f9d121..f14e1a591 100644 --- a/macosx/InfoWindowController.h +++ b/macosx/InfoWindowController.h @@ -34,13 +34,13 @@ @interface InfoWindowController : NSWindowController { NSArray * fTorrents; - + CGFloat fMinWindowWidth; - + NSViewController * fViewController; NSInteger fCurrentTabTag; IBOutlet NSMatrix * fTabMatrix; - + InfoGeneralViewController * fGeneralViewController; InfoActivityViewController * fActivityViewController; InfoTrackersViewController * fTrackersViewController; diff --git a/macosx/InfoWindowController.m b/macosx/InfoWindowController.m index 39fc715ce..70cb1a95b 100644 --- a/macosx/InfoWindowController.m +++ b/macosx/InfoWindowController.m @@ -72,25 +72,25 @@ typedef enum - (void) awakeFromNib { [fNoneSelectedField setStringValue: NSLocalizedString(@"No Torrents Selected", "Inspector -> selected torrents")]; - + //window location and size NSPanel * window = (NSPanel *)[self window]; - + [window setFloatingPanel: NO]; - + const CGFloat windowHeight = NSHeight([window frame]); fMinWindowWidth = [window minSize].width; - + [window setFrameAutosaveName: @"InspectorWindow"]; [window setFrameUsingName: @"InspectorWindow"]; - + NSRect windowRect = [window frame]; windowRect.origin.y -= windowHeight - NSHeight(windowRect); windowRect.size.height = windowHeight; [window setFrame: windowRect display: NO]; - + [window setBecomesKeyOnlyIfNeeded: YES]; - + //set tab tooltips [fTabMatrix setToolTip: NSLocalizedString(@"General Info", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_GENERAL_TAG]]; [fTabMatrix setToolTip: NSLocalizedString(@"Activity", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_ACTIVITY_TAG]]; @@ -98,7 +98,7 @@ typedef enum [fTabMatrix setToolTip: NSLocalizedString(@"Peers", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_PEERS_TAG]]; [fTabMatrix setToolTip: NSLocalizedString(@"Files", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_FILE_TAG]]; [fTabMatrix setToolTip: NSLocalizedString(@"Options", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_OPTIONS_TAG]]; - + //set selected tab fCurrentTabTag = INVALID; NSString * identifier = [[NSUserDefaults standardUserDefaults] stringForKey: @"InspectorSelected"]; @@ -122,10 +122,10 @@ typedef enum } [fTabMatrix selectCellWithTag: tag]; [self setTab: nil]; - + //set blank inspector [self setInfoForTorrents: [NSArray array]]; - + //allow for update notifications NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; [nc addObserver: self selector: @selector(resetInfoForTorrent:) name: @"ResetInspector" object: nil]; @@ -136,19 +136,19 @@ typedef enum - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + if ([fViewController respondsToSelector: @selector(saveViewSize)]) [fViewController saveViewSize]; - + [fGeneralViewController release]; [fActivityViewController release]; [fTrackersViewController release]; [fPeersViewController release]; [fFileViewController release]; [fOptionsViewController release]; - + [fTorrents release]; - + [super dealloc]; } @@ -156,10 +156,10 @@ typedef enum { if (fTorrents && [fTorrents isEqualToArray: torrents]) return; - + [fTorrents release]; fTorrents = [torrents retain]; - + [self resetInfo]; } @@ -182,27 +182,27 @@ typedef enum fCurrentTabTag = [fTabMatrix selectedTag]; if (fCurrentTabTag == oldTabTag) return; - + //take care of old view CGFloat oldHeight = 0; if (oldTabTag != INVALID) { //deselect old tab item [(InfoTabButtonCell *)[fTabMatrix cellWithTag: oldTabTag] setSelectedTab: NO]; - + if ([fViewController respondsToSelector: @selector(saveViewSize)]) [fViewController saveViewSize]; - + if ([fViewController respondsToSelector: @selector(clearView)]) [fViewController clearView]; - + NSView * oldView = [fViewController view]; oldHeight = NSHeight([oldView frame]); - + //remove old view [oldView removeFromSuperview]; } - + //set new tab item NSString * identifier; switch (fCurrentTabTag) @@ -213,7 +213,7 @@ typedef enum fGeneralViewController = [[InfoGeneralViewController alloc] init]; [fGeneralViewController setInfoForTorrents: fTorrents]; } - + fViewController = fGeneralViewController; identifier = TAB_INFO_IDENT; break; @@ -223,7 +223,7 @@ typedef enum fActivityViewController = [[InfoActivityViewController alloc] init]; [fActivityViewController setInfoForTorrents: fTorrents]; } - + fViewController = fActivityViewController; identifier = TAB_ACTIVITY_IDENT; break; @@ -233,7 +233,7 @@ typedef enum fTrackersViewController = [[InfoTrackersViewController alloc] init]; [fTrackersViewController setInfoForTorrents: fTorrents]; } - + fViewController = fTrackersViewController; identifier = TAB_TRACKER_IDENT; break; @@ -243,7 +243,7 @@ typedef enum fPeersViewController = [[InfoPeersViewController alloc] init]; [fPeersViewController setInfoForTorrents: fTorrents]; } - + fViewController = fPeersViewController; identifier = TAB_PEERS_IDENT; break; @@ -253,7 +253,7 @@ typedef enum fFileViewController = [[InfoFileViewController alloc] init]; [fFileViewController setInfoForTorrents: fTorrents]; } - + fViewController = fFileViewController; identifier = TAB_FILES_IDENT; break; @@ -263,7 +263,7 @@ typedef enum fOptionsViewController = [[InfoOptionsViewController alloc] init]; [fOptionsViewController setInfoForTorrents: fTorrents]; } - + fViewController = fOptionsViewController; identifier = TAB_OPTIONS_IDENT; break; @@ -271,30 +271,30 @@ typedef enum NSAssert1(NO, @"Unknown info tab selected: %ld", fCurrentTabTag); return; } - + [[NSUserDefaults standardUserDefaults] setObject: identifier forKey: @"InspectorSelected"]; - + NSWindow * window = [self window]; - + [window setTitle: [NSString stringWithFormat: @"%@ - %@", [fViewController title], NSLocalizedString(@"Torrent Inspector", "Inspector -> title")]]; - + //selected tab item [(InfoTabButtonCell *)[fTabMatrix selectedCell] setSelectedTab: YES]; - + NSView * view = [fViewController view]; - + [fViewController updateInfo]; - + NSRect windowRect = [window frame], viewRect = [view frame]; - + const CGFloat difference = NSHeight(viewRect) - oldHeight; windowRect.origin.y -= difference; windowRect.size.height += difference; - + const CGFloat minWindowWidth = MAX(fMinWindowWidth, [view fittingSize].width); windowRect.size.width = MAX(NSWidth(windowRect), minWindowWidth); - + if ([fViewController respondsToSelector: @selector(saveViewSize)]) //a little bit hacky, but avoids requiring an extra method { if ([window screen]) @@ -305,11 +305,11 @@ typedef enum const CGFloat difference = screenHeight - NSHeight(windowRect); windowRect.origin.y -= difference; windowRect.size.height += difference; - + viewRect.size.height += difference; } } - + [window setMinSize: NSMakeSize(minWindowWidth, NSHeight(windowRect) - NSHeight(viewRect) + TAB_MIN_HEIGHT)]; [window setMaxSize: NSMakeSize(FLT_MAX, FLT_MAX)]; } @@ -318,13 +318,13 @@ typedef enum [window setMinSize: NSMakeSize(minWindowWidth, NSHeight(windowRect))]; [window setMaxSize: NSMakeSize(FLT_MAX, NSHeight(windowRect))]; } - + viewRect.size.width = NSWidth(windowRect); [view setFrame: viewRect]; - + [window setFrame: windowRect display: YES animate: oldTabTag != INVALID]; [[window contentView] addSubview: view]; - + [[window contentView] addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"H:|-0-[view]-0-|" options: 0 metrics: nil @@ -333,7 +333,7 @@ typedef enum options: 0 metrics: nil views: @{ @"tabs": fTabMatrix, @"view": view }]]; - + if ((fCurrentTabTag == TAB_FILE_TAG || oldTabTag == TAB_FILE_TAG) && ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible])) [[QLPreviewPanel sharedPreviewPanel] reloadData]; @@ -344,7 +344,7 @@ typedef enum NSInteger tag = [fTabMatrix selectedTag]+1; if (tag >= [fTabMatrix numberOfColumns]) tag = 0; - + [fTabMatrix selectCellWithTag: tag]; [self setTab: nil]; } @@ -354,7 +354,7 @@ typedef enum NSInteger tag = [fTabMatrix selectedTag]-1; if (tag < 0) tag = [fTabMatrix numberOfColumns]-1; - + [fTabMatrix selectCellWithTag: tag]; [self setTab: nil]; } @@ -386,7 +386,7 @@ typedef enum { if (fCurrentTabTag != TAB_FILE_TAG || ![[self window] isVisible]) return NO; - + return [fFileViewController canQuickLook]; } @@ -407,12 +407,12 @@ typedef enum if (numberSelected > 0) { [fImageView setImage: [NSImage imageNamed: NSImageNameMultipleDocuments]]; - + [fNameField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ Torrents Selected", "Inspector -> selected torrents"), [NSString formattedUInteger: numberSelected]]]; [fNameField setHidden: NO]; - + uint64_t size = 0; NSUInteger fileCount = 0, magnetCount = 0; for (Torrent * torrent in fTorrents) @@ -422,7 +422,7 @@ typedef enum if ([torrent isMagnet]) ++magnetCount; } - + NSMutableArray * fileStrings = [NSMutableArray arrayWithCapacity: 2]; if (fileCount > 0) { @@ -444,15 +444,15 @@ typedef enum "Inspector -> selected torrents"), [NSString formattedUInteger: magnetCount]]; [fileStrings addObject: magnetString]; } - + NSString * fileString = [fileStrings componentsJoinedByString: @" + "]; - + if (magnetCount < numberSelected) { [fBasicInfoField setStringValue: [NSString stringWithFormat: @"%@, %@", fileString, [NSString stringWithFormat: NSLocalizedString(@"%@ total", "Inspector -> selected torrents"), [NSString stringForFileSize: size]]]]; - + NSString * byteString; if ([NSApp isOnMountainLionOrBetter]) { @@ -471,31 +471,31 @@ typedef enum [fBasicInfoField setToolTip: nil]; } [fBasicInfoField setHidden: NO]; - + [fNoneSelectedField setHidden: YES]; } else { [fImageView setImage: [NSImage imageNamed: NSImageNameApplicationIcon]]; [fNoneSelectedField setHidden: NO]; - + [fNameField setHidden: YES]; [fBasicInfoField setHidden: YES]; } - + [fNameField setToolTip: nil]; } else { Torrent * torrent = [fTorrents objectAtIndex: 0]; - + [fImageView setImage: [torrent icon]]; - + NSString * name = [torrent name]; [fNameField setStringValue: name]; [fNameField setToolTip: name]; [fNameField setHidden: NO]; - + if (![torrent isMagnet]) { NSString * basicString = [NSString stringForFileSize: [torrent size]]; @@ -511,7 +511,7 @@ typedef enum basicString = [NSString stringWithFormat: @"%@, %@", fileString, basicString]; } [fBasicInfoField setStringValue: basicString]; - + NSString * byteString; if ([NSApp isOnMountainLionOrBetter]) { @@ -530,17 +530,17 @@ typedef enum [fBasicInfoField setToolTip: nil]; } [fBasicInfoField setHidden: NO]; - + [fNoneSelectedField setHidden: YES]; } - + [fGeneralViewController setInfoForTorrents: fTorrents]; [fActivityViewController setInfoForTorrents: fTorrents]; [fTrackersViewController setInfoForTorrents: fTorrents]; [fPeersViewController setInfoForTorrents: fTorrents]; [fFileViewController setInfoForTorrents: fTorrents]; [fOptionsViewController setInfoForTorrents: fTorrents]; - + [fViewController updateInfo]; } diff --git a/macosx/MessageWindowController.h b/macosx/MessageWindowController.h index 73a05f57c..ebe1c7a49 100644 --- a/macosx/MessageWindowController.h +++ b/macosx/MessageWindowController.h @@ -25,17 +25,17 @@ @interface MessageWindowController : NSWindowController { IBOutlet NSTableView * fMessageTable; - + IBOutlet NSPopUpButton * fLevelButton; IBOutlet NSButton * fSaveButton, * fClearButton; IBOutlet NSSearchField * fFilterField; - + NSMutableArray * fMessages, * fDisplayedMessages; - + NSDictionary * fAttributes; - + NSTimer * fTimer; - + NSLock * fLock; } diff --git a/macosx/MessageWindowController.m b/macosx/MessageWindowController.m index e436401ea..da0ff8296 100644 --- a/macosx/MessageWindowController.m +++ b/macosx/MessageWindowController.m @@ -56,14 +56,14 @@ [window setFrameAutosaveName: @"MessageWindowFrame"]; [window setFrameUsingName: @"MessageWindowFrame"]; [window setRestorationClass: [self class]]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resizeColumn) name: NSTableViewColumnDidResizeNotification object: fMessageTable]; - + [window setContentBorderThickness: NSMinY([[fMessageTable enclosingScrollView] frame]) forEdge: NSMinYEdge]; - + [[self window] setTitle: NSLocalizedString(@"Message Log", "Message window -> title")]; - + //set images and text for popup button items [[fLevelButton itemAtIndex: LEVEL_ERROR] setTitle: NSLocalizedString(@"Error", "Message window -> level string")]; [[fLevelButton itemAtIndex: LEVEL_INFO] setTitle: NSLocalizedString(@"Info", "Message window -> level string")]; @@ -77,7 +77,7 @@ const CGFloat levelButtonOldWidth = NSWidth([fLevelButton frame]); [fLevelButton sizeToFit]; - + //set table column text [[[fMessageTable tableColumnWithIdentifier: @"Date"] headerCell] setTitle: NSLocalizedString(@"Date", "Message window -> table column")]; @@ -85,34 +85,34 @@ "Message window -> table column")]; [[[fMessageTable tableColumnWithIdentifier: @"Message"] headerCell] setTitle: NSLocalizedString(@"Message", "Message window -> table column")]; - + //set and size buttons [fSaveButton setTitle: [NSLocalizedString(@"Save", "Message window -> save button") stringByAppendingEllipsis]]; [fSaveButton sizeToFit]; - + NSRect saveButtonFrame = [fSaveButton frame]; saveButtonFrame.size.width += 10.0; saveButtonFrame.origin.x += NSWidth([fLevelButton frame]) - levelButtonOldWidth; [fSaveButton setFrame: saveButtonFrame]; - + const CGFloat oldClearButtonWidth = [fClearButton frame].size.width; - + [fClearButton setTitle: NSLocalizedString(@"Clear", "Message window -> save button")]; [fClearButton sizeToFit]; - + NSRect clearButtonFrame = [fClearButton frame]; clearButtonFrame.size.width = MAX(clearButtonFrame.size.width + 10.0, saveButtonFrame.size.width); clearButtonFrame.origin.x -= NSWidth(clearButtonFrame) - oldClearButtonWidth; [fClearButton setFrame: clearButtonFrame]; - + [[fFilterField cell] setPlaceholderString: NSLocalizedString(@"Filter", "Message window -> filter field")]; NSRect filterButtonFrame = [fFilterField frame]; filterButtonFrame.origin.x -= NSWidth(clearButtonFrame) - oldClearButtonWidth; [fFilterField setFrame: filterButtonFrame]; - + fAttributes = [[[[[fMessageTable tableColumnWithIdentifier: @"Message"] dataCell] attributedStringValue] attributesAtIndex: 0 effectiveRange: NULL] retain]; - + //select proper level in popup button switch ([[NSUserDefaults standardUserDefaults] integerForKey: @"MessageLevel"]) { @@ -129,26 +129,26 @@ [[NSUserDefaults standardUserDefaults] setInteger: TR_LOG_ERROR forKey: @"MessageLevel"]; [fLevelButton selectItemAtIndex: LEVEL_ERROR]; } - + fMessages = [[NSMutableArray alloc] init]; fDisplayedMessages = [[NSMutableArray alloc] init]; - + fLock = [[NSLock alloc] init]; } - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fTimer invalidate]; [fTimer release]; [fLock release]; - + [fMessages release]; [fDisplayedMessages release]; - + [fAttributes release]; - + [super dealloc]; } @@ -171,7 +171,7 @@ + (void) restoreWindowWithIdentifier: (NSString *) identifier state: (NSCoder *) state completionHandler: (void (^)(NSWindow *, NSError *)) completionHandler { NSAssert1([identifier isEqualToString: @"MessageWindow"], @"Trying to restore unexpected identifier %@", identifier); - + NSWindow * window = [[(Controller *)[NSApp delegate] messageWindowController] window]; completionHandler(window, nil); } @@ -189,28 +189,28 @@ tr_log_message * messages; if ((messages = tr_logGetQueue()) == NULL) return; - + [fLock lock]; - + static NSUInteger currentIndex = 0; - + NSScroller * scroller = [[fMessageTable enclosingScrollView] verticalScroller]; const BOOL shouldScroll = currentIndex == 0 || [scroller floatValue] == 1.0 || [scroller isHidden] || [scroller knobProportion] == 1.0; - + const NSInteger maxLevel = [[NSUserDefaults standardUserDefaults] integerForKey: @"MessageLevel"]; NSString * filterString = [fFilterField stringValue]; - + BOOL changed = NO; - + for (tr_log_message * currentMessage = messages; currentMessage != NULL; currentMessage = currentMessage->next) { NSString * name = currentMessage->name != NULL ? [NSString stringWithUTF8String: currentMessage->name] : [[NSProcessInfo processInfo] processName]; - + NSString * file = [[[NSString stringWithUTF8String: currentMessage->file] lastPathComponent] stringByAppendingFormat: @":%d", currentMessage->line]; - + NSDictionary * message = [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithUTF8String: currentMessage->message], @"Message", [NSDate dateWithTimeIntervalSince1970: currentMessage->when], @"Date", @@ -218,40 +218,40 @@ [NSNumber numberWithInteger: currentMessage->level], @"Level", name, @"Name", file, @"File", nil]; - + [fMessages addObject: message]; - + if (currentMessage->level <= maxLevel && [self shouldIncludeMessageForFilter: filterString message: message]) { [fDisplayedMessages addObject: message]; changed = YES; } } - + if ([fMessages count] > TR_LOG_MAX_QUEUE_LENGTH) { const NSUInteger oldCount = [fDisplayedMessages count]; - + NSIndexSet * removeIndexes = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fMessages count]-TR_LOG_MAX_QUEUE_LENGTH)]; NSArray * itemsToRemove = [fMessages objectsAtIndexes: removeIndexes]; - + [fMessages removeObjectsAtIndexes: removeIndexes]; [fDisplayedMessages removeObjectsInArray: itemsToRemove]; - + changed |= oldCount > [fDisplayedMessages count]; } - + if (changed) { [fDisplayedMessages sortUsingDescriptors: [fMessageTable sortDescriptors]]; - + [fMessageTable reloadData]; if (shouldScroll) [fMessageTable scrollRowToVisible: [fMessageTable numberOfRows]-1]; } - + [fLock unlock]; - + tr_logFreeQueue (messages); } @@ -293,10 +293,10 @@ - (CGFloat) tableView: (NSTableView *) tableView heightOfRow: (NSInteger) row { NSString * message = [[fDisplayedMessages objectAtIndex: row] objectForKey: @"Message"]; - + NSTableColumn * column = [tableView tableColumnWithIdentifier: @"Message"]; const CGFloat count = floorf([message sizeWithAttributes: fAttributes].width / [column width]); - + return [tableView rowHeight] * (count + 1.0); } @@ -317,12 +317,12 @@ { NSIndexSet * indexes = [fMessageTable selectedRowIndexes]; NSMutableArray * messageStrings = [NSMutableArray arrayWithCapacity: [indexes count]]; - + for (NSDictionary * message in [fDisplayedMessages objectsAtIndexes: indexes]) [messageStrings addObject: [self stringForMessage: message]]; - + NSString * messageString = [messageStrings componentsJoinedByString: @"\n"]; - + NSPasteboard * pb = [NSPasteboard generalPasteboard]; [pb clearContents]; [pb writeObjects: [NSArray arrayWithObject: messageString]]; @@ -331,10 +331,10 @@ - (BOOL) validateMenuItem: (NSMenuItem *) menuItem { SEL action = [menuItem action]; - + if (action == @selector(copy:)) return [fMessageTable numberOfSelectedRows] > 0; - + return YES; } @@ -356,32 +356,32 @@ NSAssert1(NO, @"Unknown message log level: %ld", [fLevelButton indexOfSelectedItem]); level = TR_LOG_INFO; } - + if ([[NSUserDefaults standardUserDefaults] integerForKey: @"MessageLevel"] == level) return; - + [[NSUserDefaults standardUserDefaults] setInteger: level forKey: @"MessageLevel"]; - + [fLock lock]; - + [self updateListForFilter]; - + [fLock unlock]; } - (void) changeFilter: (id) sender { [fLock lock]; - + [self updateListForFilter]; - + [fLock unlock]; } - (void) clearLog: (id) sender { [fLock lock]; - + [fMessages removeAllObjects]; [fMessageTable beginUpdates]; @@ -390,7 +390,7 @@ [fDisplayedMessages removeAllObjects]; [fMessageTable endUpdates]; - + [fLock unlock]; } @@ -399,9 +399,9 @@ NSSavePanel * panel = [NSSavePanel savePanel]; [panel setAllowedFileTypes: [NSArray arrayWithObject: @"txt"]]; [panel setCanSelectHiddenExtension: YES]; - + [panel setNameFieldStringValue: NSLocalizedString(@"untitled", "Save log panel -> default file name")]; - + [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) { @@ -410,14 +410,14 @@ NSArray * descriptors = [[NSArray alloc] initWithObjects: descriptor, nil]; NSArray * sortedMessages = [fDisplayedMessages sortedArrayUsingDescriptors: descriptors]; [descriptors release]; - + //create the text to output NSMutableArray * messageStrings = [NSMutableArray arrayWithCapacity: [sortedMessages count]]; for (NSDictionary * message in sortedMessages) [messageStrings addObject: [self stringForMessage: message]]; - + NSString * fileString = [messageStrings componentsJoinedByString: @"\n"]; - + if (![fileString writeToFile: [[panel URL] path] atomically: YES encoding: NSUTF8StringEncoding error: nil]) { NSAlert * alert = [[NSAlert alloc] init]; @@ -427,7 +427,7 @@ NSLocalizedString(@"There was a problem creating the file \"%@\".", "Save log alert panel -> message"), [[[panel URL] path] lastPathComponent]]]; [alert setAlertStyle: NSWarningAlertStyle]; - + [alert runModal]; [alert release]; } @@ -449,7 +449,7 @@ { if ([filterString isEqualToString: @""]) return YES; - + const NSStringCompareOptions searchOptions = NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch; return [[message objectForKey: @"Name"] rangeOfString: filterString options: searchOptions].location != NSNotFound || [[message objectForKey: @"Message"] rangeOfString: filterString options: searchOptions].location != NSNotFound; @@ -459,20 +459,20 @@ { const NSInteger level = [[NSUserDefaults standardUserDefaults] integerForKey: @"MessageLevel"]; NSString * filterString = [fFilterField stringValue]; - + NSIndexSet * indexes = [fMessages indexesOfObjectsWithOptions: NSEnumerationConcurrent passingTest: ^BOOL(id message, NSUInteger idx, BOOL * stop) { return [[(NSDictionary *)message objectForKey: @"Level"] integerValue] <= level && [self shouldIncludeMessageForFilter: filterString message: message]; }]; - + NSArray * tempMessages = [[fMessages objectsAtIndexes: indexes] sortedArrayUsingDescriptors: [fMessageTable sortDescriptors]]; [fMessageTable beginUpdates]; - + //figure out which rows were added/moved NSUInteger currentIndex = 0, totalCount = 0; NSMutableArray * itemsToAdd = [NSMutableArray array]; NSMutableIndexSet * itemsToAddIndexes = [NSMutableIndexSet indexSet]; - + for (NSDictionary * message in tempMessages) { const NSUInteger previousIndex = [fDisplayedMessages indexOfObject: message inRange: NSMakeRange(currentIndex, [fDisplayedMessages count]-currentIndex)]; @@ -490,10 +490,10 @@ } ++currentIndex; } - + ++totalCount; } - + //remove trailing items - those are the unused if (currentIndex < [fDisplayedMessages count]) { @@ -501,13 +501,13 @@ [fDisplayedMessages removeObjectsInRange: removeRange]; [fMessageTable removeRowsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: removeRange] withAnimation: NSTableViewAnimationSlideDown]; } - + //add new items [fDisplayedMessages insertObjects: itemsToAdd atIndexes: itemsToAddIndexes]; [fMessageTable insertRowsAtIndexes: itemsToAddIndexes withAnimation: NSTableViewAnimationSlideUp]; [fMessageTable endUpdates]; - + NSAssert2([fDisplayedMessages isEqualToArray: tempMessages], @"Inconsistency between message arrays! %@ %@", fDisplayedMessages, tempMessages); } @@ -530,7 +530,7 @@ NSAssert1(NO, @"Unknown message log level: %ld", level); levelString = @"?"; } - + return [NSString stringWithFormat: @"%@ %@ [%@] %@: %@", [message objectForKey: @"Date"], [message objectForKey: @"File"], levelString, [message objectForKey: @"Name"], [message objectForKey: @"Message"], nil]; diff --git a/macosx/NSImageAdditions.m b/macosx/NSImageAdditions.m index 1c88efa1f..af850ea7e 100644 --- a/macosx/NSImageAdditions.m +++ b/macosx/NSImageAdditions.m @@ -27,16 +27,16 @@ - (NSImage *) imageWithColor: (NSColor *) color { NSImage * coloredImage = [self copy]; - + [coloredImage lockFocus]; - + [color set]; - + const NSSize size = [coloredImage size]; NSRectFillUsingOperation(NSMakeRect(0.0, 0.0, size.width, size.height), NSCompositeSourceAtop); - + [coloredImage unlockFocus]; - + return [coloredImage autorelease]; } diff --git a/macosx/NSMutableArrayAdditions.m b/macosx/NSMutableArrayAdditions.m index 20b313028..4a66aa92c 100644 --- a/macosx/NSMutableArrayAdditions.m +++ b/macosx/NSMutableArrayAdditions.m @@ -33,9 +33,9 @@ { if (fromIndex == toIndex) return; - + id object = [[self objectAtIndex: fromIndex] retain]; - + //shift objects - more efficient than simply removing the object and re-inserting the object if (fromIndex < toIndex) { @@ -48,7 +48,7 @@ [self replaceObjectAtIndex: i withObject: [self objectAtIndex: i-1]]; } [self replaceObjectAtIndex: toIndex withObject: object]; - + [object release]; } diff --git a/macosx/NSStringAdditions.m b/macosx/NSStringAdditions.m index ee38573d5..920022214 100644 --- a/macosx/NSStringAdditions.m +++ b/macosx/NSStringAdditions.m @@ -38,12 +38,12 @@ + (NSString *) ellipsis { - return [NSString stringWithUTF8String: "\xE2\x80\xA6"]; + return [NSString stringWithUTF8String: "\xE2\x80\xA6"]; } - (NSString *) stringByAppendingEllipsis { - return [self stringByAppendingString: [NSString ellipsis]]; + return [self stringByAppendingString: [NSString ellipsis]]; } #warning use localizedStringWithFormat: directly when 10.8-only @@ -60,7 +60,7 @@ [numberFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; [numberFormatter setMaximumFractionDigits: 0]; }); - + return [numberFormatter stringFromNumber: [NSNumber numberWithUnsignedInteger: value]]; } } @@ -81,9 +81,9 @@ if ([NSApp isOnMountainLionOrBetter]) { NSByteCountFormatter * fileSizeFormatter = [[NSByteCountFormatterMtLion alloc] init]; - + fullString = [fileSizeFormatter stringFromByteCount: fullSize]; - + //figure out the magniture of the two, since we can't rely on comparing the units because of localization and pluralization issues (for example, "1 byte of 2 bytes") BOOL partialUnitsSame; if (partialSize == 0) @@ -94,10 +94,10 @@ const unsigned int magnitudeFull = fullSize < 1000 ? 0 : log(fullSize)/log(1000); //we have to catch 0 with a special case, so might as well avoid the math for all of magnitude 0 partialUnitsSame = magnitudePartial == magnitudeFull; } - + [fileSizeFormatter setIncludesUnit: !partialUnitsSame]; partialString = [fileSizeFormatter stringFromByteCount: partialSize]; - + [fileSizeFormatter release]; } else @@ -106,7 +106,7 @@ fullString = [self stringForFileSizeLion: fullSize showUnitUnless: nil unitsUsed: &units]; partialString = [self stringForFileSizeLion: partialSize showUnitUnless: units unitsUsed: nil]; } - + return [NSString stringWithFormat: NSLocalizedString(@"%@ of %@", "file size string"), partialString, fullString]; } @@ -163,10 +163,10 @@ { NSAssert(![NSApp isOnYosemiteOrBetter], @"you should be using NSDateComponentsFormatter on >= 10.10"); NSParameterAssert(max > 0); - + NSMutableArray * timeArray = [NSMutableArray arrayWithCapacity: MIN(max, 5u)]; NSUInteger remaining = seconds; //causes problems for some users when it's a uint64_t - + if (seconds >= 31557600) //official amount of seconds in one year { const NSUInteger years = remaining / 31557600; @@ -201,13 +201,13 @@ } if (max > 0 && showSeconds) [timeArray addObject: [NSString stringWithFormat: NSLocalizedString(@"%u sec", "time string"), remaining]]; - + NSString * timeString = [timeArray componentsJoinedByString: @" "]; - + if (includesTimeRemainingPhrase) { timeString = [NSString stringWithFormat: NSLocalizedString(@"%@ remaining", "time remaining string"), timeString]; } - + return timeString; } @@ -220,7 +220,7 @@ - (NSArray *) betterComponentsSeparatedByCharactersInSet: (NSCharacterSet *) separators { NSMutableArray * components = [NSMutableArray array]; - + NSCharacterSet * includededCharSet = [separators invertedSet]; NSUInteger index = 0; const NSUInteger fullLength = [self length]; @@ -229,20 +229,20 @@ const NSUInteger start = [self rangeOfCharacterFromSet: includededCharSet options: 0 range: NSMakeRange(index, fullLength - index)].location; if (start == NSNotFound) break; - + const NSRange endRange = [self rangeOfCharacterFromSet: separators options: 0 range: NSMakeRange(start, fullLength - start)]; if (endRange.location == NSNotFound) { [components addObject: [self substringFromIndex: start]]; break; } - + [components addObject: [self substringWithRange: NSMakeRange(start, endRange.location - start)]]; - + index = NSMaxRange(endRange); } while (YES); - + return components; } @@ -279,22 +279,22 @@ unit = NSLocalizedString(@"TB", "File size - terabytes"); decimals = 2; } - + //match Finder's behavior NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; [numberFormatter setMinimumFractionDigits: 0]; [numberFormatter setMaximumFractionDigits: decimals]; - + NSString * fileSizeString = [numberFormatter stringFromNumber: [NSNumber numberWithFloat: convertedSize]]; [numberFormatter release]; - + if (!notAllowedUnit || ![unit isEqualToString: notAllowedUnit]) fileSizeString = [fileSizeString stringByAppendingFormat: @" %@", unit]; - + if (unitUsed) *unitUsed = unit; - + return fileSizeString; } @@ -302,9 +302,9 @@ { if (speed <= 999.95) //0.0 KB/s to 999.9 KB/s return [NSString localizedStringWithFormat: @"%.1f %@", speed, kb]; - + speed /= 1000.0; - + if (speed <= 99.995) //1.00 MB/s to 99.99 MB/s return [NSString localizedStringWithFormat: @"%.2f %@", speed, mb]; else if (speed <= 999.95) //100.0 MB/s to 999.9 MB/s diff --git a/macosx/PeerProgressIndicatorCell.m b/macosx/PeerProgressIndicatorCell.m index 2321daac8..bd6465875 100644 --- a/macosx/PeerProgressIndicatorCell.m +++ b/macosx/PeerProgressIndicatorCell.m @@ -29,7 +29,7 @@ { PeerProgressIndicatorCell * copy = [super copyWithZone: zone]; copy->fAttributes = [fAttributes retain]; - + return copy; } @@ -52,12 +52,12 @@ { NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [paragraphStyle setAlignment: NSRightTextAlignment]; - + fAttributes = [[NSDictionary alloc] initWithObjectsAndKeys: [NSFont systemFontOfSize: 11.0], NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; [paragraphStyle release]; } - + [[NSString percentString: [self floatValue] longDecimals: NO] drawInRect: cellFrame withAttributes: fAttributes]; } else @@ -68,17 +68,17 @@ [fAttributes release]; fAttributes = nil; } - + [super drawWithFrame: cellFrame inView: controlView]; if (fSeed) { NSImage * checkImage = [NSImage imageNamed: @"CompleteCheck"]; - + const NSSize imageSize = [checkImage size]; const NSRect rect = NSMakeRect(floor(NSMidX(cellFrame) - imageSize.width * 0.5), floor(NSMidY(cellFrame) - imageSize.height * 0.5), imageSize.width, imageSize.height); - + [checkImage drawInRect: rect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; } } diff --git a/macosx/PeerTableView.m b/macosx/PeerTableView.m index db2c47ada..4dd203dce 100644 --- a/macosx/PeerTableView.m +++ b/macosx/PeerTableView.m @@ -31,7 +31,7 @@ { [[NSUserDefaults standardUserDefaults] setBool: ![[NSUserDefaults standardUserDefaults] boolForKey: @"DisplayPeerProgressBarNumber"] forKey: @"DisplayPeerProgressBarNumber"]; - + NSIndexSet * rowIndexes = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [self numberOfRows])], * columnIndexes = [NSIndexSet indexSetWithIndex: [self columnAtPoint: point]]; [self reloadDataForRowIndexes: rowIndexes columnIndexes: columnIndexes]; diff --git a/macosx/PiecesView.h b/macosx/PiecesView.h index a913f1634..c8280a79f 100644 --- a/macosx/PiecesView.h +++ b/macosx/PiecesView.h @@ -27,9 +27,9 @@ @interface PiecesView : NSImageView { int8_t * fPieces; - + NSColor * fGreenAvailabilityColor, * fBluePieceColor; - + Torrent * fTorrent; NSInteger fNumPieces, fAcross, fWidth, fExtraBorder; } diff --git a/macosx/PiecesView.m b/macosx/PiecesView.m index 0bded3a8d..7dcc75722 100644 --- a/macosx/PiecesView.m +++ b/macosx/PiecesView.m @@ -48,7 +48,7 @@ enum //store box colors fGreenAvailabilityColor = [[NSColor colorWithCalibratedRed: 0.0 green: 1.0 blue: 0.4 alpha: 1.0] retain]; fBluePieceColor = [[NSColor colorWithCalibratedRed: 0.0 green: 0.4 blue: 0.8 alpha: 1.0] retain]; - + //actually draw the box [self setTorrent: nil]; } @@ -56,41 +56,41 @@ enum - (void) dealloc { tr_free(fPieces); - + [fGreenAvailabilityColor release]; [fBluePieceColor release]; - + [super dealloc]; } - (void) setTorrent: (Torrent *) torrent { [self clearView]; - + fTorrent = (torrent && ![torrent isMagnet]) ? torrent : nil; if (fTorrent) { //determine relevant values fNumPieces = MIN([fTorrent pieceCount], MAX_ACROSS * MAX_ACROSS); fAcross = ceil(sqrt(fNumPieces)); - + const CGFloat width = [self bounds].size.width; fWidth = (width - (fAcross + 1) * BETWEEN) / fAcross; fExtraBorder = (width - ((fWidth + BETWEEN) * fAcross + BETWEEN)) / 2; } - + NSImage * back = [[NSImage alloc] initWithSize: [self bounds].size]; [back lockFocus]; - + NSGradient * gradient = [[NSGradient alloc] initWithStartingColor: [NSColor colorWithCalibratedWhite: 0.0 alpha: 0.4] endingColor: [NSColor colorWithCalibratedWhite: 0.2 alpha: 0.4]]; [gradient drawInRect: [self bounds] angle: 90.0]; [gradient release]; [back unlockFocus]; - + [self setImage: back]; [back release]; - + [self setNeedsDisplay]; } @@ -104,7 +104,7 @@ enum { if (!fTorrent) return; - + //determine if first time const BOOL first = fPieces == NULL; if (first) @@ -112,30 +112,30 @@ enum int8_t * pieces = NULL; float * piecesPercent = NULL; - + const BOOL showAvailablity = [[NSUserDefaults standardUserDefaults] boolForKey: @"PiecesViewShowAvailability"]; if (showAvailablity) - { + { pieces = (int8_t *)tr_malloc(fNumPieces * sizeof(int8_t)); [fTorrent getAvailability: pieces size: fNumPieces]; } else - { + { piecesPercent = (float *)tr_malloc(fNumPieces * sizeof(float)); [fTorrent getAmountFinished: piecesPercent size: fNumPieces]; } - + NSImage * image = [self image]; - + NSRect fillRects[fNumPieces]; NSColor * fillColors[fNumPieces]; - + NSInteger usedCount = 0; - + for (NSInteger index = 0; index < fNumPieces; index++) { NSColor * pieceColor = nil; - + if (showAvailablity ? pieces[index] == -1 : piecesPercent[index] == 1.0) { if (first || fPieces[index] != PIECE_FINISHED) @@ -176,7 +176,7 @@ enum pieceColor = [[NSColor whiteColor] blendedColorWithFraction: percent ofColor: fullColor]; fPieces[index] = PIECE_SOME; } - + if (pieceColor) { const NSInteger across = index % fAcross, @@ -185,11 +185,11 @@ enum [image size].width - (down + 1) * (fWidth + BETWEEN) - fExtraBorder, fWidth, fWidth); fillColors[usedCount] = pieceColor; - + usedCount++; } } - + if (usedCount > 0) { [image lockFocus]; @@ -197,7 +197,7 @@ enum [image unlockFocus]; [self setNeedsDisplay]; } - + tr_free(pieces); tr_free(piecesPercent); } @@ -213,10 +213,10 @@ enum { const BOOL availability = ![[NSUserDefaults standardUserDefaults] boolForKey: @"PiecesViewShowAvailability"]; [[NSUserDefaults standardUserDefaults] setBool: availability forKey: @"PiecesViewShowAvailability"]; - + [self sendAction:[self action] to:[self target]]; } - + [super mouseDown: event]; } diff --git a/macosx/PortChecker.h b/macosx/PortChecker.h index 68919f2ab..9f34da8c6 100644 --- a/macosx/PortChecker.h +++ b/macosx/PortChecker.h @@ -31,13 +31,13 @@ typedef enum } port_status_t; @interface PortChecker : NSObject -{ +{ id fDelegate; port_status_t fStatus; - + NSURLConnection * fConnection; NSMutableData * fPortProbeData; - + NSTimer * fTimer; } diff --git a/macosx/PortChecker.m b/macosx/PortChecker.m index a61eb7779..93f4dccf0 100644 --- a/macosx/PortChecker.m +++ b/macosx/PortChecker.m @@ -40,14 +40,14 @@ if ((self = [super init])) { fDelegate = delegate; - + fStatus = PORT_STATUS_CHECKING; - + fTimer = [[NSTimer scheduledTimerWithTimeInterval: CHECK_FIRE target: self selector: @selector(startProbe:) userInfo: [NSNumber numberWithInteger: portNumber] repeats: NO] retain]; if (!delay) [fTimer fire]; } - + return self; } @@ -55,7 +55,7 @@ { [fTimer invalidate]; [fTimer release]; - + [fConnection release]; [fPortProbeData release]; [super dealloc]; @@ -71,7 +71,7 @@ [fTimer invalidate]; [fTimer release]; fTimer = nil; - + [fConnection cancel]; } @@ -96,7 +96,7 @@ NSString * probeString = [[NSString alloc] initWithData: fPortProbeData encoding: NSUTF8StringEncoding]; [fPortProbeData release]; fPortProbeData = nil; - + if (probeString) { if ([probeString isEqualToString: @"1"]) @@ -125,10 +125,10 @@ { [fTimer release]; fTimer = nil; - + NSURLRequest * portProbeRequest = [NSURLRequest requestWithURL: [NSURL URLWithString: CHECKER_URL([[timer userInfo] integerValue])] cachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval: 15.0]; - + if ((fConnection = [[NSURLConnection alloc] initWithRequest: portProbeRequest delegate: self])) fPortProbeData = [[NSMutableData alloc] init]; else @@ -141,7 +141,7 @@ - (void) callBackWithStatus: (port_status_t) status { fStatus = status; - + if (fDelegate && [fDelegate respondsToSelector: @selector(portCheckerDidFinishProbing:)]) [fDelegate performSelectorOnMainThread: @selector(portCheckerDidFinishProbing:) withObject: self waitUntilDone: NO]; } diff --git a/macosx/PredicateEditorRowTemplateAny.m b/macosx/PredicateEditorRowTemplateAny.m index 81c45b03e..57fca0f96 100644 --- a/macosx/PredicateEditorRowTemplateAny.m +++ b/macosx/PredicateEditorRowTemplateAny.m @@ -28,13 +28,13 @@ { //we only make NSComparisonPredicates NSComparisonPredicate * predicate = (NSComparisonPredicate *)[super predicateWithSubpredicates: subpredicates]; - + //construct a near-identical predicate return [NSComparisonPredicate predicateWithLeftExpression: [predicate leftExpression] - rightExpression: [predicate rightExpression] - modifier: NSAnyPredicateModifier - type: [predicate predicateOperatorType] - options: [predicate options]]; + rightExpression: [predicate rightExpression] + modifier: NSAnyPredicateModifier + type: [predicate predicateOperatorType] + options: [predicate options]]; } @end diff --git a/macosx/PrefsController.h b/macosx/PrefsController.h index 60c72ff32..4b22e06ac 100644 --- a/macosx/PrefsController.h +++ b/macosx/PrefsController.h @@ -30,15 +30,15 @@ tr_session * fHandle; NSUserDefaults * fDefaults; BOOL fHasLoaded; - + IBOutlet NSView * fGeneralView, * fTransfersView, * fBandwidthView, * fPeersView, * fNetworkView, * fRemoteView, * fGroupsView; - + NSString * fInitialString; - + IBOutlet NSButton * fBuiltInGrowlButton, *fGrowlAppButton; IBOutlet NSTextField * fCheckForUpdatesLabel; IBOutlet NSButton * fCheckForUpdatesButton, * fCheckForUpdatesBetaButton; - + IBOutlet NSPopUpButton * fFolderPopUp, * fIncompleteFolderPopUp, * fImportFolderPopUp, * fDoneScriptPopUp; IBOutlet NSButton * fShowMagnetAddWindowCheck; IBOutlet NSTextField * fRatioStopField, * fIdleStopField, * fQueueDownloadField, * fQueueSeedField, * fStalledField; @@ -46,11 +46,11 @@ IBOutlet NSTextField * fUploadField, * fDownloadField, * fSpeedLimitUploadField, * fSpeedLimitDownloadField; IBOutlet NSPopUpButton * fAutoSpeedDayTypePopUp; - + IBOutlet NSTextField * fPeersGlobalField, * fPeersTorrentField, * fBlocklistURLField, * fBlocklistMessageField, * fBlocklistDateField; IBOutlet NSButton * fBlocklistButton; - + PortChecker * fPortChecker; IBOutlet NSTextField * fPortField, * fPortStatusField; IBOutlet NSButton * fNatCheck; @@ -58,7 +58,7 @@ IBOutlet NSProgressIndicator * fPortStatusProgress; NSTimer * fPortStatusTimer; int fPeerPort, fNatStatus; - + IBOutlet NSTextField * fRPCPortField, * fRPCPasswordField; IBOutlet NSTableView * fRPCWhitelistTable; NSMutableArray * fRPCWhitelistArray; diff --git a/macosx/PrefsController.m b/macosx/PrefsController.m index 4e0c99f31..7218c9ed6 100644 --- a/macosx/PrefsController.m +++ b/macosx/PrefsController.m @@ -72,19 +72,19 @@ if ((self = [super initWithWindowNibName: @"PrefsWindow"])) { fHandle = handle; - + fDefaults = [NSUserDefaults standardUserDefaults]; - + //check for old version download location (before 1.1) NSString * choice; if ((choice = [fDefaults stringForKey: @"DownloadChoice"])) { [fDefaults setBool: [choice isEqualToString: @"Constant"] forKey: @"DownloadLocationConstant"]; [fDefaults setBool: YES forKey: @"DownloadAsk"]; - + [fDefaults removeObjectForKey: @"DownloadChoice"]; } - + //check for old version blocklist (before 2.12) NSDate * blocklistDate; if ((blocklistDate = [fDefaults objectForKey: @"BlocklistLastUpdate"])) @@ -92,39 +92,39 @@ [fDefaults setObject: blocklistDate forKey: @"BlocklistNewLastUpdateSuccess"]; [fDefaults setObject: blocklistDate forKey: @"BlocklistNewLastUpdate"]; [fDefaults removeObjectForKey: @"BlocklistLastUpdate"]; - + NSURL * blocklistDir = [[[[NSFileManager defaultManager] URLsForDirectory: NSApplicationDirectory inDomains: NSUserDomainMask] objectAtIndex: 0] URLByAppendingPathComponent: @"Transmission/blocklists/"]; [[NSFileManager defaultManager] moveItemAtURL: [blocklistDir URLByAppendingPathComponent: @"level1.bin"] toURL: [blocklistDir URLByAppendingPathComponent: [NSString stringWithUTF8String: DEFAULT_BLOCKLIST_FILENAME]] error: nil]; } - + //save a new random port if ([fDefaults boolForKey: @"RandomPort"]) [fDefaults setInteger: tr_sessionGetPeerPort(fHandle) forKey: @"BindPort"]; - + //set auto import NSString * autoPath; if ([fDefaults boolForKey: @"AutoImport"] && (autoPath = [fDefaults stringForKey: @"AutoImportDirectory"])) [[(Controller *)[NSApp delegate] fileWatcherQueue] addPath: [autoPath stringByExpandingTildeInPath] notifyingAbout: VDKQueueNotifyAboutWrite]; - + //set special-handling of magnet link add window checkbox [self updateShowAddMagnetWindowField]; - + //set blocklist scheduler [[BlocklistScheduler scheduler] updateSchedule]; - + //set encryption [self setEncryptionMode: nil]; - + //update rpc whitelist [self updateRPCPassword]; - + fRPCWhitelistArray = [[fDefaults arrayForKey: @"RPCWhitelist"] mutableCopy]; if (!fRPCWhitelistArray) fRPCWhitelistArray = [[NSMutableArray arrayWithObject: @"127.0.0.1"] retain]; [self updateRPCWhitelist]; - + //reset old Sparkle settings from previous versions [fDefaults removeObjectForKey: @"SUScheduledCheckInterval"]; if ([fDefaults objectForKey: @"CheckForUpdates"]) @@ -132,20 +132,20 @@ [[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates: [fDefaults boolForKey: @"CheckForUpdates"]]; [fDefaults removeObjectForKey: @"CheckForUpdates"]; } - + //set built-in Growl [GrowlApplicationBridge setShouldUseBuiltInNotifications: ![NSApp isOnMountainLionOrBetter] && [fDefaults boolForKey: @"DisplayNotifications"]]; - + [self setAutoUpdateToBeta: nil]; } - + return self; } - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fPortStatusTimer invalidate]; [fPortStatusTimer release]; if (fPortChecker) @@ -153,11 +153,11 @@ [fPortChecker cancelProbe]; [fPortChecker release]; } - + [fRPCWhitelistArray release]; - + [fRPCPassword release]; - + [super dealloc]; } @@ -166,7 +166,7 @@ fHasLoaded = YES; [[self window] setRestorationClass: [self class]]; - + NSToolbar * toolbar = [[NSToolbar alloc] initWithIdentifier: @"Preferences Toolbar"]; [toolbar setDelegate: self]; [toolbar setAllowsUserCustomization: NO]; @@ -175,70 +175,70 @@ [toolbar setSelectedItemIdentifier: TOOLBAR_GENERAL]; [[self window] setToolbar: toolbar]; [toolbar release]; - + [self setPrefView: nil]; - + //make sure proper notification settings are shown [self updateGrowlButton]; - + //set download folder [fFolderPopUp selectItemAtIndex: [fDefaults boolForKey: @"DownloadLocationConstant"] ? DOWNLOAD_FOLDER : DOWNLOAD_TORRENT]; - + //set stop ratio [fRatioStopField setFloatValue: [fDefaults floatForKey: @"RatioLimit"]]; - + //set idle seeding minutes [fIdleStopField setIntegerValue: [fDefaults integerForKey: @"IdleLimitMinutes"]]; - + //set limits [self updateLimitFields]; - + //set speed limit [fSpeedLimitUploadField setIntValue: [fDefaults integerForKey: @"SpeedLimitUploadLimit"]]; [fSpeedLimitDownloadField setIntValue: [fDefaults integerForKey: @"SpeedLimitDownloadLimit"]]; - + //set port [fPortField setIntValue: [fDefaults integerForKey: @"BindPort"]]; fNatStatus = -1; - + [self updatePortStatus]; fPortStatusTimer = [[NSTimer scheduledTimerWithTimeInterval: 5.0 target: self selector: @selector(updatePortStatus) userInfo: nil repeats: YES] retain]; - + //set peer connections [fPeersGlobalField setIntValue: [fDefaults integerForKey: @"PeersTotal"]]; [fPeersTorrentField setIntValue: [fDefaults integerForKey: @"PeersTorrent"]]; - + //set queue values [fQueueDownloadField setIntValue: [fDefaults integerForKey: @"QueueDownloadNumber"]]; [fQueueSeedField setIntValue: [fDefaults integerForKey: @"QueueSeedNumber"]]; [fStalledField setIntValue: [fDefaults integerForKey: @"StalledMinutes"]]; - + //set blocklist NSString * blocklistURL = [fDefaults stringForKey: @"BlocklistURL"]; if (blocklistURL) [fBlocklistURLField setStringValue: blocklistURL]; - + [self updateBlocklistButton]; [self updateBlocklistFields]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateLimitFields) name: @"UpdateSpeedLimitValuesOutsidePrefs" object: nil]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateRatioStopField) name: @"UpdateRatioStopValueOutsidePrefs" object: nil]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateLimitStopField) name: @"UpdateIdleStopValueOutsidePrefs" object: nil]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateBlocklistFields) name: @"BlocklistUpdated" object: nil]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateBlocklistURLField) name: NSControlTextDidChangeNotification object: fBlocklistURLField]; - + //set rpc port [fRPCPortField setIntValue: [fDefaults integerForKey: @"RPCPort"]]; - + //set rpc password if (fRPCPassword) [fRPCPasswordField setStringValue: fRPCPassword]; @@ -357,7 +357,7 @@ const tr_port port = [sender intValue]; [fDefaults setInteger: port forKey: @"BindPort"]; tr_sessionSetPeerPort(fHandle, port); - + fPeerPort = -1; [self updatePortStatus]; } @@ -367,7 +367,7 @@ const tr_port port = tr_sessionSetPeerPortRandom(fHandle); [fDefaults setInteger: port forKey: @"BindPort"]; [fPortField setIntValue: port]; - + fPeerPort = -1; [self updatePortStatus]; } @@ -380,7 +380,7 @@ - (void) setNat: (id) sender { tr_sessionSetPortForwardingEnabled(fHandle, [fDefaults boolForKey: @"NatTraversal"]); - + fNatStatus = -1; [self updatePortStatus]; } @@ -396,11 +396,11 @@ { fNatStatus = fwd; fPeerPort = port; - + [fPortStatusField setStringValue: @""]; [fPortStatusImage setImage: nil]; [fPortStatusProgress startAnimation: self]; - + if (fPortChecker) { [fPortChecker cancelProbe]; @@ -439,13 +439,13 @@ - (NSArray *) sounds { NSMutableArray * sounds = [NSMutableArray array]; - + NSArray * directories = NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, NSUserDomainMask | NSLocalDomainMask | NSSystemDomainMask, YES); - + for (NSString * directory in directories) { directory = [directory stringByAppendingPathComponent: @"Sounds"]; - + BOOL isDirectory; if ([[NSFileManager defaultManager] fileExistsAtPath: directory isDirectory: &isDirectory] && isDirectory) { @@ -458,7 +458,7 @@ } } } - + return sounds; } @@ -506,7 +506,7 @@ - (void) setEncryptionMode: (id) sender { - const tr_encryption_mode mode = [fDefaults boolForKey: @"EncryptionPrefer"] ? + const tr_encryption_mode mode = [fDefaults boolForKey: @"EncryptionPrefer"] ? ([fDefaults boolForKey: @"EncryptionRequire"] ? TR_ENCRYPTION_REQUIRED : TR_ENCRYPTION_PREFERRED) : TR_CLEAR_PREFERRED; tr_sessionSetEncryption(fHandle, mode); } @@ -514,9 +514,9 @@ - (void) setBlocklistEnabled: (id) sender { tr_blocklistSetEnabled(fHandle, [fDefaults boolForKey: @"BlocklistNew"]); - + [[BlocklistScheduler scheduler] updateSchedule]; - + [self updateBlocklistButton]; } @@ -533,22 +533,22 @@ - (void) updateBlocklistFields { const BOOL exists = tr_blocklistExists(fHandle); - + if (exists) { NSString * countString = [NSString formattedUInteger: tr_blocklistGetRuleCount(fHandle)]; [fBlocklistMessageField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ IP address rules in list", "Prefs -> blocklist -> message"), countString]]; } - else + else [fBlocklistMessageField setStringValue: NSLocalizedString(@"A blocklist must first be downloaded", "Prefs -> blocklist -> message")]; - + NSString * updatedDateString; if (exists) { NSDate * updatedDate = [fDefaults objectForKey: @"BlocklistNewLastUpdateSuccess"]; - + if (updatedDate) updatedDateString = [NSDateFormatter localizedStringFromDate: updatedDate dateStyle: NSDateFormatterFullStyle timeStyle: NSDateFormatterShortStyle]; else @@ -556,7 +556,7 @@ } else updatedDateString = NSLocalizedString(@"Never", "Prefs -> blocklist -> message"); - + [fBlocklistDateField setStringValue: [NSString stringWithFormat: @"%@: %@", NSLocalizedString(@"Last updated", "Prefs -> blocklist -> message"), updatedDateString]]; } @@ -564,10 +564,10 @@ - (void) updateBlocklistURLField { NSString * blocklistString = [fBlocklistURLField stringValue]; - + [fDefaults setObject: blocklistString forKey: @"BlocklistURL"]; tr_blocklistSetURL(fHandle, [blocklistString UTF8String]); - + [self updateBlocklistButton]; } @@ -588,10 +588,10 @@ { tr_sessionLimitSpeed(fHandle, TR_UP, [fDefaults boolForKey: @"CheckUpload"]); tr_sessionSetSpeedLimit_KBps(fHandle, TR_UP, [fDefaults integerForKey: @"UploadLimit"]); - + tr_sessionLimitSpeed(fHandle, TR_DOWN, [fDefaults boolForKey: @"CheckDownload"]); tr_sessionSetSpeedLimit_KBps(fHandle, TR_DOWN, [fDefaults integerForKey: @"DownloadLimit"]); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"SpeedLimitUpdate" object: nil]; } @@ -599,7 +599,7 @@ { tr_sessionSetAltSpeed_KBps(fHandle, TR_UP, [fDefaults integerForKey: @"SpeedLimitUploadLimit"]); tr_sessionSetAltSpeed_KBps(fHandle, TR_DOWN, [fDefaults integerForKey: @"SpeedLimitDownloadLimit"]); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"SpeedLimitUpdate" object: nil]; } @@ -607,10 +607,10 @@ { tr_sessionSetRatioLimited(fHandle, [fDefaults boolForKey: @"RatioCheck"]); tr_sessionSetRatioLimit(fHandle, [fDefaults floatForKey: @"RatioLimit"]); - + //reload main table for seeding progress [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; - + //reload global settings in inspector [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGlobalOptions" object: nil]; } @@ -618,7 +618,7 @@ - (void) setRatioStop: (id) sender { [fDefaults setFloat: [sender floatValue] forKey: @"RatioLimit"]; - + [self applyRatioSetting: nil]; } @@ -631,7 +631,7 @@ - (void) updateRatioStopFieldOld { [self updateRatioStopField]; - + [self applyRatioSetting: nil]; } @@ -639,10 +639,10 @@ { tr_sessionSetIdleLimited(fHandle, [fDefaults boolForKey: @"IdleLimitCheck"]); tr_sessionSetIdleLimit(fHandle, [fDefaults integerForKey: @"IdleLimitMinutes"]); - + //reload main table for remaining seeding time [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; - + //reload global settings in inspector [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGlobalOptions" object: nil]; } @@ -650,7 +650,7 @@ - (void) setIdleStop: (id) sender { [fDefaults setInteger: [sender integerValue] forKey: @"IdleLimitMinutes"]; - + [self applyIdleStopSetting: nil]; } @@ -664,7 +664,7 @@ { if (!fHasLoaded) return; - + [fUploadField setIntValue: [fDefaults integerForKey: @"UploadLimit"]]; [fDownloadField setIntValue: [fDefaults integerForKey: @"DownloadLimit"]]; } @@ -710,7 +710,7 @@ NSDateComponents * comps = [[[NSDateComponents alloc] init] autorelease]; [comps setHour: sum / 60]; [comps setMinute: sum % 60]; - + return [[NSCalendar currentCalendar] dateFromComponents: comps]; } @@ -718,7 +718,7 @@ { [fInitialString release]; fInitialString = [[control stringValue] retain]; - + return YES; } @@ -784,7 +784,7 @@ //let's just do both - easier that way tr_sessionSetQueueEnabled(fHandle, TR_DOWN, [fDefaults boolForKey: @"Queue"]); tr_sessionSetQueueEnabled(fHandle, TR_UP, [fDefaults boolForKey: @"QueueSeed"]); - + //handle if any transfers switch from queued to paused [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateQueue" object: self]; } @@ -793,16 +793,16 @@ { const NSInteger number = [sender intValue]; const BOOL seed = sender == fQueueSeedField; - + [fDefaults setInteger: number forKey: seed ? @"QueueSeedNumber" : @"QueueDownloadNumber"]; - + tr_sessionSetQueueSize(fHandle, seed ? TR_UP : TR_DOWN, number); } - (void) setStalled: (id) sender { tr_sessionSetQueueStalledEnabled(fHandle, [fDefaults boolForKey: @"CheckStalled"]); - + //reload main table for stalled status [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; } @@ -812,7 +812,7 @@ const NSInteger min = [sender intValue]; [fDefaults setInteger: min forKey: @"StalledMinutes"]; tr_sessionSetQueueStalledMinutes(fHandle, min); - + //reload main table for stalled status [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: self]; } @@ -832,17 +832,17 @@ [panel setCanChooseFiles: NO]; [panel setCanChooseDirectories: YES]; [panel setCanCreateDirectories: YES]; - + [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) { [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER]; - + NSString * folder = [[[panel URLs] objectAtIndex: 0] path]; [fDefaults setObject: folder forKey: @"DownloadFolder"]; [fDefaults setBool: YES forKey: @"DownloadLocationConstant"]; [self updateShowAddMagnetWindowField]; - + assert(folder.length > 0); tr_sessionSetDownloadDir(fHandle, [folder fileSystemRepresentation]); } @@ -863,13 +863,13 @@ [panel setCanChooseFiles: NO]; [panel setCanChooseDirectories: YES]; [panel setCanCreateDirectories: YES]; - + [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) { NSString * folder = [[[panel URLs] objectAtIndex: 0] path]; [fDefaults setObject: folder forKey: @"IncompleteDownloadFolder"]; - + assert(folder.length > 0); tr_sessionSetIncompleteDir(fHandle, [folder fileSystemRepresentation]); } @@ -880,23 +880,23 @@ - (void) doneScriptSheetShow:(id)sender { NSOpenPanel * panel = [NSOpenPanel openPanel]; - + [panel setPrompt: NSLocalizedString(@"Select", "Preferences -> Open panel prompt")]; [panel setAllowsMultipleSelection: NO]; [panel setCanChooseFiles: YES]; [panel setCanChooseDirectories: NO]; [panel setCanCreateDirectories: NO]; - + [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) { if (result == NSFileHandlingPanelOKButton) { NSString * filePath = [[[panel URLs] objectAtIndex: 0] path]; - + assert(filePath.length > 0); - + [fDefaults setObject: filePath forKey: @"DoneScriptPath"]; tr_sessionSetTorrentDoneScript(fHandle, [filePath fileSystemRepresentation]); - + [fDefaults setBool: YES forKey: @"DoneScriptEnabled"]; tr_sessionSetTorrentDoneScriptEnabled(fHandle, YES); } @@ -958,7 +958,7 @@ } else [watcherQueue removeAllPaths]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self]; } else @@ -980,11 +980,11 @@ { VDKQueue * watcherQueue = [(Controller *)[NSApp delegate] fileWatcherQueue]; [watcherQueue removeAllPaths]; - + NSString * path = [[[panel URLs] objectAtIndex: 0] path]; [fDefaults setObject: path forKey: @"AutoImportDirectory"]; [watcherQueue addPath: [path stringByExpandingTildeInPath] notifyingAbout: VDKQueueNotifyAboutWrite]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self]; } else @@ -993,7 +993,7 @@ if (!path) [fDefaults setBool: NO forKey: @"AutoImport"]; } - + [fImportFolderPopUp selectItemAtIndex: 0]; }]; } @@ -1007,7 +1007,7 @@ { BOOL enable = [fDefaults boolForKey: @"RPC"]; tr_sessionSetRPCEnabled(fHandle, enable); - + [self setRPCWebUIDiscovery: nil]; } @@ -1031,10 +1031,10 @@ { [fRPCPassword release]; fRPCPassword = [[sender stringValue] copy]; - + const char * password = [[sender stringValue] UTF8String]; [self setKeychainPassword: password forService: RPC_KEYCHAIN_SERVICE username: RPC_KEYCHAIN_NAME]; - + tr_sessionSetRPCPassword(fHandle, password); } @@ -1044,7 +1044,7 @@ const char * password = nil; SecKeychainFindGenericPassword(NULL, strlen(RPC_KEYCHAIN_SERVICE), RPC_KEYCHAIN_SERVICE, strlen(RPC_KEYCHAIN_NAME), RPC_KEYCHAIN_NAME, &passwordLength, (void **)&password, NULL); - + [fRPCPassword release]; if (password != NULL) { @@ -1052,9 +1052,9 @@ strncpy(fullPassword, password, passwordLength); fullPassword[passwordLength] = '\0'; SecKeychainItemFreeContent(NULL, (void *)password); - + tr_sessionSetRPCPassword(fHandle, fullPassword); - + fRPCPassword = [[NSString alloc] initWithUTF8String: fullPassword]; [fRPCPasswordField setStringValue: fRPCPassword]; } @@ -1067,7 +1067,7 @@ int port = [sender intValue]; [fDefaults setInteger: port forKey: @"RPCPort"]; tr_sessionSetRPCPort(fHandle, port); - + [self setRPCWebUIDiscovery: nil]; } @@ -1098,13 +1098,13 @@ //don't allow add/remove when currently adding - it leads to weird results if ([fRPCWhitelistTable editedRow] != -1) return; - + if ([[sender cell] tagForSegment: [sender selectedSegment]] == RPC_IP_REMOVE_TAG) { [fRPCWhitelistArray removeObjectsAtIndexes: [fRPCWhitelistTable selectedRowIndexes]]; [fRPCWhitelistTable deselectAll: self]; [fRPCWhitelistTable reloadData]; - + [fDefaults setObject: fRPCWhitelistArray forKey: @"RPCWhitelist"]; [self updateRPCWhitelist]; } @@ -1112,7 +1112,7 @@ { [fRPCWhitelistArray addObject: @""]; [fRPCWhitelistTable reloadData]; - + const int row = [fRPCWhitelistArray count] - 1; [fRPCWhitelistTable selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO]; [fRPCWhitelistTable editColumn: 0 row: row withEvent: nil select: YES]; @@ -1134,7 +1134,7 @@ { NSArray * components = [object componentsSeparatedByString: @"."]; NSMutableArray * newComponents = [NSMutableArray arrayWithCapacity: 4]; - + //create better-formatted ip string BOOL valid = false; if ([components count] == 4) @@ -1157,17 +1157,17 @@ } } } - + NSString * newIP; if (valid) { newIP = [newComponents componentsJoinedByString: @"."]; - + //don't allow the same ip address if ([fRPCWhitelistArray containsObject: newIP] && ![[fRPCWhitelistArray objectAtIndex: row] isEqualToString: newIP]) valid = false; } - + if (valid) { [fRPCWhitelistArray replaceObjectAtIndex: row withObject: newIP]; @@ -1179,10 +1179,10 @@ if ([[fRPCWhitelistArray objectAtIndex: row] isEqualToString: @""]) [fRPCWhitelistArray removeObjectAtIndex: row]; } - + [fRPCWhitelistTable deselectAll: self]; [fRPCWhitelistTable reloadData]; - + [fDefaults setObject: fRPCWhitelistArray forKey: @"RPCWhitelist"]; [self updateRPCWhitelist]; } @@ -1222,203 +1222,203 @@ const tr_encryption_mode encryptionMode = tr_sessionGetEncryption(fHandle); [fDefaults setBool: encryptionMode != TR_CLEAR_PREFERRED forKey: @"EncryptionPrefer"]; [fDefaults setBool: encryptionMode == TR_ENCRYPTION_REQUIRED forKey: @"EncryptionRequire"]; - + //download directory NSString * downloadLocation = [[NSString stringWithUTF8String: tr_sessionGetDownloadDir(fHandle)] stringByStandardizingPath]; [fDefaults setObject: downloadLocation forKey: @"DownloadFolder"]; - + NSString * incompleteLocation = [[NSString stringWithUTF8String: tr_sessionGetIncompleteDir(fHandle)] stringByStandardizingPath]; [fDefaults setObject: incompleteLocation forKey: @"IncompleteDownloadFolder"]; - + const BOOL useIncomplete = tr_sessionIsIncompleteDirEnabled(fHandle); [fDefaults setBool: useIncomplete forKey: @"UseIncompleteDownloadFolder"]; - + const BOOL usePartialFileRanaming = tr_sessionIsIncompleteFileNamingEnabled(fHandle); [fDefaults setBool: usePartialFileRanaming forKey: @"RenamePartialFiles"]; - + //utp const BOOL utp = tr_sessionIsUTPEnabled(fHandle); [fDefaults setBool: utp forKey: @"UTPGlobal"]; - + //peers const uint16_t peersTotal = tr_sessionGetPeerLimit(fHandle); [fDefaults setInteger: peersTotal forKey: @"PeersTotal"]; - + const uint16_t peersTorrent = tr_sessionGetPeerLimitPerTorrent(fHandle); [fDefaults setInteger: peersTorrent forKey: @"PeersTorrent"]; - + //pex const BOOL pex = tr_sessionIsPexEnabled(fHandle); [fDefaults setBool: pex forKey: @"PEXGlobal"]; - + //dht const BOOL dht = tr_sessionIsDHTEnabled(fHandle); [fDefaults setBool: dht forKey: @"DHTGlobal"]; - + //lpd const BOOL lpd = tr_sessionIsLPDEnabled(fHandle); [fDefaults setBool: lpd forKey: @"LocalPeerDiscoveryGlobal"]; - + //auto start const BOOL autoStart = !tr_sessionGetPaused(fHandle); [fDefaults setBool: autoStart forKey: @"AutoStartDownload"]; - + //port const tr_port port = tr_sessionGetPeerPort(fHandle); [fDefaults setInteger: port forKey: @"BindPort"]; - + const BOOL nat = tr_sessionIsPortForwardingEnabled(fHandle); [fDefaults setBool: nat forKey: @"NatTraversal"]; - + fPeerPort = -1; fNatStatus = -1; [self updatePortStatus]; - + const BOOL randomPort = tr_sessionGetPeerPortRandomOnStart(fHandle); [fDefaults setBool: randomPort forKey: @"RandomPort"]; - + //speed limit - down const BOOL downLimitEnabled = tr_sessionIsSpeedLimited(fHandle, TR_DOWN); [fDefaults setBool: downLimitEnabled forKey: @"CheckDownload"]; - + const int downLimit = tr_sessionGetSpeedLimit_KBps(fHandle, TR_DOWN); [fDefaults setInteger: downLimit forKey: @"DownloadLimit"]; - + //speed limit - up const BOOL upLimitEnabled = tr_sessionIsSpeedLimited(fHandle, TR_UP); [fDefaults setBool: upLimitEnabled forKey: @"CheckUpload"]; - + const int upLimit = tr_sessionGetSpeedLimit_KBps(fHandle, TR_UP); [fDefaults setInteger: upLimit forKey: @"UploadLimit"]; - + //alt speed limit enabled const BOOL useAltSpeed = tr_sessionUsesAltSpeed(fHandle); [fDefaults setBool: useAltSpeed forKey: @"SpeedLimit"]; - + //alt speed limit - down const int downLimitAlt = tr_sessionGetAltSpeed_KBps(fHandle, TR_DOWN); [fDefaults setInteger: downLimitAlt forKey: @"SpeedLimitDownloadLimit"]; - + //alt speed limit - up const int upLimitAlt = tr_sessionGetAltSpeed_KBps(fHandle, TR_UP); [fDefaults setInteger: upLimitAlt forKey: @"SpeedLimitUploadLimit"]; - + //alt speed limit schedule const BOOL useAltSpeedSched = tr_sessionUsesAltSpeedTime(fHandle); [fDefaults setBool: useAltSpeedSched forKey: @"SpeedLimitAuto"]; - + NSDate * limitStartDate = [PrefsController timeSumToDate: tr_sessionGetAltSpeedBegin(fHandle)]; [fDefaults setObject: limitStartDate forKey: @"SpeedLimitAutoOnDate"]; - + NSDate * limitEndDate = [PrefsController timeSumToDate: tr_sessionGetAltSpeedEnd(fHandle)]; [fDefaults setObject: limitEndDate forKey: @"SpeedLimitAutoOffDate"]; - + const int limitDay = tr_sessionGetAltSpeedDay(fHandle); [fDefaults setInteger: limitDay forKey: @"SpeedLimitAutoDay"]; - + //blocklist const BOOL blocklist = tr_blocklistIsEnabled(fHandle); [fDefaults setBool: blocklist forKey: @"BlocklistNew"]; - + NSString * blocklistURL = [NSString stringWithUTF8String: tr_blocklistGetURL(fHandle)]; [fDefaults setObject: blocklistURL forKey: @"BlocklistURL"]; - + //seed ratio const BOOL ratioLimited = tr_sessionIsRatioLimited(fHandle); [fDefaults setBool: ratioLimited forKey: @"RatioCheck"]; - + const float ratioLimit = tr_sessionGetRatioLimit(fHandle); [fDefaults setFloat: ratioLimit forKey: @"RatioLimit"]; - + //idle seed limit const BOOL idleLimited = tr_sessionIsIdleLimited(fHandle); [fDefaults setBool: idleLimited forKey: @"IdleLimitCheck"]; - + const NSUInteger idleLimitMin = tr_sessionGetIdleLimit(fHandle); [fDefaults setInteger: idleLimitMin forKey: @"IdleLimitMinutes"]; - + //queue const BOOL downloadQueue = tr_sessionGetQueueEnabled(fHandle, TR_DOWN); [fDefaults setBool: downloadQueue forKey: @"Queue"]; - + const int downloadQueueNum = tr_sessionGetQueueSize(fHandle, TR_DOWN); [fDefaults setInteger: downloadQueueNum forKey: @"QueueDownloadNumber"]; - + const BOOL seedQueue = tr_sessionGetQueueEnabled(fHandle, TR_UP); [fDefaults setBool: seedQueue forKey: @"QueueSeed"]; - + const int seedQueueNum = tr_sessionGetQueueSize(fHandle, TR_UP); [fDefaults setInteger: seedQueueNum forKey: @"QueueSeedNumber"]; - + const BOOL checkStalled = tr_sessionGetQueueStalledEnabled(fHandle); [fDefaults setBool: checkStalled forKey: @"CheckStalled"]; - + const int stalledMinutes = tr_sessionGetQueueStalledMinutes(fHandle); [fDefaults setInteger: stalledMinutes forKey: @"StalledMinutes"]; - + //done script const BOOL doneScriptEnabled = tr_sessionIsTorrentDoneScriptEnabled(fHandle); [fDefaults setBool: doneScriptEnabled forKey: @"DoneScriptEnabled"]; - + NSString * doneScriptPath = [NSString stringWithUTF8String: tr_sessionGetTorrentDoneScript(fHandle)]; [fDefaults setObject: doneScriptPath forKey: @"DoneScriptPath"]; - + //update gui if loaded if (fHasLoaded) { //encryption handled by bindings - + //download directory handled by bindings - + //utp handled by bindings - + [fPeersGlobalField setIntValue: peersTotal]; [fPeersTorrentField setIntValue: peersTorrent]; - + //pex handled by bindings - + //dht handled by bindings - + //lpd handled by bindings - + [fPortField setIntValue: port]; //port forwarding (nat) handled by bindings //random port handled by bindings - + //limit check handled by bindings [fDownloadField setIntValue: downLimit]; - + //limit check handled by bindings [fUploadField setIntValue: upLimit]; - + [fSpeedLimitDownloadField setIntValue: downLimitAlt]; - + [fSpeedLimitUploadField setIntValue: upLimitAlt]; - + //speed limit schedule handled by bindings - + //speed limit schedule times and day handled by bindings - + [fBlocklistURLField setStringValue: blocklistURL]; [self updateBlocklistButton]; [self updateBlocklistFields]; - + //ratio limit enabled handled by bindings [fRatioStopField setFloatValue: ratioLimit]; - + //idle limit enabled handled by bindings [fIdleStopField setIntegerValue: idleLimitMin]; - + //queues enabled handled by bindings [fQueueDownloadField setIntValue: downloadQueueNum]; [fQueueSeedField setIntValue: seedQueueNum]; - + //check stalled handled by bindings [fStalledField setIntValue: stalledMinutes]; } - + [[NSNotificationCenter defaultCenter] postNotificationName: @"SpeedLimitUpdate" object: nil]; - + //reload global settings in inspector [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGlobalOptions" object: nil]; } @@ -1437,7 +1437,7 @@ } else identifier = [[NSUserDefaults standardUserDefaults] stringForKey: @"SelectedPrefView"]; - + NSView * view; if ([identifier isEqualToString: TOOLBAR_TRANSFERS]) view = fTransfersView; @@ -1456,23 +1456,23 @@ identifier = TOOLBAR_GENERAL; //general view is the default selected view = fGeneralView; } - + [[[self window] toolbar] setSelectedItemIdentifier: identifier]; - + NSWindow * window = [self window]; if ([window contentView] == view) return; - + NSRect windowRect = [window frame]; const CGFloat difference = NSHeight([view frame]) - NSHeight([[window contentView] frame]); windowRect.origin.y -= difference; windowRect.size.height += difference; - + [view setHidden: YES]; [window setContentView: view]; [window setFrame: windowRect display: YES animate: YES]; [view setHidden: NO]; - + //set title label if (sender) [window setTitle: [sender label]]; @@ -1495,12 +1495,12 @@ { [fBuiltInGrowlButton setHidden: YES]; [fGrowlAppButton setHidden: NO]; - + #warning remove NO [fGrowlAppButton setEnabled: NO && [GrowlApplicationBridge isGrowlURLSchemeAvailable]]; [fGrowlAppButton setTitle: NSLocalizedString(@"Configure In Growl", "Prefs -> Notifications")]; [fGrowlAppButton sizeToFit]; - + [fGrowlAppButton setTarget: self]; [fGrowlAppButton setAction: @selector(openGrowlApp:)]; } @@ -1508,11 +1508,11 @@ { [fBuiltInGrowlButton setHidden: YES]; [fGrowlAppButton setHidden: NO]; - + [fGrowlAppButton setEnabled: YES]; [fGrowlAppButton setTitle: NSLocalizedString(@"Configure In System Preferences", "Prefs -> Notifications")]; [fGrowlAppButton sizeToFit]; - + [fGrowlAppButton setTarget: self]; [fGrowlAppButton setAction: @selector(openNotificationSystemPrefs:)]; } @@ -1520,7 +1520,7 @@ { [fBuiltInGrowlButton setHidden: NO]; [fGrowlAppButton setHidden: YES]; - + [fBuiltInGrowlButton setState: [fDefaults boolForKey: @"DisplayNotifications"]]; } } @@ -1529,7 +1529,7 @@ { SecKeychainItemRef item = NULL; NSUInteger passwordLength = strlen(password); - + OSStatus result = SecKeychainFindGenericPassword(NULL, strlen(service), service, strlen(username), username, NULL, NULL, &item); if (result == noErr && item) { diff --git a/macosx/ProgressGradients.m b/macosx/ProgressGradients.m index cf73a770b..6851a721f 100644 --- a/macosx/ProgressGradients.m +++ b/macosx/ProgressGradients.m @@ -27,15 +27,15 @@ + (NSGradient *) progressGradientForRed: (CGFloat) redComponent green: (CGFloat) greenComponent blue: (CGFloat) blueComponent { const CGFloat alpha = [[NSUserDefaults standardUserDefaults] boolForKey: @"SmallView"] ? 0.27 : 1.0; - + NSColor * baseColor = [NSColor colorWithCalibratedRed: redComponent green: greenComponent blue: blueComponent alpha: alpha]; - + NSColor * color2 = [NSColor colorWithCalibratedRed: redComponent * 0.95 green: greenComponent * 0.95 blue: blueComponent * 0.95 alpha: alpha]; - + NSColor * color3 = [NSColor colorWithCalibratedRed: redComponent * 0.85 green: greenComponent * 0.85 blue: blueComponent * 0.85 alpha: alpha]; - + return [[[NSGradient alloc] initWithColorsAndLocations: baseColor, 0.0, color2, 0.5, color3, 0.5, baseColor, 1.0, nil] autorelease]; } diff --git a/macosx/QuickLookPlugin/GeneratePreviewForURL.m b/macosx/QuickLookPlugin/GeneratePreviewForURL.m index 3822e3df6..62af2635f 100644 --- a/macosx/QuickLookPlugin/GeneratePreviewForURL.m +++ b/macosx/QuickLookPlugin/GeneratePreviewForURL.m @@ -10,26 +10,26 @@ NSString * generateIconData(NSString * fileExtension, NSUInteger width, NSMutabl { NSString * rawFilename = ![fileExtension isEqualToString: @""] ? fileExtension : @"blank_file_name_transmission"; NSString * iconFileName = [NSString stringWithFormat: @"%ldx%@.tiff", width, rawFilename]; //we need to do this once per file extension, per size - + if (![allImgProps objectForKey: iconFileName]) { NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFileType: fileExtension]; - + const NSRect iconFrame = NSMakeRect(0.0, 0.0, width, width); NSImage * renderedIcon = [[NSImage alloc] initWithSize: iconFrame.size]; [renderedIcon lockFocus]; [icon drawInRect: iconFrame fromRect: NSZeroRect operation: NSCompositeCopy fraction: 1.0]; [renderedIcon unlockFocus]; - + NSData * iconData = [renderedIcon TIFFRepresentation]; [renderedIcon release]; - + NSDictionary * imgProps = @{ (NSString *)kQLPreviewPropertyMIMETypeKey : @"image/png", (NSString *)kQLPreviewPropertyAttachmentDataKey : iconData }; [allImgProps setObject: imgProps forKey: iconFileName]; } - + return [@"cid:" stringByAppendingString: iconFileName]; } @@ -38,10 +38,10 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, // Before proceeding make sure the user didn't cancel the request if (QLPreviewRequestIsCancelled(preview)) return noErr; - + //we need this call to ensure NSApp is initialized (not done automatically for plugins) [NSApplication sharedApplication]; - + //try to parse the torrent file tr_info inf; tr_ctor * ctor = tr_ctorNew(NULL); @@ -50,23 +50,23 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, tr_ctorFree(ctor); if (err) return noErr; - + NSBundle * bundle = [NSBundle bundleWithIdentifier: @"org.m0k.transmission.QuickLookPlugin"]; - + NSURL * styleURL = [bundle URLForResource: @"style" withExtension: @"css"]; NSString * styleContents = [NSString stringWithContentsOfURL: styleURL encoding: NSUTF8StringEncoding error: NULL]; - + NSMutableString * htmlString = [NSMutableString string]; [htmlString appendFormat: @"", styleContents]; - + NSMutableDictionary * allImgProps = [NSMutableDictionary dictionary]; - + NSString * name = [NSString stringWithUTF8String: inf.name]; NSString * fileTypeString = inf.isFolder ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [name pathExtension]; - + const NSUInteger width = 32; [htmlString appendFormat: @"

%@

", generateIconData(fileTypeString, width, allImgProps), width, width, name]; - + NSString * fileSizeString = [NSString stringForFileSize: inf.totalSize]; if (inf.isFolder) { @@ -78,7 +78,7 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, fileSizeString = [NSString stringWithFormat: @"%@, %@", fileCountString, fileSizeString]; } [htmlString appendFormat: @"

%@

", fileSizeString]; - + NSString * dateCreatedString = inf.dateCreated > 0 ? [NSDateFormatter localizedStringFromDate: [NSDate dateWithTimeIntervalSince1970: inf.dateCreated] dateStyle: NSDateFormatterLongStyle timeStyle: NSDateFormatterShortStyle] : nil; NSString * creatorString = inf.creator ? [NSString stringWithUTF8String: inf.creator] : nil; if ([creatorString isEqualToString: @""]) creatorString = nil; @@ -91,88 +91,88 @@ OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, creationString = [NSString stringWithFormat: NSLocalizedStringFromTableInBundle(@"Created with %@", nil, bundle, "quicklook creation info"), creatorString]; if (creationString) [htmlString appendFormat: @"

%@

", creationString]; - + if (inf.comment) { NSString * comment = [NSString stringWithUTF8String: inf.comment]; if (![comment isEqualToString: @""]) [htmlString appendFormat: @"

%@

", comment]; } - + NSMutableArray * lists = [NSMutableArray array]; - + if (inf.webseedCount > 0) { NSMutableString * listSection = [NSMutableString string]; [listSection appendString: @""]; - + NSString * headerTitleString = inf.webseedCount == 1 ? NSLocalizedStringFromTableInBundle(@"1 Web Seed", nil, bundle, "quicklook web seed header") : [NSString stringWithFormat: NSLocalizedStringFromTableInBundle(@"%@ Web Seeds", nil, bundle, "quicklook web seed header"), [NSString formattedUInteger: inf.webseedCount]]; [listSection appendFormat: @"", headerTitleString]; - + for (int i = 0; i < inf.webseedCount; ++i) [listSection appendFormat: @"", inf.webseeds[i]]; - + [listSection appendString:@"
%@
%s
"]; - + [lists addObject: listSection]; } - + if (inf.trackerCount > 0) { NSMutableString * listSection = [NSMutableString string]; [listSection appendString: @""]; - + NSString * headerTitleString = inf.trackerCount == 1 ? NSLocalizedStringFromTableInBundle(@"1 Tracker", nil, bundle, "quicklook tracker header") : [NSString stringWithFormat: NSLocalizedStringFromTableInBundle(@"%@ Trackers", nil, bundle, "quicklook tracker header"), [NSString formattedUInteger: inf.trackerCount]]; [listSection appendFormat: @"", headerTitleString]; - + #warning handle tiers? for (int i = 0; i < inf.trackerCount; ++i) [listSection appendFormat: @"", inf.trackers[i].announce]; - + [listSection appendString:@"
%@
%s
"]; - + [lists addObject: listSection]; } - + if (inf.isFolder) { NSMutableString * listSection = [NSMutableString string]; [listSection appendString: @""]; - + NSString * fileTitleString = inf.fileCount == 1 ? NSLocalizedStringFromTableInBundle(@"1 File", nil, bundle, "quicklook file header") : [NSString stringWithFormat: NSLocalizedStringFromTableInBundle(@"%@ Files", nil, bundle, "quicklook file header"), [NSString formattedUInteger: inf.fileCount]]; [listSection appendFormat: @"", fileTitleString]; - + #warning display size? #warning display folders? for (int i = 0; i < inf.fileCount; ++i) { NSString * fullFilePath = [NSString stringWithUTF8String: inf.files[i].name]; NSCAssert([fullFilePath hasPrefix: [name stringByAppendingString: @"/"]], @"Expected file path %@ to begin with %@/", fullFilePath, name); - + NSString * shortenedFilePath = [fullFilePath substringFromIndex: [name length]+1]; - + const NSUInteger width = 16; [listSection appendFormat: @"", generateIconData([shortenedFilePath pathExtension], width, allImgProps), width, width, shortenedFilePath]; } - + [listSection appendString:@"
%@
%@
"]; - + [lists addObject: listSection]; } - + if ([lists count] > 0) [htmlString appendFormat: @"

%@", [lists componentsJoinedByString: @"
"]]; - + [htmlString appendString: @""]; - + tr_metainfoFree(&inf); - + NSDictionary * props = @{ (NSString *)kQLPreviewPropertyTextEncodingNameKey : @"UTF-8", (NSString *)kQLPreviewPropertyMIMETypeKey : @"text/html", (NSString *)kQLPreviewPropertyAttachmentsKey : allImgProps }; - + QLPreviewRequestSetDataRepresentation(preview, (CFDataRef)[htmlString dataUsingEncoding: NSUTF8StringEncoding], kUTTypeHTML, (CFDictionaryRef)props); - + return noErr; } diff --git a/macosx/ShareToolbarItem.m b/macosx/ShareToolbarItem.m index f98c7c91c..5a0a541c5 100644 --- a/macosx/ShareToolbarItem.m +++ b/macosx/ShareToolbarItem.m @@ -16,18 +16,18 @@ { NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle: [self label] action: nil keyEquivalent: @""]; [menuItem setEnabled: [[self target] validateToolbarItem: self]]; - + if ([menuItem isEnabled]) { NSMenu *servicesMenu = [[NSMenu alloc] initWithTitle: @""]; for (NSMenuItem * item in [[ShareTorrentFileHelper sharedHelper] menuItems]) { [servicesMenu addItem:item]; } - + [menuItem setSubmenu:servicesMenu]; [servicesMenu release]; // can't believe we're not using ARC yet! } - + return menuItem; } diff --git a/macosx/ShareTorrentFileHelper.m b/macosx/ShareTorrentFileHelper.m index 76fa8e137..9f28f3d19 100644 --- a/macosx/ShareTorrentFileHelper.m +++ b/macosx/ShareTorrentFileHelper.m @@ -52,7 +52,7 @@ [items addObject: item]; [item release]; } - + return items; } diff --git a/macosx/StatsWindowController.m b/macosx/StatsWindowController.m index a62927c0f..8e36ee364 100644 --- a/macosx/StatsWindowController.m +++ b/macosx/StatsWindowController.m @@ -60,54 +60,54 @@ tr_session * fLib = NULL; - (void) awakeFromNib { [self updateStats]; - + fTimer = [[NSTimer scheduledTimerWithTimeInterval: UPDATE_SECONDS target: self selector: @selector(updateStats) userInfo: nil repeats: YES] retain]; [[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSModalPanelRunLoopMode]; [[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSEventTrackingRunLoopMode]; [[self window] setRestorationClass: [self class]]; - + [[self window] setTitle: NSLocalizedString(@"Statistics", "Stats window -> title")]; - + //set label text [fUploadedLabelField setStringValue: [NSLocalizedString(@"Uploaded", "Stats window -> label") stringByAppendingString: @":"]]; [fDownloadedLabelField setStringValue: [NSLocalizedString(@"Downloaded", "Stats window -> label") stringByAppendingString: @":"]]; [fRatioLabelField setStringValue: [NSLocalizedString(@"Ratio", "Stats window -> label") stringByAppendingString: @":"]]; [fTimeLabelField setStringValue: [NSLocalizedString(@"Running Time", "Stats window -> label") stringByAppendingString: @":"]]; [fNumOpenedLabelField setStringValue: [NSLocalizedString(@"Program Started", "Stats window -> label") stringByAppendingString: @":"]]; - + //size of all labels const CGFloat oldWidth = [fUploadedLabelField frame].size.width; - + NSArray * labels = @[fUploadedLabelField, fDownloadedLabelField, fRatioLabelField, fTimeLabelField, fNumOpenedLabelField]; - + CGFloat maxWidth = CGFLOAT_MIN; for (NSTextField * label in labels) { [label sizeToFit]; - + const CGFloat width = [label frame].size.width; maxWidth = MAX(maxWidth, width); } - + for (NSTextField * label in labels) { NSRect frame = [label frame]; frame.size.width = maxWidth; [label setFrame: frame]; } - + //resize window for new label width - fields are set in nib to adjust correctly NSRect windowRect = [[self window] frame]; windowRect.size.width += maxWidth - oldWidth; [[self window] setFrame: windowRect display: YES]; - + //resize reset button const CGFloat oldButtonWidth = [fResetButton frame].size.width; - + [fResetButton setTitle: NSLocalizedString(@"Reset", "Stats window -> reset button")]; [fResetButton sizeToFit]; - + NSRect buttonFrame = [fResetButton frame]; buttonFrame.size.width += 10.0; buttonFrame.origin.x -= buttonFrame.size.width - oldButtonWidth; @@ -119,7 +119,7 @@ tr_session * fLib = NULL; [fTimer invalidate]; [fTimer release]; fTimer = nil; - + [fStatsWindowInstance autorelease]; fStatsWindowInstance = nil; } @@ -127,7 +127,7 @@ tr_session * fLib = NULL; + (void) restoreWindowWithIdentifier: (NSString *) identifier state: (NSCoder *) state completionHandler: (void (^)(NSWindow *, NSError *)) completionHandler { NSAssert1([identifier isEqualToString: @"StatsWindow"], @"Trying to restore unexpected identifier %@", identifier); - + completionHandler([[StatsWindowController statsWindow] window], nil); } @@ -138,7 +138,7 @@ tr_session * fLib = NULL; [self performResetStats]; return; } - + NSAlert * alert = [[NSAlert alloc] init]; [alert setMessageText: NSLocalizedString(@"Are you sure you want to reset usage statistics?", "Stats reset -> title")]; [alert setInformativeText: NSLocalizedString(@"This will clear the global statistics displayed by Transmission." @@ -147,7 +147,7 @@ tr_session * fLib = NULL; [alert addButtonWithTitle: NSLocalizedString(@"Reset", "Stats reset -> button")]; [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Stats reset -> button")]; [alert setShowsSuppressionButton: YES]; - + [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: @selector(resetSheetClosed:returnCode:contextInfo:) contextInfo: nil]; } @@ -166,33 +166,33 @@ tr_session * fLib = NULL; tr_session_stats statsAll, statsSession; tr_sessionGetCumulativeStats(fLib, &statsAll); tr_sessionGetStats(fLib, &statsSession); - + NSByteCountFormatter * byteFormatter = nil; if ([NSApp isOnMountainLionOrBetter]) { byteFormatter = [[NSByteCountFormatterMtLion alloc] init]; [byteFormatter setAllowedUnits: NSByteCountFormatterUseBytes]; } - + [fUploadedField setStringValue: [NSString stringForFileSize: statsSession.uploadedBytes]]; [fUploadedField setToolTip: [NSApp isOnMountainLionOrBetter] ? [byteFormatter stringFromByteCount: statsSession.uploadedBytes] : [NSString stringWithFormat: NSLocalizedString(@"%@ bytes", "stats -> bytes"), [NSString formattedUInteger: statsSession.uploadedBytes]]]; [fUploadedAllField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [NSString stringForFileSize: statsAll.uploadedBytes]]]; [fUploadedAllField setToolTip: [NSApp isOnMountainLionOrBetter] ? [byteFormatter stringFromByteCount: statsAll.uploadedBytes] : [NSString stringWithFormat: NSLocalizedString(@"%@ bytes", "stats -> bytes"), [NSString formattedUInteger: statsAll.uploadedBytes]]]; - + [fDownloadedField setStringValue: [NSString stringForFileSize: statsSession.downloadedBytes]]; [fDownloadedField setToolTip: [NSApp isOnMountainLionOrBetter] ? [byteFormatter stringFromByteCount: statsSession.downloadedBytes] : [NSString stringWithFormat: NSLocalizedString(@"%@ bytes", "stats -> bytes"), [NSString formattedUInteger: statsSession.downloadedBytes]]]; [fDownloadedAllField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [NSString stringForFileSize: statsAll.downloadedBytes]]]; [fDownloadedAllField setToolTip: [NSApp isOnMountainLionOrBetter] ? [byteFormatter stringFromByteCount: statsAll.downloadedBytes] : [NSString stringWithFormat: NSLocalizedString(@"%@ bytes", "stats -> bytes"), [NSString formattedUInteger: statsAll.downloadedBytes]]]; - + [byteFormatter release]; - + [fRatioField setStringValue: [NSString stringForRatio: statsSession.ratio]]; - + NSString * totalRatioString = statsAll.ratio != TR_RATIO_NA ? [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [NSString stringForRatio: statsAll.ratio]] : NSLocalizedString(@"Total N/A", "stats total"); [fRatioAllField setStringValue: totalRatioString]; - + if ([NSApp isOnYosemiteOrBetter]) { static NSDateComponentsFormatter *timeFormatter; static dispatch_once_t onceToken; @@ -202,7 +202,7 @@ tr_session * fLib = NULL; timeFormatter.maximumUnitCount = 3; timeFormatter.allowedUnits = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitWeekOfMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute; }); - + [fTimeField setStringValue: [timeFormatter stringFromTimeInterval:statsSession.secondsActive]]; [fTimeAllField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [timeFormatter stringFromTimeInterval:statsAll.secondsActive]]]; } @@ -210,7 +210,7 @@ tr_session * fLib = NULL; [fTimeField setStringValue: [NSString timeString: statsSession.secondsActive includesTimeRemainingPhrase:NO showSeconds: NO]]; [fTimeAllField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [NSString timeString: statsAll.secondsActive includesTimeRemainingPhrase:NO showSeconds: NO]]]; } - + if (statsAll.sessionCount == 1) [fNumOpenedField setStringValue: NSLocalizedString(@"1 time", "stats window -> times opened")]; else @@ -226,10 +226,10 @@ tr_session * fLib = NULL; - (void) resetSheetClosed: (NSAlert *) alert returnCode: (NSInteger) code contextInfo: (void *) info { [[alert window] orderOut: nil]; - + if ([[alert suppressionButton] state] == NSOnState) [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningResetStats"]; - + if (code == NSAlertFirstButtonReturn) [self performResetStats]; } diff --git a/macosx/StatusBarController.h b/macosx/StatusBarController.h index 9809feec9..54c86ca69 100644 --- a/macosx/StatusBarController.h +++ b/macosx/StatusBarController.h @@ -29,9 +29,9 @@ IBOutlet NSButton * fStatusButton; IBOutlet NSTextField * fTotalDLField, * fTotalULField; IBOutlet NSImageView * fTotalDLImageView, * fTotalULImageView; - + tr_session * fLib; - + CGFloat fPreviousDownloadRate, fPreviousUploadRate; } diff --git a/macosx/StatusBarController.m b/macosx/StatusBarController.m index 75b67c8d7..8801b9b35 100644 --- a/macosx/StatusBarController.m +++ b/macosx/StatusBarController.m @@ -51,11 +51,11 @@ typedef enum if ((self = [super initWithNibName: @"StatusBar" bundle: nil])) { fLib = lib; - + fPreviousDownloadRate = -1.0; fPreviousUploadRate = -1.0; } - + return self; } @@ -70,15 +70,15 @@ typedef enum "Status Bar -> status menu")]; [[[fStatusButton menu] itemWithTag: STATUS_TRANSFER_SESSION_TAG] setTitle: NSLocalizedString(@"Session Transfer", "Status Bar -> status menu")]; - + [[fStatusButton cell] setBackgroundStyle: NSBackgroundStyleRaised]; [[fTotalDLField cell] setBackgroundStyle: NSBackgroundStyleRaised]; [[fTotalULField cell] setBackgroundStyle: NSBackgroundStyleRaised]; [[fTotalDLImageView cell] setBackgroundStyle: NSBackgroundStyleRaised]; [[fTotalULImageView cell] setBackgroundStyle: NSBackgroundStyleRaised]; - + [self updateSpeedFieldsToolTips]; - + //update when speed limits are changed [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateSpeedFieldsToolTips) name: @"SpeedLimitUpdate" object: nil]; @@ -89,7 +89,7 @@ typedef enum - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [super dealloc]; } @@ -101,13 +101,13 @@ typedef enum [fTotalDLField setStringValue: [NSString stringForSpeed: dlRate]]; fPreviousDownloadRate = dlRate; } - + if (ulRate != fPreviousUploadRate) { [fTotalULField setStringValue: [NSString stringForSpeed: ulRate]]; fPreviousUploadRate = ulRate; } - + //set status button text NSString * statusLabel = [[NSUserDefaults standardUserDefaults] stringForKey: @"StatusLabel"], * statusString; BOOL total; @@ -118,26 +118,26 @@ typedef enum tr_sessionGetCumulativeStats(fLib, &stats); else tr_sessionGetStats(fLib, &stats); - + statusString = [NSLocalizedString(@"Ratio", "status bar -> status label") stringByAppendingFormat: @": %@", [NSString stringForRatio: stats.ratio]]; } else //STATUS_TRANSFER_TOTAL or STATUS_TRANSFER_SESSION { total = [statusLabel isEqualToString: STATUS_TRANSFER_TOTAL]; - + tr_session_stats stats; if (total) tr_sessionGetCumulativeStats(fLib, &stats); else tr_sessionGetStats(fLib, &stats); - + statusString = [NSString stringWithFormat: @"%@: %@ %@: %@", NSLocalizedString(@"DL", "status bar -> status label"), [NSString stringForFileSize: stats.downloadedBytes], NSLocalizedString(@"UL", "status bar -> status label"), [NSString stringForFileSize: stats.uploadedBytes]]; } - - + + if (![[fStatusButton title] isEqualToString: statusString]) { [fStatusButton setTitle: statusString]; @@ -166,21 +166,21 @@ typedef enum NSAssert1(NO, @"Unknown status label tag received: %ld", [sender tag]); return; } - + [[NSUserDefaults standardUserDefaults] setObject: statusLabel forKey: @"StatusLabel"]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; } - (void) updateSpeedFieldsToolTips { NSString * uploadText, * downloadText; - + if ([[NSUserDefaults standardUserDefaults] boolForKey: @"SpeedLimit"]) { NSString * speedString = [NSString stringWithFormat: @"%@ (%@)", NSLocalizedString(@"%d KB/s", "Status Bar -> speed tooltip"), NSLocalizedString(@"Speed Limit", "Status Bar -> speed tooltip")]; - + uploadText = [NSString stringWithFormat: speedString, [[NSUserDefaults standardUserDefaults] integerForKey: @"SpeedLimitUploadLimit"]]; downloadText = [NSString stringWithFormat: speedString, @@ -193,19 +193,19 @@ typedef enum [[NSUserDefaults standardUserDefaults] integerForKey: @"UploadLimit"]]; else uploadText = NSLocalizedString(@"unlimited", "Status Bar -> speed tooltip"); - + if ([[NSUserDefaults standardUserDefaults] boolForKey: @"CheckDownload"]) downloadText = [NSString stringWithFormat: NSLocalizedString(@"%d KB/s", "Status Bar -> speed tooltip"), [[NSUserDefaults standardUserDefaults] integerForKey: @"DownloadLimit"]]; else downloadText = NSLocalizedString(@"unlimited", "Status Bar -> speed tooltip"); } - + uploadText = [NSLocalizedString(@"Global upload limit", "Status Bar -> speed tooltip") stringByAppendingFormat: @": %@", uploadText]; downloadText = [NSLocalizedString(@"Global download limit", "Status Bar -> speed tooltip") stringByAppendingFormat: @": %@", downloadText]; - + [fTotalULField setToolTip: uploadText]; [fTotalDLField setToolTip: downloadText]; } @@ -213,7 +213,7 @@ typedef enum - (BOOL) validateMenuItem: (NSMenuItem *) menuItem { const SEL action = [menuItem action]; - + //enable sort options if (action == @selector(setStatusLabel:)) { @@ -236,12 +236,12 @@ typedef enum NSAssert1(NO, @"Unknown status label tag received: %ld", [menuItem tag]); statusLabel = STATUS_RATIO_TOTAL; } - + [menuItem setState: [statusLabel isEqualToString: [[NSUserDefaults standardUserDefaults] stringForKey: @"StatusLabel"]] ? NSOnState : NSOffState]; return YES; } - + return YES; } @@ -252,15 +252,15 @@ typedef enum - (void) resizeStatusButton { [fStatusButton sizeToFit]; - + //width ends up being too long NSRect statusFrame = [fStatusButton frame]; statusFrame.size.width -= 25.0; - + const CGFloat difference = NSMaxX(statusFrame) + 5.0 - NSMinX([fTotalDLImageView frame]); if (difference > 0.0) statusFrame.size.width -= difference; - + [fStatusButton setFrame: statusFrame]; } diff --git a/macosx/StatusBarView.m b/macosx/StatusBarView.m index 59219ba14..1891cd3cb 100644 --- a/macosx/StatusBarView.m +++ b/macosx/StatusBarView.m @@ -39,14 +39,14 @@ NSColor * lightColor = [NSColor colorWithCalibratedRed: 160.0/255.0 green: 160.0/255.0 blue: 160.0/255.0 alpha: 1.0]; NSColor * darkColor = [NSColor colorWithCalibratedRed: 155.0/255.0 green: 155.0/255.0 blue: 155.0/255.0 alpha: 1.0]; fGradient = [[NSGradient alloc] initWithStartingColor: lightColor endingColor: darkColor]; - + if (![NSApp isOnYosemiteOrBetter]) { CIFilter * randomFilter = [CIFilter filterWithName: @"CIRandomGenerator"]; [randomFilter setDefaults]; - + fNoiseImage = [randomFilter valueForKey: @"outputImage"]; - + CIFilter * monochromeFilter = [CIFilter filterWithName: @"CIColorMonochrome"]; [monochromeFilter setDefaults]; [monochromeFilter setValue: fNoiseImage forKey: @"inputImage"]; @@ -56,7 +56,7 @@ } else fNoiseImage = nil; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reload) name: NSWindowDidBecomeMainNotification object: [self window]]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reload) name: NSWindowDidResignMainNotification object: [self window]]; } @@ -86,7 +86,7 @@ if ([NSApp isOnYosemiteOrBetter]) { [[NSColor windowBackgroundColor] setFill]; NSRectFill(rect); - + const NSRect lineBorderRect = NSMakeRect(NSMinX(rect), 0.0, NSWidth(rect), 1.0); if (NSIntersectsRect(lineBorderRect, rect)) { @@ -96,11 +96,11 @@ } else { const BOOL active = [[self window] isMainWindow]; - + NSInteger count = 0; NSRect gridRects[active ? 2 : 3]; NSColor * colorRects[active ? 2 : 3]; - + //bottom line NSRect lineBorderRect = NSMakeRect(NSMinX(rect), 0.0, NSWidth(rect), 1.0); NSRect intersectLineBorderRect = NSIntersectionRect(lineBorderRect, rect); @@ -110,12 +110,12 @@ colorRects[count] = active ? [NSColor colorWithCalibratedWhite: 0.25 alpha: 1.0] : [NSColor colorWithCalibratedWhite: 0.5 alpha: 1.0]; ++count; - + rect.origin.y += intersectLineBorderRect.size.height; rect.size.height -= intersectLineBorderRect.size.height; } - - + + //top line if (active) { @@ -126,11 +126,11 @@ gridRects[count] = intersectLineBorderRect; colorRects[count] = [NSColor colorWithCalibratedWhite: 0.75 alpha: 1.0]; ++count; - + rect.size.height -= intersectLineBorderRect.size.height; } } - + if (!NSIsEmptyRect(rect)) { if (active) @@ -145,9 +145,9 @@ ++count; } } - + NSRectFillListWithColors(gridRects, colorRects, count); - + if (fNoiseImage) { [fNoiseImage drawInRect: rect fromRect: [self convertRectToBacking: rect] diff --git a/macosx/Torrent.h b/macosx/Torrent.h index cf29687dc..87b847955 100644 --- a/macosx/Torrent.h +++ b/macosx/Torrent.h @@ -27,8 +27,8 @@ @class FileListNode; typedef enum { - TorrentDeterminationAutomatic = 0, - TorrentDeterminationUserSpecified + TorrentDeterminationAutomatic = 0, + TorrentDeterminationUserSpecified } TorrentDeterminationType; #define kTorrentDidChangeGroupNotification @"TorrentDidChangeGroup" @@ -38,28 +38,28 @@ typedef enum { tr_torrent * fHandle; const tr_info * fInfo; const tr_stat * fStat; - + NSUserDefaults * fDefaults; NSImage * fIcon; - + NSString * fHashString; - + tr_file_stat * fFileStat; NSArray * fFileList, * fFlatFileList; - + NSIndexSet * fPreviousFinishedIndexes; NSDate * fPreviousFinishedIndexesDate; - + BOOL fRemoveWhenFinishSeeding; - + NSInteger fGroupValue; - TorrentDeterminationType fGroupValueDetermination; - - TorrentDeterminationType fDownloadFolderDetermination; - + TorrentDeterminationType fGroupValueDetermination; + + TorrentDeterminationType fDownloadFolderDetermination; + BOOL fResumeOnWake; - + BOOL fTimeMachineExcludeInitialized; } diff --git a/macosx/Torrent.m b/macosx/Torrent.m index fca916ff3..48fad5839 100644 --- a/macosx/Torrent.m +++ b/macosx/Torrent.m @@ -102,7 +102,7 @@ void renameCallback(tr_torrent * torrent, const char * oldPathCharString, const @autoreleasepool { NSString * oldPath = [NSString stringWithUTF8String: oldPathCharString]; NSString * newName = [NSString stringWithUTF8String: newNameCharString]; - + dispatch_async(dispatch_get_main_queue(), ^{ NSDictionary * contextDict = [(NSDictionary *)contextInfo autorelease]; Torrent * torrentObject = [contextDict objectForKey: @"Torrent"]; @@ -142,7 +142,7 @@ bool trashDataFile(const char * filename, tr_error ** error) removeWhenFinishSeeding: nil downloadFolder: location legacyIncompleteFolder: nil]; - + if (self) { if (torrentDelete && ![[self torrentLocation] isEqualToString: path]) @@ -158,7 +158,7 @@ bool trashDataFile(const char * filename, tr_error ** error) removeWhenFinishSeeding: nil downloadFolder: location legacyIncompleteFolder: nil]; - + return self; } @@ -168,7 +168,7 @@ bool trashDataFile(const char * filename, tr_error ** error) lib: lib groupValue: nil removeWhenFinishSeeding: nil downloadFolder: location legacyIncompleteFolder: nil]; - + return self; } @@ -184,7 +184,7 @@ bool trashDataFile(const char * filename, tr_error ** error) downloadFolder: [history objectForKey: @"DownloadFolder"] //upgrading from versions < 1.80 legacyIncompleteFolder: [[history objectForKey: @"UseIncompleteFolder"] boolValue] //upgrading from versions < 1.80 ? [history objectForKey: @"IncompleteFolder"] : nil]; - + if (self) { //start transfer @@ -194,7 +194,7 @@ bool trashDataFile(const char * filename, tr_error ** error) fStat = tr_torrentStat(fHandle); [self startTransferNoQueue]; } - + //upgrading from versions < 1.30: get old added, activity, and done dates NSDate * date; if ((date = [history objectForKey: @"Date"])) @@ -203,7 +203,7 @@ bool trashDataFile(const char * filename, tr_error ** error) tr_torrentSetActivityDate(fHandle, [date timeIntervalSince1970]); if ((date = [history objectForKey: @"DateCompleted"])) tr_torrentSetDoneDate(fHandle, [date timeIntervalSince1970]); - + //upgrading from versions < 1.60: get old stop ratio settings NSNumber * ratioSetting; if ((ratioSetting = [history objectForKey: @"RatioSetting"])) @@ -236,20 +236,20 @@ bool trashDataFile(const char * filename, tr_error ** error) - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + if (fFileStat) tr_torrentFilesFree(fFileStat, [self fileCount]); - + [fPreviousFinishedIndexes release]; [fPreviousFinishedIndexesDate release]; - + [fHashString release]; - + [fIcon release]; - + [fFileList release]; [fFlatFileList release]; - + [super dealloc]; } @@ -267,7 +267,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { //allow the file to be indexed by Time Machine [self setTimeMachineExclude: NO]; - + tr_torrentRemove(fHandle, trashFiles, trashDataFile); } @@ -275,9 +275,9 @@ bool trashDataFile(const char * filename, tr_error ** error) { //if data existed in original download location, unexclude it before changing the location [self setTimeMachineExclude: NO]; - + tr_torrentSetDownloadDir(fHandle, [folder UTF8String]); - + fDownloadFolderDetermination = determinationType; } @@ -309,7 +309,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { [fPreviousFinishedIndexes release]; fPreviousFinishedIndexes = [indexes retain]; - + [fPreviousFinishedIndexesDate release]; fPreviousFinishedIndexesDate = indexes != nil ? [[NSDate alloc] init] : nil; } @@ -318,9 +318,9 @@ bool trashDataFile(const char * filename, tr_error ** error) { //get previous stalled value before update const BOOL wasStalled = fStat != NULL && [self isStalled]; - + fStat = tr_torrentStat(fHandle); - + //make sure the "active" filter is updated when stalled-ness changes if (wasStalled != [self isStalled]) //posting asynchronously with coalescing to prevent stack overflow on lots of torrents changing state at the same time @@ -340,7 +340,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { ignoreQueue ? tr_torrentStartNow(fHandle) : tr_torrentStart(fHandle); [self update]; - + //capture, specifically, stop-seeding settings changing to unlimited [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptions" object: nil]; } @@ -436,7 +436,7 @@ bool trashDataFile(const char * filename, tr_error ** error) - (void) setRatioLimit: (CGFloat) limit { NSParameterAssert(limit >= 0); - + tr_torrentSetRatioLimit(fHandle, limit); } @@ -463,7 +463,7 @@ bool trashDataFile(const char * filename, tr_error ** error) - (void) setIdleLimitMinutes: (NSUInteger) limit { NSParameterAssert(limit > 0); - + tr_torrentSetIdleLimit(fHandle, limit); } @@ -500,7 +500,7 @@ bool trashDataFile(const char * filename, tr_error ** error) - (void) setMaxPeerConnect: (uint16_t) count { NSParameterAssert(count > 0); - + tr_torrentSetPeerLimit(fHandle, count); } @@ -553,12 +553,12 @@ bool trashDataFile(const char * filename, tr_error ** error) NSString * oldFolder = [self currentDirectory]; if ([oldFolder isEqualToString: folder]) return; - + //check if moving inside itself NSArray * oldComponents = [oldFolder pathComponents], * newComponents = [folder pathComponents]; const NSUInteger oldCount = [oldComponents count]; - + if (oldCount < [newComponents count] && [[newComponents objectAtIndex: oldCount] isEqualToString: [self name]] && [folder hasPrefix: oldFolder]) { @@ -569,19 +569,19 @@ bool trashDataFile(const char * filename, tr_error ** error) NSLocalizedString(@"The move operation of \"%@\" cannot be done.", "Move inside itself alert -> message"), [self name]]]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Move inside itself alert -> button")]; - + [alert runModal]; [alert release]; - + return; } - + volatile int status; tr_torrentSetLocation(fHandle, [folder UTF8String], YES, NULL, &status); - + while (status == TR_LOC_MOVING) //block while moving (for now) [NSThread sleepForTimeInterval: 0.05]; - + if (status == TR_LOC_DONE) [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil]; else @@ -591,11 +591,11 @@ bool trashDataFile(const char * filename, tr_error ** error) [alert setInformativeText: [NSString stringWithFormat: NSLocalizedString(@"The move operation of \"%@\" cannot be done.", "Move error alert -> message"), [self name]]]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Move error alert -> button")]; - + [alert runModal]; [alert release]; } - + [self updateTimeMachineExclude]; } @@ -608,18 +608,18 @@ bool trashDataFile(const char * filename, tr_error ** error) { if ([self allDownloaded] || ![fDefaults boolForKey: @"WarningRemainingSpace"]) return YES; - + NSString * downloadFolder = [self currentDirectory]; NSDictionary * systemAttributes; if ((systemAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath: downloadFolder error: NULL])) { const uint64_t remainingSpace = [[systemAttributes objectForKey: NSFileSystemFreeSize] unsignedLongLongValue]; - + //if the remaining space is greater than the size left, then there is enough space regardless of preallocation if (remainingSpace < [self sizeLeft] && remainingSpace < tr_torrentGetBytesLeftToAllocate(fHandle)) { NSString * volumeName = [[[NSFileManager defaultManager] componentsToDisplayForPath: downloadFolder] objectAtIndex: 0]; - + NSAlert * alert = [[NSAlert alloc] init]; [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"Not enough remaining disk space to download \"%@\" completely.", @@ -629,7 +629,7 @@ bool trashDataFile(const char * filename, tr_error ** error) "Torrent disk space alert -> message"), volumeName]]; [alert addButtonWithTitle: NSLocalizedString(@"OK", "Torrent disk space alert -> button")]; [alert addButtonWithTitle: NSLocalizedString(@"Download Anyway", "Torrent disk space alert -> button")]; - + [alert setShowsSuppressionButton: YES]; [[alert suppressionButton] setTitle: NSLocalizedString(@"Do not check disk space again", "Torrent disk space alert -> button")]; @@ -638,7 +638,7 @@ bool trashDataFile(const char * filename, tr_error ** error) if ([[alert suppressionButton] state] == NSOnState) [fDefaults setBool: NO forKey: @"WarningRemainingSpace"]; [alert release]; - + return result != NSAlertFirstButtonReturn; } } @@ -649,7 +649,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { if ([self isMagnet]) return [NSImage imageNamed: @"Magnet"]; - + if (!fIcon) fIcon = [self isFolder] ? [[NSImage imageNamed: NSImageNameFolder] retain] : [[[NSWorkspace sharedWorkspace] iconForFileType: [[self name] pathExtension]] retain]; @@ -680,9 +680,9 @@ bool trashDataFile(const char * filename, tr_error ** error) { int count; tr_tracker_stat * stats = tr_torrentTrackers(fHandle, &count); - + NSMutableArray * trackers = [NSMutableArray arrayWithCapacity: (count > 0 ? count + (stats[count-1].tier + 1) : 0)]; - + int prevTier = -1; for (int i=0; i < count; ++i) { @@ -691,12 +691,12 @@ bool trashDataFile(const char * filename, tr_error ** error) [trackers addObject: @{ @"Tier" : @(stats[i].tier + 1), @"Name" : [self name] }]; prevTier = stats[i].tier; } - + TrackerNode * tracker = [[TrackerNode alloc] initWithTrackerStat: &stats[i] torrent: self]; [trackers addObject: tracker]; [tracker release]; } - + tr_torrentTrackersFree(stats, count); return trackers; } @@ -704,33 +704,33 @@ bool trashDataFile(const char * filename, tr_error ** error) - (NSArray *) allTrackersFlat { NSMutableArray * allTrackers = [NSMutableArray arrayWithCapacity: fInfo->trackerCount]; - + for (NSInteger i=0; i < fInfo->trackerCount; i++) [allTrackers addObject: [NSString stringWithUTF8String: fInfo->trackers[i].announce]]; - + return allTrackers; } - (BOOL) addTrackerToNewTier: (NSString *) tracker { tracker = [tracker stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; - + if ([tracker rangeOfString: @"://"].location == NSNotFound) tracker = [@"http://" stringByAppendingString: tracker]; - + //recreate the tracker structure const int oldTrackerCount = fInfo->trackerCount; tr_tracker_info * trackerStructs = tr_new(tr_tracker_info, oldTrackerCount+1); for (int i = 0; i < oldTrackerCount; ++i) trackerStructs[i] = fInfo->trackers[i]; - + trackerStructs[oldTrackerCount].announce = (char *)[tracker UTF8String]; trackerStructs[oldTrackerCount].tier = trackerStructs[oldTrackerCount-1].tier + 1; trackerStructs[oldTrackerCount].id = oldTrackerCount; - + const BOOL success = tr_torrentSetAnnounceList(fHandle, trackerStructs, oldTrackerCount+1); tr_free(trackerStructs); - + return success; } @@ -738,17 +738,17 @@ bool trashDataFile(const char * filename, tr_error ** error) { //recreate the tracker structure tr_tracker_info * trackerStructs = tr_new(tr_tracker_info, fInfo->trackerCount); - + NSUInteger newCount = 0; for (NSUInteger i = 0; i < fInfo->trackerCount; i++) { if (![trackers containsObject: [NSString stringWithUTF8String: fInfo->trackers[i].announce]]) trackerStructs[newCount++] = fInfo->trackers[i]; } - + const BOOL success = tr_torrentSetAnnounceList(fHandle, trackerStructs, newCount); NSAssert(success, @"Removing tracker addresses failed"); - + tr_free(trackerStructs); } @@ -797,14 +797,14 @@ bool trashDataFile(const char * filename, tr_error ** error) { if ([self isMagnet]) return nil; - + if ([self isFolder]) { NSString * dataLocation = [[self currentDirectory] stringByAppendingPathComponent: [self name]]; - + if (![[NSFileManager defaultManager] fileExistsAtPath: dataLocation]) return nil; - + return dataLocation; } else @@ -812,10 +812,10 @@ bool trashDataFile(const char * filename, tr_error ** error) char * location = tr_torrentFindFile(fHandle, 0); if (location == NULL) return nil; - + NSString * dataLocation = [NSString stringWithUTF8String: location]; free(location); - + return dataLocation; } } @@ -826,10 +826,10 @@ bool trashDataFile(const char * filename, tr_error ** error) { NSString * basePath = [[node path] stringByAppendingPathComponent: [node name]]; NSString * dataLocation = [[self currentDirectory] stringByAppendingPathComponent: basePath]; - + if (![[NSFileManager defaultManager] fileExistsAtPath: dataLocation]) return nil; - + return dataLocation; } else @@ -837,10 +837,10 @@ bool trashDataFile(const char * filename, tr_error ** error) char * location = tr_torrentFindFile(fHandle, [[node indexes] firstIndex]); if (location == NULL) return nil; - + NSString * dataLocation = [NSString stringWithUTF8String: location]; free(location); - + return dataLocation; } } @@ -849,9 +849,9 @@ bool trashDataFile(const char * filename, tr_error ** error) { NSParameterAssert(newName != nil); NSParameterAssert(![newName isEqualToString: @""]); - + NSDictionary * contextInfo = [@{ @"Torrent" : self, @"CompletionHandler" : [[completionHandler copy] autorelease] } retain]; - + tr_torrentRenamePath(fHandle, fInfo->name, [newName UTF8String], renameCallback, contextInfo); } @@ -860,9 +860,9 @@ bool trashDataFile(const char * filename, tr_error ** error) NSParameterAssert([node torrent] == self); NSParameterAssert(newName != nil); NSParameterAssert(![newName isEqualToString: @""]); - + NSDictionary * contextInfo = [@{ @"Torrent" : self, @"Nodes" : @[ node ], @"CompletionHandler" : [[completionHandler copy] autorelease] } retain]; - + NSString * oldPath = [[node path] stringByAppendingPathComponent: [node name]]; tr_torrentRenamePath(fHandle, [oldPath UTF8String], [newName UTF8String], renameCallback, contextInfo); } @@ -881,7 +881,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { if ([self size] == 0) //magnet links return 0.0; - + return (CGFloat)[self sizeLeft] / [self size]; } @@ -944,15 +944,15 @@ bool trashDataFile(const char * filename, tr_error ** error) { if (![self isAnyErrorOrWarning]) return @""; - + NSString * error; if (!(error = [NSString stringWithUTF8String: fStat->errorString]) && !(error = [NSString stringWithCString: fStat->errorString encoding: NSISOLatin1StringEncoding])) error = [NSString stringWithFormat: @"(%@)", NSLocalizedString(@"unreadable error", "Torrent -> error string unreadable")]; - + //libtransmission uses "Set Location", Mac client uses "Move data file to..." - very hacky! error = [error stringByReplacingOccurrencesOfString: @"Set Location" withString: [@"Move Data File To" stringByAppendingEllipsis]]; - + return error; } @@ -960,14 +960,14 @@ bool trashDataFile(const char * filename, tr_error ** error) { int totalPeers; tr_peer_stat * peers = tr_torrentPeers(fHandle, &totalPeers); - + NSMutableArray * peerDicts = [NSMutableArray arrayWithCapacity: totalPeers]; - + for (int i = 0; i < totalPeers; i++) { tr_peer_stat * peer = &peers[i]; NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithCapacity: 12]; - + [dict setObject: [self name] forKey: @"Name"]; [dict setObject: [NSNumber numberWithInt: peer->from] forKey: @"From"]; [dict setObject: [NSString stringWithUTF8String: peer->addr] forKey: @"IP"]; @@ -978,17 +978,17 @@ bool trashDataFile(const char * filename, tr_error ** error) [dict setObject: [NSNumber numberWithBool: peer->isUTP] forKey: @"uTP"]; [dict setObject: [NSString stringWithUTF8String: peer->client] forKey: @"Client"]; [dict setObject: [NSString stringWithUTF8String: peer->flagStr] forKey: @"Flags"]; - + if (peer->isUploadingTo) [dict setObject: [NSNumber numberWithDouble: peer->rateToPeer_KBps] forKey: @"UL To Rate"]; if (peer->isDownloadingFrom) [dict setObject: [NSNumber numberWithDouble: peer->rateToClient_KBps] forKey: @"DL From Rate"]; - + [peerDicts addObject: dict]; } - + tr_torrentPeersFree(peers, totalPeers); - + return peerDicts; } @@ -1000,24 +1000,24 @@ bool trashDataFile(const char * filename, tr_error ** error) - (NSArray *) webSeeds { NSMutableArray * webSeeds = [NSMutableArray arrayWithCapacity: fInfo->webseedCount]; - + double * dlSpeeds = tr_torrentWebSpeeds_KBps(fHandle); - + for (NSInteger i = 0; i < fInfo->webseedCount; i++) { NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithCapacity: 3]; - + [dict setObject: [self name] forKey: @"Name"]; [dict setObject: [NSString stringWithUTF8String: fInfo->webseeds[i]] forKey: @"Address"]; - + if (dlSpeeds[i] != -1.0) [dict setObject: [NSNumber numberWithDouble: dlSpeeds[i]] forKey: @"DL From Rate"]; - + [webSeeds addObject: dict]; } - + tr_free(dlSpeeds); - + return webSeeds; } @@ -1029,13 +1029,13 @@ bool trashDataFile(const char * filename, tr_error ** error) ? [NSString stringWithFormat: NSLocalizedString(@"%@ of torrent metadata retrieved", "Torrent -> progress string"), [NSString percentString: fStat->metadataPercentComplete longDecimals: YES]] : NSLocalizedString(@"torrent metadata needed", "Torrent -> progress string"); - + return [NSString stringWithFormat: @"%@ - %@", NSLocalizedString(@"Magnetized transfer", "Torrent -> progress string"), progressString]; } - + NSString * string; - + if (![self allDownloaded]) { CGFloat progress; @@ -1049,7 +1049,7 @@ bool trashDataFile(const char * filename, tr_error ** error) string = [NSString stringForFilePartialSize: [self haveTotal] fullSize: [self size]]; progress = [self progress]; } - + string = [string stringByAppendingFormat: @" (%@)", [NSString percentString: progress longDecimals: YES]]; } else @@ -1069,25 +1069,25 @@ bool trashDataFile(const char * filename, tr_error ** error) } else downloadString = [NSString stringForFileSize: [self size]]; - + NSString * uploadString = [NSString stringWithFormat: NSLocalizedString(@"uploaded %@ (Ratio: %@)", "Torrent -> progress string"), [NSString stringForFileSize: [self uploadedTotal]], [NSString stringForRatio: [self ratio]]]; - + string = [downloadString stringByAppendingFormat: @", %@", uploadString]; } - + //add time when downloading or seed limit set if ([self shouldShowEta]) string = [string stringByAppendingFormat: @" - %@", [self etaString]]; - + return string; } - (NSString *) statusString { NSString * string; - + if ([self isAnyErrorOrWarning]) { switch (fStat->error) @@ -1097,7 +1097,7 @@ bool trashDataFile(const char * filename, tr_error ** error) case TR_STAT_TRACKER_WARNING: string = NSLocalizedString(@"Tracker returned warning", "Torrent -> status string"); break; default: NSAssert(NO, @"unknown error state"); } - + NSString * errorString = [self errorMessage]; if (errorString && ![errorString isEqualToString: @""]) string = [string stringByAppendingFormat: @": %@", errorString]; @@ -1112,15 +1112,15 @@ bool trashDataFile(const char * filename, tr_error ** error) else string = NSLocalizedString(@"Paused", "Torrent -> status string"); break; - + case TR_STATUS_DOWNLOAD_WAIT: string = [NSLocalizedString(@"Waiting to download", "Torrent -> status string") stringByAppendingEllipsis]; break; - + case TR_STATUS_SEED_WAIT: string = [NSLocalizedString(@"Waiting to seed", "Torrent -> status string") stringByAppendingEllipsis]; break; - + case TR_STATUS_CHECK_WAIT: string = [NSLocalizedString(@"Waiting to check existing data", "Torrent -> status string") stringByAppendingEllipsis]; break; @@ -1138,7 +1138,7 @@ bool trashDataFile(const char * filename, tr_error ** error) else string = [NSString stringWithFormat: NSLocalizedString(@"Downloading from %d of 1 peer", "Torrent -> status string"), [self peersSendingToUs]]; - + const NSInteger webSeedCount = fStat->webseedsSendingToUs; if (webSeedCount > 0) { @@ -1148,10 +1148,10 @@ bool trashDataFile(const char * filename, tr_error ** error) else webSeedString = [NSString stringWithFormat: NSLocalizedString(@"%d web seeds", "Torrent -> status string"), webSeedCount]; - + string = [string stringByAppendingFormat: @" + %@", webSeedString]; } - + break; case TR_STATUS_SEED: @@ -1162,11 +1162,11 @@ bool trashDataFile(const char * filename, tr_error ** error) string = [NSString stringWithFormat: NSLocalizedString(@"Seeding to %d of 1 peer", "Torrent -> status string"), [self peersGettingFromUs]]; } - + if ([self isStalled]) string = [NSLocalizedString(@"Stalled", "Torrent -> status string") stringByAppendingFormat: @", %@", string]; } - + //append even if error if ([self isActive] && ![self isChecking]) { @@ -1178,14 +1178,14 @@ bool trashDataFile(const char * filename, tr_error ** error) string = [string stringByAppendingFormat: @" - %@: %@", NSLocalizedString(@"UL", "Torrent -> status string"), [NSString stringForSpeed: [self uploadRate]]]; } - + return string; } - (NSString *) shortStatusString { NSString * string; - + switch (fStat->activity) { case TR_STATUS_STOPPED: @@ -1194,11 +1194,11 @@ bool trashDataFile(const char * filename, tr_error ** error) else string = NSLocalizedString(@"Paused", "Torrent -> status string"); break; - + case TR_STATUS_DOWNLOAD_WAIT: string = [NSLocalizedString(@"Waiting to download", "Torrent -> status string") stringByAppendingEllipsis]; break; - + case TR_STATUS_SEED_WAIT: string = [NSLocalizedString(@"Waiting to seed", "Torrent -> status string") stringByAppendingEllipsis]; break; @@ -1212,19 +1212,19 @@ bool trashDataFile(const char * filename, tr_error ** error) NSLocalizedString(@"Checking existing data", "Torrent -> status string"), [NSString percentString: [self checkingProgress] longDecimals: YES]]; break; - + case TR_STATUS_DOWNLOAD: string = [NSString stringWithFormat: @"%@: %@, %@: %@", NSLocalizedString(@"DL", "Torrent -> status string"), [NSString stringForSpeed: [self downloadRate]], NSLocalizedString(@"UL", "Torrent -> status string"), [NSString stringForSpeed: [self uploadRate]]]; break; - + case TR_STATUS_SEED: string = [NSString stringWithFormat: @"%@: %@, %@: %@", NSLocalizedString(@"Ratio", "Torrent -> status string"), [NSString stringForRatio: [self ratio]], NSLocalizedString(@"UL", "Torrent -> status string"), [NSString stringForSpeed: [self uploadRate]]]; } - + return string; } @@ -1245,21 +1245,21 @@ bool trashDataFile(const char * filename, tr_error ** error) case TR_STATUS_SEED_WAIT: { NSString * string = NSLocalizedString(@"Paused", "Torrent -> status string"); - + NSString * extra = nil; if ([self waitingToStart]) { - extra = fStat->activity == TR_STATUS_DOWNLOAD_WAIT + extra = fStat->activity == TR_STATUS_DOWNLOAD_WAIT ? NSLocalizedString(@"Waiting to download", "Torrent -> status string") : NSLocalizedString(@"Waiting to seed", "Torrent -> status string"); } else if ([self isFinishedSeeding]) extra = NSLocalizedString(@"Seeding complete", "Torrent -> status string"); else; - + return extra ? [string stringByAppendingFormat: @" (%@)", extra] : string; } - + case TR_STATUS_CHECK_WAIT: return [NSLocalizedString(@"Waiting to check existing data", "Torrent -> status string") stringByAppendingEllipsis]; @@ -1382,7 +1382,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { fGroupValue = groupValue; [[NSNotificationCenter defaultCenter] postNotificationName: kTorrentDidChangeGroupNotification object: self]; - } + } fGroupValueDetermination = determinationType; } @@ -1416,7 +1416,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { if (fFileStat) tr_torrentFilesFree(fFileStat, [self fileCount]); - + fFileStat = tr_torrentFiles(fHandle, NULL); } @@ -1424,31 +1424,31 @@ bool trashDataFile(const char * filename, tr_error ** error) { if ([self fileCount] == 1 || [self isComplete]) return [self progress]; - + if (!fFileStat) [self updateFileStat]; - + // #5501 if ([node size] == 0) { return 1.0; } - + NSIndexSet * indexSet = [node indexes]; - + if ([indexSet count] == 1) return fFileStat[[indexSet firstIndex]].progress; - + uint64_t have = 0; for (NSInteger index = [indexSet firstIndex]; index != NSNotFound; index = [indexSet indexGreaterThanIndex: index]) have += fFileStat[index].bytesCompleted; - + return (CGFloat)have / [node size]; } - (BOOL) canChangeDownloadCheckForFile: (NSUInteger) index { NSAssert2((NSInteger)index < [self fileCount], @"Index %ld is greater than file count %ld", index, [self fileCount]); - + return [self canChangeDownloadCheckForFiles: [NSIndexSet indexSetWithIndex: index]]; } @@ -1456,10 +1456,10 @@ bool trashDataFile(const char * filename, tr_error ** error) { if ([self fileCount] == 1 || [self isComplete]) return NO; - + if (!fFileStat) [self updateFileStat]; - + __block BOOL canChange = NO; [indexSet enumerateIndexesWithOptions: NSEnumerationConcurrent usingBlock: ^(NSUInteger index, BOOL *stop) { if (fFileStat[index].progress < 1.0) @@ -1480,7 +1480,7 @@ bool trashDataFile(const char * filename, tr_error ** error) onState = YES; else offState = YES; - + if (onState && offState) return NSMixedState; } @@ -1493,10 +1493,10 @@ bool trashDataFile(const char * filename, tr_error ** error) tr_file_index_t * files = malloc(count * sizeof(tr_file_index_t)); for (NSUInteger index = [indexSet firstIndex], i = 0; index != NSNotFound; index = [indexSet indexGreaterThanIndex: index], i++) files[i] = index; - + tr_torrentSetFileDLs(fHandle, files, count, state != NSOffState); free(files); - + [self update]; [[NSNotificationCenter defaultCenter] postNotificationName: @"TorrentFileCheckChange" object: self]; } @@ -1507,7 +1507,7 @@ bool trashDataFile(const char * filename, tr_error ** error) tr_file_index_t * files = tr_malloc(count * sizeof(tr_file_index_t)); for (NSUInteger index = [indexSet firstIndex], i = 0; index != NSNotFound; index = [indexSet indexGreaterThanIndex: index], i++) files[i] = index; - + tr_torrentSetFilePriorities(fHandle, files, count, priority); tr_free(files); } @@ -1524,12 +1524,12 @@ bool trashDataFile(const char * filename, tr_error ** error) { BOOL low = NO, normal = NO, high = NO; NSMutableSet * priorities = [NSMutableSet setWithCapacity: MIN([indexSet count], 3u)]; - + for (NSUInteger index = [indexSet firstIndex]; index != NSNotFound; index = [indexSet indexGreaterThanIndex: index]) { if (![self canChangeDownloadCheckForFile: index]) continue; - + const tr_priority_t priority = fInfo->files[index].priority; switch (priority) { @@ -1551,7 +1551,7 @@ bool trashDataFile(const char * filename, tr_error ** error) default: NSAssert2(NO, @"Unknown priority %d for file index %ld", priority, index); } - + [priorities addObject: [NSNumber numberWithInteger: priority]]; if (low && normal && high) break; @@ -1597,7 +1597,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { if (fStat->idleSecs == -1) return -1; - + return fStat->idleSecs / 60; } @@ -1630,16 +1630,16 @@ bool trashDataFile(const char * filename, tr_error ** error) { int count; tr_tracker_stat * stats = tr_torrentTrackers(fHandle, &count); - + NSString * best = nil; - + for (int i=0; i < count; ++i) { NSString * tracker = [NSString stringWithUTF8String: stats[i].host]; if (!best || [tracker localizedCaseInsensitiveCompare: best] == NSOrderedAscending) best = tracker; } - + tr_torrentTrackersFree(stats, count); return best; } @@ -1668,38 +1668,38 @@ bool trashDataFile(const char * filename, tr_error ** error) { if (!(self = [super init])) return nil; - + fDefaults = [NSUserDefaults standardUserDefaults]; - + if (torrentStruct) fHandle = torrentStruct; else { //set libtransmission settings for initialization tr_ctor * ctor = tr_ctorNew(lib); - + tr_ctorSetPaused(ctor, TR_FORCE, YES); if (downloadFolder) tr_ctorSetDownloadDir(ctor, TR_FORCE, [downloadFolder UTF8String]); if (incompleteFolder) tr_ctorSetIncompleteDir(ctor, [incompleteFolder UTF8String]); - + tr_parse_result result = TR_PARSE_ERR; if (path) result = tr_ctorSetMetainfoFromFile(ctor, [path UTF8String]); - + if (result != TR_PARSE_OK && magnetAddress) result = tr_ctorSetMetainfoFromMagnetLink(ctor, [magnetAddress UTF8String]); - + //backup - shouldn't be needed after upgrade to 1.70 if (result != TR_PARSE_OK && hashString) result = tr_ctorSetMetainfoFromHash(ctor, [hashString UTF8String]); - + if (result == TR_PARSE_OK) fHandle = tr_torrentNew(ctor, NULL, NULL); - + tr_ctorFree(ctor); - + if (!fHandle) { [self release]; @@ -1708,23 +1708,23 @@ bool trashDataFile(const char * filename, tr_error ** error) } fInfo = tr_torrentInfo(fHandle); - + tr_torrentSetQueueStartCallback(fHandle, startQueueCallback, self); tr_torrentSetCompletenessCallback(fHandle, completenessChangeCallback, self); tr_torrentSetRatioLimitHitCallback(fHandle, ratioLimitHitCallback, self); tr_torrentSetIdleLimitHitCallback(fHandle, idleLimitHitCallback, self); tr_torrentSetMetadataCallback(fHandle, metadataCallback, self); - + fHashString = [[NSString alloc] initWithUTF8String: fInfo->hashString]; - + fResumeOnWake = NO; - + //don't do after this point - it messes with auto-group functionality if (![self isMagnet]) [self createFileList]; - + fDownloadFolderDetermination = TorrentDeterminationAutomatic; - + if (groupValue) { fGroupValueDetermination = TorrentDeterminationUserSpecified; @@ -1735,45 +1735,45 @@ bool trashDataFile(const char * filename, tr_error ** error) fGroupValueDetermination = TorrentDeterminationAutomatic; fGroupValue = [[GroupsController groups] groupIndexForTorrent: self]; } - + fRemoveWhenFinishSeeding = removeWhenFinishSeeding ? [removeWhenFinishSeeding boolValue] : [fDefaults boolForKey: @"RemoveWhenFinishSeeding"]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(checkGroupValueForRemoval:) name: @"GroupValueRemoved" object: nil]; - + fTimeMachineExcludeInitialized = NO; [self update]; - + return self; } - (void) createFileList { NSAssert(![self isMagnet], @"Cannot create a file list until the torrent is demagnetized"); - + if ([self isFolder]) { const NSInteger count = [self fileCount]; NSMutableArray * flatFileList = [NSMutableArray arrayWithCapacity: count]; - + FileListNode * tempNode = nil; - + for (NSInteger i = 0; i < count; i++) { tr_file * file = &fInfo->files[i]; - + NSString * fullPath = [NSString stringWithUTF8String: file->name]; NSArray * pathComponents = [fullPath pathComponents]; - + if (!tempNode) tempNode = [[FileListNode alloc] initWithFolderName:[pathComponents objectAtIndex: 0] path:@"" torrent:self]; - + [self insertPathForComponents: pathComponents withComponentIndex: 1 forParent: tempNode fileSize: file->length index: i flatList: flatFileList]; } - + [self sortFileList: [tempNode children]]; [self sortFileList: flatFileList]; - + fFileList = [[NSArray alloc] initWithArray: [tempNode children]]; fFlatFileList = [[NSArray alloc] initWithArray: flatFileList]; [tempNode release]; @@ -1792,10 +1792,10 @@ bool trashDataFile(const char * filename, tr_error ** error) { NSParameterAssert([components count] > 0); NSParameterAssert(componentIndex < [components count]); - + NSString * name = [components objectAtIndex: componentIndex]; const BOOL isFolder = componentIndex < ([components count]-1); - + //determine if folder node already exists __block FileListNode * node = nil; if (isFolder) @@ -1808,7 +1808,7 @@ bool trashDataFile(const char * filename, tr_error ** error) } }]; } - + //create new folder or file if it doesn't already exist if (!node) { @@ -1820,14 +1820,14 @@ bool trashDataFile(const char * filename, tr_error ** error) node = [[[FileListNode alloc] initWithFileName: name path: path size: size index: index torrent: self] autorelease]; [flatFileList addObject: node]; } - + [parent insertChild: node]; } - + if (isFolder) { [node insertIndex: index withSize: size]; - + [self insertPathForComponents: components withComponentIndex: (componentIndex+1) forParent: node fileSize: size index: index flatList: flatFileList]; } } @@ -1836,7 +1836,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { NSSortDescriptor * descriptor = [NSSortDescriptor sortDescriptorWithKey: @"name" ascending: YES selector: @selector(localizedStandardCompare:)]; [fileNodes sortUsingDescriptors: [NSArray arrayWithObject: descriptor]]; - + [fileNodes enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(FileListNode * node, NSUInteger idx, BOOL * stop) { if ([node isFolder]) [self sortFileList: [node children]]; @@ -1852,7 +1852,7 @@ bool trashDataFile(const char * filename, tr_error ** error) - (void) completenessChange: (tr_completeness) status wasRunning: (BOOL) wasRunning { fStat = tr_torrentStat(fHandle); //don't call update yet to avoid auto-stop - + switch (status) { case TR_SEED: @@ -1860,7 +1860,7 @@ bool trashDataFile(const char * filename, tr_error ** error) { NSDictionary * statusInfo = @{ @"Status" : @(status), @"WasRunning" : @(wasRunning) }; [[NSNotificationCenter defaultCenter] postNotificationName: @"TorrentFinishedDownloading" object: self userInfo: statusInfo]; - + //quarantine the finished data NSString * dataLocation = [[self currentDirectory] stringByAppendingPathComponent: [self name]]; FSRef ref; @@ -1872,14 +1872,14 @@ bool trashDataFile(const char * filename, tr_error ** error) } else NSLog(@"Could not find file to quarantine: %@", dataLocation); - + break; } case TR_LEECH: [[NSNotificationCenter defaultCenter] postNotificationName: @"TorrentRestartedDownloading" object: self]; break; } - + [self update]; [self updateTimeMachineExclude]; } @@ -1887,14 +1887,14 @@ bool trashDataFile(const char * filename, tr_error ** error) - (void) ratioLimitHit { fStat = tr_torrentStat(fHandle); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"TorrentFinishedSeeding" object: self]; } - (void) idleLimitHit { fStat = tr_torrentStat(fHandle); - + [[NSNotificationCenter defaultCenter] postNotificationName: @"TorrentFinishedSeeding" object: self]; } @@ -1903,13 +1903,13 @@ bool trashDataFile(const char * filename, tr_error ** error) fStat = tr_torrentStat(fHandle); [self createFileList]; - + /* If the torrent is in no group, or the group was automatically determined based on criteria evaluated * before we had metadata for this torrent, redetermine the group */ if ((fGroupValueDetermination == TorrentDeterminationAutomatic) || ([self groupValue] == -1)) [self setGroupValue: [[GroupsController groups] groupIndexForTorrent: self] determinationType: TorrentDeterminationAutomatic]; - + //change the location if the group calls for it and it's either not already set or was set automatically before if (((fDownloadFolderDetermination == TorrentDeterminationAutomatic) || !tr_torrentGetCurrentDir(fHandle)) && [[GroupsController groups] usesCustomDownloadLocationForIndex: [self groupValue]]) @@ -1917,7 +1917,7 @@ bool trashDataFile(const char * filename, tr_error ** error) NSString *location = [[GroupsController groups] customDownloadLocationForIndex: [self groupValue]]; [self changeDownloadFolderBeforeUsing: location determinationType:TorrentDeterminationAutomatic]; } - + [[NSNotificationCenter defaultCenter] postNotificationName: @"ResetInspector" object: self userInfo: @{ @"Torrent" : self }]; } @@ -1926,34 +1926,34 @@ bool trashDataFile(const char * filename, tr_error ** error) NSParameterAssert(completionHandler != nil); NSParameterAssert(oldPath != nil); NSParameterAssert(newName != nil); - + NSString * path = [oldPath stringByDeletingLastPathComponent]; - + if (success) { NSString * oldName = [oldPath lastPathComponent]; void (^__block updateNodeAndChildrenForRename)(FileListNode *) = ^(FileListNode * node) { [node updateFromOldName: oldName toNewName: newName inPath: path]; - + if ([node isFolder]) { [[node children] enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(FileListNode * childNode, NSUInteger idx, BOOL * stop) { updateNodeAndChildrenForRename(childNode); }]; } }; - + if (!nodes) nodes = fFlatFileList; [nodes enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(FileListNode * node, NSUInteger idx, BOOL *stop) { updateNodeAndChildrenForRename(node); }]; - + //resort lists NSMutableArray * fileList = [fFileList mutableCopy]; [fFileList release]; [self sortFileList: fileList]; fFileList = fileList; - + NSMutableArray * flatFileList = [fFlatFileList mutableCopy]; [fFlatFileList release]; [self sortFileList: flatFileList]; @@ -1961,7 +1961,7 @@ bool trashDataFile(const char * filename, tr_error ** error) } else NSLog(@"Error renaming %@ to %@", oldPath, [path stringByAppendingPathComponent: newName]); - + completionHandler(success); } @@ -1974,12 +1974,12 @@ bool trashDataFile(const char * filename, tr_error ** error) //ratio: show if it's set at all if (tr_torrentGetSeedRatio(fHandle, NULL)) return YES; - + //idle: show only if remaining time is less than cap if (fStat->etaIdle != TR_ETA_NOT_AVAIL && fStat->etaIdle < ETA_IDLE_DISPLAY_SEC) return YES; } - + return NO; } @@ -2000,9 +2000,9 @@ bool trashDataFile(const char * filename, tr_error ** error) } else return NSLocalizedString(@"remaining time unknown", "Torrent -> eta string"); - + NSString * idleString; - + if ([NSApp isOnYosemiteOrBetter]) { static NSDateComponentsFormatter *formatter; static dispatch_once_t onceToken; @@ -2013,17 +2013,17 @@ bool trashDataFile(const char * filename, tr_error ** error) formatter.collapsesLargestUnit = YES; formatter.includesTimeRemainingPhrase = YES; }); - + idleString = [formatter stringFromTimeInterval: eta]; } else { idleString = [NSString timeString: eta includesTimeRemainingPhrase: YES showSeconds: YES maxFields: 2]; } - + if (fromIdle) { idleString = [idleString stringByAppendingFormat: @" (%@)", NSLocalizedString(@"inactive", "Torrent -> eta string")]; } - + return idleString; } diff --git a/macosx/TorrentCell.h b/macosx/TorrentCell.h index bbcfb4189..f80b0059a 100644 --- a/macosx/TorrentCell.h +++ b/macosx/TorrentCell.h @@ -25,12 +25,12 @@ @interface TorrentCell : NSActionCell { NSUserDefaults * fDefaults; - + NSMutableDictionary * fTitleAttributes, * fStatusAttributes; - + BOOL fTracking, fMouseDownControlButton, fMouseDownRevealButton, fMouseDownActionButton, fHover, fHoverControl, fHoverReveal, fHoverAction; - + NSColor * fBarBorderColor, * fBluePieceColor, * fBarMinimalBorderColor; } diff --git a/macosx/TorrentCell.m b/macosx/TorrentCell.m index 7ca0f8214..4924c9c59 100644 --- a/macosx/TorrentCell.m +++ b/macosx/TorrentCell.m @@ -93,27 +93,27 @@ - (id) init { if ((self = [super init])) - { + { fDefaults = [NSUserDefaults standardUserDefaults]; - + NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [paragraphStyle setLineBreakMode: NSLineBreakByTruncatingMiddle]; - + fTitleAttributes = [[NSMutableDictionary alloc] initWithCapacity: 3]; [fTitleAttributes setObject: [NSFont messageFontOfSize: 12.0] forKey: NSFontAttributeName]; [fTitleAttributes setObject: paragraphStyle forKey: NSParagraphStyleAttributeName]; - + fStatusAttributes = [[NSMutableDictionary alloc] initWithCapacity: 3]; [fStatusAttributes setObject: [NSFont messageFontOfSize: 9.0] forKey: NSFontAttributeName]; [fStatusAttributes setObject: paragraphStyle forKey: NSParagraphStyleAttributeName]; - + [paragraphStyle release]; - + fBluePieceColor = [[NSColor colorWithCalibratedRed: 0.0 green: 0.4 blue: 0.8 alpha: 1.0] retain]; fBarBorderColor = [[NSColor colorWithCalibratedWhite: 0.0 alpha: 0.2] retain]; fBarMinimalBorderColor = [[NSColor colorWithCalibratedWhite: 0.0 alpha: 0.015] retain]; } - return self; + return self; } - (id) copyWithZone: (NSZone *) zone @@ -126,7 +126,7 @@ - (NSRect) iconRectForBounds: (NSRect) bounds { const CGFloat imageSize = [fDefaults boolForKey: @"SmallView"] ? IMAGE_SIZE_MIN : IMAGE_SIZE_REG; - + return NSMakeRect(NSMinX(bounds) + PADDING_HORIZONTAL, ceil(NSMidY(bounds) - imageSize * 0.5), imageSize, imageSize); } @@ -134,11 +134,11 @@ - (NSCellHitResult) hitTestForEvent: (NSEvent *) event inRect: (NSRect) cellFrame ofView: (NSView *) controlView { NSPoint point = [controlView convertPoint: [event locationInWindow] fromView: nil]; - + if (NSMouseInRect(point, [self controlButtonRectForBounds: cellFrame], [controlView isFlipped]) || NSMouseInRect(point, [self revealButtonRectForBounds: cellFrame], [controlView isFlipped])) return NSCellHitContentArea | NSCellHitTrackableArea; - + return NSCellHitContentArea; } @@ -150,23 +150,23 @@ - (BOOL) trackMouse: (NSEvent *) event inRect: (NSRect) cellFrame ofView: (NSView *) controlView untilMouseUp: (BOOL) flag { fTracking = YES; - + [self setControlView: controlView]; - + NSPoint point = [controlView convertPoint: [event locationInWindow] fromView: nil]; - + const NSRect controlRect = [self controlButtonRectForBounds: cellFrame]; const BOOL checkControl = NSMouseInRect(point, controlRect, [controlView isFlipped]); - + const NSRect revealRect = [self revealButtonRectForBounds: cellFrame]; const BOOL checkReveal = NSMouseInRect(point, revealRect, [controlView isFlipped]); - + [(TorrentTableView *)controlView removeTrackingAreas]; - + while ([event type] != NSLeftMouseUp) { point = [controlView convertPoint: [event locationInWindow] fromView: nil]; - + if (checkControl) { const BOOL inControlButton = NSMouseInRect(point, controlRect, [controlView isFlipped]); @@ -186,27 +186,27 @@ } } else; - + //send events to where necessary if ([event type] == NSMouseEntered || [event type] == NSMouseExited) [NSApp sendEvent: event]; event = [[controlView window] nextEventMatchingMask: (NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSMouseEnteredMask | NSMouseExitedMask)]; } - + fTracking = NO; if (fMouseDownControlButton) { fMouseDownControlButton = NO; - + [(TorrentTableView *)controlView toggleControlForTorrent: [self representedObject]]; } else if (fMouseDownRevealButton) { fMouseDownRevealButton = NO; [controlView setNeedsDisplayInRect: cellFrame]; - + NSString * location = [[self representedObject] dataLocation]; if (location) { @@ -215,9 +215,9 @@ } } else; - + [controlView updateTrackingAreas]; - + return YES; } @@ -225,7 +225,7 @@ mouseLocation: (NSPoint) mouseLocation { const NSTrackingAreaOptions options = NSTrackingEnabledDuringMouseDrag | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways; - + //whole row if ([fDefaults boolForKey: @"SmallView"]) { @@ -235,7 +235,7 @@ rowOptions |= NSTrackingAssumeInside; [(TorrentTableView *)controlView setRowHover: [[userInfo objectForKey: @"Row"] integerValue]]; } - + NSMutableDictionary * rowInfo = [userInfo mutableCopy]; [rowInfo setObject: @"Row" forKey: @"Type"]; NSTrackingArea * area = [[NSTrackingArea alloc] initWithRect: cellFrame options: rowOptions owner: controlView userInfo: rowInfo]; @@ -243,7 +243,7 @@ [rowInfo release]; [area release]; } - + //control button NSRect controlButtonRect = [self controlButtonRectForBounds: cellFrame]; NSTrackingAreaOptions controlOptions = options; @@ -252,7 +252,7 @@ controlOptions |= NSTrackingAssumeInside; [(TorrentTableView *)controlView setControlButtonHover: [[userInfo objectForKey: @"Row"] integerValue]]; } - + NSMutableDictionary * controlInfo = [userInfo mutableCopy]; [controlInfo setObject: @"Control" forKey: @"Type"]; NSTrackingArea * area = [[NSTrackingArea alloc] initWithRect: controlButtonRect options: controlOptions owner: controlView @@ -260,7 +260,7 @@ [controlView addTrackingArea: area]; [controlInfo release]; [area release]; - + //reveal button NSRect revealButtonRect = [self revealButtonRectForBounds: cellFrame]; NSTrackingAreaOptions revealOptions = options; @@ -269,7 +269,7 @@ revealOptions |= NSTrackingAssumeInside; [(TorrentTableView *)controlView setRevealButtonHover: [[userInfo objectForKey: @"Row"] integerValue]]; } - + NSMutableDictionary * revealInfo = [userInfo mutableCopy]; [revealInfo setObject: @"Reveal" forKey: @"Type"]; area = [[NSTrackingArea alloc] initWithRect: revealButtonRect options: revealOptions owner: controlView @@ -277,7 +277,7 @@ [controlView addTrackingArea: area]; [revealInfo release]; [area release]; - + //action button NSRect actionButtonRect = [self iconRectForBounds: cellFrame]; //use the whole icon NSTrackingAreaOptions actionOptions = options; @@ -286,7 +286,7 @@ actionOptions |= NSTrackingAssumeInside; [(TorrentTableView *)controlView setActionButtonHover: [[userInfo objectForKey: @"Row"] integerValue]]; } - + NSMutableDictionary * actionInfo = [userInfo mutableCopy]; [actionInfo setObject: @"Action" forKey: @"Type"]; area = [[NSTrackingArea alloc] initWithRect: actionButtonRect options: actionOptions owner: controlView userInfo: actionInfo]; @@ -324,15 +324,15 @@ { Torrent * torrent = [self representedObject]; NSAssert(torrent != nil, @"can't have a TorrentCell without a Torrent"); - + const BOOL minimal = [fDefaults boolForKey: @"SmallView"]; - + //bar [self drawBar: minimal ? [self barRectMinForBounds: cellFrame] : [self barRectRegForBounds: cellFrame]]; - + //group coloring const NSRect iconRect = [self iconRectForBounds: cellFrame]; - + const NSInteger groupValue = [torrent groupValue]; if (groupValue != -1) { @@ -343,16 +343,16 @@ groupRect.origin.y -= 1.0; } const CGFloat radius = minimal ? 3.0 : 6.0; - + NSColor * groupColor = [[GroupsController groups] colorForIndex: groupValue], * darkGroupColor = [groupColor blendedColorWithFraction: 0.2 ofColor: [NSColor whiteColor]]; - + //border NSBezierPath * bp = [NSBezierPath bezierPathWithRoundedRect: groupRect xRadius: radius yRadius: radius]; [darkGroupColor set]; [bp setLineWidth: 2.0]; [bp stroke]; - + //inside bp = [NSBezierPath bezierPathWithRoundedRect: groupRect xRadius: radius yRadius: radius]; NSGradient * gradient = [[NSGradient alloc] initWithStartingColor: [groupColor blendedColorWithFraction: 0.7 @@ -360,9 +360,9 @@ [gradient drawInBezierPath: bp angle: 90.0]; [gradient release]; } - + const BOOL error = [torrent isAnyErrorOrWarning]; - + //icon if (!minimal || !(!fTracking && fHoverAction)) //don't show in minimal mode when hovered over { @@ -370,7 +370,7 @@ : [torrent icon]; [icon drawInRect: iconRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; } - + //error badge if (error && !minimal) { @@ -378,7 +378,7 @@ const NSRect errorRect = NSMakeRect(NSMaxX(iconRect) - ERROR_IMAGE_SIZE, NSMaxY(iconRect) - ERROR_IMAGE_SIZE, ERROR_IMAGE_SIZE, ERROR_IMAGE_SIZE); [errorImage drawInRect: errorRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; } - + //text color NSColor * titleColor, * statusColor; if ([self backgroundStyle] == NSBackgroundStyleDark) @@ -388,32 +388,32 @@ titleColor = [NSColor controlTextColor]; statusColor = [NSColor darkGrayColor]; } - + [fTitleAttributes setObject: titleColor forKey: NSForegroundColorAttributeName]; [fStatusAttributes setObject: statusColor forKey: NSForegroundColorAttributeName]; - + //minimal status CGFloat minimalTitleRightBound; if (minimal) { NSAttributedString * minimalString = [self attributedStatusString: [self minimalStatusString]]; NSRect minimalStatusRect = [self rectForMinimalStatusWithString: minimalString inBounds: cellFrame]; - + if (!fHover) [minimalString drawInRect: minimalStatusRect]; - + minimalTitleRightBound = NSMinX(minimalStatusRect); } - + //progress if (!minimal) { NSAttributedString * progressString = [self attributedStatusString: [torrent progressString]]; NSRect progressRect = [self rectForProgressWithStringInBounds: cellFrame]; - + [progressString drawInRect: progressRect]; } - + if (!minimal || fHover) { //control button @@ -424,7 +424,7 @@ controlImageSuffix = @"Hover"; else controlImageSuffix = @"Off"; - + NSImage * controlImage; if ([torrent isActive]) controlImage = [NSImage imageNamed: [@"Pause" stringByAppendingString: controlImageSuffix]]; @@ -437,11 +437,11 @@ else controlImage = [NSImage imageNamed: [@"Resume" stringByAppendingString: controlImageSuffix]]; } - + const NSRect controlRect = [self controlButtonRectForBounds: cellFrame]; [controlImage drawInRect: controlRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; minimalTitleRightBound = MIN(minimalTitleRightBound, NSMinX(controlRect)); - + //reveal button NSString * revealImageString; if (fMouseDownRevealButton) @@ -450,10 +450,10 @@ revealImageString = @"RevealHover"; else revealImageString = @"RevealOff"; - + NSImage * revealImage = [NSImage imageNamed: revealImageString]; [revealImage drawInRect: [self revealButtonRectForBounds: cellFrame] fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; - + //action button #warning image should use new gear NSString * actionImageString; @@ -464,31 +464,31 @@ actionImageString = @"ActionHover"; else actionImageString = nil; - + if (actionImageString) { NSImage * actionImage = [NSImage imageNamed: actionImageString]; [actionImage drawInRect: [self actionButtonRectForBounds: cellFrame] fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; } } - + //title NSAttributedString * titleString = [self attributedTitle]; NSRect titleRect = [self rectForTitleWithString: titleString withRightBound: minimalTitleRightBound inBounds: cellFrame]; [titleString drawInRect: titleRect]; - + //priority icon if ([torrent priority] != TR_PRI_NORMAL) { const NSRect priorityRect = NSMakeRect(NSMaxX(titleRect) + PADDING_BETWEEN_TITLE_AND_PRIORITY, NSMidY(titleRect) - PRIORITY_ICON_HEIGHT * 0.5, PRIORITY_ICON_WIDTH, PRIORITY_ICON_HEIGHT); - + NSColor * priorityColor = [self backgroundStyle] == NSBackgroundStyleDark ? [NSColor whiteColor] : [NSColor darkGrayColor]; NSImage * priorityImage = [[NSImage imageNamed: ([torrent priority] == TR_PRI_HIGH ? @"PriorityHighTemplate" : @"PriorityLowTemplate")] imageWithColor: priorityColor]; [priorityImage drawInRect: priorityRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil]; } - + //status if (!minimal) { @@ -500,35 +500,35 @@ - (NSRect) expansionFrameWithFrame: (NSRect) cellFrame inView: (NSView *) view { BOOL minimal = [fDefaults boolForKey: @"SmallView"]; - + //this code needs to match the code in drawInteriorWithFrame:withView: CGFloat minimalTitleRightBound; if (minimal) { NSAttributedString * minimalString = [self attributedStatusString: [self minimalStatusString]]; NSRect minimalStatusRect = [self rectForMinimalStatusWithString: minimalString inBounds: cellFrame]; - + minimalTitleRightBound = NSMinX(minimalStatusRect); } - + if (!minimal || fHover) { const NSRect controlRect = [self controlButtonRectForBounds: cellFrame]; minimalTitleRightBound = MIN(minimalTitleRightBound, NSMinX(controlRect)); } - + NSAttributedString * titleString = [self attributedTitle]; NSRect realRect = [self rectForTitleWithString: titleString withRightBound: minimalTitleRightBound inBounds: cellFrame]; - + NSAssert([titleString size].width >= NSWidth(realRect), @"Full rect width should not be less than the used title rect width!"); - + if ([titleString size].width > NSWidth(realRect) && NSMouseInRect([view convertPoint: [[view window] mouseLocationOutsideOfEventStream] fromView: nil], realRect, [view isFlipped])) { realRect.size.width = [titleString size].width; return NSInsetRect(realRect, -PADDING_EXPANSION_FRAME, -PADDING_EXPANSION_FRAME); } - + return NSZeroRect; } @@ -536,7 +536,7 @@ { cellFrame.origin.x += PADDING_EXPANSION_FRAME; cellFrame.origin.y += PADDING_EXPANSION_FRAME; - + [fTitleAttributes setObject: [NSColor controlTextColor] forKey: NSForegroundColorAttributeName]; NSAttributedString * titleString = [self attributedTitle]; [titleString drawInRect: cellFrame]; @@ -549,24 +549,24 @@ - (void) drawBar: (NSRect) barRect { const BOOL minimal = [fDefaults boolForKey: @"SmallView"]; - + const CGFloat piecesBarPercent = [(TorrentTableView *)[self controlView] piecesBarPercent]; if (piecesBarPercent > 0.0) { NSRect piecesBarRect, regularBarRect; NSDivideRect(barRect, &piecesBarRect, ®ularBarRect, floor(NSHeight(barRect) * PIECES_TOTAL_PERCENT * piecesBarPercent), NSMaxYEdge); - + [self drawRegularBar: regularBarRect]; [self drawPiecesBar: piecesBarRect]; } else { [[self representedObject] setPreviousFinishedPieces: nil]; - + [self drawRegularBar: barRect]; } - + NSColor * borderColor = minimal ? fBarMinimalBorderColor : fBarBorderColor; [borderColor set]; [NSBezierPath strokeRect: NSInsetRect(barRect, 0.5, 0.5)]; @@ -575,10 +575,10 @@ - (void) drawRegularBar: (NSRect) barRect { Torrent * torrent = [self representedObject]; - + NSRect haveRect, missingRect; NSDivideRect(barRect, &haveRect, &missingRect, round([torrent progress] * NSWidth(barRect)), NSMinXEdge); - + if (!NSIsEmptyRect(haveRect)) { if ([torrent isActive]) @@ -590,7 +590,7 @@ NSRect ratioHaveRect, ratioRemainingRect; NSDivideRect(haveRect, &ratioHaveRect, &ratioRemainingRect, round([torrent progressStopRatio] * NSWidth(haveRect)), NSMinXEdge); - + [[ProgressGradients progressGreenGradient] drawInRect: ratioHaveRect angle: 90]; [[ProgressGradients progressLightGreenGradient] drawInRect: ratioRemainingRect angle: 90]; } @@ -610,14 +610,14 @@ [[ProgressGradients progressGrayGradient] drawInRect: haveRect angle: 90]; } } - + if (![torrent allDownloaded]) { const CGFloat widthRemaining = round(NSWidth(barRect) * [torrent progressLeft]); - + NSRect wantedRect; NSDivideRect(missingRect, &wantedRect, &missingRect, widthRemaining, NSMinXEdge); - + //not-available section if ([torrent isActive] && ![torrent isChecking] && [torrent availableDesired] < 1.0 && [fDefaults boolForKey: @"DisplayProgressBarAvailable"]) @@ -625,14 +625,14 @@ NSRect unavailableRect; NSDivideRect(wantedRect, &wantedRect, &unavailableRect, round(NSWidth(wantedRect) * [torrent availableDesired]), NSMinXEdge); - + [[ProgressGradients progressRedGradient] drawInRect: unavailableRect angle: 90]; } - + //remaining section [[ProgressGradients progressWhiteGradient] drawInRect: wantedRect angle: 90]; } - + //unwanted section if (!NSIsEmptyRect(missingRect)) { @@ -646,7 +646,7 @@ - (void) drawPiecesBar: (NSRect) barRect { Torrent * torrent = [self representedObject]; - + //fill an all-white bar for magnet links if ([torrent isMagnet]) { @@ -654,18 +654,18 @@ NSRectFillUsingOperation(barRect, NSCompositeSourceOver); return; } - + NSInteger pieceCount = MIN([torrent pieceCount], MAX_PIECES); float * piecesPercent = malloc(pieceCount * sizeof(float)); [torrent getAmountFinished: piecesPercent size: pieceCount]; - + NSBitmapImageRep * bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: nil pixelsWide: pieceCount pixelsHigh: 1 bitsPerSample: 8 samplesPerPixel: 4 hasAlpha: YES isPlanar: NO colorSpaceName: NSCalibratedRGBColorSpace bytesPerRow: 0 bitsPerPixel: 0]; - + NSIndexSet * previousFinishedIndexes = [torrent previousFinishedPieces]; NSMutableIndexSet * finishedIndexes = [NSMutableIndexSet indexSet]; - + for (NSInteger i = 0; i < pieceCount; i++) { NSColor * pieceColor; @@ -679,15 +679,15 @@ } else pieceColor = [[NSColor whiteColor] blendedColorWithFraction: piecesPercent[i] ofColor: fBluePieceColor]; - + //it's faster to just set color instead of checking previous color [bitmap setColor: pieceColor atX: i y: 0]; } - + free(piecesPercent); - + [torrent setPreviousFinishedPieces: [finishedIndexes count] > 0 ? finishedIndexes : nil]; //don't bother saving if none are complete - + //actually draw image [bitmap drawInRect: barRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: ([fDefaults boolForKey: @"SmallView"] ? 0.25 : 1.0) respectFlipped: YES hints: nil]; @@ -699,22 +699,22 @@ { NSRect result; result.size = [string size]; - + result.origin.x = NSMaxX(bounds) - (PADDING_HORIZONTAL + NSWidth(result)); result.origin.y = ceil(NSMidY(bounds) - NSHeight(result) * 0.5); - + return result; } - (NSRect) rectForTitleWithString: (NSAttributedString *) string withRightBound: (CGFloat) rightBound inBounds: (NSRect) bounds { const BOOL minimal = [fDefaults boolForKey: @"SmallView"]; - + NSRect result; result.origin.x = NSMinX(bounds) + PADDING_HORIZONTAL + (minimal ? IMAGE_SIZE_MIN : IMAGE_SIZE_REG) + PADDING_BETWEEN_IMAGE_AND_TITLE; result.size.height = HEIGHT_TITLE; - + if (minimal) { result.origin.y = ceil(NSMidY(bounds) - NSHeight(result) * 0.5); @@ -725,11 +725,11 @@ result.origin.y = NSMinY(bounds) + PADDING_ABOVE_TITLE; result.size.width = NSMaxX(bounds) - NSMinX(result) - PADDING_HORIZONTAL; } - + if ([(Torrent *)[self representedObject] priority] != TR_PRI_NORMAL) result.size.width -= PRIORITY_ICON_WIDTH + PADDING_BETWEEN_TITLE_AND_PRIORITY; result.size.width = MIN(NSWidth(result), [string size].width); - + return result; } @@ -738,10 +738,10 @@ NSRect result; result.origin.y = NSMinY(bounds) + PADDING_ABOVE_TITLE + HEIGHT_TITLE + PADDING_BETWEEN_TITLE_AND_PROGRESS; result.origin.x = NSMinX(bounds) + PADDING_HORIZONTAL + IMAGE_SIZE_REG + PADDING_BETWEEN_IMAGE_AND_TITLE; - + result.size.height = HEIGHT_STATUS; result.size.width = NSMaxX(bounds) - NSMinX(result) - PADDING_HORIZONTAL; - + return result; } @@ -751,10 +751,10 @@ result.origin.y = NSMinY(bounds) + PADDING_ABOVE_TITLE + HEIGHT_TITLE + PADDING_BETWEEN_TITLE_AND_PROGRESS + HEIGHT_STATUS + PADDING_BETWEEN_PROGRESS_AND_BAR + BAR_HEIGHT + PADDING_BETWEEN_BAR_AND_STATUS; result.origin.x = NSMinX(bounds) + PADDING_HORIZONTAL + IMAGE_SIZE_REG + PADDING_BETWEEN_IMAGE_AND_TITLE; - + result.size.height = HEIGHT_STATUS; result.size.width = NSMaxX(bounds) - NSMinX(result) - PADDING_HORIZONTAL; - + return result; } @@ -765,10 +765,10 @@ result.origin.x = NSMinX(bounds) + PADDING_HORIZONTAL + IMAGE_SIZE_REG + PADDING_BETWEEN_IMAGE_AND_BAR; result.origin.y = NSMinY(bounds) + PADDING_ABOVE_TITLE + HEIGHT_TITLE + PADDING_BETWEEN_TITLE_AND_PROGRESS + HEIGHT_STATUS + PADDING_BETWEEN_PROGRESS_AND_BAR; - + result.size.width = floor(NSMaxX(bounds) - NSMinX(result) - PADDING_HORIZONTAL - 2.0 * (PADDING_BETWEEN_BUTTONS + NORMAL_BUTTON_WIDTH)); - + return result; } @@ -779,7 +779,7 @@ result.origin.y = NSMinY(bounds) + PADDING_BETWEEN_BAR_AND_EDGE_MIN; result.size.height = NSHeight(bounds) - 2.0 * PADDING_BETWEEN_BAR_AND_EDGE_MIN; result.size.width = NSMaxX(bounds) - NSMinX(result) - PADDING_BETWEEN_BAR_AND_EDGE_MIN; - + return result; } @@ -789,13 +789,13 @@ result.size.height = NORMAL_BUTTON_WIDTH; result.size.width = NORMAL_BUTTON_WIDTH; result.origin.x = NSMaxX(bounds) - (PADDING_HORIZONTAL + NORMAL_BUTTON_WIDTH + PADDING_BETWEEN_BUTTONS + NORMAL_BUTTON_WIDTH); - + if (![fDefaults boolForKey: @"SmallView"]) result.origin.y = NSMinY(bounds) + PADDING_ABOVE_TITLE + HEIGHT_TITLE - (NORMAL_BUTTON_WIDTH - BAR_HEIGHT) * 0.5 + PADDING_BETWEEN_TITLE_AND_PROGRESS + HEIGHT_STATUS + PADDING_BETWEEN_PROGRESS_AND_BAR; else result.origin.y = ceil(NSMidY(bounds) - NSHeight(result) * 0.5); - + return result; } @@ -805,20 +805,20 @@ result.size.height = NORMAL_BUTTON_WIDTH; result.size.width = NORMAL_BUTTON_WIDTH; result.origin.x = NSMaxX(bounds) - (PADDING_HORIZONTAL + NORMAL_BUTTON_WIDTH); - + if (![fDefaults boolForKey: @"SmallView"]) result.origin.y = NSMinY(bounds) + PADDING_ABOVE_TITLE + HEIGHT_TITLE - (NORMAL_BUTTON_WIDTH - BAR_HEIGHT) * 0.5 + PADDING_BETWEEN_TITLE_AND_PROGRESS + HEIGHT_STATUS + PADDING_BETWEEN_PROGRESS_AND_BAR; else result.origin.y = ceil(NSMidY(bounds) - NSHeight(result) * 0.5); - + return result; } - (NSRect) actionButtonRectForBounds: (NSRect) bounds { const NSRect iconRect = [self iconRectForBounds: bounds]; - + //in minimal view the rect will be the icon rect, but avoid the extra defaults lookup with some cheap math return NSMakeRect(NSMidX(iconRect) - ACTION_BUTTON_WIDTH * 0.5, NSMidY(iconRect) - ACTION_BUTTON_WIDTH * 0.5, ACTION_BUTTON_WIDTH, ACTION_BUTTON_WIDTH); diff --git a/macosx/TorrentGroup.m b/macosx/TorrentGroup.m index 6089955c2..39952b804 100644 --- a/macosx/TorrentGroup.m +++ b/macosx/TorrentGroup.m @@ -73,7 +73,7 @@ uploaded += [torrent uploadedTotal]; downloaded += [torrent downloadedTotal]; } - + return tr_getRatio(uploaded, downloaded); } @@ -82,7 +82,7 @@ CGFloat rate = 0.0; for (Torrent * torrent in fTorrents) rate += [torrent uploadRate]; - + return rate; } @@ -91,7 +91,7 @@ CGFloat rate = 0.0; for (Torrent * torrent in fTorrents) rate += [torrent downloadRate]; - + return rate; } diff --git a/macosx/TorrentTableView.h b/macosx/TorrentTableView.h index 912864ad1..e713b9600 100644 --- a/macosx/TorrentTableView.h +++ b/macosx/TorrentTableView.h @@ -32,25 +32,25 @@ @interface TorrentTableView : NSOutlineView { IBOutlet Controller * fController; - + TorrentCell * fTorrentCell; - + NSUserDefaults * fDefaults; - + NSMutableIndexSet * fCollapsedGroups; - + IBOutlet NSMenu * fContextRow, * fContextNoRow; - + NSInteger fMouseRow, fMouseControlRow, fMouseRevealRow, fMouseActionRow; NSArray * fSelectedValues; - + IBOutlet NSMenu * fActionMenu, * fUploadMenu, * fDownloadMenu, * fRatioMenu, * fPriorityMenu; IBOutlet NSMenuItem * fGlobalLimitItem; Torrent * fMenuTorrent; - + CGFloat fPiecesBarPercent; NSAnimation * fPiecesBarAnimation; - + BOOL fActionPopoverShown; } diff --git a/macosx/TorrentTableView.m b/macosx/TorrentTableView.m index baf2eca58..e2c39aacf 100644 --- a/macosx/TorrentTableView.m +++ b/macosx/TorrentTableView.m @@ -58,43 +58,43 @@ if ((self = [super initWithCoder: decoder])) { fDefaults = [NSUserDefaults standardUserDefaults]; - + fTorrentCell = [[TorrentCell alloc] init]; - + NSData * groupData = [fDefaults dataForKey: @"CollapsedGroups"]; if (groupData) fCollapsedGroups = [[NSUnarchiver unarchiveObjectWithData: groupData] mutableCopy]; else fCollapsedGroups = [[NSMutableIndexSet alloc] init]; - + fMouseRow = -1; fMouseControlRow = -1; fMouseRevealRow = -1; fMouseActionRow = -1; - + fActionPopoverShown = NO; - + [self setDelegate: self]; - + fPiecesBarPercent = [fDefaults boolForKey: @"PiecesBar"] ? 1.0 : 0.0; } - + return self; } - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; - + [fCollapsedGroups release]; - + [fPiecesBarAnimation release]; [fMenuTorrent release]; - + [fSelectedValues release]; - + [fTorrentCell release]; - + [super dealloc]; } @@ -102,7 +102,7 @@ { //set group columns to show ratio, needs to be in awakeFromNib to size columns correctly [self setGroupStatusColumns]; - + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(setNeedsDisplay) name: @"RefreshTorrentTable" object: nil]; } @@ -110,7 +110,7 @@ { if (value == -1) value = MAX_GROUP; - + return [fCollapsedGroups containsIndex: value]; } @@ -118,7 +118,7 @@ { if (value == -1) value = MAX_GROUP; - + [fCollapsedGroups removeIndex: value]; } @@ -159,7 +159,7 @@ if (!tableColumn) { [cell setRepresentedObject: item]; - + const NSInteger row = [self rowForItem: item]; [cell setHover: row == fMouseRow]; [cell setControlHover: row == fMouseControlRow]; @@ -185,11 +185,11 @@ else { NSRect rect = [super frameOfCellAtColumn: column row: row]; - + //adjust placement for proper vertical alignment if (column == [self columnWithIdentifier: @"Group"]) rect.size.height -= 1.0f; - + return rect; } } @@ -227,17 +227,17 @@ { [super updateTrackingAreas]; [self removeTrackingAreas]; - + const NSRange rows = [self rowsInRect: [self visibleRect]]; if (rows.length == 0) return; - + NSPoint mouseLocation = [self convertPoint: [[self window] mouseLocationOutsideOfEventStream] fromView: nil]; for (NSUInteger row = rows.location; row < NSMaxRange(rows); row++) { if (![[self itemAtRow: row] isKindOfClass: [Torrent class]]) continue; - + NSDictionary * userInfo = [NSDictionary dictionaryWithObject: [NSNumber numberWithInteger: row] forKey: @"Row"]; TorrentCell * cell = (TorrentCell *)[self preparedCellAtColumn: -1 row: row]; [cell addTrackingAreasForView: self inRect: [self rectOfRow: row] withUserInfo: userInfo mouseLocation: mouseLocation]; @@ -250,7 +250,7 @@ fMouseControlRow = -1; fMouseRevealRow = -1; fMouseActionRow = -1; - + for (NSTrackingArea * area in [self trackingAreas]) { if ([area owner] == self && [[area userInfo] objectForKey: @"Row"]) @@ -261,7 +261,7 @@ - (void) setRowHover: (NSInteger) row { NSAssert([fDefaults boolForKey: @"SmallView"], @"cannot set a hover row when not in compact view"); - + fMouseRow = row; if (row >= 0) [self setNeedsDisplayInRect: [self rectOfRow: row]]; @@ -291,7 +291,7 @@ - (void) mouseEntered: (NSEvent *) event { NSDictionary * dict = (NSDictionary *)[event userData]; - + NSNumber * row; if ((row = [dict objectForKey: @"Row"])) { @@ -309,7 +309,7 @@ if (![fDefaults boolForKey: @"SmallView"]) return; } - + [self setNeedsDisplayInRect: [self rectOfRow: rowVal]]; } } @@ -317,7 +317,7 @@ - (void) mouseExited: (NSEvent *) event { NSDictionary * dict = (NSDictionary *)[event userData]; - + NSNumber * row; if ((row = [dict objectForKey: @"Row"])) { @@ -334,7 +334,7 @@ if (![fDefaults boolForKey: @"SmallView"]) return; } - + [self setNeedsDisplayInRect: [self rectOfRow: [row integerValue]]]; } } @@ -352,7 +352,7 @@ NSInteger value = [[[notification userInfo] objectForKey: @"NSObject"] groupIndex]; if (value < 0) value = MAX_GROUP; - + if ([fCollapsedGroups containsIndex: value]) { [fCollapsedGroups removeIndex: value]; @@ -365,7 +365,7 @@ NSInteger value = [[[notification userInfo] objectForKey: @"NSObject"] groupIndex]; if (value < 0) value = MAX_GROUP; - + [fCollapsedGroups addIndex: value]; [[NSNotificationCenter defaultCenter] postNotificationName: @"OutlineExpandCollapse" object: self]; } @@ -374,27 +374,27 @@ { NSPoint point = [self convertPoint: [event locationInWindow] fromView: nil]; const NSInteger row = [self rowAtPoint: point]; - + //check to toggle group status before anything else if ([self pointInGroupStatusRect: point]) { [fDefaults setBool: ![fDefaults boolForKey: @"DisplayGroupRowRatio"] forKey: @"DisplayGroupRowRatio"]; [self setGroupStatusColumns]; - + return; } - + const BOOL pushed = row != -1 && (fMouseActionRow == row || fMouseRevealRow == row || fMouseControlRow == row); - + //if pushing a button, don't change the selected rows if (pushed) fSelectedValues = [[self selectedValues] retain]; - + [super mouseDown: event]; - + [fSelectedValues release]; fSelectedValues = nil; - + //avoid weird behavior when showing menu by doing this after mouse down if (row != -1 && fMouseActionRow == row) { @@ -406,7 +406,7 @@ id item = nil; if (row != -1) item = [self itemAtRow: row]; - + if (!item || [item isKindOfClass: [Torrent class]]) [fController showInfo: nil]; else @@ -423,7 +423,7 @@ - (void) selectValues: (NSArray *) values { NSMutableIndexSet * indexSet = [NSMutableIndexSet indexSet]; - + for (id item in values) { if ([item isKindOfClass: [Torrent class]]) @@ -446,7 +446,7 @@ } } } - + [self selectRowIndexes: indexSet byExtendingSelection: NO]; } @@ -454,10 +454,10 @@ { NSIndexSet * selectedIndexes = [self selectedRowIndexes]; NSMutableArray * values = [NSMutableArray arrayWithCapacity: [selectedIndexes count]]; - + for (NSUInteger i = [selectedIndexes firstIndex]; i != NSNotFound; i = [selectedIndexes indexGreaterThanIndex: i]) [values addObject: [self itemAtRow: i]]; - + return values; } @@ -465,7 +465,7 @@ { NSIndexSet * selectedIndexes = [self selectedRowIndexes]; NSMutableArray * torrents = [NSMutableArray arrayWithCapacity: [selectedIndexes count]]; //take a shot at guessing capacity - + for (NSUInteger i = [selectedIndexes firstIndex]; i != NSNotFound; i = [selectedIndexes indexGreaterThanIndex: i]) { id item = [self itemAtRow: i]; @@ -479,7 +479,7 @@ i +=[groupTorrents count]; } } - + return torrents; } @@ -510,7 +510,7 @@ - (void) keyDown: (NSEvent *) event { const unichar firstChar = [[event charactersIgnoringModifiers] characterAtIndex: 0]; - + if (firstChar == 'f' && [event modifierFlags] & NSAlternateKeyMask && [event modifierFlags] & NSCommandKeyMask) [fController focusFilterField]; else if (firstChar == ' ') @@ -556,7 +556,7 @@ - (BOOL) validateMenuItem: (NSMenuItem *) menuItem { SEL action = [menuItem action]; - + if (action == @selector(paste:)) { if ([[[NSPasteboard generalPasteboard] types] containsObject: NSURLPboardType]) @@ -574,10 +574,10 @@ return YES; } } - + return NO; } - + return YES; } @@ -601,24 +601,24 @@ const NSInteger row = [self rowAtPoint: [self convertPoint: [event locationInWindow] fromView: nil]]; if (row < 0) return; - + const NSRect rect = [fTorrentCell iconRectForBounds: [self rectOfRow: row]]; if (fActionPopoverShown) return; - + Torrent * torrent = [self itemAtRow: row]; - + NSPopover * popover = [[NSPopover alloc] init]; [popover setBehavior: NSPopoverBehaviorTransient]; InfoOptionsViewController * infoViewController = [[InfoOptionsViewController alloc] init]; [popover setContentViewController: infoViewController]; [popover setDelegate: self]; - + [popover showRelativeToRect: rect ofView: self preferredEdge: NSMaxYEdge]; [infoViewController setInfoForTorrents: [NSArray arrayWithObject: torrent]]; [infoViewController updateInfo]; - + [infoViewController release]; [popover release]; } @@ -640,7 +640,7 @@ //this method seems to be called when it shouldn't be if (!fMenuTorrent || ![menu supermenu]) return; - + if (menu == fUploadMenu || menu == fDownloadMenu) { NSMenuItem * item; @@ -648,7 +648,7 @@ { const NSInteger speedLimitActionValue[] = { 0, 5, 10, 20, 30, 40, 50, 75, 100, 150, 200, 250, 500, 750, 1000, 1500, 2000, -1 }; - + for (NSInteger i = 0; speedLimitActionValue[i] != -1; i++) { item = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: NSLocalizedString(@"%d KB/s", @@ -660,15 +660,15 @@ [item release]; } } - + const BOOL upload = menu == fUploadMenu; const BOOL limit = [fMenuTorrent usesSpeedLimit: upload]; - + item = [menu itemWithTag: ACTION_MENU_LIMIT_TAG]; [item setState: limit ? NSOnState : NSOffState]; [item setTitle: [NSString stringWithFormat: NSLocalizedString(@"Limit (%d KB/s)", "torrent action menu -> upload/download limit"), [fMenuTorrent speedLimit: upload]]]; - + item = [menu itemWithTag: ACTION_MENU_UNLIMITED_TAG]; [item setState: !limit ? NSOnState : NSOffState]; } @@ -678,7 +678,7 @@ if ([menu numberOfItems] == 4) { const float ratioLimitActionValue[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, -1.0 }; - + for (NSInteger i = 0; ratioLimitActionValue[i] != -1.0; i++) { item = [[NSMenuItem alloc] initWithTitle: [NSString localizedStringWithFormat: @"%.2f", ratioLimitActionValue[i]] @@ -689,30 +689,30 @@ [item release]; } } - + const tr_ratiolimit mode = [fMenuTorrent ratioSetting]; - + item = [menu itemWithTag: ACTION_MENU_LIMIT_TAG]; [item setState: mode == TR_RATIOLIMIT_SINGLE ? NSOnState : NSOffState]; [item setTitle: [NSString localizedStringWithFormat: NSLocalizedString(@"Stop at Ratio (%.2f)", "torrent action menu -> ratio stop"), [fMenuTorrent ratioLimit]]]; - + item = [menu itemWithTag: ACTION_MENU_UNLIMITED_TAG]; [item setState: mode == TR_RATIOLIMIT_UNLIMITED ? NSOnState : NSOffState]; - + item = [menu itemWithTag: ACTION_MENU_GLOBAL_TAG]; [item setState: mode == TR_RATIOLIMIT_GLOBAL ? NSOnState : NSOffState]; } else if (menu == fPriorityMenu) { const tr_priority_t priority = [fMenuTorrent priority]; - + NSMenuItem * item = [menu itemWithTag: ACTION_MENU_PRIORITY_HIGH_TAG]; [item setState: priority == TR_PRI_HIGH ? NSOnState : NSOffState]; - + item = [menu itemWithTag: ACTION_MENU_PRIORITY_NORMAL_TAG]; [item setState: priority == TR_PRI_NORMAL ? NSOnState : NSOffState]; - + item = [menu itemWithTag: ACTION_MENU_PRIORITY_LOW_TAG]; [item setState: priority == TR_PRI_LOW ? NSOnState : NSOffState]; } @@ -723,7 +723,7 @@ { const BOOL limit = [sender tag] == ACTION_MENU_LIMIT_TAG; [fMenuTorrent setUseSpeedLimit: limit upload: [sender menu] == fUploadMenu]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptions" object: nil]; } @@ -732,14 +732,14 @@ const BOOL upload = [sender menu] == fUploadMenu; [fMenuTorrent setUseSpeedLimit: YES upload: upload]; [fMenuTorrent setSpeedLimit: [[sender representedObject] intValue] upload: upload]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptions" object: nil]; } - (void) setGlobalLimit: (id) sender { [fMenuTorrent setUseGlobalSpeedLimit: [(NSButton *)sender state] != NSOnState]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptions" object: nil]; } @@ -760,9 +760,9 @@ default: return; } - + [fMenuTorrent setRatioSetting: mode]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptions" object: nil]; } @@ -770,7 +770,7 @@ { [fMenuTorrent setRatioSetting: TR_RATIOLIMIT_SINGLE]; [fMenuTorrent setRatioLimit: [[sender representedObject] floatValue]]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptions" object: nil]; } @@ -792,9 +792,9 @@ NSAssert1(NO, @"Unknown priority: %ld", [sender tag]); priority = TR_PRI_NORMAL; } - + [fMenuTorrent setPriority: priority]; - + [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil]; } @@ -803,14 +803,14 @@ NSMutableArray * progressMarks = [NSMutableArray arrayWithCapacity: 16]; for (NSAnimationProgress i = 0.0625; i <= 1.0; i += 0.0625) [progressMarks addObject: [NSNumber numberWithFloat: i]]; - + //this stops a previous animation [fPiecesBarAnimation release]; fPiecesBarAnimation = [[NSAnimation alloc] initWithDuration: TOGGLE_PROGRESS_SECONDS animationCurve: NSAnimationEaseIn]; [fPiecesBarAnimation setAnimationBlockingMode: NSAnimationNonblocking]; [fPiecesBarAnimation setProgressMarks: progressMarks]; [fPiecesBarAnimation setDelegate: self]; - + [fPiecesBarAnimation startAnimation]; } @@ -831,7 +831,7 @@ fPiecesBarPercent = progress; else fPiecesBarPercent = 1.0 - progress; - + [self setNeedsDisplay: YES]; } } @@ -845,9 +845,9 @@ { NSParameterAssert(row >= 0); NSParameterAssert(row < [self numberOfRows]); - + [self selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO]; - + const NSRect rowRect = [self rectOfRow: row]; const NSRect viewRect = [[self superview] frame]; @@ -868,7 +868,7 @@ NSInteger row = [self rowAtPoint: point]; if (row < 0 || [[self itemAtRow: row] isKindOfClass: [Torrent class]]) return NO; - + NSString * ident = [[[self tableColumns] objectAtIndex: [self columnAtPoint: point]] identifier]; return [ident isEqualToString: @"UL"] || [ident isEqualToString: @"UL Image"] || [ident isEqualToString: @"DL"] || [ident isEqualToString: @"DL Image"]; @@ -877,7 +877,7 @@ - (void) setGroupStatusColumns { const BOOL ratio = [fDefaults boolForKey: @"DisplayGroupRowRatio"]; - + [[self tableColumnWithIdentifier: @"DL"] setHidden: ratio]; [[self tableColumnWithIdentifier: @"DL Image"] setHidden: ratio]; } diff --git a/macosx/TrackerCell.m b/macosx/TrackerCell.m index f2353b7a4..e4e8ce942 100644 --- a/macosx/TrackerCell.m +++ b/macosx/TrackerCell.m @@ -72,15 +72,15 @@ NSMutableSet * fTrackerIconLoading; { NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [paragraphStyle setLineBreakMode: NSLineBreakByTruncatingTail]; - + fNameAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys: [NSFont messageFontOfSize: 12.0], NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; - + fStatusAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys: [NSFont messageFontOfSize: 9.0], NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; - + [paragraphStyle release]; } return self; @@ -90,17 +90,17 @@ NSMutableSet * fTrackerIconLoading; { [fNameAttributes release]; [fStatusAttributes release]; - + [super dealloc]; } - (id) copyWithZone: (NSZone *) zone { TrackerCell * copy = [super copyWithZone: zone]; - + copy->fNameAttributes = [fNameAttributes retain]; copy->fStatusAttributes = [fStatusAttributes retain]; - + return copy; } @@ -118,60 +118,60 @@ NSMutableSet * fTrackerIconLoading; nameColor = [NSColor controlTextColor]; statusColor = [NSColor darkGrayColor]; } - + [fNameAttributes setObject: nameColor forKey: NSForegroundColorAttributeName]; [fStatusAttributes setObject: statusColor forKey: NSForegroundColorAttributeName]; - + TrackerNode * node = (TrackerNode *)[self objectValue]; - + //name NSAttributedString * nameString = [self attributedName]; const NSRect nameRect = [self rectForNameWithString: nameString inBounds: cellFrame]; [nameString drawInRect: nameRect]; - + //count strings NSAttributedString * seederString = [self attributedCount: [node totalSeeders]]; const NSRect seederRect = [self rectForCountWithString: seederString withAboveRect: nameRect inBounds: cellFrame]; [seederString drawInRect: seederRect]; - + NSAttributedString * leecherString = [self attributedCount: [node totalLeechers]]; const NSRect leecherRect = [self rectForCountWithString: leecherString withAboveRect: seederRect inBounds: cellFrame]; [leecherString drawInRect: leecherRect]; - + NSAttributedString * downloadedString = [self attributedCount: [node totalDownloaded]]; const NSRect downloadedRect = [self rectForCountWithString: downloadedString withAboveRect: leecherRect inBounds: cellFrame]; [downloadedString drawInRect: downloadedRect]; - + //count label strings NSString * seederLabelBaseString = [NSLocalizedString(@"Seeders", "tracker peer stat") stringByAppendingFormat: @": "]; NSAttributedString * seederLabelString = [self attributedStatusWithString: seederLabelBaseString]; const NSRect seederLabelRect = [self rectForCountLabelWithString: seederLabelString withRightRect: seederRect inBounds: cellFrame]; [seederLabelString drawInRect: seederLabelRect]; - + NSString * leecherLabelBaseString = [NSLocalizedString(@"Leechers", "tracker peer stat") stringByAppendingFormat: @": "]; NSAttributedString * leecherLabelString = [self attributedStatusWithString: leecherLabelBaseString]; const NSRect leecherLabelRect = [self rectForCountLabelWithString: leecherLabelString withRightRect: leecherRect inBounds: cellFrame]; [leecherLabelString drawInRect: leecherLabelRect]; - + NSString * downloadedLabelBaseString = [NSLocalizedString(@"Downloaded", "tracker peer stat") stringByAppendingFormat: @": "]; NSAttributedString * downloadedLabelString = [self attributedStatusWithString: downloadedLabelBaseString]; const NSRect downloadedLabelRect = [self rectForCountLabelWithString: downloadedLabelString withRightRect: downloadedRect inBounds: cellFrame]; [downloadedLabelString drawInRect: downloadedLabelRect]; - + //status strings NSAttributedString * lastAnnounceString = [self attributedStatusWithString: [node lastAnnounceStatusString]]; const NSRect lastAnnounceRect = [self rectForStatusWithString: lastAnnounceString withAboveRect: nameRect withRightRect: seederLabelRect inBounds: cellFrame]; [lastAnnounceString drawInRect: lastAnnounceRect]; - + NSAttributedString * nextAnnounceString = [self attributedStatusWithString: [node nextAnnounceStatusString]]; const NSRect nextAnnounceRect = [self rectForStatusWithString: nextAnnounceString withAboveRect: lastAnnounceRect withRightRect: leecherLabelRect inBounds: cellFrame]; [nextAnnounceString drawInRect: nextAnnounceRect]; - + NSAttributedString * lastScrapeString = [self attributedStatusWithString: [node lastScrapeStatusString]]; const NSRect lastScrapeRect = [self rectForStatusWithString: lastScrapeString withAboveRect: nextAnnounceRect withRightRect: downloadedLabelRect inBounds: cellFrame]; @@ -191,9 +191,9 @@ NSMutableSet * fTrackerIconLoading; { //don't try to parse ip address const BOOL separable = !tr_addressIsIP([host UTF8String]); - + NSArray * hostComponents = separable ? [host componentsSeparatedByString: @"."] : nil; - + //let's try getting the tracker address without using any subdomains NSString * baseAddress; if (separable && [hostComponents count] > 1) @@ -201,7 +201,7 @@ NSMutableSet * fTrackerIconLoading; [hostComponents objectAtIndex: [hostComponents count]-2], [hostComponents lastObject]]; else baseAddress = [NSString stringWithFormat: @"http://%@", host]; - + icon = [fTrackerIconCache objectForKey: baseAddress]; if (!icon && ![fTrackerIconLoading containsObject: baseAddress]) { @@ -209,7 +209,7 @@ NSMutableSet * fTrackerIconLoading; [NSThread detachNewThreadSelector: @selector(loadTrackerIcon:) toTarget: self withObject: baseAddress]; } } - + return (icon && icon != [NSNull null]) ? icon : [NSImage imageNamed: @"FavIcon"]; } @@ -220,33 +220,33 @@ NSMutableSet * fTrackerIconLoading; { //try favicon.png NSURL * favIconUrl = [NSURL URLWithString: [baseAddress stringByAppendingPathComponent: @"favicon.png"]]; - + NSURLRequest * request = [NSURLRequest requestWithURL: favIconUrl cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval: 30.0]; NSData * iconData = [NSURLConnection sendSynchronousRequest: request returningResponse: NULL error: NULL]; NSImage * icon = [[NSImage alloc] initWithData: iconData]; - + //try favicon.ico if (!icon) { favIconUrl = [NSURL URLWithString: [baseAddress stringByAppendingPathComponent: @"favicon.ico"]]; - + request = [NSURLRequest requestWithURL: favIconUrl cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval: 30.0]; iconData = [NSURLConnection sendSynchronousRequest: request returningResponse: NULL error: NULL]; icon = [[NSImage alloc] initWithData: iconData]; } - + if (icon) { [fTrackerIconCache setObject: icon forKey: baseAddress]; [icon release]; - + [[self controlView] setNeedsDisplay: YES]; } else [fTrackerIconCache setObject: [NSNull null] forKey: baseAddress]; - + [fTrackerIconLoading removeObject: baseAddress]; } } @@ -261,10 +261,10 @@ NSMutableSet * fTrackerIconLoading; NSRect result; result.origin.x = NSMinX(bounds) + PADDING_HORIZONAL + ICON_SIZE + PADDING_BETWEEN_ICON_AND_NAME; result.origin.y = NSMinY(bounds) + PADDING_ABOVE_NAME; - + result.size.height = [string size].height; result.size.width = NSMaxX(bounds) - NSMinX(result) - PADDING_HORIZONAL; - + return result; } @@ -280,7 +280,7 @@ NSMutableSet * fTrackerIconLoading; NSRect result = rightRect; result.size.width = [string size].width; result.origin.x -= NSWidth(result); - + return result; } @@ -290,10 +290,10 @@ NSMutableSet * fTrackerIconLoading; NSRect result; result.origin.x = NSMinX(bounds) + PADDING_STATUS_HORIZONAL; result.origin.y = NSMaxY(aboveRect) + PADDING_BETWEEN_LINES; - + result.size.height = [string size].height; result.size.width = NSMinX(rightRect) - PADDING_BETWEEN_LINES_ON_SAME_LINE - NSMinX(result); - + return result; } diff --git a/macosx/TrackerNode.h b/macosx/TrackerNode.h index 48d82d90b..25777dfa3 100644 --- a/macosx/TrackerNode.h +++ b/macosx/TrackerNode.h @@ -28,7 +28,7 @@ @interface TrackerNode : NSObject { tr_tracker_stat fStat; - + Torrent * fTorrent; } diff --git a/macosx/TrackerNode.m b/macosx/TrackerNode.m index bbff9c9a1..6879a6d3f 100644 --- a/macosx/TrackerNode.m +++ b/macosx/TrackerNode.m @@ -36,7 +36,7 @@ fStat = *stat; fTorrent = torrent; //weak reference } - + return self; } @@ -55,13 +55,13 @@ { if (self == object) return YES; - + if (![object isKindOfClass: [self class]]) return NO; - + if ([self torrent] != [object torrent]) return NO; - + return [self tier] == [object tier] && [[self fullAnnounceAddress] isEqualToString: [object fullAnnounceAddress]]; } @@ -109,20 +109,20 @@ [dateFormatter setDateStyle: NSDateFormatterFullStyle]; [dateFormatter setTimeStyle: NSDateFormatterShortStyle]; [dateFormatter setDoesRelativeDateFormatting: YES]; - + dateString = [dateFormatter stringFromDate: [NSDate dateWithTimeIntervalSince1970: fStat.lastAnnounceTime]]; [dateFormatter release]; } else dateString = NSLocalizedString(@"N/A", "Tracker last announce"); - + NSString * baseString; if (fStat.hasAnnounced && fStat.lastAnnounceTimedOut) baseString = [NSLocalizedString(@"Announce timed out", "Tracker last announce") stringByAppendingFormat: @": %@", dateString]; else if (fStat.hasAnnounced && !fStat.lastAnnounceSucceeded) { baseString = NSLocalizedString(@"Announce error", "Tracker last announce"); - + NSString * errorString = [NSString stringWithUTF8String: fStat.lastAnnounceResult]; if ([errorString isEqualToString: @""]) baseString = [baseString stringByAppendingFormat: @": %@", dateString]; @@ -143,7 +143,7 @@ baseString = [baseString stringByAppendingFormat: @" (%@)", peerString]; } } - + return baseString; } @@ -153,11 +153,11 @@ { case TR_TRACKER_ACTIVE: return [NSLocalizedString(@"Announce in progress", "Tracker next announce") stringByAppendingEllipsis]; - + case TR_TRACKER_WAITING: { const NSTimeInterval nextAnnounceTimeLeft = fStat.nextAnnounceTime - [[NSDate date] timeIntervalSince1970]; - + NSString *timeString; if ([NSApp isOnYosemiteOrBetter]) { static NSDateComponentsFormatter *formatter; @@ -168,7 +168,7 @@ formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDropLeading; formatter.collapsesLargestUnit = YES; }); - + timeString = [formatter stringFromTimeInterval: nextAnnounceTimeLeft]; } else { @@ -179,11 +179,11 @@ } case TR_TRACKER_QUEUED: return [NSLocalizedString(@"Announce is queued", "Tracker next announce") stringByAppendingEllipsis]; - + case TR_TRACKER_INACTIVE: return fStat.isBackup ? NSLocalizedString(@"Tracker will be used as a backup", "Tracker next announce") : NSLocalizedString(@"Announce not scheduled", "Tracker next announce"); - + default: NSAssert1(NO, @"unknown announce state: %d", fStat.announceState); return nil; @@ -199,20 +199,20 @@ [dateFormatter setDateStyle: NSDateFormatterFullStyle]; [dateFormatter setTimeStyle: NSDateFormatterShortStyle]; [dateFormatter setDoesRelativeDateFormatting: YES]; - + dateString = [dateFormatter stringFromDate: [NSDate dateWithTimeIntervalSince1970: fStat.lastScrapeTime]]; [dateFormatter release]; } else dateString = NSLocalizedString(@"N/A", "Tracker last scrape"); - + NSString * baseString; if (fStat.hasScraped && fStat.lastScrapeTimedOut) baseString = [NSLocalizedString(@"Scrape timed out", "Tracker last scrape") stringByAppendingFormat: @": %@", dateString]; else if (fStat.hasScraped && !fStat.lastScrapeSucceeded) { baseString = NSLocalizedString(@"Scrape error", "Tracker last scrape"); - + NSString * errorString = [NSString stringWithUTF8String: fStat.lastScrapeResult]; if ([errorString isEqualToString: @""]) baseString = [baseString stringByAppendingFormat: @": %@", dateString]; @@ -221,7 +221,7 @@ } else baseString = [NSLocalizedString(@"Last Scrape", "Tracker last scrape") stringByAppendingFormat: @": %@", dateString]; - + return baseString; } diff --git a/macosx/TrackerTableView.m b/macosx/TrackerTableView.m index f52750450..37057d50f 100644 --- a/macosx/TrackerTableView.m +++ b/macosx/TrackerTableView.m @@ -58,9 +58,9 @@ else [addresses addObject: [(TrackerNode *)item fullAnnounceAddress]]; } - + NSString * text = [addresses componentsJoinedByString: @"\n"]; - + NSPasteboard * pb = [NSPasteboard generalPasteboard]; [pb clearContents]; [pb writeObjects: [NSArray arrayWithObject: text]]; @@ -69,19 +69,19 @@ - (void) paste: (id) sender { NSAssert(fTorrent != nil, @"no torrent but trying to paste; should not be able to call this method"); - + BOOL added = NO; - + NSArray * items = [[NSPasteboard generalPasteboard] readObjectsForClasses: [NSArray arrayWithObject: [NSString class]] options: nil]; NSAssert(items != nil, @"no string items to paste; should not be able to call this method"); - + for (NSString * pbItem in items) { for (NSString * item in [pbItem componentsSeparatedByString: @"\n"]) if ([fTorrent addTrackerToNewTier: item]) added = YES; } - + //none added if (!added) NSBeep(); @@ -90,13 +90,13 @@ - (BOOL) validateMenuItem: (NSMenuItem *) menuItem { const SEL action = [menuItem action]; - + if (action == @selector(copy:)) return [self numberOfSelectedRows] > 0; - + if (action == @selector(paste:)) return fTorrent && [[NSPasteboard generalPasteboard] canReadObjectForClasses: [NSArray arrayWithObject: [NSString class]] options: nil]; - + return YES; } diff --git a/macosx/URLSheetWindowController.h b/macosx/URLSheetWindowController.h index 21acd214f..f77f29ad7 100644 --- a/macosx/URLSheetWindowController.h +++ b/macosx/URLSheetWindowController.h @@ -26,10 +26,10 @@ @interface URLSheetWindowController : NSWindowController { - IBOutlet NSTextField * fLabelField; + IBOutlet NSTextField * fLabelField; IBOutlet NSTextField * fTextField; IBOutlet NSButton * fOpenButton, * fCancelButton; - + Controller * fController; } diff --git a/macosx/URLSheetWindowController.m b/macosx/URLSheetWindowController.m index b662f5e69..21d13ca25 100644 --- a/macosx/URLSheetWindowController.m +++ b/macosx/URLSheetWindowController.m @@ -45,35 +45,35 @@ NSString * urlString = nil; - (void) awakeFromNib { [fLabelField setStringValue: NSLocalizedString(@"Internet address of torrent file:", "URL sheet label")]; - + if (urlString) { [fTextField setStringValue: urlString]; [fTextField selectText: self]; - + [self updateOpenButtonForURL: urlString]; } - + [fOpenButton setTitle: NSLocalizedString(@"Open", "URL sheet button")]; [fCancelButton setTitle: NSLocalizedString(@"Cancel", "URL sheet button")]; - + [fOpenButton sizeToFit]; [fCancelButton sizeToFit]; - + //size the two buttons the same NSRect openFrame = [fOpenButton frame]; openFrame.size.width += 10.0; NSRect cancelFrame = [fCancelButton frame]; cancelFrame.size.width += 10.0; - + if (NSWidth(openFrame) > NSWidth(cancelFrame)) cancelFrame.size.width = NSWidth(openFrame); else openFrame.size.width = NSWidth(cancelFrame); - + openFrame.origin.x = NSWidth([[self window] frame]) - NSWidth(openFrame) - 20.0 + 6.0; //I don't know why the extra 6.0 is needed [fOpenButton setFrame: openFrame]; - + cancelFrame.origin.x = NSMinX(openFrame) - NSWidth(cancelFrame); [fCancelButton setFrame: cancelFrame]; } @@ -115,7 +115,7 @@ NSString * urlString = nil; if (prefixRange.location != NSNotFound && [string length] == NSMaxRange(prefixRange)) enable = NO; } - + [fOpenButton setEnabled: enable]; } diff --git a/macosx/WebSeedTableView.m b/macosx/WebSeedTableView.m index 2a2bd9f87..7a83938b4 100644 --- a/macosx/WebSeedTableView.m +++ b/macosx/WebSeedTableView.m @@ -42,9 +42,9 @@ [fWebSeeds enumerateObjectsAtIndexes: indexes options: 0 usingBlock: ^(NSDictionary * webSeed, NSUInteger idx, BOOL * stop) { [addresses addObject: [webSeed objectForKey: @"Address"]]; }]; - + NSString * text = [addresses componentsJoinedByString: @"\n"]; - + NSPasteboard * pb = [NSPasteboard generalPasteboard]; [pb clearContents]; [pb writeObjects: [NSArray arrayWithObject: text]]; @@ -53,10 +53,10 @@ - (BOOL) validateMenuItem: (NSMenuItem *) menuItem { const SEL action = [menuItem action]; - + if (action == @selector(copy:)) return [self numberOfSelectedRows] > 0; - + return YES; }