First commit on my own 8-)

Sorting by progress, sorting no longer causes crashes.
New look for the table.
Info is now inspector: can set individual and multiple ratio limits, shows listing of files, more info in general, resizes when changing tabs, can change tabs with cmd-left and cmd-right.
Menu items moved to "Transfers" menu.
Sliding status bar in its own view.
Prefs moved into their own nib.
Toolbar items for pause and resume selected (many wanted this, but it needs better icons)
New icons for Transfers and General.
A lot of tweaking of main window to fix alignment etc.
Sparkle used for updated (still needs to be added to website to work).

And a lot more tweaking and changes that I'm too lazy to list.

...now let's hope I commit this right
This commit is contained in:
Mitchell Livingston 2006-06-06 18:05:57 +00:00
parent e9b1a6bf2d
commit 41ce603b10
97 changed files with 2560 additions and 926 deletions

1
Sparkle.framework/Headers Symbolic link
View File

@ -0,0 +1 @@
Versions/Current/Headers

1
Sparkle.framework/Resources Symbolic link
View File

@ -0,0 +1 @@
Versions/Current/Resources

1
Sparkle.framework/Sparkle Symbolic link
View File

@ -0,0 +1 @@
Versions/Current/Sparkle

View File

@ -0,0 +1,13 @@
//
// NSApplication+AppCopies.h
// Sparkle
//
// Created by Andy Matuschak on 3/16/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface NSApplication (SUAppCopies)
- (int)copiesRunning;
@end

View File

@ -0,0 +1,11 @@
//
// NSFileManager+Authentication.m
// Sparkle
//
// Created by Andy Matuschak on 3/9/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
@interface NSFileManager (SUAuthenticationAdditions)
- (BOOL)movePathWithAuthentication:(NSString *)src toPath:(NSString *)dst;
@end

View File

@ -0,0 +1,15 @@
//
// NSFileManager+Verification.h
// Sparkle
//
// Created by Andy Matuschak on 3/16/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
// For the paranoid folks!
@interface NSFileManager (SUVerification)
- (BOOL)validatePath:(NSString *)path withMD5Hash:(NSString *)hash;
- (BOOL)validatePath:(NSString *)path withEncodedDSASignature:(NSString *)encodedSignature;
@end

View File

@ -0,0 +1,61 @@
/*
BSD License
Copyright (c) 2002, Brent Simmons
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of ranchero.com or Brent Simmons nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
NSString+extras.h
NetNewsWire
Created by Brent Simmons on Fri Jun 14 2002.
Copyright (c) 2002 Brent Simmons. All rights reserved.
*/
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
@interface NSString (extras)
- (NSString *)stringWithSubstitute:(NSString *)subs forCharactersFromSet:(NSCharacterSet *)set;
- (NSString *) trimWhiteSpace;
- (NSString *) stripHTML;
- (NSString *) ellipsizeAfterNWords: (int) n;
+ (BOOL) stringIsEmpty: (NSString *) s;
@end

View File

@ -0,0 +1,98 @@
/*
BSD License
Copyright (c) 2002, Brent Simmons
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of ranchero.com or Brent Simmons nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
RSS.h
A class for reading RSS feeds.
Created by Brent Simmons on Wed Apr 17 2002.
Copyright (c) 2002 Brent Simmons. All rights reserved.
*/
#import <Cocoa/Cocoa.h>
#import <CoreFoundation/CoreFoundation.h>
#import "NSString+extras.h"
@interface RSS : NSObject {
NSDictionary *headerItems;
NSMutableArray *newsItems;
NSString *version;
BOOL flRdf;
BOOL normalize;
}
/*Public*/
- (RSS *) initWithTitle: (NSString *) title andDescription: (NSString *) description;
- (RSS *) initWithData: (NSData *) rssData normalize: (BOOL) fl;
- (RSS *) initWithURL: (NSURL *) url normalize: (BOOL) fl;
- (RSS *) initWithURL: (NSURL *) url normalize: (BOOL) fl userAgent:(NSString *)userAgent;
- (NSDictionary *) headerItems;
- (NSMutableArray *) newsItems;
- (NSString *) version;
// AMM's extensions for Sparkle
- (NSDictionary *)newestItem;
/*Private*/
- (void) createheaderdictionary: (CFXMLTreeRef) tree;
- (void) createitemsarray: (CFXMLTreeRef) tree;
- (void) setversionstring: (CFXMLTreeRef) tree;
- (void) flattenimagechildren: (CFXMLTreeRef) tree into: (NSMutableDictionary *) dictionary;
- (void) flattensourceattributes: (CFXMLNodeRef) node into: (NSMutableDictionary *) dictionary;
- (CFXMLTreeRef) getchanneltree: (CFXMLTreeRef) tree;
- (CFXMLTreeRef) getnamedtree: (CFXMLTreeRef) currentTree name: (NSString *) name;
- (void) normalizeRSSItem: (NSMutableDictionary *) rssItem;
- (NSString *) getelementvalue: (CFXMLTreeRef) tree;
@end

View File

@ -0,0 +1,27 @@
//
// SUAppcast.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@class RSS, SUAppcastItem;
@interface SUAppcast : NSObject {
NSArray *items;
id delegate;
}
- (void)fetchAppcastFromURL:(NSURL *)url;
- (void)setDelegate:delegate;
- (SUAppcastItem *)newestItem;
- (NSArray *)items;
@end
@interface NSObject (SUAppcastDelegate)
- appcastDidFinishLoading:(SUAppcast *)appcast;
@end

View File

@ -0,0 +1,53 @@
//
// SUAppcastItem.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface SUAppcastItem : NSObject {
NSString *title;
NSDate *date;
NSString *description;
NSURL *releaseNotesURL;
NSString *DSASignature;
NSString *MD5Sum;
NSURL *fileURL;
NSString *fileVersion;
}
// Initializes with data from a dictionary provided by the RSS class.
- initWithDictionary:(NSDictionary *)dict;
- (NSString *)title;
- (void)setTitle:(NSString *)aTitle;
- (NSDate *)date;
- (void)setDate:(NSDate *)aDate;
- (NSString *)description;
- (void)setDescription:(NSString *)aDescription;
- (NSURL *)releaseNotesURL;
- (void)setReleaseNotesURL:(NSURL *)aReleaseNotesURL;
- (NSString *)DSASignature;
- (void)setDSASignature:(NSString *)aDSASignature;
- (NSString *)MD5Sum;
- (void)setMD5Sum:(NSString *)aMd5Sum;
- (NSURL *)fileURL;
- (void)setFileURL:(NSURL *)aFileURL;
- (NSString *)fileVersion;
- (void)setFileVersion:(NSString *)aFileVersion;
@end

View File

@ -0,0 +1,21 @@
//
// SUAutomaticUpdateAlert.h
// Sparkle
//
// Created by Andy Matuschak on 3/18/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@class SUAppcastItem;
@interface SUAutomaticUpdateAlert : NSWindowController {
SUAppcastItem *updateItem;
}
- initWithAppcastItem:(SUAppcastItem *)item;
- (IBAction)relaunchNow:sender;
- (IBAction)relaunchLater:sender;
@end

View File

@ -0,0 +1,20 @@
//
// SUConstants.h
// Sparkle
//
// Created by Andy Matuschak on 3/16/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
extern NSString *SUUpdaterWillRestartNotification;
extern NSString *SUCheckAtStartupKey;
extern NSString *SUFeedURLKey;
extern NSString *SUShowReleaseNotesKey;
extern NSString *SUSkippedVersionKey;
extern NSString *SUScheduledCheckIntervalKey;
extern NSString *SULastCheckTimeKey;
extern NSString *SUExpectsDSASignatureKey;
extern NSString *SUPublicDSAKeyKey;
extern NSString *SUAutomaticallyUpdateKey;
extern NSString *SUAllowsAutomaticUpdatesKey;

View File

@ -0,0 +1,33 @@
//
// SUStatusController.h
// Sparkle
//
// Created by Andy Matuschak on 3/14/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface SUStatusController : NSWindowController {
double progressValue, maxProgressValue;
NSString *title, *statusText, *buttonTitle;
IBOutlet NSButton *actionButton;
}
// Pass 0 for the max progress value to get an indeterminate progress bar.
// Pass nil for the status text to not show it.
- (void)beginActionWithTitle:(NSString *)title maxProgressValue:(double)maxProgressValue statusText:(NSString *)statusText;
// If isDefault is YES, the button's key equivalent will be \r.
- (void)setButtonTitle:(NSString *)buttonTitle target:target action:(SEL)action isDefault:(BOOL)isDefault;
- (void)setButtonEnabled:(BOOL)enabled;
- (double)progressValue;
- (void)setProgressValue:(double)value;
- (double)maxProgressValue;
- (void)setMaxProgressValue:(double)value;
- (void)setStatusText:(NSString *)statusText;
@end

View File

@ -0,0 +1,25 @@
//
// SUUnarchiver.h
// Sparkle
//
// Created by Andy Matuschak on 3/16/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface SUUnarchiver : NSObject {
id delegate;
}
- (void)unarchivePath:(NSString *)path;
- (void)setDelegate:delegate;
@end
@interface NSObject (SUUnarchiverDelegate)
- (void)unarchiver:(SUUnarchiver *)unarchiver extractedLength:(long)length;
- (void)unarchiverDidFinish:(SUUnarchiver *)unarchiver;
- (void)unarchiverDidFail:(SUUnarchiver *)unarchiver;
@end

View File

@ -0,0 +1,40 @@
//
// SUUpdateAlert.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
typedef enum
{
SUInstallUpdateChoice,
SURemindMeLaterChoice,
SUSkipThisVersionChoice
} SUUpdateAlertChoice;
@class WebView, SUAppcastItem;
@interface SUUpdateAlert : NSWindowController {
SUAppcastItem *updateItem;
id delegate;
IBOutlet WebView *releaseNotesView;
IBOutlet NSTextField *description;
NSProgressIndicator *releaseNotesSpinner;
BOOL webViewFinishedLoading;
}
- initWithAppcastItem:(SUAppcastItem *)item;
- (void)setDelegate:delegate;
- (IBAction)installUpdate:sender;
- (IBAction)skipThisVersion:sender;
- (IBAction)remindMeLater:sender;
@end
@interface NSObject (SUUpdateAlertDelegate)
- (void)updateAlert:(SUUpdateAlert *)updateAlert finishedWithChoice:(SUUpdateAlertChoice)updateChoice;
@end

View File

@ -0,0 +1,55 @@
//
// SUUpdater.h
// Sparkle
//
// Created by Andy Matuschak on 1/4/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
// Before you use Sparkle in your app, you must set SUFeedURL in Info.plist to the
// address of the appcast on your webserver. If you don't already have an
// appcast, please see the Sparkle documentation to learn about how to set one up.
// .zip, .dmg, .tar, .tbz, .tgz archives are supported at this time.
// By default, Sparkle offers to show the user the release notes of the build they'll be
// getting, which it assumes are in the description (or body) field of the relevant RSS item.
// Set SUShowReleaseNotes to <false/> in Info.plist to hide the button.
@class SUAppcastItem, SUUpdateAlert, SUStatusController;
@interface SUUpdater : NSObject {
SUAppcastItem *updateItem;
SUStatusController *statusController;
SUUpdateAlert *updateAlert;
NSURLDownload *downloader;
NSString *downloadPath;
NSTimer *checkTimer;
NSTimeInterval checkInterval;
BOOL verbose;
BOOL updateInProgress;
}
// This IBAction is meant for a main menu item. Hook up any menu item to this action,
// and Sparkle will check for updates and report back its findings verbosely.
- (IBAction)checkForUpdates:sender;
// This method is similar to the above, but it's intended for updates initiated by
// the computer instead of by the user. It does not alert the user when he is up to date,
// and it remains silent about network errors in fetching the feed. This is what you
// want to call to update programmatically; only use checkForUpdates: with buttons and menu items.
- (void)checkForUpdatesInBackground;
// This method allows you to schedule a check to run every time interval. You can
// pass 0 to this method to cancel a previously scheduled timer. You probably don't want
// to call this directly: if you set a SUScheduledCheckInterval key in Info.plist or
// the user defaults, Sparkle will set this up for you automatically on startup. You might
// just want to call this every time the user changes the setting in the preferences.
- (void)scheduleCheckWithInterval:(NSTimeInterval)interval;
@end

View File

@ -0,0 +1,19 @@
//
// SUUtilities.h
// Sparkle
//
// Created by Andy Matuschak on 3/12/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
id SUInfoValueForKey(NSString *key);
NSString *SUHostAppName();
NSString *SUHostAppVersion();
NSString *SUHostAppVersionString();
NSComparisonResult SUStandardVersionComparison(NSString * versionA, NSString * versionB);
// If running make localizable-strings for genstrings, ignore the error on this line.
NSString *SULocalizedString(NSString *key, NSString *comment);

View File

@ -0,0 +1,21 @@
//
// Sparkle.h
// Sparkle
//
// Created by Andy Matuschak on 3/16/06.
// Copyright 2006 Andy Matuschak. All rights reserved.
//
#import "SUUpdater.h"
#import "SUUtilities.h"
#import "SUConstants.h"
#import "SUAppcast.h"
#import "SUAppcastItem.h"
#import "SUUpdateAlert.h"
#import "SUAutomaticUpdateAlert.h"
#import "SUStatusController.h"
#import "SUUnarchiver.h"
#import "NSApplication+AppCopies.h"
#import "NSFileManager+Authentication.h"
#import "NSFileManager+Verification.h"

View File

@ -0,0 +1,12 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {relaunchLater = id; relaunchNow = id; };
CLASS = SUAutomaticUpdateAlert;
LANGUAGE = ObjC;
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>188 110 356 240 0 0 1280 832 </string>
<key>IBFramework Version</key>
<string>443.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8H14</string>
</dict>
</plist>

View File

