2006-07-16 19:39:23 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* $ Id $
*
* Copyright ( c ) 2005 -2006 Transmission authors and contributors
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the "Software" ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
* FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
# import < IOKit / IOMessage . h >
# import "Controller.h"
# import "Torrent.h"
# import "TorrentCell.h"
# import "TorrentTableView.h"
# import "StringAdditions.h"
2006-09-05 04:28:07 +00:00
# import "UKKQueue.h"
2006-07-16 19:39:23 +00:00
# import < Sparkle / Sparkle . h >
# define TOOLBAR_OPEN @ "Toolbar Open"
# define TOOLBAR_REMOVE @ "Toolbar Remove"
# define TOOLBAR_INFO @ "Toolbar Info"
# define TOOLBAR_PAUSE _ALL @ "Toolbar Pause All"
# define TOOLBAR_RESUME _ALL @ "Toolbar Resume All"
# define TOOLBAR_PAUSE _SELECTED @ "Toolbar Pause Selected"
# define TOOLBAR_RESUME _SELECTED @ "Toolbar Resume Selected"
2006-07-23 16:28:33 +00:00
# define TOOLBAR_FILTER @ "Toolbar Toggle Filter"
# define GROWL_DOWNLOAD _COMPLETE @ "Download Complete"
# define GROWL_SEEDING _COMPLETE @ "Seeding Complete"
# define GROWL_AUTO _ADD @ "Torrent Auto Added"
2006-08-08 03:04:25 +00:00
# define GROWL_AUTO _SPEED _LIMIT @ "Speed Limit Auto Changed"
2006-07-16 19:39:23 +00:00
# define TORRENT_TABLE _VIEW _DATA _TYPE @ "TorrentTableViewDataType"
2006-07-29 17:46:32 +00:00
# define ROW_HEIGHT _REGULAR 65.0
2006-07-29 16:58:44 +00:00
# define ROW_HEIGHT _SMALL 40.0
# define WINDOW_REGULAR _WIDTH 468.0
2006-08-09 03:25:41 +00:00
# define UPDATE_UI _SECONDS 1.0
2006-10-21 20:09:28 +00:00
# define AUTO_SPEED _LIMIT _SECONDS 5.0
2006-08-08 02:11:51 +00:00
2006-07-16 19:39:23 +00:00
# define WEBSITE_URL @ "http://transmission.m0k.org/"
# define FORUM_URL @ "http://transmission.m0k.org/forum/"
2006-07-23 14:22:01 +00:00
static void sleepCallBack ( void * controller , io_service _t y , natural_t messageType , void * messageArgument )
2006-07-16 19:39:23 +00:00
{
Controller * c = controller ;
[ c sleepCallBack : messageType argument : messageArgument ] ;
}
@ implementation Controller
2006-08-21 22:07:08 +00:00
+ ( void ) initialize
{
[ [ NSUserDefaults standardUserDefaults ] registerDefaults : [ NSDictionary dictionaryWithContentsOfFile :
[ [ NSBundle mainBundle ] pathForResource : @ "Defaults" ofType : @ "plist" ] ] ] ;
}
2006-07-16 19:39:23 +00:00
- ( id ) init
{
if ( ( self = [ super init ] ) )
{
fLib = tr_init ( ) ;
fTorrents = [ [ NSMutableArray alloc ] initWithCapacity : 10 ] ;
2006-08-06 17:06:05 +00:00
fDisplayedTorrents = [ [ NSMutableArray alloc ] initWithCapacity : 10 ] ;
2006-07-16 19:39:23 +00:00
fDefaults = [ NSUserDefaults standardUserDefaults ] ;
2006-08-21 22:07:08 +00:00
fMessageController = [ [ MessageWindowController alloc ] initWithWindowNibName : @ "MessageWindow" ] ;
2006-07-16 19:39:23 +00:00
fInfoController = [ [ InfoWindowController alloc ] initWithWindowNibName : @ "InfoWindow" ] ;
2006-07-30 22:11:08 +00:00
fPrefsController = [ [ PrefsController alloc ] initWithWindowNibName : @ "PrefsWindow" handle : fLib ] ;
2006-08-21 22:07:08 +00:00
2006-07-16 19:39:23 +00:00
fBadger = [ [ Badger alloc ] init ] ;
[ GrowlApplicationBridge setGrowlDelegate : self ] ;
2006-09-05 04:28:07 +00:00
[ [ UKKQueue sharedFileWatcher ] setDelegate : self ] ;
2006-07-16 19:39:23 +00:00
}
return self ;
}
- ( void ) dealloc
{
[ [ NSNotificationCenter defaultCenter ] removeObserver : self ] ;
[ fInfoController release ] ;
2006-09-25 18:37:45 +00:00
[ fMessageController release ] ;
2006-07-16 19:39:23 +00:00
[ fPrefsController release ] ;
2006-09-25 18:37:45 +00:00
[ fToolbar release ] ;
[ fTorrents release ] ;
[ fDisplayedTorrents release ] ;
2006-07-16 19:39:23 +00:00
[ fBadger release ] ;
[ fSortType release ] ;
[ fFilterType release ] ;
2006-10-16 02:42:46 +00:00
[ fAutoImportedNames release ] ;
2006-10-16 02:35:42 +00:00
2006-07-16 19:39:23 +00:00
tr_close ( fLib ) ;
[ super dealloc ] ;
}
- ( void ) awakeFromNib
{
2006-07-22 18:47:21 +00:00
[ fStatusBar setBackgroundImage : [ NSImage imageNamed : @ "StatusBarBackground.png" ] ] ;
2006-07-16 21:02:29 +00:00
[ fFilterBar setBackgroundImage : [ NSImage imageNamed : @ "FilterBarBackground.png" ] ] ;
2006-07-16 19:39:23 +00:00
[ fWindow setAcceptsMouseMovedEvents : YES ] ; // ensure filter buttons display correctly
[ fAdvancedBarItem setState : [ fDefaults boolForKey : @ "UseAdvancedBar" ] ] ;
fToolbar = [ [ NSToolbar alloc ] initWithIdentifier : @ "Transmission Toolbar" ] ;
[ fToolbar setDelegate : self ] ;
[ fToolbar setAllowsUserCustomization : YES ] ;
[ fToolbar setAutosavesConfiguration : YES ] ;
[ fWindow setToolbar : fToolbar ] ;
[ fWindow setDelegate : self ] ;
[ fWindow makeFirstResponder : fTableView ] ;
2006-08-08 22:23:33 +00:00
[ fWindow setExcludedFromWindowsMenu : YES ] ;
2006-07-16 19:39:23 +00:00
// set table size
if ( [ fDefaults boolForKey : @ "SmallView" ] )
{
[ fTableView setRowHeight : ROW_HEIGHT _SMALL ] ;
[ fSmallViewItem setState : NSOnState ] ;
}
// window min height
NSSize contentMinSize = [ fWindow contentMinSize ] ;
contentMinSize . height = [ [ fWindow contentView ] frame ] . size . height - [ fScrollView frame ] . size . height
+ [ fTableView rowHeight ] + [ fTableView intercellSpacing ] . height ;
[ fWindow setContentMinSize : contentMinSize ] ;
2006-09-08 01:14:31 +00:00
// set info and filter keyboard shortcuts
unichar rightChar = NSRightArrowFunctionKey , leftChar = NSLeftArrowFunctionKey ;
[ fNextInfoTabItem setKeyEquivalent : [ NSString stringWithCharacters : & rightChar length : 1 ] ] ;
[ fPrevInfoTabItem setKeyEquivalent : [ NSString stringWithCharacters : & leftChar length : 1 ] ] ;
[ fNextFilterItem setKeyEquivalent : [ NSString stringWithCharacters : & rightChar length : 1 ] ] ;
[ fNextFilterItem setKeyEquivalentModifierMask : NSCommandKeyMask + NSAlternateKeyMask ] ;
[ fPrevFilterItem setKeyEquivalent : [ NSString stringWithCharacters : & leftChar length : 1 ] ] ;
[ fPrevFilterItem setKeyEquivalentModifierMask : NSCommandKeyMask + NSAlternateKeyMask ] ;
2006-07-16 19:39:23 +00:00
// set up filter bar
NSView * contentView = [ fWindow contentView ] ;
2006-07-19 00:24:54 +00:00
[ fFilterBar setHidden : YES ] ;
2006-07-16 19:39:23 +00:00
NSRect filterBarFrame = [ fFilterBar frame ] ;
filterBarFrame . size . width = [ fWindow frame ] . size . width ;
[ fFilterBar setFrame : filterBarFrame ] ;
[ contentView addSubview : fFilterBar ] ;
2006-07-23 19:22:24 +00:00
[ fFilterBar setFrameOrigin : NSMakePoint ( 0 , NSMaxY ( [ contentView frame ] ) ) ] ;
2006-07-17 02:59:22 +00:00
2006-07-16 19:39:23 +00:00
[ self showFilterBar : [ fDefaults boolForKey : @ "FilterBar" ] animate : NO ] ;
// set up status bar
2006-07-19 00:24:54 +00:00
[ fStatusBar setHidden : YES ] ;
2006-07-16 19:39:23 +00:00
NSRect statusBarFrame = [ fStatusBar frame ] ;
statusBarFrame . size . width = [ fWindow frame ] . size . width ;
[ fStatusBar setFrame : statusBarFrame ] ;
[ contentView addSubview : fStatusBar ] ;
2006-07-23 19:22:24 +00:00
[ fStatusBar setFrameOrigin : NSMakePoint ( 0 , NSMaxY ( [ contentView frame ] ) ) ] ;
2006-07-16 19:39:23 +00:00
[ self showStatusBar : [ fDefaults boolForKey : @ "StatusBar" ] animate : NO ] ;
// set speed limit
2006-07-19 02:50:07 +00:00
fSpeedLimitNormalImage = [ fSpeedLimitButton image ] ;
fSpeedLimitBlueImage = [ NSImage imageNamed : @ "SpeedLimitButtonBlue.png" ] ;
fSpeedLimitGraphiteImage = [ NSImage imageNamed : @ "SpeedLimitButtonGraphite.png" ] ;
2006-07-16 19:39:23 +00:00
[ self updateControlTint : nil ] ;
2006-07-19 02:50:07 +00:00
if ( ( fSpeedLimitEnabled = [ fDefaults boolForKey : @ "SpeedLimit" ] ) )
2006-07-16 19:39:23 +00:00
{
[ fSpeedLimitItem setState : NSOnState ] ;
[ fSpeedLimitDockItem setState : NSOnState ] ;
2006-07-19 02:50:07 +00:00
[ fSpeedLimitButton setImage : [ NSColor currentControlTint ] = = NSBlueControlTint
? fSpeedLimitBlueImage : fSpeedLimitGraphiteImage ] ;
2006-07-16 19:39:23 +00:00
}
2006-10-24 20:34:13 +00:00
[ fActionButton setToolTip : NSLocalizedString ( @ "Shortcuts for changing global settings." , "Main window -> 1st bottom left button (action) tooltip" ) ] ;
[ fSpeedLimitButton setToolTip : NSLocalizedString ( @ "Speed Limit overrides the total bandwidth limits with its own limits." , "Main window -> 2nd bottom left button (turtle) tooltip" ) ] ;
2006-07-16 19:39:23 +00:00
2006-08-06 17:06:05 +00:00
[ fTableView setTorrents : fDisplayedTorrents ] ;
2006-07-16 19:39:23 +00:00
[ [ fTableView tableColumnWithIdentifier : @ "Torrent" ] setDataCell : [ [ TorrentCell alloc ] init ] ] ;
[ fTableView registerForDraggedTypes : [ NSArray arrayWithObjects : NSFilenamesPboardType ,
TORRENT_TABLE _VIEW _DATA _TYPE , nil ] ] ;
// register for sleep notifications
IONotificationPortRef notify ;
io_object _t iterator ;
if ( fRootPort = IORegisterForSystemPower ( self , & notify , sleepCallBack , & iterator ) )
2006-09-05 04:37:07 +00:00
CFRunLoopAddSource ( CFRunLoopGetCurrent ( ) , IONotificationPortGetRunLoopSource ( notify ) , kCFRunLoopCommonModes ) ;
2006-07-16 19:39:23 +00:00
else
NSLog ( @ "Could not IORegisterForSystemPower" ) ;
// load torrents from history
Torrent * torrent ;
NSDictionary * historyItem ;
NSEnumerator * enumerator = [ [ fDefaults arrayForKey : @ "History" ] objectEnumerator ] ;
while ( ( historyItem = [ enumerator nextObject ] ) )
if ( ( torrent = [ [ Torrent alloc ] initWithHistory : historyItem lib : fLib ] ) )
{
[ fTorrents addObject : torrent ] ;
[ torrent release ] ;
}
// set sort
fSortType = [ [ fDefaults stringForKey : @ "Sort" ] retain ] ;
2006-07-22 14:08:35 +00:00
NSMenuItem * currentSortItem , * currentSortActionItem ;
2006-07-16 19:39:23 +00:00
if ( [ fSortType isEqualToString : @ "Name" ] )
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
currentSortItem = fNameSortItem ;
2006-07-22 14:08:35 +00:00
currentSortActionItem = fNameSortActionItem ;
}
2006-07-16 19:39:23 +00:00
else if ( [ fSortType isEqualToString : @ "State" ] )
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
currentSortItem = fStateSortItem ;
2006-07-22 14:08:35 +00:00
currentSortActionItem = fStateSortActionItem ;
}
2006-07-16 19:39:23 +00:00
else if ( [ fSortType isEqualToString : @ "Progress" ] )
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
currentSortItem = fProgressSortItem ;
2006-07-22 14:08:35 +00:00
currentSortActionItem = fProgressSortActionItem ;
}
2006-07-16 19:39:23 +00:00
else if ( [ fSortType isEqualToString : @ "Date" ] )
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
currentSortItem = fDateSortItem ;
2006-07-22 14:08:35 +00:00
currentSortActionItem = fDateSortActionItem ;
}
2006-07-16 19:39:23 +00:00
else
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
currentSortItem = fOrderSortItem ;
2006-07-22 14:08:35 +00:00
currentSortActionItem = fOrderSortActionItem ;
}
2006-07-16 19:39:23 +00:00
[ currentSortItem setState : NSOnState ] ;
2006-07-22 14:08:35 +00:00
[ currentSortActionItem setState : NSOnState ] ;
2006-07-16 19:39:23 +00:00
// set filter
fFilterType = [ [ fDefaults stringForKey : @ "Filter" ] retain ] ;
BarButton * currentFilterButton ;
if ( [ fFilterType isEqualToString : @ "Pause" ] )
currentFilterButton = fPauseFilterButton ;
else if ( [ fFilterType isEqualToString : @ "Seed" ] )
currentFilterButton = fSeedFilterButton ;
else if ( [ fFilterType isEqualToString : @ "Download" ] )
currentFilterButton = fDownloadFilterButton ;
else
currentFilterButton = fNoFilterButton ;
[ currentFilterButton setEnabled : YES ] ;
// set upload limit action button
2006-10-24 20:34:13 +00:00
[ fUploadLimitItem setTitle : [ NSString stringWithFormat : NSLocalizedString ( @ "Limit (%d KB/s)" , "Action context menu -> upload limit" ) ,
2006-07-16 19:39:23 +00:00
[ fDefaults integerForKey : @ "UploadLimit" ] ] ] ;
if ( [ fDefaults boolForKey : @ "CheckUpload" ] )
[ fUploadLimitItem setState : NSOnState ] ;
else
[ fUploadNoLimitItem setState : NSOnState ] ;
// set download limit action menu
2006-10-24 20:34:13 +00:00
[ fDownloadLimitItem setTitle : [ NSString stringWithFormat : NSLocalizedString ( @ "Limit (%d KB/s)" , "Action context menu -> download limit" ) ,
2006-07-16 19:39:23 +00:00
[ fDefaults integerForKey : @ "DownloadLimit" ] ] ] ;
if ( [ fDefaults boolForKey : @ "CheckDownload" ] )
[ fDownloadLimitItem setState : NSOnState ] ;
else
[ fDownloadNoLimitItem setState : NSOnState ] ;
// set ratio action menu
2006-10-24 20:34:13 +00:00
[ fRatioSetItem setTitle : [ NSString stringWithFormat : NSLocalizedString ( @ "Stop at Ratio (%.2f)" , "Action context menu -> ratio stop" ) ,
2006-07-16 19:39:23 +00:00
[ fDefaults floatForKey : @ "RatioLimit" ] ] ] ;
if ( [ fDefaults boolForKey : @ "RatioCheck" ] )
[ fRatioSetItem setState : NSOnState ] ;
else
[ fRatioNotSetItem setState : NSOnState ] ;
// observe notifications
NSNotificationCenter * nc = [ NSNotificationCenter defaultCenter ] ;
2006-07-30 18:37:29 +00:00
[ nc addObserver : self selector : @ selector ( torrentFinishedDownloading : )
name : @ "TorrentFinishedDownloading" object : nil ] ;
2006-07-16 19:39:23 +00:00
[ nc addObserver : self selector : @ selector ( updateControlTint : )
name : NSControlTintDidChangeNotification object : nil ] ;
[ nc addObserver : self selector : @ selector ( prepareForUpdate : )
name : SUUpdaterWillRestartNotification object : nil ] ;
fUpdateInProgress = NO ;
[ nc addObserver : self selector : @ selector ( limitGlobalChange : )
name : @ "LimitGlobalChange" object : nil ] ;
[ nc addObserver : self selector : @ selector ( ratioGlobalChange : )
name : @ "RatioGlobalChange" object : nil ] ;
2006-08-12 20:13:25 +00:00
[ nc addObserver : self selector : @ selector ( autoSpeedLimitChange : )
2006-08-11 22:58:14 +00:00
name : @ "AutoSpeedLimitChange" object : nil ] ;
2006-10-16 02:35:42 +00:00
[ nc addObserver : self selector : @ selector ( changeAutoImport )
2006-07-22 16:38:05 +00:00
name : @ "AutoImportSettingChange" object : nil ] ;
2006-07-23 14:50:36 +00:00
[ nc addObserver : self selector : @ selector ( setWindowSizeToFit )
2006-07-22 16:38:05 +00:00
name : @ "AutoSizeSettingChange" object : nil ] ;
2006-07-16 19:39:23 +00:00
// check to start another because of stopped torrent
[ nc addObserver : self selector : @ selector ( checkWaitingForStopped : )
name : @ "StoppedDownloading" object : nil ] ;
// check all torrents for starting
[ nc addObserver : self selector : @ selector ( globalStartSettingChange : )
name : @ "GlobalStartSettingChange" object : nil ] ;
// check if torrent should now start
[ nc addObserver : self selector : @ selector ( torrentStoppedForRatio : )
name : @ "TorrentStoppedForRatio" object : nil ] ;
2006-07-30 21:49:58 +00:00
// change that just impacts the dock badge
[ nc addObserver : self selector : @ selector ( resetDockBadge : )
name : @ "DockBadgeChange" object : nil ] ;
2006-07-16 19:39:23 +00:00
// timer to update the interface every second
fCompleted = 0 ;
[ self updateUI : nil ] ;
2006-08-09 03:25:41 +00:00
fTimer = [ NSTimer scheduledTimerWithTimeInterval : UPDATE_UI _SECONDS target : self
2006-07-16 19:39:23 +00:00
selector : @ selector ( updateUI : ) userInfo : nil repeats : YES ] ;
[ [ NSRunLoop currentRunLoop ] addTimer : fTimer forMode : NSModalPanelRunLoopMode ] ;
[ [ NSRunLoop currentRunLoop ] addTimer : fTimer forMode : NSEventTrackingRunLoopMode ] ;
[ self applyFilter : nil ] ;
2006-07-23 14:42:54 +00:00
2006-07-16 19:39:23 +00:00
[ fWindow makeKeyAndOrderFront : nil ] ;
if ( [ fDefaults boolForKey : @ "InfoVisible" ] )
[ self showInfo : nil ] ;
2006-07-22 19:00:47 +00:00
2006-08-08 02:11:51 +00:00
// timer to auto toggle speed limit
2006-08-12 20:13:25 +00:00
[ self autoSpeedLimitChange : nil ] ;
2006-08-08 02:11:51 +00:00
fSpeedLimitTimer = [ NSTimer scheduledTimerWithTimeInterval : AUTO_SPEED _LIMIT _SECONDS target : self
selector : @ selector ( autoSpeedLimit : ) userInfo : nil repeats : YES ] ;
2006-09-05 04:37:07 +00:00
2006-10-16 02:47:10 +00:00
// auto importing
fAutoImportedNames = [ [ NSMutableArray alloc ] init ] ;
2006-09-05 04:37:07 +00:00
[ self checkAutoImportDirectory ] ;
2006-07-16 19:39:23 +00:00
}
- ( BOOL ) applicationShouldHandleReopen : ( NSApplication * ) app hasVisibleWindows : ( BOOL ) visibleWindows
{
if ( ! [ fWindow isVisible ] && ! [ [ fPrefsController window ] isVisible ] )
[ fWindow makeKeyAndOrderFront : nil ] ;
return NO ;
}
- ( NSApplicationTerminateReply ) applicationShouldTerminate : ( NSApplication * ) sender
{
if ( ! fUpdateInProgress && [ fDefaults boolForKey : @ "CheckQuit" ] )
{
int active = 0 , downloading = 0 ;
Torrent * torrent ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( [ torrent isActive ] )
{
active + + ;
if ( ! [ torrent isSeeding ] )
downloading + + ;
}
if ( [ fDefaults boolForKey : @ "CheckQuitDownloading" ] ? downloading > 0 : active > 0 )
{
NSString * message = active = = 1
2006-10-24 20:34:13 +00:00
? NSLocalizedString ( @ "There is an active transfer. Do you really want to quit?" , "Confirm Quit panel -> message" )
2006-07-16 19:39:23 +00:00
: [ NSString stringWithFormat :
2006-10-24 20:34:13 +00:00
NSLocalizedString ( @ "There are %d active transfers. Do you really want to quit?" , "Confirm Quit panel -> message" ) , active ] ;
2006-07-16 19:39:23 +00:00
2006-10-24 20:34:13 +00:00
NSBeginAlertSheet ( NSLocalizedString ( @ "Confirm Quit" , "Confirm Quit panel -> title" ) , NSLocalizedString ( @ "Quit" , "Confirm Quit panel -> button" ) , NSLocalizedString ( @ "Cancel" , "Confirm Quit panel -> button" ) , nil , fWindow , self ,
2006-07-22 20:39:33 +00:00
@ selector ( quitSheetDidEnd : returnCode : contextInfo : ) , nil , nil , message ) ;
2006-07-16 19:39:23 +00:00
return NSTerminateLater ;
}
}
return NSTerminateNow ;
}
2006-07-22 20:39:33 +00:00
- ( void ) quitSheetDidEnd : ( NSWindow * ) sheet returnCode : ( int ) returnCode contextInfo : ( void * ) contextInfo
2006-07-16 19:39:23 +00:00
{
[ NSApp replyToApplicationShouldTerminate : returnCode = = NSAlertDefaultReturn ] ;
}
- ( void ) applicationWillTerminate : ( NSNotification * ) notification
{
// stop timers
2006-08-08 02:11:51 +00:00
[ fSpeedLimitTimer invalidate ] ;
2006-07-16 19:39:23 +00:00
[ fTimer invalidate ] ;
// save history and stop running torrents
[ self updateTorrentHistory ] ;
[ fTorrents makeObjectsPerformSelector : @ selector ( stopTransferForQuit ) ] ;
2006-09-25 18:37:45 +00:00
// disable NAT traversal
tr_natTraversalDisable ( fLib ) ;
2006-07-16 19:39:23 +00:00
// remember window states and close all windows
[ fDefaults setBool : [ [ fInfoController window ] isVisible ] forKey : @ "InfoVisible" ] ;
[ [ NSApp windows ] makeObjectsPerformSelector : @ selector ( close ) ] ;
[ self showStatusBar : NO animate : NO ] ;
[ self showFilterBar : NO animate : NO ] ;
// clear badge
[ fBadger clearBadge ] ;
// end quickly if the app is updating
if ( fUpdateInProgress )
return ;
2006-09-25 18:37:45 +00:00
// wait for running transfers to stop ( 5 second timeout ) and for NAT to be disabled
2006-07-16 19:39:23 +00:00
NSDate * start = [ NSDate date ] ;
BOOL timeUp = NO ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent ;
2006-09-25 18:37:45 +00:00
while ( ! timeUp && ( ( torrent = [ enumerator nextObject ] ) || tr_natTraversalStatus ( fLib ) ! = TR_NAT _TRAVERSAL _DISABLED ) )
2006-07-16 19:39:23 +00:00
while ( ! [ torrent isPaused ] && ! ( timeUp = [ start timeIntervalSinceNow ] < -5.0 ) )
{
usleep ( 100000 ) ;
[ torrent update ] ;
}
}
2006-08-02 00:04:04 +00:00
- ( NSArray * ) torrentsAtIndexes : ( NSIndexSet * ) indexSet
{
2006-08-06 17:06:05 +00:00
if ( [ fDisplayedTorrents respondsToSelector : @ selector ( objectsAtIndexes : ) ] )
return [ fDisplayedTorrents objectsAtIndexes : indexSet ] ;
2006-08-02 00:04:04 +00:00
else
{
NSMutableArray * torrents = [ NSMutableArray arrayWithCapacity : [ indexSet count ] ] ;
unsigned int i ;
for ( i = [ indexSet firstIndex ] ; i ! = NSNotFound ; i = [ indexSet indexGreaterThanIndex : i ] )
2006-08-06 17:06:05 +00:00
[ torrents addObject : [ fDisplayedTorrents objectAtIndex : i ] ] ;
2006-08-02 00:04:04 +00:00
return torrents ;
}
}
2006-07-16 19:39:23 +00:00
- ( void ) application : ( NSApplication * ) sender openFiles : ( NSArray * ) filenames
2006-08-02 00:04:04 +00:00
{
[ self openFiles : filenames ignoreDownloadFolder : NO ] ;
}
- ( void ) openFiles : ( NSArray * ) filenames ignoreDownloadFolder : ( BOOL ) ignore
2006-07-16 19:39:23 +00:00
{
NSString * downloadChoice = [ fDefaults stringForKey : @ "DownloadChoice" ] , * torrentPath ;
2006-08-09 00:09:19 +00:00
if ( ignore || [ downloadChoice isEqualToString : @ "Ask" ] )
{
2006-08-09 03:25:41 +00:00
[ self openFilesAsk : [ filenames mutableCopy ] ] ;
2006-08-09 00:09:19 +00:00
return ;
}
2006-07-16 19:39:23 +00:00
Torrent * torrent ;
NSEnumerator * enumerator = [ filenames objectEnumerator ] ;
while ( ( torrentPath = [ enumerator nextObject ] ) )
{
if ( ! ( torrent = [ [ Torrent alloc ] initWithPath : torrentPath lib : fLib ] ) )
continue ;
// add it to the "File > Open Recent" menu
2006-08-09 00:09:19 +00:00
[ [ NSDocumentController sharedDocumentController ] noteNewRecentDocumentURL : [ NSURL fileURLWithPath : torrentPath ] ] ;
2006-07-16 19:39:23 +00:00
2006-08-09 00:09:19 +00:00
NSString * folder = [ downloadChoice isEqualToString : @ "Constant" ]
? [ [ fDefaults stringForKey : @ "DownloadFolder" ] stringByExpandingTildeInPath ]
: [ torrentPath stringByDeletingLastPathComponent ] ;
2006-07-16 19:39:23 +00:00
2006-08-09 00:09:19 +00:00
[ torrent setDownloadFolder : folder ] ;
[ torrent update ] ;
[ self attemptToStartAuto : torrent ] ;
[ fTorrents addObject : torrent ] ;
2006-07-16 19:39:23 +00:00
[ torrent release ] ;
}
[ self updateUI : nil ] ;
[ self applyFilter : nil ] ;
2006-07-22 16:38:05 +00:00
2006-07-16 19:39:23 +00:00
[ self updateTorrentHistory ] ;
}
2006-08-09 00:09:19 +00:00
// called by the main open method to show sheet for choosing download location
- ( void ) openFilesAsk : ( NSMutableArray * ) files
{
NSString * torrentPath ;
Torrent * torrent ;
do
{
if ( [ files count ] = = 0 ) // recursive base case
{
[ files release ] ;
2006-08-09 00:11:00 +00:00
[ self updateTorrentHistory ] ;
2006-08-09 00:09:19 +00:00
return ;
}
torrentPath = [ files objectAtIndex : 0 ] ;
torrent = [ [ Torrent alloc ] initWithPath : torrentPath lib : fLib ] ;
[ files removeObjectAtIndex : 0 ] ;
} while ( ! torrent ) ;
// add it to the "File > Open Recent" menu
[ [ NSDocumentController sharedDocumentController ] noteNewRecentDocumentURL : [ NSURL fileURLWithPath : torrentPath ] ] ;
NSOpenPanel * panel = [ NSOpenPanel openPanel ] ;
[ panel setPrompt : @ "Select" ] ;
[ panel setAllowsMultipleSelection : NO ] ;
[ panel setCanChooseFiles : NO ] ;
[ panel setCanChooseDirectories : YES ] ;
2006-10-24 20:34:13 +00:00
[ panel setMessage : [ NSString stringWithFormat : NSLocalizedString ( @ "Select the download folder for \" % @ \ "" , "Open torrent -> select destination folder" ) , [ torrent name ] ] ] ;
2006-08-09 00:09:19 +00:00
2006-09-25 18:37:45 +00:00
NSDictionary * dictionary = [ [ NSDictionary alloc ] initWithObjectsAndKeys : torrent , @ "Torrent" , files , @ "Files" , nil ] ;
2006-08-09 00:09:19 +00:00
[ panel beginSheetForDirectory : nil file : nil types : nil modalForWindow : fWindow modalDelegate : self
didEndSelector : @ selector ( folderChoiceClosed : returnCode : contextInfo : ) contextInfo : dictionary ] ;
}
2006-08-06 17:06:05 +00:00
- ( void ) folderChoiceClosed : ( NSOpenPanel * ) openPanel returnCode : ( int ) code
2006-08-09 00:09:19 +00:00
contextInfo : ( NSDictionary * ) dictionary
2006-08-06 17:06:05 +00:00
{
2006-08-09 00:09:19 +00:00
Torrent * torrent = [ dictionary objectForKey : @ "Torrent" ] ;
2006-08-06 17:06:05 +00:00
if ( code = = NSOKButton )
{
[ torrent setDownloadFolder : [ [ openPanel filenames ] objectAtIndex : 0 ] ] ;
[ torrent update ] ;
[ self attemptToStartAuto : torrent ] ;
[ fTorrents addObject : torrent ] ;
2006-08-08 23:18:50 +00:00
[ self updateUI : nil ] ;
[ self applyFilter : nil ] ;
2006-08-06 17:06:05 +00:00
}
2006-08-09 00:09:19 +00:00
[ self performSelectorOnMainThread : @ selector ( openFilesAsk : ) withObject : [ dictionary objectForKey : @ "Files" ]
waitUntilDone : NO ] ;
2006-08-09 03:25:41 +00:00
[ torrent release ] ;
2006-08-09 00:09:19 +00:00
[ dictionary release ] ;
2006-08-06 17:06:05 +00:00
}
2006-08-02 00:04:04 +00:00
// called on by applescript
- ( void ) open : ( NSArray * ) files
2006-07-16 19:39:23 +00:00
{
2006-08-02 00:04:04 +00:00
[ self performSelectorOnMainThread : @ selector ( openFiles : ) withObject : files waitUntilDone : NO ] ;
2006-07-16 19:39:23 +00:00
}
2006-08-02 00:04:04 +00:00
- ( void ) openFiles : ( NSArray * ) filenames
2006-07-16 19:39:23 +00:00
{
2006-08-02 00:04:04 +00:00
[ self openFiles : filenames ignoreDownloadFolder : NO ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) openShowSheet : ( id ) sender
{
NSOpenPanel * panel = [ NSOpenPanel openPanel ] ;
[ panel setAllowsMultipleSelection : YES ] ;
[ panel setCanChooseFiles : YES ] ;
[ panel setCanChooseDirectories : NO ] ;
[ panel beginSheetForDirectory : nil file : nil types : [ NSArray arrayWithObject : @ "torrent" ]
2006-08-06 19:10:47 +00:00
modalForWindow : fWindow modalDelegate : self didEndSelector : @ selector ( openSheetClosed : returnCode : contextInfo : )
2006-08-02 00:04:04 +00:00
contextInfo : [ NSNumber numberWithBool : sender = = fOpenIgnoreDownloadFolder ] ] ;
2006-07-16 19:39:23 +00:00
}
2006-08-02 00:04:04 +00:00
- ( void ) openSheetClosed : ( NSOpenPanel * ) panel returnCode : ( int ) code contextInfo : ( NSNumber * ) ignore
2006-07-16 19:39:23 +00:00
{
if ( code = = NSOKButton )
2006-08-02 00:04:04 +00:00
{
NSDictionary * dictionary = [ [ NSDictionary alloc ] initWithObjectsAndKeys :
[ panel filenames ] , @ "Files" , ignore , @ "Ignore" , nil ] ;
[ self performSelectorOnMainThread : @ selector ( openFromSheet : ) withObject : dictionary waitUntilDone : NO ] ;
}
2006-07-16 19:39:23 +00:00
}
2006-08-02 00:04:04 +00:00
- ( void ) openFromSheet : ( NSDictionary * ) dictionary
2006-07-16 19:39:23 +00:00
{
2006-08-02 00:04:04 +00:00
[ self openFiles : [ dictionary objectForKey : @ "Files" ]
ignoreDownloadFolder : [ [ dictionary objectForKey : @ "Ignore" ] boolValue ] ] ;
[ dictionary release ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) resumeSelectedTorrents : ( id ) sender
{
[ self resumeTorrents : [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ] ] ;
}
- ( void ) resumeAllTorrents : ( id ) sender
{
[ self resumeTorrents : fTorrents ] ;
}
2006-09-25 18:37:45 +00:00
- ( void ) resumeTorrents : ( NSArray * ) torrents
{
NSEnumerator * enumerator = [ torrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
[ torrent setWaitToStart : YES ] ;
[ self attemptToStartMultipleAuto : torrents ] ;
[ self updateUI : nil ] ;
[ self applyFilter : nil ] ;
[ self updateTorrentHistory ] ;
}
- ( void ) resumeSelectedTorrentsNoWait : ( id ) sender
{
[ self resumeTorrentsNoWait : [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ] ] ;
}
2006-08-01 23:09:33 +00:00
- ( void ) resumeWaitingTorrents : ( id ) sender
{
NSMutableArray * torrents = [ NSMutableArray arrayWithCapacity : [ fTorrents count ] ] ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( [ torrent waitingToStart ] )
[ torrents addObject : torrent ] ;
2006-09-25 18:37:45 +00:00
[ self resumeTorrentsNoWait : torrents ] ;
2006-08-01 23:09:33 +00:00
}
2006-09-25 18:37:45 +00:00
- ( void ) resumeTorrentsNoWait : ( NSArray * ) torrents
2006-07-16 19:39:23 +00:00
{
2006-10-02 04:20:05 +00:00
// iterate through instead of all at once to ensure no conflicts
2006-10-01 16:34:02 +00:00
NSEnumerator * enumerator = [ torrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
[ torrent startTransfer ] ;
2006-07-16 19:39:23 +00:00
[ self updateUI : nil ] ;
[ self applyFilter : nil ] ;
[ self updateTorrentHistory ] ;
}
- ( void ) stopSelectedTorrents : ( id ) sender
{
[ self stopTorrents : [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ] ] ;
}
- ( void ) stopAllTorrents : ( id ) sender
{
[ self stopTorrents : fTorrents ] ;
}
2006-07-19 00:06:32 +00:00
- ( void ) stopTorrents : ( NSArray * ) torrents
2006-07-16 19:39:23 +00:00
{
// don ' t want any of these starting then stopping
NSEnumerator * enumerator = [ torrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
[ torrent setWaitToStart : NO ] ;
[ torrents makeObjectsPerformSelector : @ selector ( stopTransfer ) ] ;
[ self updateUI : nil ] ;
[ self applyFilter : nil ] ;
[ self updateTorrentHistory ] ;
}
- ( void ) removeTorrents : ( NSArray * ) torrents
deleteData : ( BOOL ) deleteData deleteTorrent : ( BOOL ) deleteTorrent
{
[ torrents retain ] ;
int active = 0 , downloading = 0 ;
if ( [ fDefaults boolForKey : @ "CheckRemove" ] )
{
Torrent * torrent ;
NSEnumerator * enumerator = [ torrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( [ torrent isActive ] )
{
active + + ;
if ( ! [ torrent isSeeding ] )
downloading + + ;
}
if ( [ fDefaults boolForKey : @ "CheckRemoveDownloading" ] ? downloading > 0 : active > 0 )
{
NSDictionary * dict = [ [ NSDictionary alloc ] initWithObjectsAndKeys :
torrents , @ "Torrents" ,
[ NSNumber numberWithBool : deleteData ] , @ "DeleteData" ,
[ NSNumber numberWithBool : deleteTorrent ] , @ "DeleteTorrent" , nil ] ;
NSString * title , * message ;
int selected = [ fTableView numberOfSelectedRows ] ;
if ( selected = = 1 )
{
2006-10-24 20:34:13 +00:00
title = [ NSString stringWithFormat : NSLocalizedString ( @ "Confirm Removal of \" % @ \ "" , "Removal confirm panel -> title" ) ,
2006-08-06 17:06:05 +00:00
[ [ fDisplayedTorrents objectAtIndex : [ fTableView selectedRow ] ] name ] ] ;
2006-10-24 20:34:13 +00:00
message = NSLocalizedString ( @ "This transfer is active."
2006-07-16 19:39:23 +00:00
" Once removed, continuing the transfer will require the torrent file."
2006-10-24 20:34:13 +00:00
" Do you really want to remove it?" , "Removal confirm panel -> message" ) ;
2006-07-16 19:39:23 +00:00
}
else
{
2006-10-24 20:34:13 +00:00
title = [ NSString stringWithFormat : NSLocalizedString ( @ "Confirm Removal of %d Transfers" , "Removal confirm panel -> title" ) , selected ] ;
2006-07-16 19:39:23 +00:00
if ( selected = = active )
2006-10-24 20:34:13 +00:00
message = [ NSString stringWithFormat : NSLocalizedString ( @ "There are %d active transfers." , "Removal confirm panel -> message part 1" ) , active ] ;
2006-07-16 19:39:23 +00:00
else
2006-10-24 20:34:13 +00:00
message = [ NSString stringWithFormat : NSLocalizedString ( @ "There are %d transfers (%d active)." , "Removal confirm panel -> message part 1" ) , selected , active ] ;
2006-07-16 19:39:23 +00:00
message = [ message stringByAppendingString :
2006-10-24 20:34:13 +00:00
NSLocalizedString ( @ " Once removed, continuing the transfers will require the torrent files."
" Do you really want to remove them?" , "Removal confirm panel -> message part 2" ) ] ;
2006-07-16 19:39:23 +00:00
}
2006-10-24 20:34:13 +00:00
NSBeginAlertSheet ( title , NSLocalizedString ( @ "Remove" , "Removal confirm panel -> button" ) , NSLocalizedString ( @ "Cancel" , "Removal confirm panel -> button" ) , nil , fWindow , self ,
2006-07-22 18:25:11 +00:00
nil , @ selector ( removeSheetDidEnd : returnCode : contextInfo : ) , dict , message ) ;
2006-07-16 19:39:23 +00:00
return ;
}
}
[ self confirmRemoveTorrents : torrents deleteData : deleteData deleteTorrent : deleteTorrent ] ;
}
- ( void ) removeSheetDidEnd : ( NSWindow * ) sheet returnCode : ( int ) returnCode contextInfo : ( NSDictionary * ) dict
{
NSArray * torrents = [ dict objectForKey : @ "Torrents" ] ;
BOOL deleteData = [ [ dict objectForKey : @ "DeleteData" ] boolValue ] ,
deleteTorrent = [ [ dict objectForKey : @ "DeleteTorrent" ] boolValue ] ;
[ dict release ] ;
if ( returnCode = = NSAlertDefaultReturn )
[ self confirmRemoveTorrents : torrents deleteData : deleteData deleteTorrent : deleteTorrent ] ;
else
[ torrents release ] ;
}
- ( void ) confirmRemoveTorrents : ( NSArray * ) torrents deleteData : ( BOOL ) deleteData deleteTorrent : ( BOOL ) deleteTorrent
{
// don ' t want any of these starting then stopping
NSEnumerator * enumerator = [ torrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
[ torrent setWaitToStart : NO ] ;
NSNumber * lowestOrderValue = [ NSNumber numberWithInt : [ torrents count ] ] , * currentOrderValue ;
enumerator = [ torrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
{
[ torrent stopTransfer ] ;
if ( deleteData )
[ torrent trashData ] ;
if ( deleteTorrent )
[ torrent trashTorrent ] ;
// determine lowest order value
currentOrderValue = [ torrent orderValue ] ;
if ( [ lowestOrderValue compare : currentOrderValue ] = = NSOrderedDescending )
lowestOrderValue = currentOrderValue ;
[ torrent removeForever ] ;
[ fTorrents removeObject : torrent ] ;
2006-08-06 17:06:05 +00:00
[ fDisplayedTorrents removeObject : torrent ] ;
2006-07-16 19:39:23 +00:00
}
[ torrents release ] ;
// reset the order values if necessary
if ( [ lowestOrderValue intValue ] < [ fTorrents count ] )
{
NSSortDescriptor * orderDescriptor = [ [ [ NSSortDescriptor alloc ] initWithKey :
@ "orderValue" ascending : YES ] autorelease ] ;
NSArray * descriptors = [ [ NSArray alloc ] initWithObjects : orderDescriptor , nil ] ;
NSArray * tempTorrents = [ fTorrents sortedArrayUsingDescriptors : descriptors ] ;
[ descriptors release ] ;
int i ;
for ( i = [ lowestOrderValue intValue ] ; i < [ tempTorrents count ] ; i + + )
[ [ tempTorrents objectAtIndex : i ] setOrderValue : i ] ;
}
2006-07-25 02:12:18 +00:00
[ fTableView deselectAll : nil ] ;
2006-07-23 14:42:54 +00:00
2006-07-16 19:39:23 +00:00
[ self updateUI : nil ] ;
2006-07-25 02:12:18 +00:00
[ self applyFilter : nil ] ;
2006-07-22 16:38:05 +00:00
2006-07-16 19:39:23 +00:00
[ self updateTorrentHistory ] ;
}
- ( void ) removeNoDelete : ( id ) sender
{
[ self removeTorrents : [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ]
deleteData : NO deleteTorrent : NO ] ;
}
- ( void ) removeDeleteData : ( id ) sender
{
[ self removeTorrents : [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ]
deleteData : YES deleteTorrent : NO ] ;
}
- ( void ) removeDeleteTorrent : ( id ) sender
{
[ self removeTorrents : [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ]
deleteData : NO deleteTorrent : YES ] ;
}
- ( void ) removeDeleteDataAndTorrent : ( id ) sender
{
[ self removeTorrents : [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ]
deleteData : YES deleteTorrent : YES ] ;
}
- ( void ) copyTorrentFile : ( id ) sender
{
[ self copyTorrentFileForTorrents : [ [ NSMutableArray alloc ] initWithArray :
[ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ] ] ] ;
}
- ( void ) copyTorrentFileForTorrents : ( NSMutableArray * ) torrents
{
if ( [ torrents count ] = = 0 )
{
[ torrents release ] ;
return ;
}
Torrent * torrent = [ torrents objectAtIndex : 0 ] ;
// warn user if torrent file can ' t be found
if ( ! [ [ NSFileManager defaultManager ] fileExistsAtPath : [ torrent torrentLocation ] ] )
{
NSAlert * alert = [ [ NSAlert alloc ] init ] ;
2006-10-24 20:34:13 +00:00
[ alert addButtonWithTitle : NSLocalizedString ( @ "OK" , "Torrent file copy alert -> button" ) ] ;
[ alert setMessageText : [ NSString stringWithFormat : NSLocalizedString ( @ "Copy of \" % @ \ " Cannot Be Created" , "Torrent file copy alert -> title" ) , [ torrent name ] ] ] ;
2006-07-16 19:39:23 +00:00
[ alert setInformativeText : [ NSString stringWithFormat :
2006-10-24 20:34:13 +00:00
NSLocalizedString ( @ "The torrent file (%@) cannot be found." , "Torrent file copy alert -> message" ) , [ torrent torrentLocation ] ] ] ;
2006-07-16 19:39:23 +00:00
[ alert setAlertStyle : NSWarningAlertStyle ] ;
[ alert runModal ] ;
[ torrents removeObjectAtIndex : 0 ] ;
[ self copyTorrentFileForTorrents : torrents ] ;
}
else
{
NSSavePanel * panel = [ NSSavePanel savePanel ] ;
[ panel setRequiredFileType : @ "torrent" ] ;
[ panel setCanSelectHiddenExtension : YES ] ;
2006-08-22 23:00:53 +00:00
[ panel beginSheetForDirectory : nil file : [ torrent name ] modalForWindow : fWindow modalDelegate : self
didEndSelector : @ selector ( saveTorrentCopySheetClosed : returnCode : contextInfo : ) contextInfo : torrents ] ;
2006-07-16 19:39:23 +00:00
}
}
2006-08-22 23:00:53 +00:00
- ( void ) saveTorrentCopySheetClosed : ( NSSavePanel * ) panel returnCode : ( int ) code contextInfo : ( NSMutableArray * ) torrents
2006-07-16 19:39:23 +00:00
{
// if save successful , copy torrent to new location with name of data file
if ( code = = NSOKButton )
[ [ NSFileManager defaultManager ] copyPath : [ [ torrents objectAtIndex : 0 ] torrentLocation ]
2006-07-30 20:53:25 +00:00
toPath : [ panel filename ] handler : nil ] ;
2006-07-16 19:39:23 +00:00
[ torrents removeObjectAtIndex : 0 ] ;
2006-08-22 23:00:53 +00:00
[ self performSelectorOnMainThread : @ selector ( copyTorrentFileForTorrents : ) withObject : torrents waitUntilDone : NO ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) revealFile : ( id ) sender
{
NSIndexSet * indexSet = [ fTableView selectedRowIndexes ] ;
unsigned int i ;
for ( i = [ indexSet firstIndex ] ; i ! = NSNotFound ; i = [ indexSet indexGreaterThanIndex : i ] )
2006-08-06 17:06:05 +00:00
[ [ fDisplayedTorrents objectAtIndex : i ] revealData ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) showPreferenceWindow : ( id ) sender
{
NSWindow * window = [ fPrefsController window ] ;
if ( ! [ window isVisible ] )
[ window center ] ;
[ window makeKeyAndOrderFront : nil ] ;
}
- ( void ) showInfo : ( id ) sender
{
if ( [ [ fInfoController window ] isVisible ] )
[ fInfoController close ] ;
else
{
[ fInfoController updateInfoStats ] ;
[ [ fInfoController window ] orderFront : nil ] ;
}
}
- ( void ) setInfoTab : ( id ) sender
{
if ( sender = = fNextInfoTabItem )
[ fInfoController setNextTab ] ;
else
[ fInfoController setPreviousTab ] ;
}
2006-08-21 22:07:08 +00:00
- ( void ) showMessageWindow : ( id ) sender
{
[ fMessageController showWindow : nil ] ;
}
2006-07-16 19:39:23 +00:00
- ( void ) updateControlTint : ( NSNotification * ) notification
{
2006-07-19 03:58:33 +00:00
if ( fSpeedLimitEnabled )
2006-07-19 02:50:07 +00:00
[ fSpeedLimitButton setImage : [ NSColor currentControlTint ] = = NSBlueControlTint
? fSpeedLimitBlueImage : fSpeedLimitGraphiteImage ] ;
2006-07-16 19:39:23 +00:00
}
2006-08-16 01:52:20 +00:00
- ( void ) updateUI : ( NSTimer * ) timer
2006-07-16 19:39:23 +00:00
{
2006-07-30 18:37:29 +00:00
[ fTorrents makeObjectsPerformSelector : @ selector ( update ) ] ;
2006-07-16 19:39:23 +00:00
2006-07-30 18:44:38 +00:00
// resort if necessary or just update the table
2006-07-16 19:39:23 +00:00
if ( [ fSortType isEqualToString : @ "Progress" ] || [ fSortType isEqualToString : @ "State" ] )
[ self sortTorrents ] ;
else
[ fTableView reloadData ] ;
// update the global DL / UL rates
float downloadRate , uploadRate ;
tr_torrentRates ( fLib , & downloadRate , & uploadRate ) ;
2006-07-29 18:09:35 +00:00
if ( ! [ fStatusBar isHidden ] )
2006-07-16 19:39:23 +00:00
{
2006-10-24 20:34:13 +00:00
[ fTotalDLField setStringValue : [ NSLocalizedString ( @ "Total DL: " , "Status bar -> total download" ) stringByAppendingString : [ NSString stringForSpeed : downloadRate ] ] ] ;
[ fTotalULField setStringValue : [ NSLocalizedString ( @ "Total UL: " , "Status bar -> total upload" ) stringByAppendingString : [ NSString stringForSpeed : uploadRate ] ] ] ;
2006-07-16 19:39:23 +00:00
}
2006-07-30 18:44:38 +00:00
// update non - constant parts of info window
2006-07-16 19:39:23 +00:00
if ( [ [ fInfoController window ] isVisible ] )
[ fInfoController updateInfoStats ] ;
// badge dock
2006-07-22 20:39:33 +00:00
[ fBadger updateBadgeWithCompleted : fCompleted uploadRate : uploadRate downloadRate : downloadRate ] ;
2006-07-16 19:39:23 +00:00
}
2006-07-30 18:37:29 +00:00
- ( void ) torrentFinishedDownloading : ( NSNotification * ) notification
{
Torrent * torrent = [ notification object ] ;
[ self applyFilter : nil ] ;
[ self checkToStartWaiting : torrent ] ;
2006-08-07 00:46:47 +00:00
if ( [ fDefaults boolForKey : @ "PlayDownloadSound" ] )
{
NSSound * sound ;
2006-08-07 02:28:31 +00:00
if ( ( sound = [ NSSound soundNamed : [ fDefaults stringForKey : @ "DownloadSound" ] ] ) )
2006-08-07 00:46:47 +00:00
[ sound play ] ;
}
2006-10-24 20:34:13 +00:00
[ GrowlApplicationBridge notifyWithTitle : NSLocalizedString ( @ "Download Complete" , "Growl notification title" ) description : [ torrent name ]
2006-07-30 18:37:29 +00:00
notificationName : GROWL_DOWNLOAD _COMPLETE iconData : nil priority : 0 isSticky : NO clickContext : nil ] ;
if ( ! [ fWindow isKeyWindow ] )
fCompleted + + ;
}
2006-07-16 19:39:23 +00:00
- ( void ) updateTorrentHistory
{
NSMutableArray * history = [ NSMutableArray arrayWithCapacity : [ fTorrents count ] ] ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
[ history addObject : [ torrent history ] ] ;
[ fDefaults setObject : history forKey : @ "History" ] ;
[ fDefaults synchronize ] ;
}
- ( void ) sortTorrents
{
// remember selected rows if needed
NSArray * selectedTorrents = nil ;
int numSelected = [ fTableView numberOfSelectedRows ] ;
2006-08-06 17:06:05 +00:00
if ( numSelected > 0 && numSelected < [ fDisplayedTorrents count ] )
2006-07-16 19:39:23 +00:00
selectedTorrents = [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ] ;
[ self sortTorrentsIgnoreSelected ] ; // actually sort
// set selected rows if needed
if ( selectedTorrents )
{
Torrent * torrent ;
NSEnumerator * enumerator = [ selectedTorrents objectEnumerator ] ;
NSMutableIndexSet * indexSet = [ [ NSMutableIndexSet alloc ] init ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
2006-08-06 17:06:05 +00:00
[ indexSet addIndex : [ fDisplayedTorrents indexOfObject : torrent ] ] ;
2006-07-16 19:39:23 +00:00
[ fTableView selectRowIndexes : indexSet byExtendingSelection : NO ] ;
[ indexSet release ] ;
}
}
2006-07-16 21:02:29 +00:00
// doesn ' t remember selected rows
2006-07-16 19:39:23 +00:00
- ( void ) sortTorrentsIgnoreSelected
{
2006-07-23 21:29:24 +00:00
NSSortDescriptor * nameDescriptor = [ [ [ NSSortDescriptor alloc ] initWithKey : @ "name"
ascending : YES selector : @ selector ( caseInsensitiveCompare : ) ] autorelease ] ,
* orderDescriptor = [ [ [ NSSortDescriptor alloc ] initWithKey : @ "orderValue"
ascending : YES ] autorelease ] ;
2006-07-16 19:39:23 +00:00
NSArray * descriptors ;
if ( [ fSortType isEqualToString : @ "Name" ] )
descriptors = [ [ NSArray alloc ] initWithObjects : nameDescriptor , orderDescriptor , nil ] ;
else if ( [ fSortType isEqualToString : @ "State" ] )
{
NSSortDescriptor * stateDescriptor = [ [ [ NSSortDescriptor alloc ] initWithKey :
@ "stateSortKey" ascending : NO ] autorelease ] ,
* progressDescriptor = [ [ [ NSSortDescriptor alloc ] initWithKey :
@ "progressSortKey" ascending : NO ] autorelease ] ;
descriptors = [ [ NSArray alloc ] initWithObjects : stateDescriptor , progressDescriptor ,
nameDescriptor , orderDescriptor , nil ] ;
}
else if ( [ fSortType isEqualToString : @ "Progress" ] )
{
NSSortDescriptor * progressDescriptor = [ [ [ NSSortDescriptor alloc ] initWithKey :
@ "progressSortKey" ascending : YES ] autorelease ] ;
descriptors = [ [ NSArray alloc ] initWithObjects : progressDescriptor , nameDescriptor , orderDescriptor , nil ] ;
}
else if ( [ fSortType isEqualToString : @ "Date" ] )
{
2006-07-23 21:29:24 +00:00
NSSortDescriptor * dateDescriptor = [ [ [ NSSortDescriptor alloc ] initWithKey : @ "date" ascending : YES ] autorelease ] ;
2006-07-16 19:39:23 +00:00
descriptors = [ [ NSArray alloc ] initWithObjects : dateDescriptor , orderDescriptor , nil ] ;
}
else
descriptors = [ [ NSArray alloc ] initWithObjects : orderDescriptor , nil ] ;
2006-08-06 17:06:05 +00:00
[ fDisplayedTorrents sortUsingDescriptors : descriptors ] ;
2006-07-16 19:39:23 +00:00
[ descriptors release ] ;
[ fTableView reloadData ] ;
}
- ( void ) setSort : ( id ) sender
{
2006-07-22 14:08:35 +00:00
// get checked items
NSMenuItem * prevSortItem , * prevSortActionItem ;
2006-07-16 19:39:23 +00:00
if ( [ fSortType isEqualToString : @ "Name" ] )
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
prevSortItem = fNameSortItem ;
2006-07-22 14:08:35 +00:00
prevSortActionItem = fNameSortActionItem ;
}
2006-07-16 19:39:23 +00:00
else if ( [ fSortType isEqualToString : @ "State" ] )
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
prevSortItem = fStateSortItem ;
2006-07-22 14:08:35 +00:00
prevSortActionItem = fStateSortActionItem ;
}
2006-07-16 19:39:23 +00:00
else if ( [ fSortType isEqualToString : @ "Progress" ] )
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
prevSortItem = fProgressSortItem ;
2006-07-22 14:08:35 +00:00
prevSortActionItem = fProgressSortActionItem ;
}
2006-07-16 19:39:23 +00:00
else if ( [ fSortType isEqualToString : @ "Date" ] )
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
prevSortItem = fDateSortItem ;
2006-07-22 14:08:35 +00:00
prevSortActionItem = fDateSortActionItem ;
}
2006-07-16 19:39:23 +00:00
else
2006-07-22 14:08:35 +00:00
{
2006-07-16 19:39:23 +00:00
prevSortItem = fOrderSortItem ;
2006-07-22 14:08:35 +00:00
prevSortActionItem = fOrderSortActionItem ;
}
2006-07-16 19:39:23 +00:00
2006-07-22 14:08:35 +00:00
if ( sender ! = prevSortItem && sender ! = prevSortActionItem )
2006-07-16 19:39:23 +00:00
{
[ fSortType release ] ;
2006-07-22 14:08:35 +00:00
// get new items to check
NSMenuItem * currentSortItem , * currentSortActionItem ;
if ( sender = = fNameSortItem || sender = = fNameSortActionItem )
{
currentSortItem = fNameSortItem ;
currentSortActionItem = fNameSortActionItem ;
2006-07-16 19:39:23 +00:00
fSortType = [ [ NSString alloc ] initWithString : @ "Name" ] ;
2006-07-22 14:08:35 +00:00
}
else if ( sender = = fStateSortItem || sender = = fStateSortActionItem )
{
currentSortItem = fStateSortItem ;
currentSortActionItem = fStateSortActionItem ;
2006-07-16 19:39:23 +00:00
fSortType = [ [ NSString alloc ] initWithString : @ "State" ] ;
2006-07-22 14:08:35 +00:00
}
else if ( sender = = fProgressSortItem || sender = = fProgressSortActionItem )
{
currentSortItem = fProgressSortItem ;
currentSortActionItem = fProgressSortActionItem ;
2006-07-16 19:39:23 +00:00
fSortType = [ [ NSString alloc ] initWithString : @ "Progress" ] ;
2006-07-22 14:08:35 +00:00
}
else if ( sender = = fDateSortItem || sender = = fDateSortActionItem )
{
currentSortItem = fDateSortItem ;
currentSortActionItem = fDateSortActionItem ;
2006-07-16 19:39:23 +00:00
fSortType = [ [ NSString alloc ] initWithString : @ "Date" ] ;
2006-07-22 14:08:35 +00:00
}
2006-07-16 19:39:23 +00:00
else
2006-07-22 14:08:35 +00:00
{
currentSortItem = fOrderSortItem ;
currentSortActionItem = fOrderSortActionItem ;
2006-07-16 19:39:23 +00:00
fSortType = [ [ NSString alloc ] initWithString : @ "Order" ] ;
2006-07-22 14:08:35 +00:00
}
[ prevSortItem setState : NSOffState ] ;
[ prevSortActionItem setState : NSOffState ] ;
[ currentSortItem setState : NSOnState ] ;
[ currentSortActionItem setState : NSOnState ] ;
2006-07-16 19:39:23 +00:00
[ fDefaults setObject : fSortType forKey : @ "Sort" ] ;
}
[ self sortTorrents ] ;
}
- ( void ) applyFilter : ( id ) sender
{
// remember selected rows if needed
NSArray * selectedTorrents = [ fTableView numberOfSelectedRows ] > 0
? [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ] : nil ;
NSMutableArray * tempTorrents = [ [ NSMutableArray alloc ] initWithCapacity : [ fTorrents count ] ] ;
2006-07-25 02:12:18 +00:00
BOOL filtering = YES ;
2006-07-16 19:39:23 +00:00
if ( [ fFilterType isEqualToString : @ "Pause" ] )
{
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( ! [ torrent isActive ] )
[ tempTorrents addObject : torrent ] ;
}
else if ( [ fFilterType isEqualToString : @ "Seed" ] )
{
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( [ torrent isActive ] && [ torrent progress ] >= 1.0 )
[ tempTorrents addObject : torrent ] ;
}
else if ( [ fFilterType isEqualToString : @ "Download" ] )
{
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( [ torrent isActive ] && [ torrent progress ] < 1.0 )
[ tempTorrents addObject : torrent ] ;
}
else
2006-07-25 02:12:18 +00:00
{
filtering = NO ;
2006-07-16 19:39:23 +00:00
[ tempTorrents setArray : fTorrents ] ;
2006-07-25 02:12:18 +00:00
}
2006-07-16 19:39:23 +00:00
NSString * searchString = [ fSearchFilterField stringValue ] ;
2006-08-06 20:18:00 +00:00
if ( [ searchString length ] > 0 )
2006-07-16 19:39:23 +00:00
{
2006-08-06 20:18:00 +00:00
filtering = YES ;
2006-07-16 19:39:23 +00:00
int i ;
for ( i = [ tempTorrents count ] - 1 ; i >= 0 ; i - - )
if ( [ [ [ tempTorrents objectAtIndex : i ] name ] rangeOfString : searchString
options : NSCaseInsensitiveSearch ] . location = = NSNotFound )
[ tempTorrents removeObjectAtIndex : i ] ;
}
2006-08-06 17:06:05 +00:00
[ fDisplayedTorrents setArray : tempTorrents ] ;
2006-07-16 19:39:23 +00:00
[ tempTorrents release ] ;
[ self sortTorrentsIgnoreSelected ] ;
// set selected rows if needed
if ( selectedTorrents )
{
Torrent * torrent ;
NSEnumerator * enumerator = [ selectedTorrents objectEnumerator ] ;
NSMutableIndexSet * indexSet = [ [ NSMutableIndexSet alloc ] init ] ;
unsigned index ;
while ( ( torrent = [ enumerator nextObject ] ) )
2006-08-06 17:06:05 +00:00
if ( ( index = [ fDisplayedTorrents indexOfObject : torrent ] ) ! = NSNotFound )
2006-07-16 19:39:23 +00:00
[ indexSet addIndex : index ] ;
[ fTableView selectRowIndexes : indexSet byExtendingSelection : NO ] ;
[ indexSet release ] ;
}
2006-07-23 14:42:54 +00:00
2006-07-26 02:42:07 +00:00
// set status bar torrent count text
2006-07-25 02:12:18 +00:00
NSMutableString * totalTorrentsString = [ NSMutableString stringWithString : @ "" ] ;
if ( filtering )
2006-08-06 17:06:05 +00:00
[ totalTorrentsString appendFormat : @ "%d/" , [ fDisplayedTorrents count ] ] ;
2006-07-25 02:12:18 +00:00
int totalCount = [ fTorrents count ] ;
2006-10-24 20:34:13 +00:00
if ( totalCount > 1 )
[ totalTorrentsString appendFormat : NSLocalizedString ( @ "%d Transfers" , "Status bar transfer count" ) , totalCount ] ;
else
[ totalTorrentsString appendFormat : NSLocalizedString ( @ "%d Transfer" , "Status bar transfer count" ) , totalCount ] ;
2006-07-25 02:12:18 +00:00
[ fTotalTorrentsField setStringValue : totalTorrentsString ] ;
2006-07-23 14:42:54 +00:00
[ self setWindowSizeToFit ] ;
2006-07-16 19:39:23 +00:00
}
// resets filter and sorts torrents
- ( void ) setFilter : ( id ) sender
{
BarButton * prevFilterButton ;
if ( [ fFilterType isEqualToString : @ "Pause" ] )
prevFilterButton = fPauseFilterButton ;
else if ( [ fFilterType isEqualToString : @ "Seed" ] )
prevFilterButton = fSeedFilterButton ;
else if ( [ fFilterType isEqualToString : @ "Download" ] )
prevFilterButton = fDownloadFilterButton ;
else
prevFilterButton = fNoFilterButton ;
if ( sender ! = prevFilterButton )
{
[ prevFilterButton setEnabled : NO ] ;
[ sender setEnabled : YES ] ;
[ fFilterType release ] ;
if ( sender = = fDownloadFilterButton )
fFilterType = [ [ NSString alloc ] initWithString : @ "Download" ] ;
else if ( sender = = fPauseFilterButton )
fFilterType = [ [ NSString alloc ] initWithString : @ "Pause" ] ;
else if ( sender = = fSeedFilterButton )
fFilterType = [ [ NSString alloc ] initWithString : @ "Seed" ] ;
else
fFilterType = [ [ NSString alloc ] initWithString : @ "None" ] ;
[ fDefaults setObject : fFilterType forKey : @ "Filter" ] ;
}
[ self applyFilter : nil ] ;
}
2006-09-08 01:14:31 +00:00
- ( void ) switchFilter : ( id ) sender
{
NSButton * button ;
if ( [ fFilterType isEqualToString : @ "None" ] )
button = sender = = fNextFilterItem ? fDownloadFilterButton : fPauseFilterButton ;
else if ( [ fFilterType isEqualToString : @ "Download" ] )
button = sender = = fNextFilterItem ? fSeedFilterButton : fNoFilterButton ;
else if ( [ fFilterType isEqualToString : @ "Seed" ] )
button = sender = = fNextFilterItem ? fPauseFilterButton : fDownloadFilterButton ;
else if ( [ fFilterType isEqualToString : @ "Pause" ] )
button = sender = = fNextFilterItem ? fNoFilterButton : fSeedFilterButton ;
else
button = fNoFilterButton ;
[ self setFilter : button ] ;
}
2006-07-16 19:39:23 +00:00
- ( void ) toggleSpeedLimit : ( id ) sender
{
2006-07-19 02:50:07 +00:00
fSpeedLimitEnabled = ! fSpeedLimitEnabled ;
int state = fSpeedLimitEnabled ? NSOnState : NSOffState ;
2006-07-16 19:39:23 +00:00
[ fSpeedLimitItem setState : state ] ;
[ fSpeedLimitDockItem setState : state ] ;
2006-07-19 02:50:07 +00:00
[ fSpeedLimitButton setImage : ! fSpeedLimitEnabled ? fSpeedLimitNormalImage
: ( [ NSColor currentControlTint ] = = NSBlueControlTint ? fSpeedLimitBlueImage : fSpeedLimitGraphiteImage ) ] ;
[ fPrefsController enableSpeedLimit : fSpeedLimitEnabled ] ;
2006-07-16 19:39:23 +00:00
}
2006-08-12 20:13:25 +00:00
- ( void ) autoSpeedLimitChange : ( NSNotification * ) notification
2006-08-08 02:11:51 +00:00
{
2006-08-11 22:58:14 +00:00
if ( ! [ fDefaults boolForKey : @ "SpeedLimitAuto" ] )
2006-08-08 02:11:51 +00:00
return ;
2006-08-12 20:36:17 +00:00
int onHour = [ fDefaults integerForKey : @ "SpeedLimitAutoOnHour" ] ,
offHour = [ fDefaults integerForKey : @ "SpeedLimitAutoOffHour" ] ;
2006-08-08 02:11:51 +00:00
2006-08-12 20:36:17 +00:00
// check if should be on if within range
2006-08-11 23:18:56 +00:00
BOOL shouldBeOn ;
2006-08-11 22:58:14 +00:00
int hour = [ [ NSCalendarDate calendarDate ] hourOfDay ] ;
2006-08-11 23:18:56 +00:00
if ( onHour < offHour )
shouldBeOn = hour >= onHour && hour < offHour ;
else
shouldBeOn = hour < offHour || hour >= onHour ;
2006-08-11 22:58:14 +00:00
2006-08-12 00:38:26 +00:00
if ( fSpeedLimitEnabled ! = shouldBeOn )
2006-08-12 20:13:25 +00:00
[ self toggleSpeedLimit : nil ] ;
}
- ( void ) autoSpeedLimit : ( NSTimer * ) timer
{
2006-08-12 20:36:17 +00:00
if ( ! [ fDefaults boolForKey : @ "SpeedLimitAuto" ] )
2006-08-12 20:13:25 +00:00
return ;
// toggle if within first few seconds of hour
2006-08-12 20:36:17 +00:00
NSCalendarDate * currentDate = [ NSCalendarDate calendarDate ] ;
2006-08-12 20:13:25 +00:00
if ( [ currentDate minuteOfHour ] = = 0 && [ currentDate secondOfMinute ] < AUTO_SPEED _LIMIT _SECONDS
2006-10-21 20:09:28 +00:00
&& [ currentDate hourOfDay ] = = [ fDefaults integerForKey : fSpeedLimitEnabled
? @ "SpeedLimitAutoOffHour" : @ "SpeedLimitAutoOnHour" ] )
2006-08-08 03:04:25 +00:00
{
2006-08-08 02:11:51 +00:00
[ self toggleSpeedLimit : nil ] ;
2006-08-08 03:04:25 +00:00
2006-10-21 20:09:28 +00:00
[ GrowlApplicationBridge notifyWithTitle : fSpeedLimitEnabled
2006-10-24 20:34:13 +00:00
? NSLocalizedString ( @ "Speed Limit Auto Enabled" , "Growl notification title" )
: NSLocalizedString ( @ "Speed Limit Auto Disabled" , "Growl notification title" )
description : NSLocalizedString ( @ "Bandwidth settings changed" , "Growl notification description" )
2006-08-08 03:04:25 +00:00
notificationName : GROWL_AUTO _SPEED _LIMIT iconData : nil priority : 0 isSticky : NO clickContext : nil ] ;
}
2006-08-08 02:11:51 +00:00
}
2006-07-16 19:39:23 +00:00
- ( void ) setLimitGlobalEnabled : ( id ) sender
{
[ fPrefsController setLimitEnabled : ( sender = = fUploadLimitItem || sender = = fDownloadLimitItem )
type : ( sender = = fUploadLimitItem || sender = = fUploadNoLimitItem ) ? @ "Upload" : @ "Download" ] ;
}
- ( void ) setQuickLimitGlobal : ( id ) sender
{
[ fPrefsController setQuickLimit : [ [ sender title ] intValue ]
type : [ sender menu ] = = fUploadMenu ? @ "Upload" : @ "Download" ] ;
}
- ( void ) limitGlobalChange : ( NSNotification * ) notification
{
NSDictionary * dict = [ notification object ] ;
NSMenuItem * limitItem , * noLimitItem ;
if ( [ [ dict objectForKey : @ "Type" ] isEqualToString : @ "Upload" ] )
{
limitItem = fUploadLimitItem ;
noLimitItem = fUploadNoLimitItem ;
}
else
{
limitItem = fDownloadLimitItem ;
noLimitItem = fDownloadNoLimitItem ;
}
BOOL enable = [ [ dict objectForKey : @ "Enable" ] boolValue ] ;
[ limitItem setState : enable ? NSOnState : NSOffState ] ;
[ noLimitItem setState : ! enable ? NSOnState : NSOffState ] ;
2006-10-24 20:34:13 +00:00
[ limitItem setTitle : [ NSString stringWithFormat : NSLocalizedString ( @ "Limit (%d KB/s)" , "Action context menu -> upload/download limit" ) ,
2006-07-16 19:39:23 +00:00
[ [ dict objectForKey : @ "Limit" ] intValue ] ] ] ;
[ dict release ] ;
}
- ( void ) setRatioGlobalEnabled : ( id ) sender
{
[ fPrefsController setRatioEnabled : sender = = fRatioSetItem ] ;
}
- ( void ) setQuickRatioGlobal : ( id ) sender
{
[ fPrefsController setQuickRatio : [ [ sender title ] floatValue ] ] ;
}
- ( void ) ratioGlobalChange : ( NSNotification * ) notification
{
NSDictionary * dict = [ notification object ] ;
BOOL enable = [ [ dict objectForKey : @ "Enable" ] boolValue ] ;
[ fRatioSetItem setState : enable ? NSOnState : NSOffState ] ;
[ fRatioNotSetItem setState : ! enable ? NSOnState : NSOffState ] ;
2006-10-24 20:34:13 +00:00
[ fRatioSetItem setTitle : [ NSString stringWithFormat : NSLocalizedString ( @ "Stop at Ratio (%.2f)" , "Action context menu -> ratio stop" ) ,
2006-07-16 19:39:23 +00:00
[ [ dict objectForKey : @ "Ratio" ] floatValue ] ] ] ;
[ dict release ] ;
}
- ( void ) checkWaitingForStopped : ( NSNotification * ) notification
{
[ self checkToStartWaiting : [ notification object ] ] ;
2006-07-17 11:17:31 +00:00
[ self updateUI : nil ] ;
2006-07-17 11:22:50 +00:00
[ self applyFilter : nil ] ;
2006-07-17 11:17:31 +00:00
[ self updateTorrentHistory ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) checkToStartWaiting : ( Torrent * ) finishedTorrent
{
// don ' t try to start a transfer if there should be none waiting
2006-09-25 18:37:45 +00:00
if ( ! [ fDefaults boolForKey : @ "Queue" ] )
2006-07-16 19:39:23 +00:00
return ;
2006-09-25 18:37:45 +00:00
int desiredActive = [ fDefaults integerForKey : @ "QueueDownloadNumber" ] ;
2006-07-16 19:39:23 +00:00
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent , * torrentToStart = nil ;
while ( ( torrent = [ enumerator nextObject ] ) )
{
// ignore the torrent just stopped
if ( torrent = = finishedTorrent )
continue ;
if ( [ torrent isActive ] )
{
2006-09-29 05:30:36 +00:00
if ( ! [ torrent isSeeding ] && ! [ torrent isError ] )
2006-07-16 19:39:23 +00:00
{
desiredActive - - ;
if ( desiredActive <= 0 )
return ;
}
}
else
{
// use as next if it is waiting to start and either no previous or order value is lower
if ( [ torrent waitingToStart ] && ( ! torrentToStart
|| [ [ torrentToStart orderValue ] compare : [ torrent orderValue ] ] = = NSOrderedDescending ) )
torrentToStart = torrent ;
}
}
// since it hasn ' t returned , the queue amount has not been met
if ( torrentToStart )
{
[ torrentToStart startTransfer ] ;
[ self updateUI : nil ] ;
2006-07-17 11:22:50 +00:00
[ self applyFilter : nil ] ;
2006-07-16 19:39:23 +00:00
[ self updateTorrentHistory ] ;
}
}
- ( void ) torrentStartSettingChange : ( NSNotification * ) notification
{
[ self attemptToStartMultipleAuto : [ notification object ] ] ;
[ self updateUI : nil ] ;
2006-07-17 11:22:50 +00:00
[ self applyFilter : nil ] ;
2006-07-16 19:39:23 +00:00
[ self updateTorrentHistory ] ;
}
- ( void ) globalStartSettingChange : ( NSNotification * ) notification
{
[ self attemptToStartMultipleAuto : fTorrents ] ;
[ self updateUI : nil ] ;
2006-07-17 11:22:50 +00:00
[ self applyFilter : nil ] ;
2006-07-16 19:39:23 +00:00
[ self updateTorrentHistory ] ;
}
- ( void ) torrentStoppedForRatio : ( NSNotification * ) notification
{
[ self applyFilter : nil ] ;
2006-09-25 18:37:45 +00:00
[ fInfoController updateInfoStats ] ;
[ fInfoController updateInfoSettings ] ;
2006-07-16 19:39:23 +00:00
2006-08-07 01:03:14 +00:00
if ( [ fDefaults boolForKey : @ "PlaySeedingSound" ] )
{
NSSound * sound ;
2006-08-07 02:28:31 +00:00
if ( ( sound = [ NSSound soundNamed : [ fDefaults stringForKey : @ "SeedingSound" ] ] ) )
2006-08-07 01:03:14 +00:00
[ sound play ] ;
}
2006-10-24 20:34:13 +00:00
[ GrowlApplicationBridge notifyWithTitle : NSLocalizedString ( @ "Seeding Complete" , "Growl notification title" ) description : [ [ notification object ] name ]
2006-07-30 18:37:29 +00:00
notificationName : GROWL_SEEDING _COMPLETE iconData : nil priority : 0 isSticky : NO clickContext : nil ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) attemptToStartAuto : ( Torrent * ) torrent
{
[ self attemptToStartMultipleAuto : [ NSArray arrayWithObject : torrent ] ] ;
}
// will try to start , taking into consideration the start preference
- ( void ) attemptToStartMultipleAuto : ( NSArray * ) torrents
{
2006-09-25 18:37:45 +00:00
if ( ! [ fDefaults boolForKey : @ "Queue" ] )
2006-07-16 19:39:23 +00:00
{
NSEnumerator * enumerator = [ torrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( [ torrent waitingToStart ] )
[ torrent startTransfer ] ;
return ;
}
// determine the number of downloads needed to start
2006-09-25 18:37:45 +00:00
int desiredActive = [ fDefaults integerForKey : @ "QueueDownloadNumber" ] ;
2006-07-16 19:39:23 +00:00
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent ;
while ( ( torrent = [ enumerator nextObject ] ) )
2006-09-29 05:30:36 +00:00
if ( [ torrent isActive ] && ! [ torrent isSeeding ] && ! [ torrent isError ] )
2006-07-16 19:39:23 +00:00
{
desiredActive - - ;
if ( desiredActive <= 0 )
break ;
}
// sort torrents by order value
NSArray * sortedTorrents ;
if ( [ torrents count ] > 1 && desiredActive > 0 )
{
NSSortDescriptor * orderDescriptor = [ [ [ NSSortDescriptor alloc ] initWithKey :
@ "orderValue" ascending : YES ] autorelease ] ;
NSArray * descriptors = [ [ NSArray alloc ] initWithObjects : orderDescriptor , nil ] ;
sortedTorrents = [ torrents sortedArrayUsingDescriptors : descriptors ] ;
[ descriptors release ] ;
}
else
sortedTorrents = torrents ;
enumerator = [ sortedTorrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
{
2006-08-01 23:22:48 +00:00
if ( [ torrent waitingToStart ] )
2006-07-16 19:39:23 +00:00
{
2006-08-01 23:22:48 +00:00
if ( [ torrent progress ] >= 1.0 )
[ torrent startTransfer ] ;
else if ( desiredActive > 0 )
2006-07-16 19:39:23 +00:00
{
[ torrent startTransfer ] ;
desiredActive - - ;
}
2006-08-06 19:10:47 +00:00
else
continue ;
[ torrent update ] ;
2006-07-16 19:39:23 +00:00
}
}
}
2006-09-05 21:17:59 +00:00
- ( void ) watcher : ( id < UKFileWatcher > ) watcher receivedNotification : ( NSString * ) notification forPath : ( NSString * ) path
2006-09-05 04:28:07 +00:00
{
2006-09-05 21:17:59 +00:00
if ( [ notification isEqualToString : UKFileWatcherWriteNotification ] )
2006-09-05 04:28:07 +00:00
[ self checkAutoImportDirectory ] ;
}
2006-10-16 02:35:42 +00:00
- ( void ) changeAutoImport
{
2006-10-16 02:42:46 +00:00
[ fAutoImportedNames removeAllObjects ] ;
2006-10-16 03:17:25 +00:00
[ self checkAutoImportDirectory ] ;
2006-10-16 02:35:42 +00:00
}
2006-09-05 04:28:07 +00:00
- ( void ) checkAutoImportDirectory
2006-07-16 19:39:23 +00:00
{
if ( ! [ fDefaults boolForKey : @ "AutoImport" ] )
return ;
NSString * path = [ [ fDefaults stringForKey : @ "AutoImportDirectory" ] stringByExpandingTildeInPath ] ;
2006-09-05 04:28:07 +00:00
NSArray * importedNames ;
if ( ! ( importedNames = [ [ NSFileManager defaultManager ] directoryContentsAtPath : path ] ) )
2006-07-16 19:39:23 +00:00
return ;
2006-10-16 02:35:42 +00:00
// only import those that have not been imported yet
NSMutableArray * newNames = [ importedNames mutableCopy ] ;
[ newNames removeObjectsInArray : fAutoImportedNames ] ;
2006-10-16 02:47:10 +00:00
[ fAutoImportedNames setArray : importedNames ] ;
2006-10-16 02:35:42 +00:00
NSEnumerator * enumerator = [ newNames objectEnumerator ] ;
2006-07-16 19:39:23 +00:00
NSString * file ;
unsigned oldCount ;
while ( ( file = [ enumerator nextObject ] ) )
2006-10-16 02:35:42 +00:00
{
2006-07-16 19:39:23 +00:00
if ( [ [ file pathExtension ] caseInsensitiveCompare : @ "torrent" ] = = NSOrderedSame )
{
oldCount = [ fTorrents count ] ;
2006-08-02 00:04:04 +00:00
[ self openFiles : [ NSArray arrayWithObject : [ path stringByAppendingPathComponent : file ] ] ] ;
2006-07-16 19:39:23 +00:00
// import only actually happened if the torrent array is larger
if ( oldCount < [ fTorrents count ] )
2006-10-24 20:34:13 +00:00
[ GrowlApplicationBridge notifyWithTitle : NSLocalizedString ( @ "Torrent File Auto Added" , "Growl notification title" ) description : file
2006-07-30 18:37:29 +00:00
notificationName : GROWL_AUTO _ADD iconData : nil priority : 0 isSticky : NO clickContext : nil ] ;
2006-07-16 19:39:23 +00:00
}
2006-10-16 02:35:42 +00:00
}
[ newNames release ] ;
2006-07-16 19:39:23 +00:00
}
- ( int ) numberOfRowsInTableView : ( NSTableView * ) t
{
2006-08-06 17:06:05 +00:00
return [ fDisplayedTorrents count ] ;
2006-07-16 19:39:23 +00:00
}
2006-09-11 23:52:03 +00:00
- ( id ) tableView : ( NSTableView * ) tableView objectValueForTableColumn : ( NSTableColumn * ) tableColumn row : ( int ) row
{
return [ [ fDisplayedTorrents objectAtIndex : row ] infoForCurrentView ] ;
2006-07-16 19:39:23 +00:00
}
- ( BOOL ) tableView : ( NSTableView * ) tableView writeRowsWithIndexes : ( NSIndexSet * ) indexes
toPasteboard : ( NSPasteboard * ) pasteboard
{
// only allow reordering of rows if sorting by order with no filter
2006-07-19 00:06:32 +00:00
if ( [ fSortType isEqualToString : @ "Order" ] && [ fFilterType isEqualToString : @ "None" ]
2006-08-06 20:40:12 +00:00
&& [ [ fSearchFilterField stringValue ] length ] = = 0 )
2006-07-16 19:39:23 +00:00
{
[ pasteboard declareTypes : [ NSArray arrayWithObject : TORRENT_TABLE _VIEW _DATA _TYPE ] owner : self ] ;
[ pasteboard setData : [ NSKeyedArchiver archivedDataWithRootObject : indexes ]
forType : TORRENT_TABLE _VIEW _DATA _TYPE ] ;
return YES ;
}
return NO ;
}
- ( NSDragOperation ) tableView : ( NSTableView * ) t validateDrop : ( id < NSDraggingInfo > ) info
proposedRow : ( int ) row proposedDropOperation : ( NSTableViewDropOperation ) operation
{
NSPasteboard * pasteboard = [ info draggingPasteboard ] ;
if ( [ [ pasteboard types ] containsObject : NSFilenamesPboardType ] )
{
// check if any files to add have "torrent" as an extension
NSEnumerator * enumerator = [ [ pasteboard propertyListForType : NSFilenamesPboardType ] objectEnumerator ] ;
NSString * file ;
while ( ( file = [ enumerator nextObject ] ) )
if ( [ [ file pathExtension ] caseInsensitiveCompare : @ "torrent" ] = = NSOrderedSame )
{
[ fTableView setDropRow : -1 dropOperation : NSTableViewDropOn ] ;
return NSDragOperationGeneric ;
}
}
else if ( [ [ pasteboard types ] containsObject : TORRENT_TABLE _VIEW _DATA _TYPE ] )
{
[ fTableView setDropRow : row dropOperation : NSTableViewDropAbove ] ;
return NSDragOperationGeneric ;
}
2006-08-06 17:06:05 +00:00
else
return NSDragOperationNone ;
2006-07-16 19:39:23 +00:00
}
- ( BOOL ) tableView : ( NSTableView * ) t acceptDrop : ( id < NSDraggingInfo > ) info
row : ( int ) newRow dropOperation : ( NSTableViewDropOperation ) operation
{
NSPasteboard * pasteboard = [ info draggingPasteboard ] ;
if ( [ [ pasteboard types ] containsObject : NSFilenamesPboardType ] )
{
// create an array of files with the "torrent" extension
NSMutableArray * filesToOpen = [ [ NSMutableArray alloc ] init ] ;
NSEnumerator * enumerator = [ [ pasteboard propertyListForType : NSFilenamesPboardType ] objectEnumerator ] ;
NSString * file ;
while ( ( file = [ enumerator nextObject ] ) )
if ( [ [ file pathExtension ] caseInsensitiveCompare : @ "torrent" ] = = NSOrderedSame )
[ filesToOpen addObject : file ] ;
[ self application : NSApp openFiles : filesToOpen ] ;
[ filesToOpen release ] ;
}
else
{
// remember selected rows if needed
NSArray * selectedTorrents = nil ;
int numSelected = [ fTableView numberOfSelectedRows ] ;
2006-08-06 17:06:05 +00:00
if ( numSelected > 0 && numSelected < [ fDisplayedTorrents count ] )
2006-07-16 19:39:23 +00:00
selectedTorrents = [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ] ;
NSIndexSet * indexes = [ NSKeyedUnarchiver unarchiveObjectWithData :
[ pasteboard dataForType : TORRENT_TABLE _VIEW _DATA _TYPE ] ] ;
// move torrent in array
NSArray * movingTorrents = [ [ self torrentsAtIndexes : indexes ] retain ] ;
2006-08-06 17:06:05 +00:00
[ fDisplayedTorrents removeObjectsInArray : movingTorrents ] ;
2006-07-16 19:39:23 +00:00
// determine the insertion index now that transfers to move have been removed
int i , decrease = 0 ;
for ( i = [ indexes firstIndex ] ; i < newRow && i ! = NSNotFound ; i = [ indexes indexGreaterThanIndex : i ] )
decrease + + ;
// insert objects at new location
for ( i = 0 ; i < [ movingTorrents count ] ; i + + )
2006-08-06 17:06:05 +00:00
[ fDisplayedTorrents insertObject : [ movingTorrents objectAtIndex : i ] atIndex : newRow - decrease + i ] ;
2006-07-16 19:39:23 +00:00
[ movingTorrents release ] ;
// redo order values
int low = [ indexes firstIndex ] , high = [ indexes lastIndex ] ;
if ( newRow < low )
low = newRow ;
else if ( newRow > high + 1 )
high = newRow - 1 ;
else ;
for ( i = low ; i <= high ; i + + )
2006-08-06 17:06:05 +00:00
[ [ fDisplayedTorrents objectAtIndex : i ] setOrderValue : i ] ;
2006-07-16 19:39:23 +00:00
[ fTableView reloadData ] ;
// set selected rows if needed
if ( selectedTorrents )
{
Torrent * torrent ;
NSEnumerator * enumerator = [ selectedTorrents objectEnumerator ] ;
NSMutableIndexSet * indexSet = [ [ NSMutableIndexSet alloc ] init ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
2006-08-06 17:06:05 +00:00
[ indexSet addIndex : [ fDisplayedTorrents indexOfObject : torrent ] ] ;
2006-07-16 19:39:23 +00:00
[ fTableView selectRowIndexes : indexSet byExtendingSelection : NO ] ;
[ indexSet release ] ;
}
}
return YES ;
}
- ( void ) tableViewSelectionDidChange : ( NSNotification * ) notification
{
2006-09-25 20:53:10 +00:00
[ fInfoController updateInfoForTorrents : [ self torrentsAtIndexes : [ fTableView selectedRowIndexes ] ] ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) toggleSmallView : ( id ) sender
{
BOOL makeSmall = ! [ fDefaults boolForKey : @ "SmallView" ] ;
[ fTableView setRowHeight : makeSmall ? ROW_HEIGHT _SMALL : ROW_HEIGHT _REGULAR ] ;
[ fSmallViewItem setState : makeSmall ] ;
[ fDefaults setBool : makeSmall forKey : @ "SmallView" ] ;
// window min height
NSSize contentMinSize = [ fWindow contentMinSize ] ,
contentSize = [ [ fWindow contentView ] frame ] . size ;
contentMinSize . height = contentSize . height - [ fScrollView frame ] . size . height
+ [ fTableView rowHeight ] + [ fTableView intercellSpacing ] . height ;
[ fWindow setContentMinSize : contentMinSize ] ;
2006-07-23 15:59:06 +00:00
// resize for larger min height if not set to auto size
2006-07-23 16:28:33 +00:00
if ( ! [ fDefaults boolForKey : @ "AutoSize" ] )
2006-07-16 19:39:23 +00:00
{
2006-07-23 16:28:33 +00:00
if ( ! makeSmall && contentSize . height < contentMinSize . height )
{
NSRect frame = [ fWindow frame ] ;
float heightChange = contentMinSize . height - contentSize . height ;
frame . size . height + = heightChange ;
frame . origin . y - = heightChange ;
[ fWindow setFrame : frame display : YES ] ;
[ fTableView reloadData ] ;
}
2006-07-16 19:39:23 +00:00
}
2006-07-23 16:28:33 +00:00
else
[ self setWindowSizeToFit ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) toggleStatusBar : ( id ) sender
{
2006-07-29 18:09:35 +00:00
[ self showStatusBar : [ fStatusBar isHidden ] animate : YES ] ;
[ fDefaults setBool : ! [ fStatusBar isHidden ] forKey : @ "StatusBar" ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) showStatusBar : ( BOOL ) show animate : ( BOOL ) animate
{
2006-08-06 17:06:05 +00:00
if ( show ! = [ fStatusBar isHidden ] )
2006-07-16 19:39:23 +00:00
return ;
2006-07-19 00:24:54 +00:00
if ( show )
[ fStatusBar setHidden : NO ] ;
2006-07-16 19:39:23 +00:00
NSRect frame = [ fWindow frame ] ;
float heightChange = [ fStatusBar frame ] . size . height ;
if ( ! show )
heightChange * = -1 ;
2006-10-15 19:24:08 +00:00
// allow bar to show even if not enough room
if ( show && ! [ fDefaults boolForKey : @ "AutoSize" ] )
{
float maxHeight = [ [ fWindow screen ] visibleFrame ] . size . height - heightChange ;
if ( frame . size . height > maxHeight )
{
float change = maxHeight - frame . size . height ;
frame . size . height + = change ;
frame . origin . y - = change ;
[ fWindow setFrame : frame display : NO animate : NO ] ;
}
}
2006-07-16 19:39:23 +00:00
frame . size . height + = heightChange ;
frame . origin . y - = heightChange ;
[ self updateUI : nil ] ;
// set views to not autoresize
unsigned int statsMask = [ fStatusBar autoresizingMask ] ;
unsigned int filterMask = [ fFilterBar autoresizingMask ] ;
unsigned int scrollMask = [ fScrollView autoresizingMask ] ;
[ fStatusBar setAutoresizingMask : 0 ] ;
[ fFilterBar setAutoresizingMask : 0 ] ;
[ fScrollView setAutoresizingMask : 0 ] ;
[ fWindow setFrame : frame display : YES animate : animate ] ;
// re - enable autoresize
[ fStatusBar setAutoresizingMask : statsMask ] ;
[ fFilterBar setAutoresizingMask : filterMask ] ;
[ fScrollView setAutoresizingMask : scrollMask ] ;
// change min size
NSSize minSize = [ fWindow contentMinSize ] ;
minSize . height + = heightChange ;
[ fWindow setContentMinSize : minSize ] ;
2006-07-19 00:24:54 +00:00
if ( ! show )
[ fStatusBar setHidden : YES ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) toggleFilterBar : ( id ) sender
{
// disable filtering when hiding
2006-07-29 18:09:35 +00:00
if ( ! [ fFilterBar isHidden ] )
2006-07-16 19:39:23 +00:00
{
[ fSearchFilterField setStringValue : @ "" ] ;
[ self setFilter : fNoFilterButton ] ;
}
2006-07-23 14:46:13 +00:00
2006-07-29 18:09:35 +00:00
[ self showFilterBar : [ fFilterBar isHidden ] animate : YES ] ;
[ fDefaults setBool : ! [ fFilterBar isHidden ] forKey : @ "FilterBar" ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) showFilterBar : ( BOOL ) show animate : ( BOOL ) animate
{
2006-08-06 17:06:05 +00:00
if ( show ! = [ fFilterBar isHidden ] )
2006-07-16 19:39:23 +00:00
return ;
2006-07-19 00:24:54 +00:00
if ( show )
[ fFilterBar setHidden : NO ] ;
2006-07-16 19:39:23 +00:00
NSRect frame = [ fWindow frame ] ;
float heightChange = [ fFilterBar frame ] . size . height ;
if ( ! show )
heightChange * = -1 ;
2006-10-15 19:24:08 +00:00
// allow bar to show even if not enough room
if ( show && ! [ fDefaults boolForKey : @ "AutoSize" ] )
{
float maxHeight = [ [ fWindow screen ] visibleFrame ] . size . height - heightChange ;
if ( frame . size . height > maxHeight )
{
float change = maxHeight - frame . size . height ;
frame . size . height + = change ;
frame . origin . y - = change ;
[ fWindow setFrame : frame display : NO animate : NO ] ;
}
}
2006-07-16 19:39:23 +00:00
frame . size . height + = heightChange ;
frame . origin . y - = heightChange ;
// set views to not autoresize
unsigned int filterMask = [ fFilterBar autoresizingMask ] ;
unsigned int scrollMask = [ fScrollView autoresizingMask ] ;
[ fFilterBar setAutoresizingMask : 0 ] ;
[ fScrollView setAutoresizingMask : 0 ] ;
2006-10-15 19:24:08 +00:00
[ fWindow setFrame : frame display : YES animate : animate ] ;
2006-07-16 19:39:23 +00:00
// re - enable autoresize
[ fFilterBar setAutoresizingMask : filterMask ] ;
[ fScrollView setAutoresizingMask : scrollMask ] ;
// change min size
NSSize minSize = [ fWindow contentMinSize ] ;
minSize . height + = heightChange ;
[ fWindow setContentMinSize : minSize ] ;
2006-07-17 03:02:56 +00:00
if ( ! show )
2006-07-19 00:27:38 +00:00
{
2006-07-19 00:24:54 +00:00
[ fFilterBar setHidden : YES ] ;
2006-07-19 00:27:38 +00:00
[ fWindow makeFirstResponder : fTableView ] ;
}
2006-07-16 19:39:23 +00:00
}
- ( void ) toggleAdvancedBar : ( id ) sender
{
int state = ! [ fAdvancedBarItem state ] ;
[ fAdvancedBarItem setState : state ] ;
[ fDefaults setBool : state forKey : @ "UseAdvancedBar" ] ;
2006-07-22 14:08:35 +00:00
2006-07-16 19:39:23 +00:00
[ fTableView display ] ;
}
- ( NSToolbarItem * ) toolbar : ( NSToolbar * ) t itemForItemIdentifier :
( NSString * ) ident willBeInsertedIntoToolbar : ( BOOL ) flag
{
NSToolbarItem * item = [ [ NSToolbarItem alloc ] initWithItemIdentifier : ident ] ;
if ( [ ident isEqualToString : TOOLBAR_OPEN ] )
{
2006-10-24 20:34:13 +00:00
[ item setLabel : NSLocalizedString ( @ "Open" , "Open toolbar item -> label" ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Open Torrent Files" , "Open toolbar item -> palette label" ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Open torrent files" , "Open toolbar item -> tooltip" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setImage : [ NSImage imageNamed : @ "Open.png" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( openShowSheet : ) ] ;
}
else if ( [ ident isEqualToString : TOOLBAR_REMOVE ] )
{
2006-10-24 20:34:13 +00:00
[ item setLabel : NSLocalizedString ( @ "Remove" , "Remove toolbar item -> label" ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Remove Selected" , "Remove toolbar item -> palette label" ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Remove selected transfers" , "Remove toolbar item -> tooltip" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setImage : [ NSImage imageNamed : @ "Remove.png" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( removeNoDelete : ) ] ;
}
else if ( [ ident isEqualToString : TOOLBAR_INFO ] )
{
2006-10-24 20:34:13 +00:00
[ item setLabel : NSLocalizedString ( @ "Inspector" , "Inspector toolbar item -> label" ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Toggle Inspector" , "Inspector toolbar item -> palette label" ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Toggle the torrent inspector" , "Inspector toolbar item -> tooltip" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setImage : [ NSImage imageNamed : @ "Info.png" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( showInfo : ) ] ;
}
else if ( [ ident isEqualToString : TOOLBAR_PAUSE _ALL ] )
{
2006-10-24 20:34:13 +00:00
[ item setLabel : NSLocalizedString ( @ "Pause All" , "Pause All toolbar item -> label" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setPaletteLabel : [ item label ] ] ;
2006-10-24 20:34:13 +00:00
[ item setToolTip : NSLocalizedString ( @ "Pause all transfers" , "Pause All toolbar item -> tooltip" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setImage : [ NSImage imageNamed : @ "PauseAll.png" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( stopAllTorrents : ) ] ;
}
else if ( [ ident isEqualToString : TOOLBAR_RESUME _ALL ] )
{
2006-10-24 20:34:13 +00:00
[ item setLabel : NSLocalizedString ( @ "Resume All" , "Resume All toolbar item -> label" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setPaletteLabel : [ item label ] ] ;
2006-10-24 20:34:13 +00:00
[ item setToolTip : NSLocalizedString ( @ "Resume all transfers" , "Resume All toolbar item -> tooltip" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setImage : [ NSImage imageNamed : @ "ResumeAll.png" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( resumeAllTorrents : ) ] ;
}
else if ( [ ident isEqualToString : TOOLBAR_PAUSE _SELECTED ] )
{
2006-10-24 20:34:13 +00:00
[ item setLabel : NSLocalizedString ( @ "Pause" , "Pause toolbar item -> label" ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Pause Selected" , "Pause toolbar item -> palette label" ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Pause selected transfers" , "Pause toolbar item -> tooltip" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setImage : [ NSImage imageNamed : @ "PauseSelected.png" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( stopSelectedTorrents : ) ] ;
}
else if ( [ ident isEqualToString : TOOLBAR_RESUME _SELECTED ] )
{
2006-10-24 20:34:13 +00:00
[ item setLabel : NSLocalizedString ( @ "Resume" , "Resume toolbar item -> label" ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Resume Selected" , "Resume toolbar item -> palette label" ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Resume selected transfers" , "Resume toolbar item -> tooltip" ) ] ;
2006-07-16 19:39:23 +00:00
[ item setImage : [ NSImage imageNamed : @ "ResumeSelected.png" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( resumeSelectedTorrents : ) ] ;
}
2006-07-20 21:58:25 +00:00
else if ( [ ident isEqualToString : TOOLBAR_FILTER ] )
{
2006-10-24 20:34:13 +00:00
[ item setLabel : NSLocalizedString ( @ "Filter" , "Filter toolbar item -> label" ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Toggle Filter" , "Filter toolbar item -> palette label" ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Toggle the filter bar" , "Filter toolbar item -> tooltip" ) ] ;
2006-07-21 04:33:20 +00:00
[ item setImage : [ NSImage imageNamed : @ "Filter.png" ] ] ;
2006-07-20 21:58:25 +00:00
[ item setTarget : self ] ;
[ item setAction : @ selector ( toggleFilterBar : ) ] ;
}
2006-07-16 19:39:23 +00:00
else
{
[ item release ] ;
return nil ;
}
return item ;
}
- ( NSArray * ) toolbarAllowedItemIdentifiers : ( NSToolbar * ) t
{
return [ NSArray arrayWithObjects :
TOOLBAR_OPEN , TOOLBAR_REMOVE ,
TOOLBAR_PAUSE _SELECTED , TOOLBAR_RESUME _SELECTED ,
2006-07-20 21:58:25 +00:00
TOOLBAR_PAUSE _ALL , TOOLBAR_RESUME _ALL , TOOLBAR_FILTER , TOOLBAR_INFO ,
2006-07-16 19:39:23 +00:00
NSToolbarSeparatorItemIdentifier ,
NSToolbarSpaceItemIdentifier ,
NSToolbarFlexibleSpaceItemIdentifier ,
NSToolbarCustomizeToolbarItemIdentifier , nil ] ;
}
- ( NSArray * ) toolbarDefaultItemIdentifiers : ( NSToolbar * ) t
{
return [ NSArray arrayWithObjects :
TOOLBAR_OPEN , TOOLBAR_REMOVE ,
NSToolbarSeparatorItemIdentifier ,
TOOLBAR_PAUSE _ALL , TOOLBAR_RESUME _ALL ,
NSToolbarFlexibleSpaceItemIdentifier ,
2006-07-20 21:58:25 +00:00
TOOLBAR_FILTER , TOOLBAR_INFO , nil ] ;
2006-07-16 19:39:23 +00:00
}
- ( BOOL ) validateToolbarItem : ( NSToolbarItem * ) toolbarItem
{
NSString * ident = [ toolbarItem itemIdentifier ] ;
// enable remove item
if ( [ ident isEqualToString : TOOLBAR_REMOVE ] )
return [ fTableView numberOfSelectedRows ] > 0 ;
// enable pause all item
if ( [ ident isEqualToString : TOOLBAR_PAUSE _ALL ] )
{
Torrent * torrent ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
2006-09-25 18:37:45 +00:00
if ( [ torrent isActive ] || [ torrent waitingToStart ] )
2006-07-16 19:39:23 +00:00
return YES ;
return NO ;
}
// enable resume all item
if ( [ ident isEqualToString : TOOLBAR_RESUME _ALL ] )
{
Torrent * torrent ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
2006-09-25 18:37:45 +00:00
if ( [ torrent isPaused ] && ! [ torrent waitingToStart ] )
2006-07-16 19:39:23 +00:00
return YES ;
return NO ;
}
// enable pause item
if ( [ ident isEqualToString : TOOLBAR_PAUSE _SELECTED ] )
{
Torrent * torrent ;
NSIndexSet * indexSet = [ fTableView selectedRowIndexes ] ;
unsigned int i ;
for ( i = [ indexSet firstIndex ] ; i ! = NSNotFound ; i = [ indexSet indexGreaterThanIndex : i ] )
2006-09-25 18:37:45 +00:00
{
torrent = [ fDisplayedTorrents objectAtIndex : i ] ;
if ( [ torrent isActive ] || [ torrent waitingToStart ] )
2006-07-16 19:39:23 +00:00
return YES ;
2006-09-25 18:37:45 +00:00
}
2006-07-16 19:39:23 +00:00
return NO ;
}
// enable resume item
if ( [ ident isEqualToString : TOOLBAR_RESUME _SELECTED ] )
{
2006-09-25 18:37:45 +00:00
Torrent * torrent ;
2006-07-16 19:39:23 +00:00
NSIndexSet * indexSet = [ fTableView selectedRowIndexes ] ;
unsigned int i ;
for ( i = [ indexSet firstIndex ] ; i ! = NSNotFound ; i = [ indexSet indexGreaterThanIndex : i ] )
2006-09-25 18:37:45 +00:00
{
torrent = [ fDisplayedTorrents objectAtIndex : i ] ;
if ( [ torrent isPaused ] && ! [ torrent waitingToStart ] )
2006-07-16 19:39:23 +00:00
return YES ;
2006-09-25 18:37:45 +00:00
}
2006-07-16 19:39:23 +00:00
return NO ;
}
return YES ;
}
- ( BOOL ) validateMenuItem : ( NSMenuItem * ) menuItem
{
SEL action = [ menuItem action ] ;
// only enable some items if it is in a context menu or the window is useable
2006-09-08 01:14:31 +00:00
BOOL canUseTable = [ fWindow isKeyWindow ] || [ [ [ menuItem menu ] title ] isEqualToString : @ "Context" ] ;
2006-07-16 19:39:23 +00:00
2006-08-06 17:06:05 +00:00
// enable open items
if ( action = = @ selector ( openShowSheet : ) )
return [ fWindow attachedSheet ] = = nil ;
2006-09-08 01:14:31 +00:00
// enable sort and advanced bar items
if ( action = = @ selector ( setSort : ) || action = = @ selector ( toggleAdvancedBar : ) || action = = @ selector ( toggleSmallView : ) )
return [ fWindow isVisible ] ;
2006-08-06 17:06:05 +00:00
2006-07-16 19:39:23 +00:00
// enable show info
if ( action = = @ selector ( showInfo : ) )
{
2006-10-24 20:34:13 +00:00
NSString * title = [ [ fInfoController window ] isVisible ] ? NSLocalizedString ( @ "Hide Inspector" , "View menu -> Inspector" ) : NSLocalizedString ( @ "Show Inspector" , "View menu -> Inspector" ) ;
2006-07-16 19:39:23 +00:00
if ( ! [ [ menuItem title ] isEqualToString : title ] )
[ menuItem setTitle : title ] ;
return YES ;
}
// enable prev / next inspector tab
if ( action = = @ selector ( setInfoTab : ) )
return [ [ fInfoController window ] isVisible ] ;
// enable toggle status bar
if ( action = = @ selector ( toggleStatusBar : ) )
{
2006-10-24 20:34:13 +00:00
NSString * title = [ fStatusBar isHidden ] ? NSLocalizedString ( @ "Show Status Bar" , "View menu -> Status Bar" ) : NSLocalizedString ( @ "Hide Status Bar" , "View menu -> Status Bar" ) ;
2006-07-16 19:39:23 +00:00
if ( ! [ [ menuItem title ] isEqualToString : title ] )
2006-09-08 01:17:26 +00:00
[ menuItem setTitle : title ] ;
2006-07-16 19:39:23 +00:00
2006-09-08 01:14:31 +00:00
return [ fWindow isVisible ] ;
2006-07-16 19:39:23 +00:00
}
// enable toggle filter bar
if ( action = = @ selector ( toggleFilterBar : ) )
{
2006-10-24 20:34:13 +00:00
NSString * title = [ fFilterBar isHidden ] ? NSLocalizedString ( @ "Show Filter Bar" , "View menu -> Filter Bar" ) : NSLocalizedString ( @ "Hide Filter Bar" , "View menu -> Filter Bar" ) ;
2006-07-16 19:39:23 +00:00
if ( ! [ [ menuItem title ] isEqualToString : title ] )
2006-09-08 01:17:26 +00:00
[ menuItem setTitle : title ] ;
2006-07-16 19:39:23 +00:00
2006-09-08 01:14:31 +00:00
return [ fWindow isVisible ] ;
2006-07-16 19:39:23 +00:00
}
2006-09-08 01:14:31 +00:00
// enable prev / next filter button
if ( action = = @ selector ( switchFilter : ) )
2006-09-08 01:17:26 +00:00
return [ fWindow isVisible ] && ! [ fFilterBar isHidden ] ;
2006-07-16 19:39:23 +00:00
// enable reveal in finder
if ( action = = @ selector ( revealFile : ) )
2006-09-08 01:14:31 +00:00
return canUseTable && [ fTableView numberOfSelectedRows ] > 0 ;
2006-07-16 19:39:23 +00:00
// enable remove items
if ( action = = @ selector ( removeNoDelete : ) || action = = @ selector ( removeDeleteData : )
|| action = = @ selector ( removeDeleteTorrent : ) || action = = @ selector ( removeDeleteDataAndTorrent : ) )
{
BOOL warning = NO ,
onlyDownloading = [ fDefaults boolForKey : @ "CheckRemoveDownloading" ] ,
canDelete = action ! = @ selector ( removeDeleteTorrent : ) && action ! = @ selector ( removeDeleteDataAndTorrent : ) ;
Torrent * torrent ;
NSIndexSet * indexSet = [ fTableView selectedRowIndexes ] ;
unsigned int i ;
for ( i = [ indexSet firstIndex ] ; i ! = NSNotFound ; i = [ indexSet indexGreaterThanIndex : i ] )
{
2006-08-06 17:06:05 +00:00
torrent = [ fDisplayedTorrents objectAtIndex : i ] ;
2006-07-16 19:39:23 +00:00
if ( ! warning && [ torrent isActive ] )
{
warning = onlyDownloading ? ! [ torrent isSeeding ] : YES ;
if ( warning && canDelete )
break ;
}
if ( ! canDelete && [ torrent publicTorrent ] )
{
canDelete = YES ;
if ( warning )
break ;
}
}
// append or remove ellipsis when needed
NSString * title = [ menuItem title ] , * ellipsis = [ NSString ellipsis ] ;
if ( warning && [ fDefaults boolForKey : @ "CheckRemove" ] )
{
if ( ! [ title hasSuffix : ellipsis ] )
[ menuItem setTitle : [ title stringByAppendingEllipsis ] ] ;
}
else
{
if ( [ title hasSuffix : ellipsis ] )
[ menuItem setTitle : [ title substringToIndex : [ title rangeOfString : ellipsis ] . location ] ] ;
}
2006-09-08 01:14:31 +00:00
return canUseTable && canDelete && [ fTableView numberOfSelectedRows ] > 0 ;
2006-07-16 19:39:23 +00:00
}
2006-08-01 23:09:33 +00:00
// enable pause all item
if ( action = = @ selector ( stopAllTorrents : ) )
{
Torrent * torrent ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
2006-09-25 18:37:45 +00:00
if ( [ torrent isActive ] || [ torrent waitingToStart ] )
2006-08-01 23:09:33 +00:00
return YES ;
return NO ;
}
// enable resume all item
if ( action = = @ selector ( resumeAllTorrents : ) )
{
Torrent * torrent ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
2006-09-25 18:37:45 +00:00
if ( [ torrent isPaused ] && ! [ torrent waitingToStart ] )
2006-08-01 23:09:33 +00:00
return YES ;
return NO ;
}
2006-09-25 18:37:45 +00:00
// enable resume all waiting item
2006-08-01 23:09:33 +00:00
if ( action = = @ selector ( resumeWaitingTorrents : ) )
{
2006-09-25 18:37:45 +00:00
if ( ! [ fDefaults boolForKey : @ "Queue" ] )
2006-08-01 23:09:33 +00:00
return NO ;
Torrent * torrent ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( [ torrent waitingToStart ] )
return YES ;
return NO ;
}
2006-09-25 18:37:45 +00:00
// enable resume selected waiting item
if ( action = = @ selector ( resumeSelectedTorrentsNoWait : ) )
{
if ( ! [ fDefaults boolForKey : @ "Queue" ] )
return NO ;
Torrent * torrent ;
NSIndexSet * indexSet = [ fTableView selectedRowIndexes ] ;
unsigned int i ;
for ( i = [ indexSet firstIndex ] ; i ! = NSNotFound ; i = [ indexSet indexGreaterThanIndex : i ] )
{
torrent = [ fDisplayedTorrents objectAtIndex : i ] ;
2006-09-26 03:27:41 +00:00
if ( [ torrent isPaused ] && [ torrent progress ] < 1.0 )
2006-09-25 18:37:45 +00:00
return YES ;
}
return NO ;
}
2006-08-01 23:09:33 +00:00
2006-07-16 19:39:23 +00:00
// enable pause item
if ( action = = @ selector ( stopSelectedTorrents : ) )
{
2006-09-08 01:14:31 +00:00
if ( ! canUseTable )
2006-07-16 19:39:23 +00:00
return NO ;
Torrent * torrent ;
NSIndexSet * indexSet = [ fTableView selectedRowIndexes ] ;
unsigned int i ;
for ( i = [ indexSet firstIndex ] ; i ! = NSNotFound ; i = [ indexSet indexGreaterThanIndex : i ] )
{
2006-08-06 17:06:05 +00:00
torrent = [ fDisplayedTorrents objectAtIndex : i ] ;
2006-09-25 18:37:45 +00:00
if ( [ torrent isActive ] || [ torrent waitingToStart ] )
2006-07-16 19:39:23 +00:00
return YES ;
}
return NO ;
}
// enable resume item
if ( action = = @ selector ( resumeSelectedTorrents : ) )
{
2006-09-08 01:14:31 +00:00
if ( ! canUseTable )
2006-07-16 19:39:23 +00:00
return NO ;
Torrent * torrent ;
NSIndexSet * indexSet = [ fTableView selectedRowIndexes ] ;
unsigned int i ;
for ( i = [ indexSet firstIndex ] ; i ! = NSNotFound ; i = [ indexSet indexGreaterThanIndex : i ] )
{
2006-08-06 17:06:05 +00:00
torrent = [ fDisplayedTorrents objectAtIndex : i ] ;
2006-09-25 18:37:45 +00:00
if ( [ torrent isPaused ] && ! [ torrent waitingToStart ] )
2006-07-16 19:39:23 +00:00
return YES ;
}
return NO ;
}
// enable copy torrent file item
if ( action = = @ selector ( copyTorrentFile : ) )
2006-09-08 01:14:31 +00:00
return canUseTable && [ fTableView numberOfSelectedRows ] > 0 ;
2006-07-16 19:39:23 +00:00
return YES ;
}
- ( void ) sleepCallBack : ( natural_t ) messageType argument : ( void * ) messageArgument
{
NSEnumerator * enumerator ;
Torrent * torrent ;
BOOL active ;
switch ( messageType )
{
case kIOMessageSystemWillSleep :
// close all connections before going to sleep and remember we should resume when we wake up
[ fTorrents makeObjectsPerformSelector : @ selector ( sleep ) ] ;
// wait for running transfers to stop ( 5 second timeout )
NSDate * start = [ NSDate date ] ;
BOOL timeUp = NO ;
NSEnumerator * enumerator = [ fTorrents objectEnumerator ] ;
Torrent * torrent ;
while ( ! timeUp && ( torrent = [ enumerator nextObject ] ) )
while ( ! [ torrent isPaused ] && ! ( timeUp = [ start timeIntervalSinceNow ] < -5.0 ) )
{
usleep ( 100000 ) ;
[ torrent update ] ;
}
IOAllowPowerChange ( fRootPort , ( long ) messageArgument ) ;
break ;
case kIOMessageCanSystemSleep :
// pevent idle sleep unless all paused
active = NO ;
enumerator = [ fTorrents objectEnumerator ] ;
while ( ( torrent = [ enumerator nextObject ] ) )
if ( [ torrent isActive ] )
{
active = YES ;
break ;
}
if ( active )
IOCancelPowerChange ( fRootPort , ( long ) messageArgument ) ;
else
IOAllowPowerChange ( fRootPort , ( long ) messageArgument ) ;
break ;
case kIOMessageSystemHasPoweredOn :
// resume sleeping transfers after we wake up
[ fTorrents makeObjectsPerformSelector : @ selector ( wakeUp ) ] ;
break ;
}
}
2006-07-30 21:49:58 +00:00
- ( void ) resetDockBadge : ( NSNotification * ) notification
{
float downloadRate , uploadRate ;
tr_torrentRates ( fLib , & downloadRate , & uploadRate ) ;
[ fBadger updateBadgeWithCompleted : fCompleted uploadRate : uploadRate downloadRate : downloadRate ] ;
}
2006-07-16 19:39:23 +00:00
- ( NSRect ) windowWillUseStandardFrame : ( NSWindow * ) window defaultFrame : ( NSRect ) defaultFrame
{
2006-07-23 21:50:41 +00:00
// if auto size is enabled , the current frame shouldn ' t need to change
NSRect frame = [ fDefaults boolForKey : @ "AutoSize" ] ? [ window frame ] : [ self sizedWindowFrame ] ;
2006-07-22 21:00:58 +00:00
2006-07-23 19:22:24 +00:00
frame . size . width = [ fDefaults boolForKey : @ "SmallView" ] ? [ fWindow minSize ] . width : WINDOW_REGULAR _WIDTH ;
2006-07-22 21:00:58 +00:00
return frame ;
2006-07-16 19:39:23 +00:00
}
2006-07-22 16:38:05 +00:00
- ( void ) setWindowSizeToFit
{
2006-07-22 17:08:54 +00:00
if ( [ fDefaults boolForKey : @ "AutoSize" ] )
2006-10-13 15:21:40 +00:00
{
[ fScrollView setHasVerticalScroller : NO ] ;
2006-07-23 21:50:41 +00:00
[ fWindow setFrame : [ self sizedWindowFrame ] display : YES animate : YES ] ;
2006-10-13 15:21:40 +00:00
[ fScrollView setHasVerticalScroller : YES ] ;
}
2006-07-22 16:57:41 +00:00
}
2006-07-23 21:50:41 +00:00
- ( NSRect ) sizedWindowFrame
2006-07-22 16:57:41 +00:00
{
2006-07-22 16:38:05 +00:00
NSRect frame = [ fWindow frame ] ;
float newHeight = frame . size . height - [ fScrollView frame ] . size . height
2006-08-06 17:06:05 +00:00
+ [ fDisplayedTorrents count ] * ( [ fTableView rowHeight ] + [ fTableView intercellSpacing ] . height ) ;
2006-07-22 16:38:05 +00:00
2006-07-29 18:00:51 +00:00
float minHeight = [ fWindow minSize ] . height ;
if ( newHeight < minHeight )
2006-07-22 16:38:05 +00:00
newHeight = minHeight ;
2006-07-29 18:00:51 +00:00
else
{
float maxHeight = [ [ fWindow screen ] visibleFrame ] . size . height ;
2006-07-29 18:09:35 +00:00
if ( [ fStatusBar isHidden ] )
2006-07-29 18:00:51 +00:00
maxHeight - = [ fStatusBar frame ] . size . height ;
2006-07-29 18:09:35 +00:00
if ( [ fFilterBar isHidden ] )
2006-07-29 18:00:51 +00:00
maxHeight - = [ fFilterBar frame ] . size . height ;
if ( newHeight > maxHeight )
newHeight = maxHeight ;
}
2006-07-22 16:38:05 +00:00
frame . origin . y - = ( newHeight - frame . size . height ) ;
frame . size . height = newHeight ;
2006-07-22 16:57:41 +00:00
return frame ;
2006-07-22 16:38:05 +00:00
}
2006-07-16 19:39:23 +00:00
- ( void ) showMainWindow : ( id ) sender
{
[ fWindow makeKeyAndOrderFront : nil ] ;
}
- ( void ) windowDidBecomeKey : ( NSNotification * ) notification
{
2006-07-19 00:06:32 +00:00
// reset dock badge for completed
if ( fCompleted > 0 )
{
fCompleted = 0 ;
2006-07-30 21:49:58 +00:00
[ self resetDockBadge : nil ] ;
2006-07-19 00:06:32 +00:00
}
2006-07-16 19:39:23 +00:00
}
2006-07-22 16:38:05 +00:00
- ( NSSize ) windowWillResize : ( NSWindow * ) sender toSize : ( NSSize ) proposedFrameSize
{
2006-08-06 20:18:00 +00:00
// only resize horizontally if autosize is enabled
2006-07-22 16:38:05 +00:00
if ( [ fDefaults boolForKey : @ "AutoSize" ] )
proposedFrameSize . height = [ fWindow frame ] . size . height ;
return proposedFrameSize ;
}
2006-07-16 19:39:23 +00:00
- ( void ) windowDidResize : ( NSNotification * ) notification
{
// hide search filter if it overlaps filter buttons
2006-08-06 20:18:00 +00:00
[ fSearchFilterField setHidden : NSMaxX ( [ fPauseFilterButton frame ] ) + 2.0 > [ fSearchFilterField frame ] . origin . x ] ;
2006-07-16 19:39:23 +00:00
}
- ( void ) linkHomepage : ( id ) sender
{
[ [ NSWorkspace sharedWorkspace ] openURL : [ NSURL URLWithString : WEBSITE_URL ] ] ;
}
- ( void ) linkForums : ( id ) sender
{
[ [ NSWorkspace sharedWorkspace ] openURL : [ NSURL URLWithString : FORUM_URL ] ] ;
}
- ( void ) checkUpdate : ( id ) sender
{
[ fPrefsController checkUpdate ] ;
}
- ( void ) prepareForUpdate : ( NSNotification * ) notification
{
fUpdateInProgress = YES ;
}
- ( NSDictionary * ) registrationDictionaryForGrowl
{
2006-08-08 03:04:25 +00:00
NSArray * notifications = [ NSArray arrayWithObjects : GROWL_DOWNLOAD _COMPLETE , GROWL_SEEDING _COMPLETE ,
GROWL_AUTO _ADD , GROWL_AUTO _SPEED _LIMIT , nil ] ;
2006-07-16 19:39:23 +00:00
return [ NSDictionary dictionaryWithObjectsAndKeys : notifications , GROWL_NOTIFICATIONS _ALL ,
notifications , GROWL_NOTIFICATIONS _DEFAULT , nil ] ;
}
@ end