@ -0,0 +1,21 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; },
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlert;
LANGUAGE = ObjC;
OUTLETS = {delegate = id; description = id; releaseNotesView = WebView; };
SUPERCLASS = NSWindowController;
},
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlertController;
LANGUAGE = ObjC;
OUTLETS = {releaseNotesView = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>62 61 356 240 0 0 1280 832 </string>
<key>IBFramework Version</key>
<string>446.1</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8I127</string>
</dict>
</plist>

View File

@ -0,0 +1,21 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; },
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlert;
LANGUAGE = ObjC;
OUTLETS = {delegate = id; description = id; releaseNotesView = WebView; };
SUPERCLASS = NSWindowController;
},
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlertController;
LANGUAGE = ObjC;
OUTLETS = {releaseNotesView = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>62 61 356 240 0 0 1280 832 </string>
<key>IBFramework Version</key>
<string>443.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8I127</string>
</dict>
</plist>

View File

@ -0,0 +1,21 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; },
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlert;
LANGUAGE = ObjC;
OUTLETS = {delegate = id; description = id; releaseNotesView = WebView; };
SUPERCLASS = NSWindowController;
},
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlertController;
LANGUAGE = ObjC;
OUTLETS = {releaseNotesView = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>62 61 356 240 0 0 1280 832 </string>
<key>IBFramework Version</key>
<string>443.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8I127</string>
</dict>
</plist>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Sparkle</string>
<key>CFBundleIdentifier</key>
<string>org.andymatuschak.Sparkle</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Sparkle</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@ -0,0 +1,21 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; },
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlert;
LANGUAGE = ObjC;
OUTLETS = {delegate = id; description = id; releaseNotesView = WebView; };
SUPERCLASS = NSWindowController;
},
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlertController;
LANGUAGE = ObjC;
OUTLETS = {releaseNotesView = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>62 61 356 240 0 0 1280 832 </string>
<key>IBFramework Version</key>
<string>443.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8I127</string>
</dict>
</plist>

View File

@ -0,0 +1,21 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; },
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlert;
LANGUAGE = ObjC;
OUTLETS = {delegate = id; description = id; releaseNotesView = WebView; };
SUPERCLASS = NSWindowController;
},
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlertController;
LANGUAGE = ObjC;
OUTLETS = {releaseNotesView = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>62 61 356 240 0 0 1280 832 </string>
<key>IBFramework Version</key>
<string>443.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8I127</string>
</dict>
</plist>

View File

@ -0,0 +1,12 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
CLASS = SUStatusController;
LANGUAGE = ObjC;
OUTLETS = {actionButton = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>69 10 356 240 0 0 1280 832 </string>
<key>IBFramework Version</key>
<string>443.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8H14</string>
</dict>
</plist>

Binary file not shown.

View File

@ -0,0 +1,21 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = NSObject; LANGUAGE = ObjC; },
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlert;
LANGUAGE = ObjC;
OUTLETS = {delegate = id; description = id; releaseNotesView = WebView; };
SUPERCLASS = NSWindowController;
},
{
ACTIONS = {installUpdate = id; remindMeLater = id; skipThisVersion = id; };
CLASS = SUUpdateAlertController;
LANGUAGE = ObjC;
OUTLETS = {releaseNotesView = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>62 61 356 240 0 0 1280 832 </string>
<key>IBFramework Version</key>
<string>443.0</string>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<string>8I127</string>
</dict>
</plist>

Binary file not shown.

View File

@ -0,0 +1 @@
A

View File

@ -79,12 +79,23 @@
A200B9200A22798F007BBB1E /* InfoWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = A200B83A0A2263BA007BBB1E /* InfoWindowController.m */; };
A200B9B60A22893D007BBB1E /* InfoWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = A200B9620A227FD0007BBB1E /* InfoWindow.nib */; };
A21610FC0A050B1700E8E4C1 /* MenuButton.m in Sources */ = {isa = PBXBuildFile; fileRef = A21610FB0A050B1700E8E4C1 /* MenuButton.m */; };
A2173E1C0A33C1B300B0D8AB /* ActionButtonPressed.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2173E1B0A33C1B300B0D8AB /* ActionButtonPressed.tiff */; };
A21DFF100A292B2B007C5F76 /* Transfers.png in Resources */ = {isa = PBXBuildFile; fileRef = A21DFF0F0A292B2B007C5F76 /* Transfers.png */; };
A2495B6D0A2F697C0098B31F /* ResumeSelected.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2495B6B0A2F697C0098B31F /* ResumeSelected.tiff */; };
A2495B6E0A2F697D0098B31F /* PauseSelected.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2495B6C0A2F697C0098B31F /* PauseSelected.tiff */; };
A2519D490A2FADFC00479D0C /* SmoothAquaView.m in Sources */ = {isa = PBXBuildFile; fileRef = A2519D470A2FADFC00479D0C /* SmoothAquaView.m */; };
A2519D4A0A2FADFC00479D0C /* SmoothAquaView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A2519D480A2FADFC00479D0C /* SmoothAquaView.h */; };
A26D450B0A0503AC00A10BB3 /* peermessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D1838A309DEC0430047D688 /* peermessages.h */; };
A27A53570A06A76400E1F16F /* StatusSep.png in Resources */ = {isa = PBXBuildFile; fileRef = A27A53560A06A76400E1F16F /* StatusSep.png */; };
A27A53660A06AEDB00E1F16F /* StatusBorder.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A27A53650A06AEDB00E1F16F /* StatusBorder.tiff */; };
A2A84AD00A04FCD000C898D4 /* ActionButton.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2A84ACF0A04FCD000C898D4 /* ActionButton.tiff */; };
A289EB0C0A33C56D00B082A3 /* ButtonBorder.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A289EB0B0A33C56D00B082A3 /* ButtonBorder.tiff */; };
A28DBADC0A33C1D800F4B4A7 /* ActionButton.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A28DBADB0A33C1D800F4B4A7 /* ActionButton.tiff */; };
A2912C540A2956E80097A0CA /* PrefsWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = A2912C520A2956E80097A0CA /* PrefsWindow.nib */; };
A2BD40070A09BBEA008CCE96 /* bencode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D1838B709DEC0430047D688 /* bencode.h */; };
A2C655650A04FEDC00E9FD82 /* BottomBorder.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2C655640A04FEDC00E9FD82 /* BottomBorder.tiff */; };
A2D5CCFD0A2661590089A8C2 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2D5CCFC0A2661590089A8C2 /* Sparkle.framework */; };
A2D5CD100A2661610089A8C2 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = A2D5CCFC0A2661590089A8C2 /* Sparkle.framework */; };
A2F8951F0A2D4BA500ED2127 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = A2F8951E0A2D4BA500ED2127 /* Credits.rtf */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -104,6 +115,47 @@
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
A2D5CCDD0A265F790089A8C2 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A2D5CCF80A2660660089A8C2 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A2D5CD110A2661660089A8C2 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 7;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A2D5CD130A26616F0089A8C2 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
A2D5CD100A2661610089A8C2 /* Sparkle.framework in CopyFiles */,
A2519D4A0A2FADFC00479D0C /* SmoothAquaView.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = macosx/English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
@ -193,13 +245,23 @@
A200B9630A227FD0007BBB1E /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = macosx/English.lproj/InfoWindow.nib; sourceTree = "<group>"; };
A21610FA0A050B1700E8E4C1 /* MenuButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MenuButton.h; path = macosx/MenuButton.h; sourceTree = "<group>"; };
A21610FB0A050B1700E8E4C1 /* MenuButton.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = MenuButton.m; path = macosx/MenuButton.m; sourceTree = "<group>"; };
A2173E1B0A33C1B300B0D8AB /* ActionButtonPressed.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = ActionButtonPressed.tiff; path = macosx/Images/ActionButtonPressed.tiff; sourceTree = "<group>"; };
A21DFF0F0A292B2B007C5F76 /* Transfers.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Transfers.png; path = macosx/Images/Transfers.png; sourceTree = "<group>"; };
A2495B6B0A2F697C0098B31F /* ResumeSelected.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = ResumeSelected.tiff; path = macosx/Images/ResumeSelected.tiff; sourceTree = "<group>"; };
A2495B6C0A2F697C0098B31F /* PauseSelected.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = PauseSelected.tiff; path = macosx/Images/PauseSelected.tiff; sourceTree = "<group>"; };
A2519D470A2FADFC00479D0C /* SmoothAquaView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = SmoothAquaView.m; path = macosx/SmoothAquaView.m; sourceTree = "<group>"; };
A2519D480A2FADFC00479D0C /* SmoothAquaView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SmoothAquaView.h; path = macosx/SmoothAquaView.h; sourceTree = "<group>"; };
A27A53420A06A62500E1F16F /* StatusSep.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = StatusSep.png; path = macosx/Images/StatusSep.png; sourceTree = "<group>"; };
A27A53560A06A76400E1F16F /* StatusSep.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = StatusSep.png; path = macosx/Images/StatusSep.png; sourceTree = "<group>"; };
A27A53640A06AED200E1F16F /* StatusBorder.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = StatusBorder.tiff; path = macosx/Images/StatusBorder.tiff; sourceTree = "<group>"; };
A27A53650A06AEDB00E1F16F /* StatusBorder.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = StatusBorder.tiff; path = macosx/Images/StatusBorder.tiff; sourceTree = "<group>"; };
A2A84ACF0A04FCD000C898D4 /* ActionButton.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = ActionButton.tiff; path = macosx/Images/ActionButton.tiff; sourceTree = "<group>"; };
A289EB0B0A33C56D00B082A3 /* ButtonBorder.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = ButtonBorder.tiff; path = macosx/Images/ButtonBorder.tiff; sourceTree = "<group>"; };
A28DBADB0A33C1D800F4B4A7 /* ActionButton.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = ActionButton.tiff; path = macosx/Images/ActionButton.tiff; sourceTree = "<group>"; };
A2912C530A2956E80097A0CA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = macosx/English.lproj/PrefsWindow.nib; sourceTree = "<group>"; };
A2A84AD20A04FCDC00C898D4 /* BottomBorder.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = BottomBorder.tiff; path = macosx/Images/BottomBorder.tiff; sourceTree = "<group>"; };
A2C655640A04FEDC00E9FD82 /* BottomBorder.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = BottomBorder.tiff; path = macosx/Images/BottomBorder.tiff; sourceTree = "<group>"; };
A2D5CCFC0A2661590089A8C2 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
A2F8951E0A2D4BA500ED2127 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = Credits.rtf; path = macosx/Credits.rtf; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -227,6 +289,7 @@
4D3EA0AA08AE13C600EA10C2 /* IOKit.framework in Frameworks */,
4D1838DD09DEC0E80047D688 /* libtransmission.a in Frameworks */,
4D4B7F6109E055660053C1EB /* libcrypto.0.9.dylib in Frameworks */,
A2D5CCFD0A2661590089A8C2 /* Sparkle.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -256,6 +319,8 @@
32CA4F630368D1EE00C91783 /* Transmission_Prefix.pch */,
A21610FA0A050B1700E8E4C1 /* MenuButton.h */,
A21610FB0A050B1700E8E4C1 /* MenuButton.m */,
A2519D470A2FADFC00479D0C /* SmoothAquaView.m */,
A2519D480A2FADFC00479D0C /* SmoothAquaView.h */,
);
name = Sources;
sourceTree = "<group>";
@ -277,6 +342,7 @@
4DDBB71F09E16BFE00284745 /* CLI */,
4DDBB70A09E16B3200284745 /* GUI */,
4DDBB71509E16B3F00284745 /* Libraries */,
A250C8590A27511C000F3E9F /* Linked Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = Transmission;
@ -285,6 +351,10 @@
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
A2F8951E0A2D4BA500ED2127 /* Credits.rtf */,
A2495B6B0A2F697C0098B31F /* ResumeSelected.tiff */,
A2495B6C0A2F697C0098B31F /* PauseSelected.tiff */,
A21DFF0F0A292B2B007C5F76 /* Transfers.png */,
A27A53640A06AED200E1F16F /* StatusBorder.tiff */,
A27A53420A06A62500E1F16F /* StatusSep.png */,
A2A84AD20A04FCDC00C898D4 /* BottomBorder.tiff */,
@ -312,10 +382,12 @@
29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
A200B9620A227FD0007BBB1E /* InfoWindow.nib */,
A2C655640A04FEDC00E9FD82 /* BottomBorder.tiff */,
A2A84ACF0A04FCD000C898D4 /* ActionButton.tiff */,
A2A84ACF0A04FCD000C898D4 /* ActionButton.tiff */,
A289EB0B0A33C56D00B082A3 /* ButtonBorder.tiff */,
A28DBADB0A33C1D800F4B4A7 /* ActionButton.tiff */,
A2173E1B0A33C1B300B0D8AB /* ActionButtonPressed.tiff */,
A27A53560A06A76400E1F16F /* StatusSep.png */,
A27A53650A06AEDB00E1F16F /* StatusBorder.tiff */,
A2912C520A2956E80097A0CA /* PrefsWindow.nib */,
);
name = Resources;
sourceTree = "<group>";
@ -400,6 +472,14 @@
name = CLI;
sourceTree = "<group>";
};
A250C8590A27511C000F3E9F /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
A2D5CCFC0A2661590089A8C2 /* Sparkle.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -440,6 +520,9 @@
4D18389309DEC0030047D688 /* Headers */,
4D18389409DEC0030047D688 /* Sources */,
4D18389509DEC0030047D688 /* Frameworks */,
A2D5CCDD0A265F790089A8C2 /* CopyFiles */,
A2D5CCF80A2660660089A8C2 /* CopyFiles */,
A2D5CD110A2661660089A8C2 /* CopyFiles */,
);
buildRules = (
);
@ -474,6 +557,7 @@
8D1107290486CEB800E47090 /* Resources */,
8D11072C0486CEB800E47090 /* Sources */,
8D11072E0486CEB800E47090 /* Frameworks */,
A2D5CD130A26616F0089A8C2 /* CopyFiles */,
);
buildRules = (
);
@ -530,10 +614,17 @@
4DE5CCCB0981D9BE00BE280E /* Defaults.plist in Resources */,
4DDFDD22099A5D8E00189D81 /* DownloadBadge.png in Resources */,
4DDFDD23099A5D8E00189D81 /* UploadBadge.png in Resources */,
A2A84AD00A04FCD000C898D4 /* ActionButton.tiff in Resources */,
A2C655650A04FEDC00E9FD82 /* BottomBorder.tiff in Resources */,
A27A53570A06A76400E1F16F /* StatusSep.png in Resources */,
A27A53660A06AEDB00E1F16F /* StatusBorder.tiff in Resources */,
A21DFF100A292B2B007C5F76 /* Transfers.png in Resources */,
A2912C540A2956E80097A0CA /* PrefsWindow.nib in Resources */,
A2F8951F0A2D4BA500ED2127 /* Credits.rtf in Resources */,
A2495B6D0A2F697C0098B31F /* ResumeSelected.tiff in Resources */,
A2495B6E0A2F697D0098B31F /* PauseSelected.tiff in Resources */,
A2173E1C0A33C1B300B0D8AB /* ActionButtonPressed.tiff in Resources */,
A28DBADC0A33C1D800F4B4A7 /* ActionButton.tiff in Resources */,
A289EB0C0A33C56D00B082A3 /* ButtonBorder.tiff in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -584,6 +675,7 @@
4DCCBB3E09C3D71100D3CABF /* TorrentCell.m in Sources */,
A21610FC0A050B1700E8E4C1 /* MenuButton.m in Sources */,
A200B9200A22798F007BBB1E /* InfoWindowController.m in Sources */,
A2519D490A2FADFC00479D0C /* SmoothAquaView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -627,12 +719,25 @@
name = InfoWindow.nib;
sourceTree = "<group>";
};
A2912C520A2956E80097A0CA /* PrefsWindow.nib */ = {
isa = PBXVariantGroup;
children = (
A2912C530A2956E80097A0CA /* English */,
);
name = PrefsWindow.nib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
4D18389C09DEC01E0047D688 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)\"";
OTHER_CFLAGS = (
"-D_FILE_OFFSET_BITS=64",
"-D_LARGEFILE_SOURCE",
@ -666,6 +771,11 @@
isa = XCBuildConfiguration;
buildSettings = {
CONFIGURATION_BUILD_DIR = "$(SRCROOT)/macosx";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)\"";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = macosx/Transmission_Prefix.pch;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)/libtransmission\"";
@ -683,6 +793,7 @@
ppc,
i386,
);
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 3;
GCC_VERSION_i386 = 4.0;

View File

@ -39,8 +39,8 @@
}
- (void) updateBadgeWithCompleted: (int) completed
uploadRate: (NSString *) uploadRate
downloadRate: (NSString *) downloadRate;
uploadRate: (int) uploadRate
downloadRate: (int) downloadRate;
- (void) clearBadge;
@end

View File

@ -24,7 +24,6 @@
#import "Badger.h"
#import "StringAdditions.h"
#import "Utils.h"
@interface Badger (Private)
@ -74,8 +73,8 @@
}
- (void) updateBadgeWithCompleted: (int) completed
uploadRate: (NSString *) uploadRate
downloadRate: (NSString *) downloadRate
uploadRate: (int) uploadRate
downloadRate: (int) downloadRate
{
NSImage * dockIcon = nil;
NSSize iconSize = [fDockIcon size];
@ -118,7 +117,13 @@
}
//set upload and download rate badges
BOOL speedShown = uploadRate || downloadRate;
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSString * uploadRateString = uploadRate >= 0.1 && [defaults boolForKey: @"BadgeUploadRate"]
? [NSString stringForSpeedAbbrev: uploadRate] : nil,
* downloadRateString = downloadRate >= 0.1 && [defaults boolForKey: @"BadgeDownloadRate"]
? [NSString stringForSpeedAbbrev: downloadRate] : nil;
BOOL speedShown = uploadRateString || downloadRateString;
if (speedShown)
{
NSRect badgeRect, stringRect;
@ -136,20 +141,20 @@
[dockIcon lockFocus];
if (uploadRate)
if (uploadRateString)
{
//place badge
[fUploadBadge compositeToPoint: badgeRect.origin
operation: NSCompositeSourceOver];
//place badge text
[self badgeString: uploadRate forRect: stringRect];
[self badgeString: uploadRateString forRect: stringRect];
}
if (downloadRate)
if (downloadRateString)
{
//download rate above upload rate
if (uploadRate)
if (uploadRateString)
{
float spaceBetween = badgeRect.size.height + 2.0;
badgeRect.origin.y += spaceBetween;
@ -161,7 +166,7 @@
operation: NSCompositeSourceOver];
//place badge text
[self badgeString: downloadRate forRect: stringRect];
[self badgeString: downloadRateString forRect: stringRect];
}
[dockIcon unlockFocus];

View File

@ -30,6 +30,7 @@
#import "PrefsController.h"
#import "InfoWindowController.h"
#import "Badger.h"
#import "SmoothAquaView.h"
@class TorrentTableView;
@ -39,47 +40,41 @@
int fCompleted;
NSMutableArray * fTorrents;
PrefsController * fPrefsController;
NSUserDefaults * fDefaults;
InfoWindowController * fInfoController;
NSToolbar * fToolbar;
IBOutlet NSMenuItem * fAdvancedBarItem;
IBOutlet NSMenuItem * fPauseResumeItem;
IBOutlet NSMenuItem * fRemoveItem;
IBOutlet NSMenuItem * fRemoveTorrentItem;
IBOutlet NSMenuItem * fRemoveDataItem;
IBOutlet NSMenuItem * fRemoveBothItem;
IBOutlet NSMenuItem * fRevealItem;
IBOutlet NSMenuItem * fShowHideToolbar;
IBOutlet NSWindow * fWindow;
IBOutlet NSScrollView * fScrollView;
IBOutlet TorrentTableView * fTableView;
NSToolbar * fToolbar;
IBOutlet NSMenuItem * fAdvancedBarItem;
IBOutlet NSButton * fActionButton;
IBOutlet SmoothAquaView * fStatusBar;
BOOL fStatusBarVisible;
IBOutlet NSTextField * fTotalDLField;
IBOutlet NSTextField * fTotalULField;
IBOutlet NSTextField * fTotalTorrentsField;
IBOutlet NSBox * fStats;
BOOL fStatusBar;
IBOutlet NSButton * fActionButton;
NSString * fSortType;
IBOutlet NSMenuItem * fNameSortItem,
* fStateSortItem,
* fDateSortItem;
NSMenuItem * fCurrentSortItem;
IBOutlet NSMenuItem * fNameSortItem, * fStateSortItem,
* fProgressSortItem, * fDateSortItem;
IBOutlet NSMenuItem * fNextInfoTabItem, * fPrevInfoTabItem;
IBOutlet NSMenu * fUploadMenu, * fDownloadMenu;
IBOutlet NSMenuItem * fUploadLimitItem, * fUploadNoLimitItem,
* fDownloadLimitItem, * fDownloadNoLimitItem,
* fRatioSetItem, * fRatioNotSetItem;
io_connect_t fRootPort;
NSTimer * fTimer;
NSTimer * fUpdateTimer;
IBOutlet NSPanel * fPrefsWindow;
IBOutlet PrefsController * fPrefsController;
NSUserDefaults * fDefaults;
BOOL fHasGrowl;
Badger * fBadger;
BOOL fCheckIsAutomatic;
Badger * fBadger;
BOOL fUpdateInProgress;
}
- (void) advancedChanged: (id) sender;
@ -100,13 +95,13 @@
- (void) stopAllTorrents: (id) sender;
- (void) stopTorrentWithIndex: (NSIndexSet *) indexSet;
- (void) removeTorrent: (id) sender;
- (void) removeTorrentDeleteFile: (id) sender;
- (void) removeTorrentDeleteData: (id) sender;
- (void) removeTorrentDeleteBoth: (id) sender;
- (void) removeTorrentWithIndex: (NSIndexSet *) indexSet
deleteTorrent: (BOOL) deleteTorrent
deleteData: (BOOL) deleteData;
- (void) removeTorrent: (id) sender;
- (void) removeTorrentDeleteTorrent: (id) sender;
- (void) removeTorrentDeleteData: (id) sender;
- (void) removeTorrentDeleteBoth: (id) sender;
- (void) removeTorrentWithIndex: (NSIndexSet *) indexSet
deleteTorrent: (BOOL) deleteTorrent
deleteData: (BOOL) deleteData;
- (void) removeSheetDidEnd: (NSWindow *) sheet returnCode: (int) returnCode
contextInfo: (NSDictionary *) dict;
@ -114,24 +109,33 @@
deleteTorrent: (BOOL) deleteTorrent
deleteData: (BOOL) deleteData;
- (void) revealTorrent: (id) sender;
- (void) showInfo: (id) sender;
- (void) updateInfo;
- (void) updateInfoStats;
- (void) revealFile: (id) sender;
- (void) updateUI: (NSTimer *) timer;
- (void) showPreferenceWindow: (id) sender;
- (void) showInfo: (id) sender;
- (void) setInfoTab: (id) sender;
- (void) updateUI: (NSTimer *) timer;
- (void) updateTorrentHistory;
- (void) sortTorrents;
- (void) setSort: (id) sender;
- (void) sleepCallBack: (natural_t) messageType argument:
- (void) setLimitGlobalEnabled: (id) sender;
- (void) setQuickLimitGlobal: (id) sender;
- (void) limitGlobalChange: (NSNotification *) notification;
- (void) setRatioGlobalEnabled: (id) sender;
- (void) setQuickRatioGlobal: (id) sender;
- (void) ratioGlobalChange: (NSNotification *) notification;
- (void) ratioSingleChange: (NSNotification *) notification;
- (void) sleepCallBack: (natural_t) messageType argument:
(void *) messageArgument;
- (void) toggleStatusBar: (id) sender;
- (void) showPreferenceWindow: (id) sender;
- (void) showStatusBar: (BOOL) show animate: (BOOL) animate;
- (void) showMainWindow: (id) sender;
- (void) linkHomepage: (id) sender;
@ -139,9 +143,8 @@
- (void) notifyGrowl: (NSString *) file;
- (void) growlRegister: (id) sender;
- (void) checkForUpdate: (id) sender;
- (void) checkForUpdateTimer: (NSTimer *) timer;
- (void) checkForUpdateAuto: (BOOL) automatic;
- (void) checkUpdate: (id) sender;
- (void) prepareForUpdate: (NSNotification *) notification;
@end

File diff suppressed because it is too large Load Diff

55
macosx/Credits.rtf Normal file
View File

@ -0,0 +1,55 @@
{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf380
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\vieww9000\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 Transmission is written and maintained by:\
\
Eric Petit <{\field{\*\fldinst{HYPERLINK "mailto:titer@m0k.org"}}{\fldrslt titer@m0k.org}}>\
+ Back-end\
+ OS X interface\
\
Josh Elsasser <{\field{\*\fldinst{HYPERLINK "mailto:josh@elsasser.org"}}{\fldrslt josh@elsasser.org}}>\
+ Back-end\
+ GTK+ interface\
\
Bryan Varner <{\field{\*\fldinst{HYPERLINK "mailto:bryan@varnernet.com"}}{\fldrslt bryan@varnernet.com}}>\
+ BeOS interface\
\
Michael Demars <{\field{\*\fldinst{HYPERLINK "mailto:keul@m0k.org"}}{\fldrslt keul@m0k.org}}>\
+ OS X interface (Growl notifications, AppleScript)\
\
\
Thanks to:\
\
Mitchell Livingston\
+ OS X patches (Badging, preferences, sorting, and much more)\
\
Omar and Adrien\
+ Beta testing\
\
Various people\
+ Writing {\field{\*\fldinst{HYPERLINK "http://wiki.theory.org/BitTorrentSpecification"}}{\fldrslt http://wiki.theory.org/BitTorrentSpecification}}\
\
vi@nwr.jp\
+ Free SHA1 implementation (sha1.[ch])\
\
John Blitch\
+ OS X patch (Contextual menu)\
\
Ahmad M. Afuni\
+ NetBSD patch\
\
Jeremy Messenger\
+ FreeBSD patch\
\
Mike Matas <{\field{\*\fldinst{HYPERLINK "http://www.mikematas.com/"}}{\fldrslt http://www.mikematas.com/}}>\
+ OS X toolbar icons\
\
Martin Stadtmueller\
+ Icon tweaking\
\
FOOOD\
+ Badging images\
}

View File

@ -38,17 +38,19 @@
<false/>
<key>RatioLimit</key>
<integer>2</integer>
<key>SUScheduledCheckInterval</key>
<integer>86400</integer>
<key>ShowInspector</key>
<false/>
<key>Sort</key>
<string>Date</string>
<key>StatusBar</key>
<true/>
<key>UpdateCheck</key>
<string>Daily</string>
<key>UploadLimit</key>
<integer>20</integer>
<key>UseAdvancedBar</key>
<false/>
<key>VersionCheck</key>
<string>Weekly</string>
</dict>
</plist>

View File

@ -1,4 +1,4 @@
/* Localized versions of Info.plist keys */
CFBundleName = "Transmission";
NSHumanReadableCopyright = "Copyright 2005 Eric Petit";
NSHumanReadableCopyright = "Copyright 2005-2006 Eric Petit";

View File

@ -2,24 +2,41 @@
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {revealFile = id; setRatioCheck = id; setRatioLimit = id; };
CLASS = InfoWindowController;
LANGUAGE = ObjC;
OUTLETS = {
fAnnounce = NSTextField;
fDownloaded = NSTextField;
fHash = NSTextField;
fAnnounceField = NSTextField;
fConnectedPeersField = NSTextField;
fDataLocationField = NSTextField;
fDateStartedField = NSTextField;
fDownloadRateField = NSTextField;
fDownloadedField = NSTextField;
fDownloadingFromField = NSTextField;
fFileTable = NSTableView;
fHashField = NSTextField;
fImageView = NSImageView;
fLeechers = NSTextField;
fName = NSTextField;
fPieceSize = NSTextField;
fPieces = NSTextField;
fSeeders = NSTextField;
fSize = NSTextField;
fTracker = NSTextField;
fUploaded = NSTextField;
fLeechersField = NSTextField;
fNameField = NSTextField;
fPercentField = NSTextField;
fPieceSizeField = NSTextField;
fPiecesField = NSTextField;
fRatioField = NSTextField;
fRatioLimitField = NSTextField;
fRatioMatrix = NSMatrix;
fSeedersField = NSTextField;
fSizeField = NSTextField;
fStateField = NSTextField;
fTabView = NSTabView;
fTorrentLocationField = NSTextField;
fTrackerField = NSTextField;
fUploadRateField = NSTextField;
fUploadedField = NSTextField;
fUploadingToField = NSTextField;
};
SUPERCLASS = NSWindowController;
}
},
{CLASS = NSSegmentedControl; LANGUAGE = ObjC; SUPERCLASS = NSControl; }
);
IBVersion = 1;
}

View File

@ -10,6 +10,10 @@
<array>
<integer>5</integer>
</array>
<key>IBLockedTabItems</key>
<array>
<integer>332</integer>
</array>
<key>IBOpenObjects</key>
<array>
<integer>5</integer>

View File

@ -3,7 +3,7 @@
{
ACTIONS = {
advancedChanged = id;
checkForUpdate = id;
checkUpdate = id;
growlRegister = id;
linkForums = id;
linkHomepage = id;
@ -11,10 +11,15 @@
removeTorrent = id;
removeTorrentDeleteBoth = id;
removeTorrentDeleteData = id;
removeTorrentDeleteFile = id;
removeTorrentDeleteTorrent = id;
resumeAllTorrents = id;
resumeTorrent = id;
revealTorrent = id;
revealFile = id;
setInfoTab = id;
setLimitGlobalEnabled = id;
setQuickLimitGlobal = id;
setQuickRatioGlobal = id;
setRatioGlobalEnabled = id;
setSort = id;
showInfo = id;
showMainWindow = id;
@ -29,28 +34,35 @@
fActionButton = NSButton;
fAdvancedBarItem = NSMenuItem;
fDateSortItem = NSMenuItem;
fDownloadLimitItem = NSMenuItem;
fDownloadMenu = NSMenu;
fDownloadNoLimitItem = NSMenuItem;
fNameSortItem = NSMenuItem;
fPauseResumeItem = NSMenuItem;
fPrefsController = PrefsController;
fPrefsWindow = NSPanel;
fRemoveBothItem = NSMenuItem;
fRemoveDataItem = NSMenuItem;
fRemoveItem = NSMenuItem;
fRemoveTorrentItem = NSMenuItem;
fRevealItem = NSMenuItem;
fNextInfoTabItem = NSMenuItem;
fPrevInfoTabItem = NSMenuItem;
fProgressSortItem = NSMenuItem;
fRatioNotSetItem = NSMenuItem;
fRatioSetItem = NSMenuItem;
fScrollView = NSScrollView;
fShowHideToolbar = NSMenuItem;
fStateSortItem = NSMenuItem;
fStats = NSBox;
fStatusBar = SmoothAquaView;
fTableView = TorrentTableView;
fTotalDLField = NSTextField;
fTotalTorrentsField = NSTextField;
fTotalULField = NSTextField;
fUploadLimitItem = NSMenuItem;
fUploadMenu = NSMenu;
fUploadNoLimitItem = NSMenuItem;
fWindow = NSWindow;
};
SUPERCLASS = NSObject;
},
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {revealFile = id; setNextTab = id; setPreviousTab = id; };
CLASS = FirstResponder;
LANGUAGE = ObjC;
SUPERCLASS = NSObject;
},
{CLASS = MenuButton; LANGUAGE = ObjC; SUPERCLASS = NSButton; },
{CLASS = NSSegmentedControl; LANGUAGE = ObjC; SUPERCLASS = NSControl; },
{CLASS = NameCell; LANGUAGE = ObjC; SUPERCLASS = NSCell; },
@ -97,6 +109,7 @@
fRemoveCheck = NSButton;
fTransfersView = NSView;
fUpdatePopUp = NSPopUpButton;
fUpdater = SUUpdater;
fUploadCheck = NSButton;
fUploadField = NSTextField;
fUploadLimitItem = NSMenuItem;
@ -107,6 +120,13 @@
SUPERCLASS = NSObject;
},
{CLASS = ProgressCell; LANGUAGE = ObjC; SUPERCLASS = NSCell; },
{
ACTIONS = {checkForUpdates = id; };
CLASS = SUUpdater;
LANGUAGE = ObjC;
SUPERCLASS = NSObject;
},
{CLASS = SmoothAquaView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
{
CLASS = TorrentTableView;
LANGUAGE = ObjC;

View File

@ -3,32 +3,31 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>51 70 426 365 0 0 1152 842 </string>
<string>28 75 422 283 0 0 1152 842 </string>
<key>IBEditorPositions</key>
<dict>
<key>1041</key>
<string>344 478 208 99 0 0 1152 842 </string>
<key>1343</key>
<string>344 526 463 104 0 0 1152 842 </string>
<key>1480</key>
<string>400 366 420 60 0 0 1152 842 </string>
<key>29</key>
<string>154 771 371 44 0 0 1152 842 </string>
<string>154 771 451 44 0 0 1152 842 </string>
<key>456</key>
<string>212 488 144 137 0 0 1152 842 </string>
<key>581</key>
<string>324 628 112 68 0 0 1152 842 </string>
<key>589</key>
<string>54 521 103 68 0 0 1152 842 </string>
<key>783</key>
<string>347 472 457 212 0 0 1152 842 </string>
<key>796</key>
<string>347 461 457 234 0 0 1152 842 </string>
<key>825</key>
<string>348 524 463 107 0 0 1152 842 </string>
</dict>
<key>IBFramework Version</key>
<string>446.1</string>
<key>IBOldestOS</key>
<integer>3</integer>
<key>IBOpenObjects</key>
<array>
<integer>21</integer>
<integer>1480</integer>
</array>
<key>IBSystem Version</key>
<string>8I127</string>
</dict>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,57 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = MenuButton; LANGUAGE = ObjC; SUPERCLASS = NSButton; },
{
ACTIONS = {
folderSheetShow = id;
setAutoStart = id;
setBadge = id;
setDownloadLocation = id;
setLimit = id;
setLimitCheck = id;
setPort = id;
setRatio = id;
setRatioCheck = id;
setShowMessage = id;
setUpdate = id;
};
CLASS = PrefsController;
LANGUAGE = ObjC;
OUTLETS = {
fAutoStartCheck = NSButton;
fBadgeDownloadRateCheck = NSButton;
fBadgeUploadRateCheck = NSButton;
fDownloadCheck = NSButton;
fDownloadField = NSTextField;
fFolderPopUp = NSPopUpButton;
fGeneralView = NSView;
fNetworkView = NSView;
fPortField = NSTextField;
fQuitCheck = NSButton;
fRatioCheck = NSButton;
fRatioField = NSTextField;
fRemoveCheck = NSButton;
fTransfersView = NSView;
fUpdatePopUp = NSPopUpButton;
fUpdater = SUUpdater;
fUploadCheck = NSButton;
fUploadField = NSTextField;
};
SUPERCLASS = NSWindowController;
},
{
ACTIONS = {checkForUpdates = id; };
CLASS = SUUpdater;
LANGUAGE = ObjC;
SUPERCLASS = NSObject;
},
{
CLASS = TorrentTableView;
LANGUAGE = ObjC;
OUTLETS = {fContextNoRow = NSMenu; fContextRow = NSMenu; fController = Controller; };
SUPERCLASS = NSTableView;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>39 83 356 286 0 0 1152 842 </string>
<key>IBEditorPositions</key>
<dict>
<key>28</key>
<string>347 472 462 212 0 0 1152 842 </string>
<key>41</key>
<string>345 461 462 234 0 0 1152 842 </string>
<key>66</key>
<string>347 526 462 104 0 0 1152 842 </string>
</dict>
<key>IBFramework Version</key>
<string>446.1</string>
<key>IBSystem Version</key>
<string>8I127</string>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Binary file not shown.

BIN
macosx/Images/Transfers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -27,23 +27,37 @@
@interface InfoWindowController : NSWindowController
{
IBOutlet NSImageView * fImageView;
IBOutlet NSTextField * fName;
IBOutlet NSTextField * fSize;
IBOutlet NSTextField * fTracker;
IBOutlet NSTextField * fAnnounce;
IBOutlet NSTextField * fPieceSize;
IBOutlet NSTextField * fPieces;
IBOutlet NSTextField * fHash;
IBOutlet NSTextField * fSeeders;
IBOutlet NSTextField * fLeechers;
IBOutlet NSTextField * fDownloaded;
IBOutlet NSTextField * fUploaded;
NSMutableArray * fTorrents, * fFiles;
NSImage * fAppIcon;
NSImage * fAppIcon;
IBOutlet NSTabView * fTabView;
IBOutlet NSImageView * fImageView;
IBOutlet NSTextField * fNameField, * fSizeField, * fTrackerField,
* fAnnounceField, * fPieceSizeField, * fPiecesField,
* fHashField,
* fTorrentLocationField, * fDataLocationField,
* fDateStartedField,
* fStateField, * fPercentField,
* fDownloadRateField, * fUploadRateField,
* fDownloadedField, * fUploadedField, * fRatioField,
* fSeedersField, * fLeechersField,
* fConnectedPeersField, * fDownloadingFromField, * fUploadingToField;
IBOutlet NSTableView * fFileTable;
IBOutlet NSMatrix * fRatioMatrix;
IBOutlet NSTextField * fRatioLimitField;
}
- (void) updateInfoForTorrents: (NSArray *) torrents;
- (void) updateInfoStatsForTorrents: (NSArray *) torrents;
- (void) updateInfoStats;
- (void) setNextTab;
- (void) setPreviousTab;
- (void) revealFile: (id) sender;
- (void) setRatioCheck: (id) sender;
- (void) setRatioLimit: (id) sender;
@end

View File

@ -25,39 +25,65 @@
#import "InfoWindowController.h"
#import "StringAdditions.h"
#define RATIO_NO_CHECK_TAG 0
#define RATIO_GLOBAL_TAG 1
#define RATIO_CHECK_TAG 2
#define TAB_INFO_IDENT @"Info"
#define TAB_STATUS_IDENT @"Status"
#define TAB_OPTIONS_IDENT @"Options"
#define TAB_FILES_IDENT @"Files"
#define TAB_INFO_HEIGHT 191.0
#define TAB_STATUS_HEIGHT 241.0
#define TAB_OPTIONS_HEIGHT 82.0
#define TAB_FILES_HEIGHT 250.0
@implementation InfoWindowController
- (void) awakeFromNib
{
fAppIcon = [[NSApp applicationIconImage] copy];
fFiles = [[NSMutableArray alloc] initWithCapacity: 6];
[fFileTable setDoubleAction: @selector(revealFile:)];
//window location and size
NSWindow * window = [self window];
[window setFrameAutosaveName: @"InspectorWindowFrame"];
[window setFrameUsingName: @"InspectorWindowFrame" force: YES];
NSRect frame = [window frame];
float difference = TAB_INFO_HEIGHT - [[[fTabView selectedTabViewItem]
view] frame].size.height;
frame.origin.y -= difference;
frame.size.height += difference;
[window setFrame: frame display: YES];
}
- (void) dealloc
{
if (fTorrents)
[fTorrents release];
[fFiles release];
[fAppIcon release];
[super dealloc];
}
- (void) updateInfoForTorrents: (NSArray *) torrents
{
int numberSelected = [torrents count];
if (fTorrents)
[fTorrents release];
fTorrents = [torrents retain];
int numberSelected = [fTorrents count];
if (numberSelected != 1)
{
[fImageView setImage: fAppIcon];
[fTracker setStringValue: @""];
[fAnnounce setStringValue: @""];
[fPieceSize setStringValue: @""];
[fPieces setStringValue: @""];
[fHash setStringValue: @""];
[fSeeders setStringValue: @""];
[fLeechers setStringValue: @""];
if (numberSelected > 0)
{
[fName setStringValue: [[NSString stringWithInt: numberSelected]
stringByAppendingString: @" Torrents Selected"]];
[fNameField setStringValue: [NSString stringWithFormat:
@"%d Torrents Selected", numberSelected]];
uint64_t size = 0;
NSEnumerator * enumerator = [torrents objectEnumerator];
@ -65,63 +91,325 @@
while ((torrent = [enumerator nextObject]))
size += [torrent size];
[fSize setStringValue: [[NSString
stringForFileSize: size] stringByAppendingString: @" Total"]];
[fSizeField setStringValue: [[NSString stringForFileSize: size]
stringByAppendingString: @" Total"]];
}
else
{
[fName setStringValue: @"No Torrents Selected"];
[fSize setStringValue: @""];
[fDownloaded setStringValue: @""];
[fUploaded setStringValue: @""];
[fNameField setStringValue: @"No Torrents Selected"];
[fSizeField setStringValue: @""];
[fDownloadRateField setStringValue: @""];
[fUploadRateField setStringValue: @""];
[fDownloadedField setStringValue: @""];
[fUploadedField setStringValue: @""];
}
[fImageView setImage: fAppIcon];
[fNameField setToolTip: nil];
[fTrackerField setStringValue: @""];
[fTrackerField setToolTip: nil];
[fAnnounceField setStringValue: @""];
[fAnnounceField setToolTip: nil];
[fPieceSizeField setStringValue: @""];
[fPiecesField setStringValue: @""];
[fHashField setStringValue: @""];
[fTorrentLocationField setStringValue: @""];
[fTorrentLocationField setToolTip: nil];
[fDataLocationField setStringValue: @""];
[fDataLocationField setToolTip: nil];
[fDateStartedField setStringValue: @""];
[fStateField setStringValue: @""];
[fPercentField setStringValue: @""];
[fRatioField setStringValue: @""];
[fSeedersField setStringValue: @""];
[fLeechersField setStringValue: @""];
[fConnectedPeersField setStringValue: @""];
[fDownloadingFromField setStringValue: @""];
[fUploadingToField setStringValue: @""];
}
else
{
Torrent * torrent = [torrents objectAtIndex: 0];
Torrent * torrent = [fTorrents objectAtIndex: 0];
[fImageView setImage: [torrent iconNonFlipped]];
[fImageView setImage: [torrent icon]];
[fName setStringValue: [torrent name]];
[fSize setStringValue: [NSString stringForFileSize: [torrent size]]];
[fTracker setStringValue: [torrent tracker]];
[fAnnounce setStringValue: [torrent announce]];
[fPieceSize setStringValue: [NSString stringForFileSize: [torrent pieceSize]]];
[fPieces setIntValue: [torrent pieceCount]];
[fHash setStringValue: [torrent hash]];
NSString * name = [torrent name];
[fNameField setStringValue: name];
[fNameField setToolTip: name];
[fSizeField setStringValue: [NSString stringForFileSize: [torrent size]]];
NSString * tracker = [torrent tracker], * announce = [torrent announce];
[fTrackerField setStringValue: tracker];
[fTrackerField setToolTip: tracker];
[fAnnounceField setStringValue: announce];
[fAnnounceField setToolTip: announce];
[fPieceSizeField setStringValue: [NSString stringForFileSize: [torrent pieceSize]]];
[fPiecesField setIntValue: [torrent pieceCount]];
[fHashField setStringValue: [torrent hashString]];
[fTorrentLocationField setStringValue: [[torrent torrentLocation]
stringByAbbreviatingWithTildeInPath]];
[fTorrentLocationField setToolTip: [torrent torrentLocation]];
[fDataLocationField setStringValue: [[torrent dataLocation]
stringByAbbreviatingWithTildeInPath]];
[fDataLocationField setToolTip: [torrent dataLocation]];
[fDateStartedField setObjectValue: [torrent date]];
}
[self updateInfoStats];
[self updateInfoStatsForTorrents: torrents];
}
- (void) updateInfoStatsForTorrents: (NSArray *) torrents
{
int numberSelected = [torrents count];
//set file table
[fFiles removeAllObjects];
Torrent * torrent;
NSEnumerator * enumerator = [fTorrents objectEnumerator];
while ((torrent = [enumerator nextObject]))
[fFiles addObjectsFromArray: [torrent fileList]];
[fFileTable deselectAll: nil];
[fFileTable reloadData];
//set ratio settings
if (numberSelected > 0)
{
Torrent * torrent;
if (numberSelected == 1)
{
torrent = [torrents objectAtIndex: 0];
NSEnumerator * enumerator = [fTorrents objectEnumerator];
Torrent * torrent = [enumerator nextObject]; //first torrent
const int INVALID = -99;
int ratioSetting = [torrent stopRatioSetting];
float ratioLimit = [torrent ratioLimit];
while ((ratioSetting != INVALID || ratioLimit != INVALID)
&& (torrent = [enumerator nextObject]))
{
if (ratioSetting != INVALID && ratioSetting != [torrent stopRatioSetting])
ratioSetting = INVALID;
int seeders = [torrent seeders], leechers = [torrent leechers];
[fSeeders setStringValue: seeders < 0 ?
@"?" : [NSString stringWithInt: seeders]];
[fLeechers setStringValue: leechers < 0 ?
@"?" : [NSString stringWithInt: leechers]];
if (ratioLimit != INVALID && ratioLimit != [torrent ratioLimit])
ratioLimit = INVALID;
}
[fRatioMatrix setEnabled: YES];
if (ratioSetting == RATIO_CHECK)
{
[fRatioMatrix selectCellWithTag: RATIO_CHECK_TAG];
[fRatioLimitField setEnabled: YES];
}
else
{
if (ratioSetting == RATIO_NO_CHECK)
[fRatioMatrix selectCellWithTag: RATIO_NO_CHECK_TAG];
else if (ratioSetting == RATIO_GLOBAL)
[fRatioMatrix selectCellWithTag: RATIO_GLOBAL_TAG];
else
[fRatioMatrix deselectAllCells];
[fRatioLimitField setEnabled: NO];
}
if (ratioLimit != INVALID)
[fRatioLimitField setFloatValue: ratioLimit];
else
[fRatioLimitField setStringValue: @""];
}
else
{
[fRatioMatrix deselectAllCells];
[fRatioMatrix setEnabled: NO];
[fRatioLimitField setEnabled: NO];
[fRatioLimitField setStringValue: @""];
}
}
- (void) updateInfoStats
{
int numberSelected = [fTorrents count];
if (numberSelected > 0)
{
float downloadRate = 0, uploadRate = 0;
uint64_t downloaded = 0, uploaded = 0;
NSEnumerator * enumerator = [torrents objectEnumerator];
Torrent * torrent;
NSEnumerator * enumerator = [fTorrents objectEnumerator];
while ((torrent = [enumerator nextObject]))
{
downloadRate += [torrent downloadRate];
uploadRate += [torrent uploadRate];
downloaded += [torrent downloaded];
uploaded += [torrent uploaded];
}
[fDownloaded setStringValue: [NSString stringForFileSize: downloaded]];
[fUploaded setStringValue: [NSString stringForFileSize: uploaded]];
[fDownloadRateField setStringValue: [NSString stringForSpeed: downloadRate]];
[fUploadRateField setStringValue: [NSString stringForSpeed: uploadRate]];
[fDownloadedField setStringValue: [NSString stringForFileSize: downloaded]];
[fUploadedField setStringValue: [NSString stringForFileSize: uploaded]];
if (numberSelected == 1)
{
torrent = [fTorrents objectAtIndex: 0];
[fStateField setStringValue: [torrent state]];
[fPercentField setStringValue: [NSString stringWithFormat:
@"%.2f%%", 100 * [torrent progress]]];
int seeders = [torrent seeders], leechers = [torrent leechers];
[fSeedersField setStringValue: seeders < 0 ?
@"N/A" : [NSString stringWithInt: seeders]];
[fLeechersField setStringValue: leechers < 0 ?
@"N/A" : [NSString stringWithInt: leechers]];
BOOL active = [torrent isActive];
[fConnectedPeersField setStringValue: active ? [NSString
stringWithInt: [torrent totalPeers]] : @"N/A"];
[fDownloadingFromField setStringValue: active ? [NSString
stringWithInt: [torrent peersUploading]] : @"N/A"];
[fUploadingToField setStringValue: active ? [NSString
stringWithInt: [torrent peersDownloading]] : @"N/A"];
[fRatioField setStringValue: [NSString stringForRatioWithDownload:
downloaded upload: uploaded]];
}
}
}
- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
{
SEL action = [menuItem action];
if (action == @selector(revealFile:))
return [fFileTable numberOfSelectedRows] > 0 &&
[[[fTabView selectedTabViewItem] identifier] isEqualToString: TAB_FILES_IDENT];
return YES;
}
- (void) tabView: (NSTabView *) tabView didSelectTabViewItem: (NSTabViewItem *) tabViewItem
{
NSWindow * window = [self window];
NSRect frame = [window frame];
float height;
NSString * identifier = [tabViewItem identifier];
if ([identifier isEqualToString: TAB_INFO_IDENT])
height = TAB_INFO_HEIGHT;
else if ([identifier isEqualToString: TAB_STATUS_IDENT])
height = TAB_STATUS_HEIGHT;
else if ([identifier isEqualToString: TAB_OPTIONS_IDENT])
height = TAB_OPTIONS_HEIGHT;
else
height = TAB_FILES_HEIGHT;
NSView * view = [tabViewItem view];
float difference = height - [view frame].size.height;
frame.origin.y -= difference;
frame.size.height += difference;
[view setHidden: YES];
[window setFrame: frame display: YES animate: YES];
[view setHidden: NO];
}
- (void) setNextTab
{
if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]]
== [fTabView numberOfTabViewItems] - 1)
[fTabView selectFirstTabViewItem: nil];
else
[fTabView selectNextTabViewItem: nil];
}
- (void) setPreviousTab
{
if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]] == 0)
[fTabView selectLastTabViewItem: nil];
else
[fTabView selectPreviousTabViewItem: nil];
}
- (int) numberOfRowsInTableView: (NSTableView *) tableView
{
return [fFiles count];
}
- (id) tableView: (NSTableView *) tableView objectValueForTableColumn:
(NSTableColumn *) column row: (int) row
{
NSString * file = [fFiles objectAtIndex: row];
if ([[column identifier] isEqualToString: @"Icon"])
return [[NSWorkspace sharedWorkspace] iconForFileType: [file pathExtension]];
else
return [file lastPathComponent];
}
//only called on >= 10.4
- (NSString *) tableView: (NSTableView *) tableView toolTipForCell: (NSCell *) cell
rect: (NSRectPointer) rect tableColumn: (NSTableColumn *) column
row: (int) row mouseLocation: (NSPoint) mouseLocation
{
return [fFiles objectAtIndex: row];
}
- (void) revealFile: (id) sender
{
if ([fFileTable numberOfSelectedRows] > 0)
[[NSWorkspace sharedWorkspace] selectFile: [fFiles objectAtIndex: [fFileTable selectedRow]]
inFileViewerRootedAtPath: nil];
}
- (void) setRatioCheck: (id) sender
{
NSButtonCell * selected = [fRatioMatrix selectedCell];
int ratioSetting;
if (selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG])
ratioSetting = RATIO_CHECK;
else if (selected == [fRatioMatrix cellWithTag: RATIO_NO_CHECK_TAG])
ratioSetting = RATIO_NO_CHECK;
else
ratioSetting = RATIO_GLOBAL;
Torrent * torrent;
NSEnumerator * enumerator = [fTorrents objectEnumerator];
while ((torrent = [enumerator nextObject]))
[torrent setStopRatioSetting: ratioSetting];
[self setRatioLimit: fRatioLimitField];
[fRatioLimitField setEnabled: selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG]];
}
- (void) setRatioLimit: (id) sender
{
Torrent * torrent;
NSEnumerator * enumerator = [fTorrents objectEnumerator];
float ratioLimit = [sender floatValue];
if (![[sender stringValue] isEqualToString:
[NSString stringWithFormat: @"%.2f", ratioLimit]]
|| ratioLimit < 0)
{
NSBeep();
float ratioLimit = [[enumerator nextObject] ratioLimit]; //use first torrent
while ((torrent = [enumerator nextObject]))
if (ratioLimit != [torrent ratioLimit])
{
[sender setStringValue: @""];
return;
}
[sender setFloatValue: ratioLimit];
}
else
{
while ((torrent = [enumerator nextObject]))
[torrent setRatioLimit: ratioLimit];
}
}

View File

@ -28,12 +28,12 @@
- (void) mouseDown: (NSEvent *) event
{
[self setState: NSOnState];
[self highlight: YES];
NSPoint location = NSMakePoint(3, -2);
NSEvent * theEvent= [NSEvent mouseEventWithType: [event type]
NSImage * image = [self image];
[self setImage: [self alternateImage]];
NSPoint location = NSMakePoint(3, -2);
NSEvent * theEvent= [NSEvent mouseEventWithType: [event type]
location: location
modifierFlags: [event modifierFlags]
timestamp: [event timestamp]
@ -43,10 +43,9 @@
clickCount: [event clickCount]
pressure: [event pressure]];
[NSMenu popUpContextMenu: [self menu] withEvent: theEvent forView: self];
[self setState: NSOffState];
[self highlight: NO];
[NSMenu popUpContextMenu: [self menu] withEvent: theEvent forView: self];
[self setImage: image];
}
- (NSMenu *) menuForEvent: (NSEvent *) e

View File

@ -24,16 +24,14 @@
#import <Cocoa/Cocoa.h>
#import <transmission.h>
#import <Sparkle/Sparkle.h>
@interface PrefsController : NSObject
@interface PrefsController : NSWindowController
{
tr_handle_t * fHandle;
IBOutlet NSPanel * fPrefsWindow;
NSToolbar * fToolbar;
IBOutlet NSView * fGeneralView, * fTransfersView,
* fNetworkView, * fBlankView;
IBOutlet NSView * fGeneralView, * fTransfersView, * fNetworkView;
IBOutlet NSPopUpButton * fFolderPopUp;
IBOutlet NSButton * fQuitCheck, * fRemoveCheck,
@ -41,20 +39,13 @@
* fAutoStartCheck;
IBOutlet NSPopUpButton * fUpdatePopUp;
IBOutlet NSTextField * fPortField;
IBOutlet NSButton * fUploadCheck;
IBOutlet NSTextField * fUploadField;
IBOutlet NSButton * fDownloadCheck;
IBOutlet NSTextField * fDownloadField;
IBOutlet NSTextField * fPortField, * fUploadField, * fDownloadField;
IBOutlet NSButton * fUploadCheck, * fDownloadCheck;
IBOutlet NSButton * fRatioCheck;
IBOutlet NSTextField * fRatioField;
IBOutlet NSMenu * fUploadMenu, * fDownloadMenu;
IBOutlet NSMenuItem * fUploadLimitItem, * fUploadNoLimitItem,
* fDownloadLimitItem, * fDownloadNoLimitItem,
* fRatioSetItem, * fRatioNotSetItem;
IBOutlet NSWindow * fWindow;
IBOutlet SUUpdater * fUpdater;
NSString * fDownloadFolder;
NSUserDefaults * fDefaults;
@ -65,19 +56,21 @@
- (void) setShowMessage: (id) sender;
- (void) setBadge: (id) sender;
- (void) setUpdate: (id) sender;
- (void) checkUpdate;
- (void) setAutoStart: (id) sender;
- (void) setDownloadLocation: (id) sender;
- (void) folderSheetShow: (id) sender;
- (void) setPort: (id) sender;
- (void) setLimitCheck: (id) sender;
- (void) setLimit: (id) sender;
- (void) setLimitMenu: (id) sender;
- (void) setQuickSpeed: (id) sender;
- (void) setLimitCheck: (id) sender;
- (void) setLimitEnabled: (BOOL) enable type: (NSString *) type;
- (void) setQuickLimit: (int) limit type: (NSString *) type;
- (void) setRatio: (id) sender;
- (void) setRatioCheck: (id) sender;
- (void) setRatioMenu: (id) sender;
- (void) setQuickRatio: (id) sender;
- (void) setRatioEnabled: (BOOL) enable;
- (void) setQuickRatio: (float) ratioLimit;
@end

View File

@ -26,6 +26,9 @@
#import "StringAdditions.h"
#import "Utils.h"
#define MIN_PORT 1
#define MAX_PORT 65535
#define DOWNLOAD_FOLDER 0
#define DOWNLOAD_TORRENT 2
#define DOWNLOAD_ASK 3
@ -35,7 +38,7 @@
#define UPDATE_NEVER 2
#define TOOLBAR_GENERAL @"General"
#define TOOLBAR_TRANSFERS @"Transfers"
#define TOOLBAR_TRANSFERS @"Transfers"
#define TOOLBAR_NETWORK @"Network"
@interface PrefsController (Private)
@ -73,7 +76,7 @@
fToolbar = [[NSToolbar alloc] initWithIdentifier: @"Preferences Toolbar"];
[fToolbar setDelegate: self];
[fToolbar setAllowsUserCustomization: NO];
[fPrefsWindow setToolbar: fToolbar];
[[self window] setToolbar: fToolbar];
[fToolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
[fToolbar setSizeMode: NSToolbarSizeModeRegular];
@ -88,18 +91,12 @@
fDownloadFolder = [[fDefaults stringForKey: @"DownloadFolder"] stringByExpandingTildeInPath];
[fDownloadFolder retain];
if( [downloadChoice isEqualToString: @"Constant"] )
{
if ([downloadChoice isEqualToString: @"Constant"])
[fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
}
else if( [downloadChoice isEqualToString: @"Torrent"] )
{
else if ([downloadChoice isEqualToString: @"Torrent"])
[fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
}
else
{
[fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
}
[self updatePopUp];
//set bind port
@ -123,13 +120,6 @@
[fUploadField setIntValue: uploadLimit];
[fUploadField setEnabled: checkUpload];
[fUploadLimitItem setTitle:
[NSString stringWithFormat: @"Limit (%d KB/s)", uploadLimit]];
if (checkUpload)
[fUploadLimitItem setState: NSOnState];
else
[fUploadNoLimitItem setState: NSOnState];
tr_setUploadLimit( fHandle, checkUpload ? uploadLimit : -1 );
//set download limit
@ -140,28 +130,13 @@
[fDownloadField setIntValue: downloadLimit];
[fDownloadField setEnabled: checkDownload];
[fDownloadLimitItem setTitle:
[NSString stringWithFormat: @"Limit (%d KB/s)", downloadLimit]];
if (checkDownload)
[fDownloadLimitItem setState: NSOnState];
else
[fDownloadNoLimitItem setState: NSOnState];
tr_setDownloadLimit( fHandle, checkDownload ? downloadLimit : -1 );
//set ratio limit
BOOL ratioCheck = [fDefaults boolForKey: @"RatioCheck"];
float ratioLimit = [fDefaults floatForKey: @"RatioLimit"];
[fRatioCheck setState: ratioCheck ? NSOnState : NSOffState];
[fRatioField setEnabled: ratioCheck];
[fRatioField setFloatValue: ratioLimit];
[fRatioSetItem setTitle: [NSString stringWithFormat: @"Stop at Ratio (%.1f)", ratioLimit]];
if (ratioCheck)
[fRatioSetItem setState: NSOnState];
else
[fRatioNotSetItem setState: NSOnState];
[fRatioField setFloatValue: [fDefaults floatForKey: @"RatioLimit"]];
//set remove and quit prompts
[fQuitCheck setState: [fDefaults boolForKey: @"CheckQuit"] ?
@ -176,19 +151,14 @@
//set auto start
[fAutoStartCheck setState: [fDefaults boolForKey: @"AutoStartDownload"]];
/* Check for update */
NSString * versionCheck = [fDefaults stringForKey: @"VersionCheck"];
if( [versionCheck isEqualToString: @"Daily"] )
[fUpdatePopUp selectItemAtIndex: UPDATE_DAILY];
else if( [versionCheck isEqualToString: @"Weekly"] )
//set update check
NSString * updateCheck = [fDefaults stringForKey: @"UpdateCheck"];
if ([updateCheck isEqualToString: @"Weekly"])
[fUpdatePopUp selectItemAtIndex: UPDATE_WEEKLY];
else if( [versionCheck isEqualToString: @"Never"] )
else if ([updateCheck isEqualToString: @"Never"])
[fUpdatePopUp selectItemAtIndex: UPDATE_NEVER];
else
{
[fDefaults setObject: @"Weekly" forKey: @"VersionCheck"];
[fUpdatePopUp selectItemAtIndex: UPDATE_WEEKLY];
}
[fUpdatePopUp selectItemAtIndex: UPDATE_DAILY];
}
- (NSToolbarItem *) toolbar: (NSToolbar *) t itemForItemIdentifier:
@ -246,137 +216,159 @@
- (void) setPort: (id) sender
{
int bindPort = [fPortField intValue];
tr_setBindPort( fHandle, bindPort );
[fDefaults setInteger: bindPort forKey: @"BindPort"];
int bindPort = [sender intValue];
if (![[NSString stringWithInt: bindPort] isEqualToString: [sender stringValue]]
|| bindPort < MIN_PORT || bindPort > MAX_PORT)
{
NSBeep();
bindPort = [fDefaults integerForKey: @"BindPort"];
[sender setIntValue: bindPort];
}
else
{
tr_setBindPort( fHandle, bindPort );
[fDefaults setInteger: bindPort forKey: @"BindPort"];
}
}
- (void) setLimit: (id) sender
{
NSString * key;
NSMenuItem * menuItem;
NSButton * check;
NSString * type;
if (sender == fUploadField)
{
key = @"UploadLimit";
menuItem = fUploadLimitItem;
check = fUploadCheck;
type = @"Upload";
}
else
{
key = @"DownloadLimit";
menuItem = fDownloadLimitItem;
check = fDownloadCheck;
type = @"Download";
}
int limit = [sender intValue];
[fDefaults setInteger: limit forKey: key];
[menuItem setTitle: [NSString stringWithFormat: @"Limit (%d KB/s)", limit]];
if( sender == fUploadField )
tr_setUploadLimit( fHandle,
( [fUploadCheck state] == NSOffState ) ? -1 : limit );
if (![[sender stringValue] isEqualToString:
[NSString stringWithFormat: @"%d", limit]]
|| limit < 0)
{
NSBeep();
limit = [fDefaults integerForKey: key];
[sender setIntValue: limit];
}
else
tr_setDownloadLimit( fHandle,
( [fDownloadCheck state] == NSOffState ) ? -1 : limit );
{
if( sender == fUploadField )
tr_setUploadLimit( fHandle,
( [fUploadCheck state] == NSOffState ) ? -1 : limit );
else
tr_setDownloadLimit( fHandle,
( [fDownloadCheck state] == NSOffState ) ? -1 : limit );
[fDefaults setInteger: limit forKey: key];
}
NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool: [check state]], @"Enable",
[NSNumber numberWithInt: limit], @"Limit",
type, @"Type", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:
@"LimitGlobalChange" object: dict];
}
- (void) setLimitCheck: (id) sender
{
NSString * key;
NSTextField * field;
NSMenuItem * limitItem, * noLimitItem;
if( sender == fUploadCheck )
if (sender == fUploadCheck)
{
key = @"CheckUpload";
field = fUploadField;
limitItem = fUploadLimitItem;
noLimitItem = fUploadNoLimitItem;
}
else
{
key = @"CheckDownload";
field = fDownloadField;
limitItem = fDownloadLimitItem;
noLimitItem = fDownloadNoLimitItem;
}
BOOL check = [sender state] == NSOnState;
[limitItem setState: check ? NSOnState : NSOffState];
[noLimitItem setState: !check ? NSOnState : NSOffState];
[self setLimit: field];
[field setEnabled: check];
[fDefaults setBool: check forKey: key];
[field setIntValue: [field intValue]]; //set to valid value
[self setLimit: field];
[field setEnabled: check];
}
- (void) setLimitMenu: (id) sender
- (void) setLimitEnabled: (BOOL) enable type: (NSString *) type
{
NSButton * check = (sender == fUploadLimitItem || sender == fUploadNoLimitItem)
NSButton * check = [type isEqualToString: @"Upload"]
? fUploadCheck : fDownloadCheck;
int state = (sender == fUploadLimitItem || sender == fDownloadLimitItem)
? NSOnState : NSOffState;
[check setState: state];
[check setState: enable ? NSOnState : NSOffState];
[self setLimitCheck: check];
}
- (void) setQuickSpeed: (id) sender
- (void) setQuickLimit: (int) limit type: (NSString *) type
{
NSString * title = [sender title];
int limit = [[title substringToIndex: [title length] - [@" KB/s" length]] intValue];
if ([sender menu] == fUploadMenu)
NSButton * check;
if ([type isEqualToString: @"Upload"])
{
[fUploadField setIntValue: limit];
[self setLimitMenu: fUploadLimitItem];
check = fUploadCheck;
}
else
{
[fDownloadField setIntValue: limit];
[self setLimitMenu: fDownloadLimitItem];
check = fDownloadCheck;
}
[check setState: NSOnState];
[self setLimitCheck: check];
}
- (void) setRatio: (id) sender
{
float ratio = [sender floatValue];
[fDefaults setFloat: ratio forKey: @"RatioLimit"];
float ratioLimit = [sender floatValue];
if (![[sender stringValue] isEqualToString:
[NSString stringWithFormat: @"%.2f", ratioLimit]]
|| ratioLimit < 0)
{
NSBeep();
ratioLimit = [fDefaults floatForKey: @"RatioLimit"];
[sender setFloatValue: ratioLimit];
}
else
[fDefaults setFloat: ratioLimit forKey: @"RatioLimit"];
[fRatioSetItem setTitle: [NSString stringWithFormat: @"Stop at Ratio (%.1f)", ratio]];
NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool: [fRatioCheck state]], @"Enable",
[NSNumber numberWithFloat: ratioLimit], @"Ratio", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:
@"RatioGlobalChange" object: dict];
}
- (void) setRatioCheck: (id) sender
{
BOOL check = [sender state] == NSOnState;
[fDefaults setBool: check forKey: @"RatioCheck"];
[fRatioField setFloatValue: [fRatioField floatValue]]; //set to valid value
[self setRatio: fRatioField];
[fRatioField setEnabled: check];
[fRatioSetItem setState: check ? NSOnState : NSOffState];
[fRatioNotSetItem setState: !check ? NSOnState : NSOffState];
[fDefaults setBool: check forKey: @"RatioCheck"];
}
- (void) setRatioMenu: (id) sender
- (void) setRatioEnabled: (BOOL) enable
{
int state = sender == fRatioSetItem ? NSOnState : NSOffState;
int state = enable ? NSOnState : NSOffState;
[fRatioCheck setState: state];
[self setRatioCheck: fRatioCheck];
}
- (void) setQuickRatio: (id) sender
- (void) setQuickRatio: (float) ratioLimit
{
float limit = [[sender title] floatValue];
[fRatioField setFloatValue: limit];
[self setRatioMenu: fRatioSetItem];
[fRatioField setFloatValue: ratioLimit];
[fRatioCheck setState: NSOnState];
[self setRatioCheck: fRatioCheck];
}
- (void) setShowMessage: (id) sender
@ -399,18 +391,27 @@
- (void) setUpdate: (id) sender
{
switch( [fUpdatePopUp indexOfSelectedItem] )
NSString * schedule;
int index = [fUpdatePopUp indexOfSelectedItem];
NSTimeInterval seconds;
if (index == UPDATE_DAILY)
{
case UPDATE_DAILY:
[fDefaults setObject: @"Daily" forKey: @"VersionCheck"];
break;
case UPDATE_WEEKLY:
[fDefaults setObject: @"Weekly" forKey: @"VersionCheck"];
break;
case UPDATE_NEVER:
[fDefaults setObject: @"Never" forKey: @"VersionCheck"];
break;
[fDefaults setObject: @"Daily" forKey: @"UpdateCheck"];
seconds = 86400;
}
else if (index == UPDATE_WEEKLY)
{
[fDefaults setObject: @"Weekly" forKey: @"UpdateCheck"];
seconds = 604800;
}
else
{
[fDefaults setObject: @"Never" forKey: @"UpdateCheck"];
seconds = 0;
}
[fDefaults setInteger: seconds forKey: @"SUScheduledCheckInterval"];
[fUpdater scheduleCheckWithInterval: seconds];
}
- (void) setAutoStart: (id) sender
@ -435,6 +436,11 @@
}
}
- (void) checkUpdate
{
[fUpdater checkForUpdates: nil];
}
- (void) folderSheetShow: (id) sender
{
NSOpenPanel * panel = [NSOpenPanel openPanel];
@ -445,12 +451,12 @@
[panel setCanChooseDirectories: YES];
[panel beginSheetForDirectory: NULL file: NULL types: NULL
modalForWindow: fPrefsWindow modalDelegate: self didEndSelector:
modalForWindow: [self window] modalDelegate: self didEndSelector:
@selector( folderSheetClosed:returnCode:contextInfo: )
contextInfo: NULL];
}
@end // @implementation PrefsController
@end
@implementation PrefsController (Private)
@ -471,16 +477,19 @@
- (void) setPrefView: (NSView *) view
{
NSRect windowRect = [fPrefsWindow frame];
int difference = [view frame].size.height - [[fPrefsWindow contentView] frame].size.height;
NSWindow * window = [self window];
NSRect windowRect = [window frame];
int difference = [view frame].size.height - [[window contentView] frame].size.height;
windowRect.origin.y -= difference;
windowRect.size.height += difference;
[window setTitle: [fToolbar selectedItemIdentifier]];
[fPrefsWindow setTitle: [fToolbar selectedItemIdentifier]];
[fPrefsWindow setContentView: fBlankView];
[fPrefsWindow setFrame: windowRect display: YES animate: YES];
[fPrefsWindow setContentView: view];
[window setContentView: view];
[view setHidden: YES];
[window setFrame: windowRect display: YES animate: YES];
[view setHidden: NO];
}
- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code
@ -519,13 +528,10 @@
- (void) updatePopUp
{
NSMenuItem * menuItem;
NSImage * image32, * image16;
// Get the icon for the folder
image32 = [[NSWorkspace sharedWorkspace] iconForFile:
NSImage * image32 = [[NSWorkspace sharedWorkspace] iconForFile:
fDownloadFolder];
image16 = [[NSImage alloc] initWithSize: NSMakeSize(16,16)];
NSImage * image16 = [[NSImage alloc] initWithSize: NSMakeSize(16,16)];
// 32x32 -> 16x16 scaling
[image16 lockFocus];
@ -537,11 +543,11 @@
[image16 unlockFocus];
// Update the menu item
menuItem = (NSMenuItem *) [fFolderPopUp itemAtIndex: 0];
NSMenuItem * menuItem = (NSMenuItem *) [fFolderPopUp itemAtIndex: 0];
[menuItem setTitle: [fDownloadFolder lastPathComponent]];
[menuItem setImage: image16];
[image16 release];
}
@end /* @implementation PrefsController (Private) */
@end

10
macosx/SmoothAquaView.h Normal file
View File

@ -0,0 +1,10 @@
/* SmoothAquaView */
#import <Cocoa/Cocoa.h>
@interface SmoothAquaView : NSView
{
NSColor * fBackgroundColor;
}
@end

29
macosx/SmoothAquaView.m Normal file
View File

@ -0,0 +1,29 @@
#import "SmoothAquaView.h"
@implementation SmoothAquaView
- (id) initWithFrame: (NSRect) frameRect
{
if ((self = [super initWithFrame:frameRect]))
{
fBackgroundColor = [NSColor colorWithPatternImage:
[NSImage imageNamed: @"StatusBorder"]];
[fBackgroundColor retain];
}
return self;
}
- (void) dealloc
{
[fBackgroundColor release];
[super dealloc];
}
- (void) drawRect: (NSRect) rect
{
[fBackgroundColor set];
[[NSGraphicsContext currentContext] setPatternPhase: [self frame].origin];
NSRectFill([self bounds]);
}
@end

View File

@ -27,11 +27,13 @@
@interface NSString (StringAdditions)
+ (NSString *) stringWithInt: (int) value;
+ (NSString *) stringForFileSize: (uint64_t) size;
+ (NSString *) stringForSpeed: (float) speed;
+ (NSString *) stringForSpeedAbbrev: (float) speed;
+ (NSString *) stringForRatio: (uint64_t) down upload: (uint64_t) up;
- (NSString *) stringFittingInWidth: (float) width
withAttributes: (NSDictionary *) attributes;
+ (NSString *) stringForRatioWithDownload: (uint64_t) down upload: (uint64_t) up;
- (NSAttributedString *) attributedStringFittingInWidth: (float) width
attributes: (NSDictionary *) attributes;
@end

View File

@ -90,12 +90,10 @@
return [NSString stringWithFormat: @"%.2f G", speed / 1048576];
}
+ (NSString *) stringForRatio: (uint64_t) down upload: (uint64_t) up
+ (NSString *) stringForRatioWithDownload: (uint64_t) down upload: (uint64_t) up
{
if( !down && !up )
return @"N/A";
if( !down )
return [NSString stringWithUTF8String: "\xE2\x88\x9E"];
if (down == 0)
return up == 0 ? @"N/A" : [NSString stringWithUTF8String: "\xE2\x88\x9E"];
float ratio = (float) up / (float) down;
if( ratio < 10.0 )
@ -106,22 +104,24 @@
return [NSString stringWithFormat: @"%.0f", ratio];
}
- (NSString *) stringFittingInWidth: (float) width
withAttributes: (NSDictionary *) attributes
- (NSAttributedString *) attributedStringFittingInWidth: (float) width
attributes: (NSDictionary *) attributes
{
int i;
float realWidth = [self sizeWithAttributes: attributes].width;
/* The whole string fits */
if( realWidth <= width )
return self;
return [[[NSAttributedString alloc] initWithString: self attributes: attributes] autorelease];
float ellipsisWidth = [NS_ELLIPSIS sizeWithAttributes: attributes].width;
/* Width is too small */
if ( [NS_ELLIPSIS sizeWithAttributes: attributes].width > width )
return @"";
if ( ellipsisWidth > width )
return [[[NSAttributedString alloc] initWithString: @"" attributes: attributes] autorelease];
/* Don't worry about ellipsis until the end */
width -= [NS_ELLIPSIS sizeWithAttributes: attributes].width;
width -= ellipsisWidth;
/* Approximate how many characters we'll need to drop... */
i = [self length] * (width / realWidth);
@ -150,7 +150,8 @@
}
else;
return [newString stringByAppendingString: NS_ELLIPSIS];
return [[[NSAttributedString alloc] initWithString: [newString stringByAppendingString: NS_ELLIPSIS]
attributes: attributes] autorelease];
}
@end

View File

@ -25,6 +25,10 @@
#import <Cocoa/Cocoa.h>
#import <transmission.h>
#define RATIO_CHECK 1
#define RATIO_GLOBAL -1
#define RATIO_NO_CHECK 0
@interface Torrent : NSObject
{
tr_handle_t * fLib;
@ -36,12 +40,8 @@
NSUserDefaults * fDefaults;
NSImage * fIcon;
NSImage * fIconNonFlipped;
NSMutableString * fStatusString;
NSMutableString * fInfoString;
NSMutableString * fDownloadString;
NSMutableString * fUploadString;
NSImage * fIcon, * fIconFlipped;
NSMutableString * fNameString, * fProgressString, * fStatusString;
int fStopRatioSetting;
float fRatioLimit;
@ -51,8 +51,8 @@
- (id) initWithHistory: (NSDictionary *) history lib: (tr_handle_t *) lib;
- (NSDictionary *) history;
- (void) setFolder: (NSString *) path;
- (NSString *) getFolder;
- (void) setDownloadFolder: (NSString *) path;
- (NSString *) downloadFolder;
- (void) getAvailability: (int8_t *) tab size: (int) size;
- (void) update;
@ -61,42 +61,55 @@
- (void) sleep;
- (void) wakeUp;
- (float) ratio;
- (int) stopRatioSetting;
- (void) setStopRatioSetting: (int) setting;
- (float) ratioLimit;
- (void) setRatioLimit: (float) limit;
- (float) ratio;
- (int) stopRatioSetting;
- (void) setStopRatioSetting: (int) setting;
- (float) ratioLimit;
- (void) setRatioLimit: (float) limit;
- (NSNumber *) stateSortKey;
- (void) reveal;
- (void) trashTorrent;
- (void) trashData;
- (void) reveal;
- (void) trashTorrent;
- (void) trashData;
- (NSImage *) icon;
- (NSImage *) iconNonFlipped;
- (NSString *) path;
- (NSImage *) iconFlipped;
- (NSString *) name;
- (uint64_t) size;
- (NSString *) tracker;
- (NSString *) announce;
- (int) pieceSize;
- (int) pieceCount;
- (NSString *) hash;
- (NSString *) hashString;
- (NSString *) torrentLocation;
- (NSString *) dataLocation;
- (float) progress;
- (BOOL) isActive;
- (BOOL) isSeeding;
- (BOOL) isPaused;
- (BOOL) justFinished;
- (NSString *) statusString;
- (NSString *) infoString;
- (NSString *) downloadString;
- (NSString *) uploadString;
- (int) seeders;
- (int) leechers;
- (uint64_t) downloaded;
- (uint64_t) uploaded;
- (NSDate *) date;
- (NSString *) state;
- (float) progress;
- (BOOL) isActive;
- (BOOL) isSeeding;
- (BOOL) isPaused;
- (BOOL) justFinished;
- (NSString *) progressString;
- (NSString *) statusString;
- (int) seeders;
- (int) leechers;
- (int) totalPeers;
- (int) peersUploading;
- (int) peersDownloading;
- (float) downloadRate;
- (float) uploadRate;
- (uint64_t) downloaded;
- (uint64_t) uploaded;
- (NSArray *) fileList;
- (NSDate *) date;
- (NSNumber *) stateSortKey;
- (NSNumber *) progressSortKey;
@end

View File

@ -57,21 +57,20 @@
if (!(downloadFolder = [history objectForKey: @"DownloadFolder"]))
downloadFolder = [[fDefaults stringForKey: @"DownloadFolder"]
stringByExpandingTildeInPath];
[self setFolder: downloadFolder];
[self setDownloadFolder: downloadFolder];
NSString * paused;
if (!(paused = [history objectForKey: @"Paused"]) || [paused isEqualToString: @"NO"])
[self start];
}
return self;
}
- (NSDictionary *) history
{
return [NSDictionary dictionaryWithObjectsAndKeys:
[self path], @"TorrentPath",
[self getFolder], @"DownloadFolder",
[self torrentLocation], @"TorrentPath",
[self downloadFolder], @"DownloadFolder",
[self isActive] ? @"NO" : @"YES", @"Paused",
[self date], @"Date",
[NSNumber numberWithInt: fStopRatioSetting], @"StopRatioSetting",
@ -86,21 +85,19 @@
[fDate release];
[fIcon release];
[fIconNonFlipped release];
[fIconFlipped release];
[fProgressString release];
[fStatusString release];
[fInfoString release];
[fDownloadString release];
[fUploadString release];
}
[super dealloc];
}
- (void) setFolder: (NSString *) path
- (void) setDownloadFolder: (NSString *) path
{
tr_torrentSetFolder( fHandle, [path UTF8String] );
}
- (NSString *) getFolder
- (NSString *) downloadFolder
{
return [NSString stringWithUTF8String: tr_torrentGetFolder( fHandle )];
}
@ -115,84 +112,87 @@
fStat = tr_torrentStat( fHandle );
if ([self isSeeding])
if ((fStopRatioSetting == 1 && [self ratio] >= fRatioLimit)
|| (fStopRatioSetting == -1 && [fDefaults boolForKey: @"RatioCheck"]
if ((fStopRatioSetting == RATIO_CHECK && [self ratio] >= fRatioLimit)
|| (fStopRatioSetting == RATIO_GLOBAL && [fDefaults boolForKey: @"RatioCheck"]
&& [self ratio] >= [fDefaults floatForKey: @"RatioLimit"]))
{
[self stop];
[self setStopRatioSetting: 0];
[self setStopRatioSetting: RATIO_NO_CHECK];
fStat = tr_torrentStat( fHandle );
[[NSNotificationCenter defaultCenter] postNotificationName:
@"TorrentRatioChanged" object: self];
}
[fStatusString setString: @""];
[fInfoString setString: @""];
[fProgressString setString: @""];
if ([self progress] < 1.0)
[fProgressString appendFormat: @"%@ of %@ completed (%.2f%%)", [NSString stringForFileSize:
[self downloaded]], [NSString stringForFileSize: [self size]], 100 * [self progress]];
else
[fProgressString appendFormat: @"%@, uploaded %@ (ratio: %@)", [NSString stringForFileSize:
[self size]], [NSString stringForFileSize: [self uploaded]],
[NSString stringForRatioWithDownload: [self downloaded] upload: [self uploaded]]];
switch( fStat->status )
{
case TR_STATUS_PAUSE:
[fStatusString appendFormat: @"Paused (%.2f %%)",
100 * fStat->progress];
[fStatusString setString: @"Paused"];
break;
case TR_STATUS_CHECK:
[fStatusString appendFormat:
@"Checking existing files (%.2f %%)",
100 * fStat->progress];
[fStatusString setString: [@"Checking existing files" stringByAppendingString: NS_ELLIPSIS]];
break;
case TR_STATUS_DOWNLOAD:
if( fStat->eta < 0 )
{
[fStatusString appendFormat:
@"Finishing in --:--:-- (%.2f %%)",
100 * fStat->progress];
}
[fStatusString setString: @""];
[fStatusString appendFormat:
@"Downloading from %d of %d peer%s",
[self peersUploading], [self totalPeers],
([self totalPeers] == 1) ? "" : "s"];
int eta = fStat->eta;
if (eta < 0)
[fProgressString appendString: @" - remaining time unknown"];
else
{
[fStatusString appendFormat:
@"Finishing in %02d:%02d:%02d (%.2f %%)",
fStat->eta / 3600, ( fStat->eta / 60 ) % 60,
fStat->eta % 60, 100 * fStat->progress];
if (eta < 60)
[fProgressString appendFormat: @" - %d sec remaining", eta];
else if (eta < 3600)
[fProgressString appendFormat: @" - %d min %02d sec remaining",
eta / 60, eta % 60];
else
[fProgressString appendFormat: @" - %d hr %02d min remaining",
eta / 3600, (eta / 60) % 60];
}
[fInfoString appendFormat:
@"Downloading from %d of %d peer%s",
fStat->peersUploading, fStat->peersTotal,
( fStat->peersTotal == 1 ) ? "" : "s"];
break;
case TR_STATUS_SEED:
[fStatusString setString: @""];
[fStatusString appendFormat:
@"Seeding, uploading to %d of %d peer%s",
fStat->peersDownloading, fStat->peersTotal,
( fStat->peersTotal == 1 ) ? "" : "s"];
@"Seeding to %d of %d peer%s",
[self peersDownloading], [self totalPeers],
([self totalPeers] == 1) ? "" : "s"];
break;
case TR_STATUS_STOPPING:
[fStatusString setString: [@"Stopping"
stringByAppendingString: NS_ELLIPSIS]];
[fStatusString setString: [@"Stopping" stringByAppendingString: NS_ELLIPSIS]];
break;
}
if( fStat->error & TR_ETRACKER )
{
[fInfoString setString: [@"Error: " stringByAppendingString:
[fStatusString setString: [@"Error: " stringByAppendingString:
[NSString stringWithUTF8String: fStat->trackerError]]];
}
if( fStat->progress == 1.0 )
if ([self isActive])
{
[fDownloadString setString: [@"Ratio: " stringByAppendingString:
[NSString stringForRatio: fStat->downloaded
upload: fStat->uploaded]]];
if ([self progress] < 1.0)
[fStatusString appendFormat: @" - DL: %@, ", [NSString stringForSpeed: [self downloadRate]]];
[fStatusString appendString: [@"UL: " stringByAppendingString:
[NSString stringForSpeed: [self uploadRate]]]];
}
else
{
[fDownloadString setString: [@"DL: " stringByAppendingString:
[NSString stringForSpeed: fStat->rateDownload]]];
}
[fUploadString setString: [@"UL: " stringByAppendingString:
[NSString stringForSpeed: fStat->rateUpload]]];
}
- (void) start
@ -229,13 +229,10 @@
- (float) ratio
{
uint64_t downloaded = [self downloaded];
return downloaded > 0 ? [self uploaded] / downloaded : -1;
float downloaded = [self downloaded];
return downloaded > 0 ? (float)[self uploaded] / downloaded : -1;
}
/* 1: Check ratio
0: Don't check ratio
-1: Use defaults */
- (int) stopRatioSetting
{
return fStopRatioSetting;
@ -259,20 +256,18 @@
- (void) reveal
{
[[NSWorkspace sharedWorkspace] selectFile: [[self getFolder]
stringByAppendingPathComponent: [self name]]
[[NSWorkspace sharedWorkspace] selectFile: [self dataLocation]
inFileViewerRootedAtPath: nil];
}
- (void) trashTorrent
{
[self trashPath: [self path]];
[self trashPath: [self torrentLocation]];
}
- (void) trashData
{
[self trashPath: [[self getFolder]
stringByAppendingPathComponent: [self name]]];
[self trashPath: [self dataLocation]];
}
- (NSImage *) icon
@ -280,14 +275,9 @@
return fIcon;
}
- (NSImage *) iconNonFlipped
- (NSImage *) iconFlipped
{
return fIconNonFlipped;
}
- (NSString *) path
{
return [NSString stringWithUTF8String: fInfo->torrent];
return fIconFlipped;
}
- (NSString *) name
@ -321,7 +311,7 @@
return fInfo->pieceCount;
}
- (NSString *) hash
- (NSString *) hashString
{
NSMutableString * string = [NSMutableString
stringWithCapacity: SHA_DIGEST_LENGTH];
@ -333,6 +323,45 @@
return string;
}
- (NSString *) torrentLocation
{
return [NSString stringWithUTF8String: fInfo->torrent];;
}
- (NSString *) dataLocation
{
return [[self downloadFolder] stringByAppendingPathComponent: [self name]];
}
- (NSString *) state
{
switch( fStat->status )
{
case TR_STATUS_PAUSE:
return @"Paused";
break;
case TR_STATUS_CHECK:
return [@"Checking existing files" stringByAppendingString: NS_ELLIPSIS];
break;
case TR_STATUS_DOWNLOAD:
return @"Downloading";
break;
case TR_STATUS_SEED:
return @"Seeding";
break;
case TR_STATUS_STOPPING:
return [@"Stopping" stringByAppendingString: NS_ELLIPSIS];
break;
default:
return @"N/A";
}
}
- (float) progress
{
return fStat->progress;
@ -358,26 +387,16 @@
return tr_getFinished( fHandle );
}
- (NSString *) progressString
{
return fProgressString;
}
- (NSString *) statusString
{
return fStatusString;
}
- (NSString *) infoString
{
return fInfoString;
}
- (NSString *) downloadString
{
return fDownloadString;
}
- (NSString *) uploadString
{
return fUploadString;
}
- (int) seeders
{
return fStat->seeders;
@ -388,6 +407,33 @@
return fStat->leechers;
}
- (int) totalPeers
{
return fStat->peersTotal;
}
//peers uploading to you
- (int) peersUploading
{
return fStat->peersUploading;
}
//peers downloading from you
- (int) peersDownloading
{
return fStat->peersDownloading;
}
- (float) downloadRate
{
return fStat->rateDownload;
}
- (float) uploadRate
{
return fStat->rateUpload;
}
- (uint64_t) downloaded
{
return fStat->downloaded;
@ -398,6 +444,16 @@
return fStat->uploaded;
}
- (NSArray *) fileList
{
int count = fInfo->fileCount, i;
NSMutableArray * files = [NSMutableArray arrayWithCapacity: count];
for (i = 0; i < count; i++)
[files addObject: [[self downloadFolder] stringByAppendingPathComponent:
[NSString stringWithUTF8String: fInfo->files[i].name]]];
return files;
}
- (NSDate *) date
{
return fDate;
@ -413,6 +469,11 @@
return [NSNumber numberWithInt: 2];
}
- (NSNumber *) progressSortKey
{
return [NSNumber numberWithFloat: [self progress]];
}
@end
@ -444,15 +505,13 @@
NSString * fileType = ( fInfo->fileCount > 1 ) ?
NSFileTypeForHFSTypeCode('fldr') : [[self name] pathExtension];
fIcon = [[NSWorkspace sharedWorkspace] iconForFileType: fileType];
[fIcon setFlipped: YES];
[fIcon retain];
fIconNonFlipped = [[NSWorkspace sharedWorkspace] iconForFileType: fileType];
[fIconNonFlipped retain];
fIconFlipped = [fIcon copy];
[fIconFlipped setFlipped: YES];
fStatusString = [[NSMutableString alloc] initWithCapacity: 50];
fInfoString = [[NSMutableString alloc] initWithCapacity: 50];
fDownloadString = [[NSMutableString alloc] initWithCapacity: 10];
fUploadString = [[NSMutableString alloc] initWithCapacity: 10];
fProgressString = [[NSMutableString alloc] initWithCapacity: 50];
fStatusString = [[NSMutableString alloc] initWithCapacity: 75];
[self update];
return self;

View File

@ -30,15 +30,9 @@
@interface TorrentCell : NSCell
{
Torrent * fTorrent;
NSColor * fTextColor;
NSBitmapImageRep * fBitmap;
int fWidth;
int8_t * fPieces;
Torrent * fTorrent;
}
- (void) setTorrent: (Torrent *) torrent;
- (void) setTextColor: (NSColor *) color;
@end
#endif

View File

@ -96,37 +96,16 @@ static uint32_t kGreen[] =
fTorrent = torrent;
}
- (void) setTextColor: (NSColor *) color
{
fTextColor = color;
}
/***********************************************************************
* init
***********************************************************************
* Prepares the NSBitmapImageReps we are going to need in order to
* draw.
**********************************************************************/
- (id) init
{
self = [super init];
return self;
}
/***********************************************************************
* buildSimpleBar
**********************************************************************/
- (void) buildSimpleBar
- (void) buildSimpleBar: (int) width bitmap: (NSBitmapImageRep *) bitmap
{
int h, w, end, pixelsPerRow;
uint32_t * p;
uint32_t * colors;
pixelsPerRow = [fBitmap bytesPerRow] / 4;
pixelsPerRow = [bitmap bytesPerRow] / 4;
p = (uint32_t *) [fBitmap bitmapData] + 1;
end = lrintf( floor( [fTorrent progress] * ( fWidth - 2 ) ) );
p = (uint32_t *) [bitmap bitmapData] + 1;
end = lrintf( floor( [fTorrent progress] * ( width - 2 ) ) );
if( [fTorrent isSeeding] )
colors = kGreen;
@ -141,7 +120,7 @@ static uint32_t kGreen[] =
{
p[w] = htonl( colors[h] );
}
for( w = end; w < fWidth - 2; w++ )
for( w = end; w < width - 2; w++ )
{
p[w] = htonl( kBack[h] );
}
@ -149,30 +128,27 @@ static uint32_t kGreen[] =
}
}
/***********************************************************************
* buildAdvancedBar
**********************************************************************/
- (void) buildAdvancedBar
- (void) buildAdvancedBar: (int) width bitmap: (NSBitmapImageRep *) bitmap
{
int h, w, end, pixelsPerRow;
uint32_t * p, * colors;
uint8_t * bitmapData = [fBitmap bitmapData];
int bytesPerRow = [fBitmap bytesPerRow];
uint8_t * bitmapData = [bitmap bitmapData];
int bytesPerRow = [bitmap bytesPerRow];
fPieces = malloc( fWidth );
[fTorrent getAvailability: fPieces size: fWidth];
int8_t * pieces = malloc( width );
[fTorrent getAvailability: pieces size: width];
if( [fTorrent isSeeding] )
{
/* All green, same as the simple bar */
[self buildSimpleBar];
[self buildSimpleBar: width bitmap: bitmap];
return;
}
pixelsPerRow = [fBitmap bytesPerRow] / 4;
pixelsPerRow = bytesPerRow / 4;
/* First two lines: dark blue to show progression */
end = lrintf( floor( [fTorrent progress] * ( fWidth - 2 ) ) );
end = lrintf( floor( [fTorrent progress] * ( width - 2 ) ) );
for( h = 0; h < 2; h++ )
{
p = (uint32_t *) ( bitmapData + h * bytesPerRow ) + 1;
@ -180,7 +156,7 @@ static uint32_t kGreen[] =
{
p[w] = htonl( kBlue4[h] );
}
for( w = end; w < fWidth - 2; w++ )
for( w = end; w < width - 2; w++ )
{
p[w] = htonl( kBack[h] );
}
@ -188,25 +164,25 @@ static uint32_t kGreen[] =
/* Lines 2 to 14: blue or grey depending on whether
we have the piece or not */
for( w = 0; w < fWidth - 2; w++ )
for( w = 0; w < width - 2; w++ )
{
/* Point to pixel ( 2 + w, 2 ). We will then draw
"vertically" */
p = (uint32_t *) ( bitmapData + 2 * bytesPerRow ) + 1 + w;
if( fPieces[w] < 0 )
if( pieces[w] < 0 )
{
colors = kGray;
}
else if( fPieces[w] < 1 )
else if( pieces[w] < 1 )
{
colors = kRed;
}
else if( fPieces[w] < 2 )
else if( pieces[w] < 2 )
{
colors = kBlue1;
}
else if( fPieces[w] < 3 )
else if( pieces[w] < 3 )
{
colors = kBlue2;
}
@ -222,110 +198,105 @@ static uint32_t kGreen[] =
}
}
free( fPieces );
free( pieces );
}
- (void) buildBar
- (void) buildBarWithWidth: (int) width bitmap: (NSBitmapImageRep *) bitmap
{
int h;
uint32_t * p;
/* Left and right borders */
p = (uint32_t *) [fBitmap bitmapData];
p = (uint32_t *) [bitmap bitmapData];
for( h = 0; h < BAR_HEIGHT; h++ )
{
p[0] = htonl( kBorder[h] );
p[fWidth - 1] = htonl( kBorder[h] );
p += [fBitmap bytesPerRow] / 4;
p[width - 1] = htonl( kBorder[h] );
p += [bitmap bytesPerRow] / 4;
}
/* ...and redraw the progress bar on the top of it */
if( [[NSUserDefaults standardUserDefaults]
boolForKey:@"UseAdvancedBar"])
{
[self buildAdvancedBar];
}
if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseAdvancedBar"])
[self buildAdvancedBar: width bitmap: bitmap];
else
{
[self buildSimpleBar];
}
[self buildSimpleBar: width bitmap: bitmap];
}
/***********************************************************************
* drawWithFrame
***********************************************************************
* We have the strings, we have the bitmap. Let's just draw them where
* they belong.
**********************************************************************/
- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) view
{
if( ![view lockFocusIfCanDraw] )
{
return;
}
NSMutableDictionary * attributes;
attributes = [NSMutableDictionary dictionaryWithCapacity: 2];
[attributes setObject: fTextColor
forKey: NSForegroundColorAttributeName];
BOOL highlighted = [self isHighlighted] && [[view window] isKeyWindow];
NSDictionary * nameAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
highlighted ? [NSColor whiteColor] : [NSColor blackColor],
NSForegroundColorAttributeName,
[NSFont messageFontOfSize: 12], NSFontAttributeName, nil];
NSDictionary * statusAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
highlighted ? [NSColor whiteColor] : [NSColor darkGrayColor],
NSForegroundColorAttributeName,
[NSFont messageFontOfSize: 9], NSFontAttributeName, nil];
NSPoint pen = cellFrame.origin;
float padding = 3.0, linePadding = 2.0;
/* Draw the icon */
pen.x += 5; pen.y += 10;
NSImage * icon = [fTorrent icon];
//icon
NSImage * icon = [fTorrent iconFlipped];
NSSize iconSize = [icon size];
pen.x += padding;
pen.y += (cellFrame.size.height - iconSize.height) * 0.5;
[icon drawAtPoint: pen fromRect:
NSMakeRect( 0, 0, [icon size].width, [icon size].height )
NSMakeRect( 0, 0, iconSize.width, iconSize.height )
operation: NSCompositeSourceOver fraction: 1.0];
NSString * string;
fWidth = NSWidth( cellFrame ) - [icon size].width - 15;
float extraNameShift = 1.0,
mainWidth = cellFrame.size.width - iconSize.width - 3.0 * padding - extraNameShift;
/* Draw file or folder name */
pen.x += [icon size].width + 5; pen.y -= 7;
[attributes setObject: [NSFont messageFontOfSize: 11]
forKey: NSFontAttributeName];
NSString * sizeString = [NSString stringWithFormat: @" (%@)",
[NSString stringForFileSize: [fTorrent size]]];
string = [[[fTorrent name] stringFittingInWidth: fWidth - 50 -
[sizeString sizeWithAttributes: attributes].width
withAttributes: attributes] stringByAppendingString: sizeString];
[string drawAtPoint: pen withAttributes: attributes];
//name string
pen.x += iconSize.width + padding + extraNameShift;
pen.y = cellFrame.origin.y + padding;
NSAttributedString * nameString = [[fTorrent name] attributedStringFittingInWidth: mainWidth
attributes: nameAttributes];
[nameString drawAtPoint: pen];
//progress string
pen.y += [nameString size].height + linePadding - 1.0;
NSAttributedString * progressString = [[fTorrent progressString]
attributedStringFittingInWidth: mainWidth attributes: statusAttributes];
[progressString drawAtPoint: pen];
/* Draw the progress bar */
pen.y += 17;
fBitmap = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: nil pixelsWide: fWidth
//progress bar
pen.x -= extraNameShift;
pen.y += [progressString size].height + linePadding;
float barWidth = mainWidth + extraNameShift - 39.5 - padding;
NSBitmapImageRep * bitmap = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: nil pixelsWide: barWidth
pixelsHigh: BAR_HEIGHT bitsPerSample: 8 samplesPerPixel: 4
hasAlpha: YES isPlanar: NO colorSpaceName:
NSCalibratedRGBColorSpace bytesPerRow: 0 bitsPerPixel: 0];
NSImage * img = [[NSImage alloc] initWithSize: [fBitmap size]];
[img addRepresentation: fBitmap];
NSImage * img = [[NSImage alloc] initWithSize: [bitmap size]];
[img addRepresentation: bitmap];
[img setFlipped: YES];
[self buildBar];
[self buildBarWithWidth: barWidth bitmap: bitmap];
[img drawAtPoint: pen fromRect: NSMakeRect( 0, 0,
[img size].width, [img size].height )
operation: NSCompositeSourceOver fraction: 1.0];
[img release];
[fBitmap release];
[bitmap release];
/* Status strings */
[attributes setObject: [NSFont messageFontOfSize: 9]
forKey: NSFontAttributeName];
pen.y += BAR_HEIGHT + 2;
[[fTorrent statusString] drawAtPoint: pen withAttributes: attributes];
pen.y += 13;
string = [[fTorrent infoString] stringFittingInWidth:
( fWidth - 80 ) withAttributes: attributes];
[string drawAtPoint: pen withAttributes: attributes];
/* Rates */
pen.x += fWidth - 70; pen.y -= 13;
[[fTorrent downloadString] drawAtPoint: pen withAttributes: attributes];
pen.y += 13;
[[fTorrent uploadString] drawAtPoint: pen withAttributes: attributes];
[view unlockFocus];
//status strings
pen.x += extraNameShift;
pen.y += BAR_HEIGHT + linePadding;
NSAttributedString * statusString = [[fTorrent statusString]
attributedStringFittingInWidth: mainWidth attributes: statusAttributes];
[statusString drawAtPoint: pen];
[nameAttributes release];
[statusAttributes release];
}
@end

View File

@ -35,8 +35,7 @@
NSPoint fClickPoint;
IBOutlet NSMenu * fContextRow;
IBOutlet NSMenu * fContextNoRow;
IBOutlet NSMenu * fContextRow, * fContextNoRow;
}
- (void) setTorrents: (NSArray *) torrents;

View File

@ -27,6 +27,11 @@
#import "Torrent.h"
#import "Utils.h"
#define BUTTON_WIDTH 14.0
#define BUTTON_TO_TOP 32.5
#define AREA_CENTER 23.0
#define DISTANCE_FROM_CENTER 2.5
@implementation TorrentTableView
- (void) setTorrents: (NSArray *) torrents
@ -36,28 +41,22 @@
- (NSRect) pauseRectForRow: (int) row
{
int col;
NSRect cellRect, rect;
col = [self columnWithIdentifier: @"Torrent"];
cellRect = [self frameOfCellAtColumn: col row: row];
rect = NSMakeRect( cellRect.origin.x + cellRect.size.width - 39,
cellRect.origin.y + 3, 14, 14 );
return rect;
NSRect cellRect = [self frameOfCellAtColumn:
[self columnWithIdentifier: @"Torrent"] row: row];
return NSMakeRect(cellRect.origin.x + cellRect.size.width
- AREA_CENTER - DISTANCE_FROM_CENTER - BUTTON_WIDTH,
cellRect.origin.y + BUTTON_TO_TOP, BUTTON_WIDTH, BUTTON_WIDTH);
}
- (NSRect) revealRectForRow: (int) row
{
int col;
NSRect cellRect, rect;
col = [self columnWithIdentifier: @"Torrent"];
cellRect = [self frameOfCellAtColumn: col row: row];
rect = NSMakeRect( cellRect.origin.x + cellRect.size.width - 20,
cellRect.origin.y + 3, 14, 14 );
return rect;
NSRect cellRect = [self frameOfCellAtColumn:
[self columnWithIdentifier: @"Torrent"] row: row];
return NSMakeRect(cellRect.origin.x + cellRect.size.width
- AREA_CENTER + DISTANCE_FROM_CENTER,
cellRect.origin.y + BUTTON_TO_TOP, BUTTON_WIDTH, BUTTON_WIDTH);
}
- (BOOL) pointInPauseRect: (NSPoint) point
@ -184,7 +183,7 @@
{
[image setFlipped: YES];
[image drawAtPoint: rect.origin fromRect:
NSMakeRect( 0, 0, 14, 14 ) operation:
NSMakeRect(0, 0, BUTTON_WIDTH, BUTTON_WIDTH) operation:
NSCompositeSourceOver fraction: 1.0];
}
@ -194,7 +193,7 @@
[NSImage imageNamed: @"RevealOff.png"];
[image setFlipped: YES];
[image drawAtPoint: rect.origin fromRect:
NSMakeRect( 0, 0, 14, 14 ) operation:
NSMakeRect(0, 0, BUTTON_WIDTH, BUTTON_WIDTH) operation:
NSCompositeSourceOver fraction: 1.0];
}
}