From 0600f3d4aa8d9fd275b05d1d0085bb4a476c9ada Mon Sep 17 00:00:00 2001 From: Josh Elsasser Date: Fri, 9 Jun 2006 19:53:35 +0000 Subject: [PATCH] Add support to libtransmission and the MacOS X GUI for saving private copies of torrent files. --- cli/transmissioncli.c | 2 +- gtk/tr_torrent.c | 2 +- libtransmission/fastresume.h | 13 +- libtransmission/inout.c | 13 +- libtransmission/internal.h | 1 + libtransmission/metainfo.c | 58 ++++++++- libtransmission/metainfo.h | 4 +- libtransmission/platform.c | 122 ++++++++++++++---- libtransmission/platform.h | 3 + libtransmission/transmission.c | 57 ++++++-- libtransmission/transmission.h | 34 ++++- libtransmission/utils.c | 51 ++++++++ libtransmission/utils.h | 8 ++ macosx/Controller.h | 4 - macosx/Controller.m | 40 ++---- macosx/Defaults.plist | 4 + macosx/English.lproj/MainMenu.nib/classes.nib | 2 - macosx/English.lproj/MainMenu.nib/info.nib | 7 +- .../MainMenu.nib/keyedobjects.nib | Bin 35983 -> 34594 bytes .../English.lproj/PrefsWindow.nib/classes.nib | 3 + macosx/English.lproj/PrefsWindow.nib/info.nib | 8 +- .../PrefsWindow.nib/keyedobjects.nib | Bin 16847 -> 18148 bytes macosx/PrefsController.h | 3 +- macosx/PrefsController.m | 37 +++++- macosx/Torrent.h | 15 ++- macosx/Torrent.m | 111 +++++++++++----- 26 files changed, 444 insertions(+), 158 deletions(-) diff --git a/cli/transmissioncli.c b/cli/transmissioncli.c index 3b080d747..66a3d2e27 100644 --- a/cli/transmissioncli.c +++ b/cli/transmissioncli.c @@ -109,7 +109,7 @@ int main( int argc, char ** argv ) h = tr_init(); /* Open and parse torrent file */ - if( !( tor = tr_torrentInit( h, torrentPath, &error ) ) ) + if( !( tor = tr_torrentInit( h, torrentPath, 0, &error ) ) ) { printf( "Failed opening torrent file `%s'\n", torrentPath ); goto failed; diff --git a/gtk/tr_torrent.c b/gtk/tr_torrent.c index aae1a1946..61cbb2440 100644 --- a/gtk/tr_torrent.c +++ b/gtk/tr_torrent.c @@ -270,7 +270,7 @@ tr_torrent_new(GObject *backend, const char *torrent, const char *dir, errcode = -1; handle = tr_torrentInit(tr_backend_handle(TR_BACKEND(backend)), - torrent, &errcode); + torrent, 0, &errcode); if(NULL == handle) { switch(errcode) { case TR_EINVALID: diff --git a/libtransmission/fastresume.h b/libtransmission/fastresume.h index bc03ed516..8e72bc953 100644 --- a/libtransmission/fastresume.h +++ b/libtransmission/fastresume.h @@ -63,17 +63,10 @@ static char * fastResumeFileName( tr_io_t * io ) { - char * ret, * p; - int i; + char * ret; - asprintf( &ret, "%s/resume.%40d", tr_getPrefsDirectory(), 0 ); - - p = &ret[ strlen( ret ) - 2 * SHA_DIGEST_LENGTH ]; - for( i = 0; i < SHA_DIGEST_LENGTH; i++ ) - { - sprintf( p, "%02x", io->tor->info.hash[i] ); - p += 2; - } + asprintf( &ret, "%s/resume.%s", tr_getCacheDirectory(), + io->tor->info.hashString ); return ret; } diff --git a/libtransmission/inout.c b/libtransmission/inout.c index 96051acac..3f3513af1 100644 --- a/libtransmission/inout.c +++ b/libtransmission/inout.c @@ -216,24 +216,15 @@ static int createFiles( tr_io_t * io ) asprintf( &path, "%s/%s", tor->destination, inf->files[i].name ); /* Create folders */ - p = path; - while( ( p = strchr( p, '/' ) ) ) + if( NULL != ( p = strrchr( path, '/' ) ) ) { *p = '\0'; - if( stat( path, &sb ) ) + if( tr_mkdir( path ) ) { - /* Folder doesn't exist yet */ - mkdir( path, 0777 ); - } - else if( ( sb.st_mode & S_IFMT ) != S_IFDIR ) - { - /* Node exists but isn't a folder */ - printf( "Remove %s, it's in the way.\n", path ); free( path ); return 1; } *p = '/'; - p++; } if( stat( path, &sb ) ) diff --git a/libtransmission/internal.h b/libtransmission/internal.h index 12ded06bf..1a954e56e 100644 --- a/libtransmission/internal.h +++ b/libtransmission/internal.h @@ -45,6 +45,7 @@ #include #include #include +#include #ifdef BEOS_NETSERVER # define in_port_t uint16_t #else diff --git a/libtransmission/metainfo.c b/libtransmission/metainfo.c index 26cc50321..57d788563 100644 --- a/libtransmission/metainfo.c +++ b/libtransmission/metainfo.c @@ -34,7 +34,8 @@ static void strcatUTF8( char *, char * ); *********************************************************************** * **********************************************************************/ -int tr_metainfoParse( tr_info_t * inf, const char * path ) +int tr_metainfoParse( tr_info_t * inf, const char * path, + const char * savedHash, int saveCopy ) { FILE * file; char * buf; @@ -43,7 +44,16 @@ int tr_metainfoParse( tr_info_t * inf, const char * path ) int i; struct stat sb; - snprintf( inf->torrent, MAX_PATH_LENGTH, "%s", path ); + assert( NULL == path || NULL == savedHash ); + /* if savedHash isn't null, saveCopy should be false */ + assert( NULL == savedHash || !saveCopy ); + + if ( NULL != savedHash ) + { + snprintf( inf->torrent, MAX_PATH_LENGTH, "%s/%s", + tr_getTorrentsDirectory(), savedHash ); + path = inf->torrent; + } if( stat( path, &sb ) ) { @@ -97,8 +107,41 @@ int tr_metainfoParse( tr_info_t * inf, const char * path ) } SHA1( (uint8_t *) beInfo->begin, (long) beInfo->end - (long) beInfo->begin, inf->hash ); + for( i = 0; i < SHA_DIGEST_LENGTH; i++ ) + { + sprintf( inf->hashString + i * 2, "%02x", inf->hash[i] ); + } - /* No that we got the hash, we won't need this anymore */ + if( saveCopy ) + { + /* Save a copy of the torrent file in the private torrent directory */ + snprintf( inf->torrent, MAX_PATH_LENGTH, "%s/%s", + tr_getTorrentsDirectory(), inf->hashString ); + file = fopen( inf->torrent, "wb" ); + if( !file ) + { + fprintf( stderr, "Could not open file (%s) (%s)\n", inf->torrent, strerror(errno) ); + tr_bencFree( &meta ); + free( buf ); + return 1; + } + fseek( file, 0, SEEK_SET ); + if( fwrite( buf, sb.st_size, 1, file ) != 1 ) + { + fprintf( stderr, "Write error (%s)\n", inf->torrent ); + tr_bencFree( &meta ); + free( buf ); + fclose( file ); + return 1; + } + fclose( file ); + } + else + { + snprintf( inf->torrent, MAX_PATH_LENGTH, "%s", path ); + } + + /* We won't need this anymore */ free( buf ); if( !( val = tr_bencDictFind( &meta, "announce" ) ) ) @@ -224,6 +267,15 @@ int tr_metainfoParse( tr_info_t * inf, const char * path ) return 0; } +void tr_metainfoRemoveSaved( const char * hashString ) +{ + char file[MAX_PATH_LENGTH]; + + snprintf( file, MAX_PATH_LENGTH, "%s/%s", + tr_getTorrentsDirectory(), hashString ); + unlink(file); +} + /*********************************************************************** * strcatUTF8 *********************************************************************** diff --git a/libtransmission/metainfo.h b/libtransmission/metainfo.h index aaf2bc5b9..f1ebc53de 100644 --- a/libtransmission/metainfo.h +++ b/libtransmission/metainfo.h @@ -25,6 +25,8 @@ #ifndef TR_METAINFO_H #define TR_METAINFO_H 1 -int tr_metainfoParse( tr_info_t *, const char * ); +int tr_metainfoParse( tr_info_t *, const char * path, + const char * savedHash, int saveCopy ); +void tr_metainfoRemoveSaved( const char * hashString ); #endif diff --git a/libtransmission/platform.c b/libtransmission/platform.c index 446cde7d5..ed1b36879 100644 --- a/libtransmission/platform.c +++ b/libtransmission/platform.c @@ -26,13 +26,38 @@ #include #include #endif -#ifdef SYS_DARWIN - #include - #include -#endif +#include +#include #include "transmission.h" +static void +tr_migrateResume( const char *oldDirectory, const char *newDirectory ) +{ + DIR * dirh; + struct dirent * dirp; + char oldFile[MAX_PATH_LENGTH]; + char newFile[MAX_PATH_LENGTH]; + + if( ( dirh = opendir( oldDirectory ) ) ) + { + while( ( dirp = readdir( dirh ) ) ) + { + if( strncmp( "resume.", dirp->d_name, 7 ) ) + { + continue; + } + snprintf( oldFile, MAX_PATH_LENGTH, "%s/%s", + oldDirectory, dirp->d_name ); + snprintf( newFile, MAX_PATH_LENGTH, "%s/%s", + newDirectory, dirp->d_name ); + rename( oldFile, newFile ); + } + + closedir( dirh ); + } +} + char * tr_getPrefsDirectory() { static char prefsDirectory[MAX_PATH_LENGTH]; @@ -55,41 +80,82 @@ char * tr_getPrefsDirectory() getenv( "HOME" ) ); #endif - mkdir( prefsDirectory, 0755 ); + tr_mkdir( prefsDirectory ); init = 1; #ifdef SYS_DARWIN - DIR * dirh; - struct dirent * dirp; char oldDirectory[MAX_PATH_LENGTH]; - char oldFile[MAX_PATH_LENGTH]; - char newFile[MAX_PATH_LENGTH]; snprintf( oldDirectory, MAX_PATH_LENGTH, "%s/.transmission", getenv( "HOME" ) ); - if( ( dirh = opendir( oldDirectory ) ) ) - { - while( ( dirp = readdir( dirh ) ) ) - { - if( !strcmp( ".", dirp->d_name ) || - !strcmp( "..", dirp->d_name ) ) - { - continue; - } - snprintf( oldFile, MAX_PATH_LENGTH, "%s/%s", - oldDirectory, dirp->d_name ); - snprintf( newFile, MAX_PATH_LENGTH, "%s/%s", - prefsDirectory, dirp->d_name ); - rename( oldFile, newFile ); - } - - closedir( dirh ); - rmdir( oldDirectory ); - } + tr_migrateResume( oldDirectory, prefsDirectory ); + rmdir( oldDirectory ); #endif return prefsDirectory; } +char * tr_getCacheDirectory() +{ + static char cacheDirectory[MAX_PATH_LENGTH]; + static int init = 0; + + if( init ) + { + return cacheDirectory; + } + +#ifdef SYS_BEOS + /* XXX hey Bryan, is this fine with you? */ + snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s/Cache", + tr_getPrefsDirectory() ); +#elif defined( SYS_DARWIN ) + snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s", + tr_getPrefsDirectory() ); +#else + snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s/cache", + tr_getPrefsDirectory() ); +#endif + + tr_mkdir( cacheDirectory ); + init = 1; + + if( strcmp( tr_getPrefsDirectory(), cacheDirectory ) ) + { + tr_migrateResume( tr_getPrefsDirectory(), cacheDirectory ); + } + + return cacheDirectory; +} + +char * tr_getTorrentsDirectory() +{ + static char torrentsDirectory[MAX_PATH_LENGTH]; + static int init = 0; + + if( init ) + { + return torrentsDirectory; + } + +#ifdef SYS_BEOS + /* XXX hey Bryan, is this fine with you? */ + snprintf( torrentsDirectory, MAX_PATH_LENGTH, "%s/Torrents", + tr_getPrefsDirectory() ); +#elif defined( SYS_DARWIN ) + snprintf( torrentsDirectory, MAX_PATH_LENGTH, + "%s/Library/Application Support/Transmission/Torrents", + getenv( "HOME" ) ); +#else + snprintf( torrentsDirectory, MAX_PATH_LENGTH, "%s/torrents", + tr_getPrefsDirectory() ); +#endif + + tr_mkdir( torrentsDirectory ); + init = 1; + + return torrentsDirectory; +} + void tr_threadCreate( tr_thread_t * t, void (*func)(void *), void * arg ) { #ifdef SYS_BEOS diff --git a/libtransmission/platform.h b/libtransmission/platform.h index 01d298986..83fc77ddb 100644 --- a/libtransmission/platform.h +++ b/libtransmission/platform.h @@ -34,6 +34,9 @@ typedef pthread_mutex_t tr_lock_t; #endif +char * tr_getCacheDirectory(); +char * tr_getTorrentsDirectory(); + void tr_threadCreate ( tr_thread_t *, void (*func)(void *), void * arg ); void tr_threadJoin ( tr_thread_t * ); void tr_lockInit ( tr_lock_t * ); diff --git a/libtransmission/transmission.c b/libtransmission/transmission.c index 4892aefc6..e46443402 100644 --- a/libtransmission/transmission.c +++ b/libtransmission/transmission.c @@ -27,6 +27,8 @@ /*********************************************************************** * Local prototypes **********************************************************************/ +static tr_torrent_t * torrentRealInit( tr_handle_t *, tr_torrent_t * tor, + int flags, int * error ); static void torrentReallyStop( tr_torrent_t * ); static void downloadLoop( void * ); static void acceptLoop( void * ); @@ -174,30 +176,55 @@ void tr_torrentRates( tr_handle_t * h, float * dl, float * ul ) } } +tr_torrent_t * tr_torrentInit( tr_handle_t * h, const char * path, + int flags, int * error ) +{ + tr_torrent_t * tor = calloc( sizeof( tr_torrent_t ), 1 ); + int saveCopy = ( TR_FSAVEPRIVATE & flags ); + + /* Parse torrent file */ + if( tr_metainfoParse( &tor->info, path, NULL, saveCopy ) ) + { + *error = TR_EINVALID; + free( tor ); + return NULL; + } + + return torrentRealInit( h, tor, flags, error ); +} + +tr_torrent_t * tr_torrentInitSaved( tr_handle_t * h, const char * hashStr, + int flags, int * error ) +{ + tr_torrent_t * tor = calloc( sizeof( tr_torrent_t ), 1 ); + + /* Parse torrent file */ + if( tr_metainfoParse( &tor->info, NULL, hashStr, 0 ) ) + { + *error = TR_EINVALID; + free( tor ); + return NULL; + } + + return torrentRealInit( h, tor, ( TR_FSAVEPRIVATE | flags ), error ); +} + /*********************************************************************** * tr_torrentInit *********************************************************************** * Allocates a tr_torrent_t structure, then relies on tr_metainfoParse * to fill it. **********************************************************************/ -tr_torrent_t * tr_torrentInit( tr_handle_t * h, const char * path, - int * error ) +static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor, + int flags, int * error ) { - tr_torrent_t * tor, * tor_tmp; + tr_torrent_t * tor_tmp; tr_info_t * inf; int i; char * s1, * s2; - tor = calloc( sizeof( tr_torrent_t ), 1 ); - inf = &tor->info; - - /* Parse torrent file */ - if( tr_metainfoParse( inf, path ) ) - { - *error = TR_EINVALID; - free( tor ); - return NULL; - } + inf = &tor->info; + inf->flags = flags; /* Make sure this torrent is not already open */ for( tor_tmp = h->torrentList; tor_tmp; tor_tmp = tor_tmp->next ) @@ -481,6 +508,10 @@ void tr_torrentAvailability( tr_torrent_t * tor, int8_t * tab, int size ) tr_lockUnlock( &tor->lock ); } +void tr_torrentRemoveSaved( tr_torrent_t * tor ) { + tr_metainfoRemoveSaved( tor->info.hashString ); +} + /*********************************************************************** * tr_torrentClose *********************************************************************** diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 4a1c6df18..d97e5f000 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -59,9 +59,8 @@ tr_handle_t * tr_init(); /*********************************************************************** * tr_getPrefsDirectory *********************************************************************** - * Returns the full path to the directory used by libtransmission to - * store the resume files. The string belongs to libtransmission, do - * not free it. + * Returns the full path to a directory which can be used to store + * preferences. The string belongs to libtransmission, do not free it. **********************************************************************/ char * tr_getPrefsDirectory(); @@ -123,14 +122,25 @@ void tr_close( tr_handle_t * ); * Opens and parses torrent file at 'path'. If the file exists and is a * valid torrent file, returns an handle and adds it to the list of * torrents (but doesn't start it). Returns NULL and sets *error - * otherwise. + * otherwise. If the TR_FSAVEPRIVATE flag is passed then a private copy + * of the torrent file will be saved. **********************************************************************/ #define TR_EINVALID 1 #define TR_EUNSUPPORTED 2 #define TR_EDUPLICATE 3 #define TR_EOTHER 666 tr_torrent_t * tr_torrentInit( tr_handle_t *, const char * path, - int * error ); + int flags, int * error ); + +/*********************************************************************** + * tr_torrentInitSaved + *********************************************************************** + * Opens and parses a torrent file as with tr_torrentInit, only taking + * the hash string of a saved torrent file instead of a filename. There + * are currently no valid flags for this function. + **********************************************************************/ +tr_torrent_t * tr_torrentInitSaved( tr_handle_t *, const char * hashStr, + int flags, int * error ); typedef struct tr_info_s tr_info_t; tr_info_t * tr_torrentInfo( tr_torrent_t * ); @@ -200,6 +210,14 @@ tr_stat_t * tr_torrentStat( tr_torrent_t * ); **********************************************************************/ void tr_torrentAvailability( tr_torrent_t *, int8_t * tab, int size ); +/*********************************************************************** + * tr_torrentRemoveSaved + *********************************************************************** + * Removes the private saved copy of a torrent file for torrents which + * the TR_FSAVEPRIVATE flag is set. + **********************************************************************/ +void tr_torrentRemoveSaved( tr_torrent_t * ); + /*********************************************************************** * tr_torrentClose *********************************************************************** @@ -208,7 +226,6 @@ void tr_torrentAvailability( tr_torrent_t *, int8_t * tab, int size ); **********************************************************************/ void tr_torrentClose( tr_handle_t *, tr_torrent_t * ); - /*********************************************************************** * tr_info_s **********************************************************************/ @@ -225,8 +242,13 @@ struct tr_info_s /* General info */ uint8_t hash[SHA_DIGEST_LENGTH]; + char hashString[2*SHA_DIGEST_LENGTH+1]; char name[MAX_PATH_LENGTH]; + /* Flags */ +#define TR_FSAVEPRIVATE 0x01 /* save a private copy of the torrent */ + int flags; + /* Tracker info */ char trackerAddress[256]; int trackerPort; diff --git a/libtransmission/utils.c b/libtransmission/utils.c index b50a9bb8b..caa3e1b17 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -93,3 +93,54 @@ void * tr_memmem( const void *vbig, size_t big_len, return NULL; } + +int tr_mkdir( char * path ) +{ + char * p, * pp; + struct stat sb; + int done; + + p = path; + while( '/' == *p ) + p++; + pp = p; + done = 0; + while( ( p = strchr( pp, '/' ) ) || ( p = strchr( pp, '\0' ) ) ) + { + if( '\0' == *p) + { + done = 1; + } + else + { + *p = '\0'; + } + if( stat( path, &sb ) ) + { + /* Folder doesn't exist yet */ + if( mkdir( path, 0777 ) ) + { + tr_err( "Could not create directory %s (%s)", path, + strerror( errno ) ); + *p = '/'; + return 1; + } + } + else if( ( sb.st_mode & S_IFMT ) != S_IFDIR ) + { + /* Node exists but isn't a folder */ + tr_err( "Remove %s, it's in the way.", path ); + *p = '/'; + return 1; + } + if( done ) + { + break; + } + *p = '/'; + p++; + pp = p; + } + + return 0; +} diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 9196b291b..0d162bf45 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -37,6 +37,14 @@ int tr_rand ( int ); void * tr_memmem( const void *, size_t, const void *, size_t ); +/*********************************************************************** + * tr_mkdir + *********************************************************************** + * Create a directory and any needed parent directories. + * Note that the string passed in must be writable! + **********************************************************************/ +int tr_mkdir( char * path ); + /*********************************************************************** * tr_date *********************************************************************** diff --git a/macosx/Controller.h b/macosx/Controller.h index 9d7fd2081..1928b2562 100644 --- a/macosx/Controller.h +++ b/macosx/Controller.h @@ -96,17 +96,13 @@ - (void) stopTorrentWithIndex: (NSIndexSet *) indexSet; - (void) removeTorrent: (id) sender; -- (void) removeTorrentDeleteTorrent: (id) sender; - (void) removeTorrentDeleteData: (id) sender; -- (void) removeTorrentDeleteBoth: (id) sender; - (void) removeTorrentWithIndex: (NSIndexSet *) indexSet - deleteTorrent: (BOOL) deleteTorrent deleteData: (BOOL) deleteData; - (void) removeSheetDidEnd: (NSWindow *) sheet returnCode: (int) returnCode contextInfo: (NSDictionary *) dict; - (void) confirmRemoveTorrents: (NSArray *) torrents - deleteTorrent: (BOOL) deleteTorrent deleteData: (BOOL) deleteData; - (void) revealFile: (id) sender; diff --git a/macosx/Controller.m b/macosx/Controller.m index aed5b3e7c..448c5730f 100644 --- a/macosx/Controller.m +++ b/macosx/Controller.m @@ -524,7 +524,6 @@ static void sleepCallBack( void * controller, io_service_t y, } - (void) removeTorrentWithIndex: (NSIndexSet *) indexSet - deleteTorrent: (BOOL) deleteTorrent deleteData: (BOOL) deleteData { NSArray * torrents = [[self torrentsAtIndexes: indexSet] retain]; @@ -540,7 +539,6 @@ static void sleepCallBack( void * controller, io_service_t y, { NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys: torrents, @"Torrents", - [NSNumber numberWithBool: deleteTorrent], @"DeleteTorrent", [NSNumber numberWithBool: deleteData], @"DeleteData", nil]; @@ -551,17 +549,22 @@ static void sleepCallBack( void * controller, io_service_t y, { title = [NSString stringWithFormat: @"Comfirm Removal of \"%@\"", [[fTorrents objectAtIndex: [fTableView selectedRow]] name]]; - message = @"This torrent is active. Do you really want to remove it?"; + message = @"This transfer is active." + " Onced removed, continuing the transfer will require the torrent file." + " Do you really want to remove it?"; } else { title = [NSString stringWithFormat: @"Comfirm Removal of %d Torrents", selected]; if (selected == active) message = [NSString stringWithFormat: - @"There are %d active torrents. Do you really want to remove them?", active]; + @"There are %d active transfers.", active]; else message = [NSString stringWithFormat: - @"There are %d torrents (%d active). Do you really want to remove them?", selected, active]; + @"There are %d transfers (%d active).", selected, active]; + message = [message stringByAppendingString: + @" Onced removed, continuing the transfers will require the torrent files." + " Do you really want to remove them?"]; } NSBeginAlertSheet(title, @@ -572,7 +575,6 @@ static void sleepCallBack( void * controller, io_service_t y, else { [self confirmRemoveTorrents: torrents - deleteTorrent: deleteTorrent deleteData: deleteData]; } } @@ -583,14 +585,12 @@ static void sleepCallBack( void * controller, io_service_t y, [NSApp stopModal]; NSArray * torrents = [dict objectForKey: @"Torrents"]; - BOOL deleteTorrent = [[dict objectForKey: @"DeleteTorrent"] boolValue]; BOOL deleteData = [[dict objectForKey: @"DeleteData"] boolValue]; [dict release]; if (returnCode == NSAlertDefaultReturn) { [self confirmRemoveTorrents: torrents - deleteTorrent: deleteTorrent deleteData: deleteData]; } else @@ -598,7 +598,6 @@ static void sleepCallBack( void * controller, io_service_t y, } - (void) confirmRemoveTorrents: (NSArray *) torrents - deleteTorrent: (BOOL) deleteTorrent deleteData: (BOOL) deleteData { Torrent * torrent; @@ -609,10 +608,8 @@ static void sleepCallBack( void * controller, io_service_t y, if( deleteData ) [torrent trashData]; - - if( deleteTorrent ) - [torrent trashTorrent]; + [torrent removeForever]; [fTorrents removeObject: torrent]; } [torrents release]; @@ -625,22 +622,12 @@ static void sleepCallBack( void * controller, io_service_t y, - (void) removeTorrent: (id) sender { - [self removeTorrentWithIndex: [fTableView selectedRowIndexes] deleteTorrent: NO deleteData: NO]; -} - -- (void) removeTorrentDeleteTorrent: (id) sender -{ - [self removeTorrentWithIndex: [fTableView selectedRowIndexes] deleteTorrent: YES deleteData: NO]; + [self removeTorrentWithIndex: [fTableView selectedRowIndexes] deleteData: NO]; } - (void) removeTorrentDeleteData: (id) sender { - [self removeTorrentWithIndex: [fTableView selectedRowIndexes] deleteTorrent: NO deleteData: YES]; -} - -- (void) removeTorrentDeleteBoth: (id) sender -{ - [self removeTorrentWithIndex: [fTableView selectedRowIndexes] deleteTorrent: YES deleteData: YES]; + [self removeTorrentWithIndex: [fTableView selectedRowIndexes] deleteData: YES]; } - (void) revealFile: (id) sender @@ -1207,10 +1194,7 @@ static void sleepCallBack( void * controller, io_service_t y, } //enable remove items - if (action == @selector(removeTorrent:) - || action == @selector(removeTorrentDeleteTorrent:) - || action == @selector(removeTorrentDeleteData:) - || action == @selector(removeTorrentDeleteBoth:)) + if (action == @selector(removeTorrent:) || action == @selector(removeTorrentDeleteData:)) { BOOL active = NO; Torrent * torrent; diff --git a/macosx/Defaults.plist b/macosx/Defaults.plist index 140655d71..5f76db5cd 100644 --- a/macosx/Defaults.plist +++ b/macosx/Defaults.plist @@ -18,6 +18,8 @@ CheckUpload + DeleteOriginalTorrent + DownloadChoice Constant DownloadFolder @@ -40,6 +42,8 @@ 2 SUScheduledCheckInterval 86400 + SavePrivateTorrent + ShowInspector Sort diff --git a/macosx/English.lproj/MainMenu.nib/classes.nib b/macosx/English.lproj/MainMenu.nib/classes.nib index 9eb5b01d3..5b0cdc51c 100644 --- a/macosx/English.lproj/MainMenu.nib/classes.nib +++ b/macosx/English.lproj/MainMenu.nib/classes.nib @@ -9,9 +9,7 @@ linkHomepage = id; openShowSheet = id; removeTorrent = id; - removeTorrentDeleteBoth = id; removeTorrentDeleteData = id; - removeTorrentDeleteTorrent = id; resumeAllTorrents = id; resumeTorrent = id; revealFile = id; diff --git a/macosx/English.lproj/MainMenu.nib/info.nib b/macosx/English.lproj/MainMenu.nib/info.nib index faf0de790..60c977211 100644 --- a/macosx/English.lproj/MainMenu.nib/info.nib +++ b/macosx/English.lproj/MainMenu.nib/info.nib @@ -9,11 +9,11 @@ 1041 344 478 208 99 0 0 1152 842 1480 - 366 548 420 60 0 0 1152 842 + 423 269 420 60 0 0 1152 842 29 - 154 771 451 44 0 0 1152 842 + 195 519 451 44 0 0 1152 842 456 - 212 488 144 137 0 0 1152 842 + 212 488 153 168 0 0 1152 842 581 324 628 112 68 0 0 1152 842 589 @@ -30,7 +30,6 @@ IBOpenObjects 21 - 1480 IBSystem Version 8I127 diff --git a/macosx/English.lproj/MainMenu.nib/keyedobjects.nib b/macosx/English.lproj/MainMenu.nib/keyedobjects.nib index 6b289e58532eb50e9372798241f3e37b25a23d38..82cc2b94a161647853d1939b8d41bc78b0b4f2c7 100644 GIT binary patch literal 34594 zcmcG12YeL87x0wbyS>Zp-fbYg_nurTO+*6HdqQu95e20eMLN=pA|hZx;Cr*13l{ndqlUC|feDU0_a30eBK&QCY0l@wJKX?V3tZy+CJLzyTS<)KH=W2iZ5h1#J_=xg*n zI*N{=&+KPNGN>NhT>Io#c?lB%ib-tw>wa ziF76fq#Nl)`jRI|F)1OXZV0X&4Qs5j2t}({!3avuPe}Qmd>LZB5(L z&a?|Hpj~M<+MP_IJ!o&*hZfPnw3H5^L+NljnvSPW(g}1TokSAyO!Y*OA zZ~)pI5>5)2gv-Lu@cXKWM6)P~cF`dQi&0{kf)$!!{Lsxpl?J!zU?Vy3C4=SUNOxxy>41&T5fvNw9@o0 zT<@DcHhm6%H=4dOeP`Nk+F{yh+GjdMKQrBT@r-iPjOTsSGWz$uGnvMyA=?~LC z^oHpYy=kUq$!s?}%&OVn8~|4+Tv2evn^VlGaAm@k2UjDw9)s&~xZ1$g5w1eGdcxHY zu41?b!!-=93b;nY^(0&jt|@R$H_tN9hU;bXtLE3>dIPRE;aUmT8uME7$L96s4dyS+ zo6TFz+sr%7yUhE|2h4}ehs`IK^q#a@`dC^gZIm`i-+Ip>X`i%TIw&2Hj!MU*%)nfIvhL9=NSZkKGk@XSlK0R$8m96RZ=hQ$g}ClS$Uu*2UJhtshv|TQ^u6L9MT?yWsaO>u&20WD4A!uwH=Q z7pxbpH>`Jj%svj`vX8?@_3`%!@Cou+?Q_zmqHk=zwmP=DHa}aSE!Y-ZOye=o>Q0=EU=CnYIvHmMs^`@@%0{ zR?qf`t*P8f>8Ny4I+LbK7o|WcRJtnNl8l?dkupFjR!S6? zGEf<$3|2~&A<9stOc|z>D{f`DGD4|PDwQf_q%ukwt&CB|D&v&#%9F|jWuo$wqA5&y zTA8FwR-RF&D9#<{j+DdzF34 ze&vAjz4C){Q29|gq#Ra`C`XlJ%5mj{a#Hz8Ii;Ld&M0SOK$6nX&XZN=U*aPiB_F#L6J=7j%54T6yBkfW4XnTx3)*fe% zw&+aI^Lu(!0gvbVOkvA4Civ$wZ*uy?d~vKQF9*?V@4EgxA{cEaI{WTYTF zav&A?qB^K9@44I*(yFn|+~wuqmbfbn$D~6Q4VlH?>VPW6Eq5lnhpm~u(+rSDBp+bq57x+YS_c*maDRtaZ?V}m!O8IQ9o!u zva-rO%;-`NPv7>T#(?5c)C6cvudJ#lEg#h1;b@)T%w6m*s_B+yGB7kn`AbngYK9u= z1KfUORS~eXKyL;hjhlVwaRAu@wS+;e_9-hDYmxz>HEOdIwLxuBBN!o1dskIgXzZ#o zTDC_US38EI4yYsQggT=xr~nnBuBaR8j(VV;s2A#u`k=n3AL@^uKt*T(Dn=#9g$ANQ zXfP^8L(ouEhK8YXu5Zq4DTRGyzRSPazF4^fa1;CZlK2 z6!a{bik?H$&~)@XdI8NqGtn$G8_hv4qLZRy^j zpk2`bR~Z*O_sEK3m*%epXg)upZ_rk>4SkEgL)*~~sJ|2KLc7r(v={9|`_TcIiS1qG zBVqouFLw=dmzNf|a~Jn_sQSw2@ew0SN40mCv@fb03J3~ItIAw3F*=sF9tQIn*9K6Ur*U0+a}NRu_Yrf79EzXL$S4}kw5`Vk#MhtUzh%x5pmWKKZq zD%Y?|My4_HyawuEdaq_>uA+)aUeswnIspx{&`Ip%aqCWXm%~x{(aXM;a z8bX_9gI&c#hZR)}HKy4)bbcv1k1p_u3cAmj`W`UQ+qi!}^Ps%MQEGKL4!tF(NAGDt zRZ*480RAhwx&&QCjesAXo)~K68fwzt;aAK%(#2KmDz9qpE*?1y{#G{hXpkG|=2CPM z{lN+I1BR3i0R3B4;V!GO2GC#QsbL%rpuehz-HC3&z~6?EYwoJ7DlOMFpGLG$826xq z`nca4^}A>nMxHU(g0+zQh6S6j86CzTkgqbbn2*70{T;qd2e?O8MHW^Rl~)cc1yjX! zD`-e;<6R4LSCqIaT2uhVz>e~gqKXo|ey5^xR~dBCi&pGFUtwRME()j%zh5djeSX*< z?ZtsyDz#u=FtSLC05T)F^z?33TH=cASTz_H@|_3wclZy6&-zC%wO`rL8)GD3j0TMH zfHCHQ7}0JV2N)9!j9M%pi{r>ZAar!z-R{Z})`Fi7@SOlZ8Q>>A41Ts3&yzen?@=(= zJvy>!SsC6_qF;_J+*Noz|mN90*2K4FyJP9CgaDT2l;vr(zJBIkimPfA0``2 zHQWM5v=t*O_;9`jVqevHj4^)gP?N&qkyS8A9#kCxRc9?1P-Q&~RUx42R*fnfP~~t` zT{{(3R=GNlGT`<>O}Y)|54<4v2gpTQLx5cGVUSAz^1y1y^#O7N4!Ku>s|*|>&Zy2s z2KX}6q*tZ>6drn^a07}FS`$F=$iq-n0g6%8C>jHbM>&eZX71r*I~N>;*|_wZ`G2EUI#z#rm|@LK#aUWY%ypW@H(db|PdHsVeA3;ZSCjK9KL@YnboycKWj z?*Qkpb$OKw>`+-*!SJGD@T0nymQ=ya1-G}EyKLmJ@}?uf*L78vj)Ss-sf!EkP&QyKy0}NTa+MAmTm_b>a8!%3qCu5#_joyXy-NB!LO~x^ z6b%~0q3TwG18U)}0JBz92F(jb0^diKx<>bR1l~`i0lB}U4p_O0QUFp^R^w;(cSJk{ zb_aL44j#;4Gj~O~tD+mg2VA!XUH#!#m*kcGeL! zLU%<4m>C^SH7Pashw%;==ru6JJMk{O8}Gp%fj-}h_u>6;Erg$g_(yyQ9|m()FmeFr zl)eyvQ2=Ytp#itSkX7I1x70fY&x#F_wJF+U?OC|m!H>%!s1~G6?KM6pH#;>lvtIUu z1AzS)$BEMM349X&1h!k}lZLb|Dn?pCe@ET%<8$igq((X?q(+X<%;OCwOwf%jK7-FL z!)Nh1d>%FG+uxht;7?TdwMJTW2O3{Q8{fc}w60p&5&R1TO0VEw@m2gAzJ`Ct*YOSL z{Y~igpZG8QH@*d8y&m7ecL_2a4P89B2*KF4autCHHUp97roOaXmuMhg{|n`t?ZN z#nF#90=5k8UOk`(@rQ&Gfr!YTn24E3#6qmZhuDaWH-n57!XSBu1LSNAE*s^>mS>!bD4dTKqi0losegANco_tc1ksKl4lA$5VXT!=v`2kMQZn>s=E zdTG5?TWFtlBa2H*iduq)P-6H)B!C1iA%Un7G~q>mbnM%Zefx3gu|ru*ZOuV7z^fT7^srL`ta58$U|2urz_uCgE@mZmlG$+Bv~Yz zyJavv^~rN@^mVnw;j}1qm6dQlLU)=L^OYz60R85FJcE^M3>H2}>XG_*A!$e&kw-YS zhNH)2R&!~CwGt43A-;8^?mVVSUSsg6J_b#rn|7+^xlq@e7tKg>gBRK$Z6NP2_!Pwk zRLWUvGUpGJ!15lYZ3{*LP;+WH!jo zs~M^yGGGZAV65hO_@ZER(Qwf2y$053yBe!UTx6hb^(wRvxz#&HhLEA8j0_{?#7%~i z5u}1t!bnw-kz^EJM@Ew|WGop+#*-(>1Tv94MKr>6VKD4>Z5w4g;|vG01G*5D1D`R# z2ctw^In{j9EeeQ?Q3gwcD)>-PT;Xz+^AEgz(HP#orcSl8?Ov$QKM;HVKnJ6nDqVka zdsskGI1Mv)!OicaF#ua2Rz_H673m$T8s6b10omhxOVR&{6Mdt8{HkW}uDB$V|MC z%qDZRv0w-0Xp6P7L!k9nf;({x+zZhCFtf6NtrN&AWFB5m7T`_fHS)SP8h*xWPg+zQ z3#M&?Hm(<6Q00%Ts&bbDJ;n|6c>MUZ%xde9os}Ayl|5m?ak7LgCCj*SB)Mccd6TRF zG;e{Ld>a(yJ7gt!m()l5$V?FKHROHr0r`-8g!bXh`egR3V~ff_QR)l5re)y0z?#aX zuPb5bI)JNIRHlCd?QW2wk46?OlR6Z1a#fVNOG=A%uV++I8MN@Kqa*QDY3?d38mo_6 z4HA!v)}GchZ6c@wMH}k~@-VDxsfgO4ZvgzO=E$v(259Dw^D$U%_RRv_B$GVZc=D5$IvV9!HfRCVvU zco`D`YBwELRjECrOGHO)miB^*eH{+%Ijy5MyQ2dF3&y|vDG2e)5WPca<5IwSfb4~8 z&uK4cWybRp+yPh!>J>giV33?9XO@vOh7ZB*V_E5Nj{8S0qvV|7osje70{BDlLw?35 z$uHyz`4#9dEUFmf;xiNmldtIEk-=XObpA60jdZ^u3`$&+p{=a&n#AsG-PH4tO|kfP4DA zTr-iWNKJg`sRgg6KGa5Ks^Il7?A!}496KChui%|m`#$=3E`a$Rtu4}C)n2sd14LES z@=fYX>(IK?kNVR9?Imrl_OkYhHcy+cNzezrICe#LYThDJUtA7wL#QFL3V`=_WOi`% zD2#l(ytrt1<;XIauqBb5+?7?p!qVYYk)txxv+i#buD2;{-J(V0sGM}?{S|_%5w>nt zcz+?pX>V9a`Ss20U7>sf+>029K8OtRHCf6%uf=X?f`|=wv0gnq{Sf%C*-l+Cs=%xPyEN%!z6h zKvQ%T@Vc%d^4*|6hvmC@utpa+>ZF;=XeQMi92hBGsp)PE%=MZNM%5geyPW2FWYbgm zzvQ3+(0>x-;1Svwuh$3sEenkH+u9q|qx~2k?WQ!JHlxkyK*<*oKtP?aY}m!*x>1W2fgzvjn3=F!|1%eumFe+?#VkhdqzhK@wugjw0q`- zF>f<-VchEHWKEdR6NZpamwGUBg2!j4=Qy+KXSq_c!F+mss0P=Q_F6)FRmU5vodDOc z;aotw4>Ug4_$GKZ?T5aiPr#D@69_e|eMqQ*7Nfn?RUK;h7(xx}c&Nbz`vSuu-d`RW z-`U;IJ=|5!qe}&YU9PHoK?Pbyhw0wWXWB;Y{oIFvj^M!zS^*fUbPVgY4S?ZuuV4lp zgAUVij6BVQ8IyoXO-n`dvmR}(4uH|wK=X@? ze9UQH2Q+(oIFYT~!(785klnYew0x-NLoEX40RanufNz0-tq&vMbuR+8c?bZ*TMHLN zAVvsw4EM|H34?| z0ocRCbggy^cyUSl2O@MMD_wnHw`+LyIYyn>-@;;co!UkP8bD`pJ> z{}-UY1?bNK`ZEthf5!{`Sr7W2`XC!f9DJxBh=N`c%zAL~q;?rtND8@st=nM1hBhvt zx1jT9v=h~ik^pHJOF$SK^(b){59L+8SS9$OuY>@g^(xT%%LC*_2;$5Vf<4rdcJ2^)z$XCs>j3`ReXOVkp6me*pnvy(u7QG_LMA}Th9Lc4 z0OjU=P!Mc80Eu~MuTWo?i(u^!fbu7o3s~!Q9$8v@@1ygGUa%?{#`jvh_5$ci;W1q< zcQ9<`f@v_cIokLZeM@K|v=mwit%Wv1TbO3swcFZVh7rSrVS!;$+XIWEhfR2)lc#^= z7EHQ3o*s5HMC!hFLU%(^fB;r+@8R{}U$?F-06kYx1oIQ1C>|)5``UXHjZjq6ew_xr z!k#98c$j;X>){PcYa0H@8&Xe0Q1nLANFMu&f!NZ_vjia5rTxL_2Ik1u+P2Wn*#GeNB{}Hrv0Lo_4Tyu;D)x< zdnUs3AYC&URH(+E?o>O4BIt3!wxUAD!c+SU_K+OxrtiS10n~d z!(i#(d6>RP6JF;VZFL~1!M6%{VNun{3Mjv~Ng*r-DwZ(p$Em3EFe;XNc%)NN*Tba3 zUT*iWKGop)eM3**Rsq!23!bgq0ygDd4KFh z5cmOW-@05cfxgs?2A(Z^4wyG-Eg25yxI-R>do%ELOATK`IbXwcg`NorxEX3+#6z?^ zy~W!Y3EKgD3l2UKbi(a^hC;s2FbaEwz4%2klVQ+K6F@A+)+l)4d#>Px9~q9}8lK@; zW5OSX$cJ!5I4T?yjx!v`aC3%>87|Sv4jU6(_zAY4ze=ONu?mIJ(>MNvUx2`08BXHl zB^%`ZhBmGet_i;j*M%FxP2msWPvI}&Z{e2kk8oSK!*B}2X$)sD>|{8L;T(qZ7_QH7 zLxvw=_)&%*V>n+cyMH)N^L~iL(+h@y>{JigJ-e2dahhEv4{KK+_u48619 zUnVw*Y@44^nN-b2&O}i)(iw#Af{vbRJiH!$!#u<5VZGYAvUzExz9j_oaGhr{z*-(g zMrbWEGCgE;%hho|tW|8SR(w-bC%${8^FN!V)@qhp(=6-1o8{DMRist-VRP9SK3#sAc$)QqsKtM>vQMpcP4Bh) zA7qx)YR7kObuxQoRpa}QIV+Zl!#u6U3Vo)6I(gg!g5egRvW=PA+&#LyX0BFGPH`kU zERJTl6`!1~^~ouYg~=(76UU2BiW9_%;!~m~GVy6~k~mp>Mx4TM8;094+=1ba40mR@ zfZ?tTcW1aK!@U{q%W!`Nd+hg5PO(g%oYOqyG7OZq^-y}BR99CAljRu;sNUXF{ekn( zXi|Ir0T$rq!>3#|nm1~p>EuE4Fsk0FRlUpqs=m5b^}_#E{o`8IyZx`~pVzA1<9}7( zQmcBe|5bf^t?GULSM?fqPaocX|Ev0;TF{^PU)4|6sy@I|{ejY87`1;(L$tRv{MW>~ zD*om{Cf?L1)*yym9*hhRge80dEN&tTT&@!CU=&qxD_H9GOs&6QYC)piU_P}Q=L!{rRS86LrKCBtBLVPcMDc>IIr(p5f}Ogw&wb0Mx$FAWeLOP4 zY^DKduc<^|aIR-q zG(PjlPq}BkV44V6G=`t&Sf)J;%Or0s(>+++kZ9iwQj&RMvKvyBOCc%Qg(4x%*$qEs zXaJ-&S474`{!PWm@@nKp3TNp!J?pU(#K^0>m*l4Drsp|l7>4E9EY6yTQB-53zse`*nqV z0FeJ+EEJb9yqsfylVh*88K%SNu<0lx>$!_bKLy*j`yODNLEe-AHu#Ji{+6#c_nK|CLp?cPP5 zq3AX*I>3t_^DgQJMR$1754AtctysGPV%De-bGbV^fWJm&^)Yryo<&{(Ij4Uh8OkrE&{70 zPUb}rQHOPschMv$dWIKW;6?qti>5-+6kc?R7ZrIIy#PfzqkiT^LkzjqUC@Wi?TgUn zE(dpow<+@m2OCT#%!?q34t}VY1bV@&HS`Oig}_@}<1M_s5A#we5_u8C%)ycM#>1_L zi5K1EMG(uXev1HRA_V$Ox&ru<7mcqe5>A^xFzg$|bN=S`t@l79@KkFjKrAzVVpId@ z{}^6~XVqJ~;vMrwqayg-cX&ncZ3gPy?BK3~*PUuvSMjcSi&49b5oCbX>)uy!ocTMW zVjD(?0k-Zy4+S0E`b@43dc1j$(V`tAg3-darp5jBg=^*?jQS~zm^}3jRy+v4@Voh_ zQ9q3l$*AwBX5IbJVFXUW*v)MMmsUf!OX-_s0H~ z`Dak~SGc;@@)>~_Zy3=-8lCTLvzgYKuN$N-U_|Al^&6<$^!q#x^Izt_^_rv(BYwQ* zeOL`=)_m8?Wgsi$&;5P)@N7wfK5|t^0(dX$)CeLJ$snVI7wO^X z5#B|R;rjmwNKSzl zv|<^F{JuKZ2~ypp7%3Kh;t3@4H(;cm{=b8^O3x_B;#mQiJg1-@zsZ5b4o{vgsZRcs zk|FuiDy2#OkpB6Rl0ogM7{D#y1nH@-dh&wQKx+7=)KF^Vm8VgYpV|kKI%+=j9a!jwB-!Te^wiaR%z9L6VlXR# zk(7rq>+x!4!5bw8vl8KLA>dS!&W7w9$SKs>kjHQSgAE;|NB_l!WJVISA=Sin{Woz1 zQlUW{%%{wU5!VZd>jNX%&qG`~jHIB`mjNr6@#8aj0y-b1`aJ*XKgcVQ3jReNj8~dA zq?a?&vuO(e4Mut%)Mh8%Ck^EkYm*tt<^=a1Xry%UyqSAUA1;kB`jyK_AH84F$m;BT zo*$njjgm&AbZM+KP8u&g3As0qkAXyP{t^}=y%@=Z*ELBGhn11ujP%rl9nwTdb(3I7 z>S<-i4DpqomL^G)@iFNc{E;+;d?!5%;yhIvE)D0|M$&ZYdFchbPMRTw;G5Dcp8BUJ z3K=O)a6pQlx(XRpr98bEXwX0NWFgqA=s0j7I86NY06o_M_81{04xZ<`$ME)y)Mo_x z2LC%V(vgu)l0G=y4O-`LT0`JTb)KH|GTQj2^a@Pe`O>4(t5N|Y4PkmP@+e3LBcRjL zG{~yviKMkB@f+20xy&>4jSRVbM3>9VJU-rh;PqD!{$t?ZkzUaUepSu%Yz!p8^mM@V z?5R(j$mZ=DK8S=5s!3SuA)$#u!efSpXaG4x1_}J;KS)?F&Hon(O`-qVkZSB*+ckVZ z`kk)HHUkA)s7?At+6u3-R!`72Fb5#{ijlUAG&9n#r0*d8O4=^%kakMDq}|dUMw&D7 zI3q0>0WAu1yERY3f(etQPZZ8L577_GSCe4B#gnhbNV|J!SkjL?4U3WXJP)g<5x#(Z zXk#u`vm+-HlBaSY6%LkrdY+;uMUJb~9LQ1ZHXd%A6Fj-})h|9sC#9dHQ_^Y9D!iGI zLPokV0`k&D8`4!5(0{+fu%ExK;H6gaR_SuJS{=qnS0m58P8DnoKR9b%y2^9V+dCtj z>GhrZKc1j&DBs_u>&v9;M(!A-<$&<_9G}B8E;H*-=vOcd-g6(^bi~LaKKG3Ve@cHX zlm4nntu#UzyttQcjP)o_jg|oGcN={rasQD#!3|@-`wX$M(QNVBfm0ai?^&nu^knE) zWKE7vBxJ|;hIz}=bl}$8yR`VAuPic0Rl-pXco-^&$L90hWKw(&l?n^?QKfE(UUBFg zQ%y%KvL(<^cLNw1$kiS9|9JgsLTWi_(p^iqQ5zKcU{7t{kq6brvn{bec|50l7^i&5 zec1){9U~lINkV%qDcnoqFMWf`fCw%lW%_bmg56-A-*De0O_&FT@2oB%_zS5(X_H?SSTAXOUC>%HKg+1ODmTr)s5+r2P3*s}T`9grDAKoWk z701y9rc)-f@Rv9ljKM3y9q~!iui&4|wv-E-#HWS7rTOA`Is#7;r&vZ~X6i4N2}iNh zBAfP`M6?Aj6en3G2{$3L@CnPa!ZE49WU@?${GyhY8J3x*O3Q51THM6)lCVUCI6iI+ zIWV`-UDGYg>z0LP5s?gemi3{FPzb*VDJ|!G6o9Q&j z2bf`+F3b|Hi+3#REgQ%L%SOv4x`Dohi-ZJxNw_U)maX8Mg_tNFA>5$1gwv+Y^oV7z z`7iOVB}bfK`N0xzBCy|mO=zRR8}*~LaNV9v)HXwA1K&;~HrS6Y&hV^(mvC`hCtx57|b2tiXd|# z%M4Bpc$Sed5Wi()5rpqF@PuA~Y!6r?YcX0XhzUdicy#7NM&4&+AtUd?#)h_-Cm2C+ zI9lJ?n8wH(e2<^Ni~@oPtT(j^&87wEyZf-E2q_DnXkUSRVObBHLb^%@-z6acb)Ghw z5s>EBAz^8|Ru8gbU;`2|0=hCXLHCBk!THu8QNXF4(RXkcYKIy50Q`7Z@xpxJJD22b zn3(!j3nUjnx`DvRrw`l>vdq*2cl#|hTThm=diQ~Vu^wf^$hex649j`T1$5YQiIJBX z`Gg1ZUg@d3BoI8TG^WWfkd9^AYdU4wYKgbxSlXL@HQmz39EgG*Krh{lOoX@`FtH|M zqjsu+p+Nq<`?Ab?_vL|`V*ju0j0IM0d>~9-JF5>wXPAT9%|K88&vySCoz6*X9NM^& zmRY(%0DQXnFVk8}xv9TplBv?9X`jLDfxt7D9zO63^vUp)F4?e&J?$ZU{ojZS`C{0> z-WZ%jP&qR&v%Ex)m@o3_@+?d&@&Xq)TMY`KRZ63Cr{7y z?g;7Ak?;-{xUqV=lC^{JjtuBoYZq`=(H5Aj{Iz{}^VFzTbEE^0bv$r5s!`WUPyy8U zk78|#jmWv>Su1Q7!B~R5vJQe74yu9FY*R2Yt49HUn;DJ~s+kMcA=aVjuoc`I&_yrt zx$vUVm%;b?G6HRcm$D#F3i{yz@X!tzl+>0dI6}g!13h@E6>o10(Nk#S3d;t|3eeO) zSlUBi$CVFPATZrPle`N`&&Nec&kn ze{0qUhDd)K#cO*eHQ9 zhK&bC-Yn!V@E9E516gjkF&=?CL&8a__K21R*1*Hc2LY!etThP-*5e#Fhy(1Ac!00` z55k05)>Acvorku%zq#sOPHsOF8!fVUG|EmW5zi;kTq;ZwkUIZa#se=Mw&|tx-GJa1on;q}&BZX+NDN%o5A+Byhj> z3#aKyP{2<3xl1pJWpo5Mi?hfC;W*q+Gwm0z3a24o$0>#Izoz|C2)yexg0~k=OCe$z zOz{;^eiu)Ir$>c7=&mr!(nh?Bc7mJ9p`GSVq-C_Q2Wnr1Y2u_SK_xl?=UqC&vJt2N zSkS%+xT&Wt8-Su&=&og^cop!hBomNRybASZ3a5oxQV3lMFr1bdfCZ@G*evTI&3hKq zSOib5T4q{i5*P0$^lBw;A_U=u)pQS+V#TZQxH_m3S3;SOyNO-cQa8F8aE% z0f%N8i~vvCZOI)taH5v+T*4h-g5hOg(10g-$$ISyH?E^~7qTU90JXqXgrIp#jqruI ze#;+2q+>MSX66w2Q(gwnJZMDl%US}!d|uidP;pld7FGas5IAU)c`1}6>YgN-!D-=b z!5#n|JD?eXl3+fsmT^jTii5Q@o(>II=IJCUT!F&;83Z)!fD7EeLA(V#0#X54IIlj4 zll&}4&*?WP0Zk2+6 z|Ae+yI|D~ctOsVmu(bp>?BUZkjl04N!O4cf*GOxrpFV&2{Oxng=O3TjK6iZX`dqPL z8?jNFU=wX7o7pDWEH& z<0lw7$;eNPoMPlOBWD-^AN?F7=k=Nwpwkdcoc7YI`n*iH>P=D5!Uj0*fbOV z74l!Yn_}}vO*+@(FDAn|Q^Hp6vp}4ncJ-`GZ_t@uptHT2>9@vP&ON|Q(_dhLQ02Wy ztarm419=>3(uez+36+r@N5erbn#l`zgMRv(%KGaAhPMMGS|@N4tK(aco^v0unVCEy zs=tQljgV)l|EpKMjO-l_8lY6;(qA~J!Dh<_?qofHC7D?TnOVR=@KkN}Ek~EYK@&4U zgh5h`No8xyAASMrxAxk&nuqxykPszDJ>XcucR?$TMNGH}lj$y=4aZBZfjpd*XsGxU zdd<`y^)gioe?nN{j?e;@=w)b*WdrI+pMXH^E2w~OFl{!O&I6p-PBQ%}PC}hg z5gai1tk4=P)pd)Ew!o2rucN-OjGqA+2PJTnU{`ck9B)~H7EANd=Wu{w6`3h&!fH5r z@F~#ucZ7dTX7rXN9^%MWOgIL@RAH;4<5 zK&9rt&{8-|aV?rC1fUNg6ZaX@TJ)yr76dD<3AYghQc!o(UO2k&6*N_xg5Ea?XfnQp zTzDTEDfx>GJz-gd-T*6l*U}H{>21_cXbZ<2t`MIT{zlKxsi;_3BD6&F@IuIG`b?Y* zhcH&6cObmd8ID(c)iN6_;Y3(jt%qY5XM>trU^c^Xi5t-KmNuxI9zhU>L7!M&7ZN}j z{*H!Ny5VR`IRr!|p@C#J9JRPWI1YZWh<)h=2zRuBLlOzphKo#a z3IuuyO&4xKXyj>OlN5qx3fZRl5W+bsmcfCG3H&rd43Pi`L4b#pr7OLDpx8iPf>oFc z=M`!<^aSKzAeNy)+9WLO^7If&KIlUmKZ_C6#XLC8aV;bHT*Ibldvsk0fe3)GP6K5D zW?{GX5kw4hH!K1c-r!1R>M;#po{mY%HLJc_03-4jwH!(>1RVueT~hq!AniSLo%?iy%xFwcK*Yg@)3Vnwtd z?Mny%F#>I<9-(Ro=Ualu_&vD8{4KPzpddimm+A@R&+rp7`FWHxAV|i~y1cB1n!uOn z%$M~a>c?Ro1ar1kUsc8PQz+qJOzxxDVC9XU<3`j4Ubc1(j48yKwBL9rEe1jWJajZ! zJI-TcX8nlF5`9$$fjAyx11<;*&cDRp^Aj%N)J(9kJjRCfGdqhl5P@?2n9gJRS)7mP z!K9wL3lBcfelXw=aNrTM=DJg1s5`l}q1og%a$C8b++OY=ca%HHo#ifafm|qemAlE^ z$S!%HJV+iam&!xrp>ml#OfHw*@^E>CTp?G= zRq{xAlssAZfGHTiXUp}a_5EWaTyk(bKL*P=5Pvy_#_3{S!b9tk@N&Z6qQr;|oC2x_x zmcNm=%G=~`GlyD_NiBzJLXeCC8RpOL*B|%A4l9Xg6MM+iClyoISaVnWgmXfXHD7i|WQctO` zG*B8Ujg&`}#>%5g6Xh|bsgkcWQ<^J}D=n0kN-L$c(ne{kv{TwM0`u$&Bfm0ol@X9J z5Ypcnxy}eod~gB(VB}9m{$k{BMs6|k4g^MiHZ!QNk!?RA5wO)Wj$pP%JTO zVbsc~52H3lWkwZ7?Tk7YRT=eVv<{v4Mnf45V>F!62u33r zjbb#K(HKT!8I5B!p3wwG6B$inG?~#9MpGG0V>F%73`U)dW-^+^Xf~rcjOH?$$7nr9 z>oeMb(T0pRV)PM48#DSSqfHonjM1iy<}=!i(dLXk&S(opTQb^;(bkN%VYDry?HFy( zXa`0+GTMpJ&Wv_pw1Ck((f*7+!Dtbq0~jr4 zw1iO?qXQWo#OPo~OBo%)=uk$>7#+rFIiqeyhch~Y(F#T@8LeV;B%^S|^JqrLFglje zag2^<^hri1FglUZrx?{3WsE+}=p;rbGx`jpQy6`g(W#6+$LKUhr!)FIqc1QzgVC9c z&SG>nqjMO%_fKD9bS|SWGx`dn^BA4a=mJJxW%M;hUuSe7ql*|_%;+18E@5;jqstgw z&gh$ru3+>nM&D-i9Y$9&`YxlZ7=4e?)r_uT^nFG@VDv*qKVoz(qaQQ6j?qsT{glzq z7+ufk21Y+;bR(mi82y6LFB#p;=vRzxVf1T8zhQJMquUt$meKDR-OlI^Mt3s0i_zVT z?qPHDlw@-lqv|02`U|>ii;fe9WxxQRB^8=?r?x3 zx!u83F;%5&RdJ?D+Nk0lRa~IrR8{<1r5~sQ0RF|X*s;dZQKhR@F z5k7}IURDKFr5~x{WEC%0#gA3-OI5h*cv2M?JLagONfl?Q;xnoc=a{GBW2y*EUsA>2 z979wgP!$h3CaU5Os`!qIyQ$(9mAMblD?|AQ5DyyxT`82RK;gi0+fBP3Q4K} zy*I1kI#ryaisw}!S`{K4YgN3>@uez`S4E(DnJUgz1*amc*fNl|0lvM)dXI1etRa~KpVU8`T z810y?k`}5Eq>9&6@e5UaT@}x$BH-VqiZIq!RgtPIy7_W-Ysp1=|I8PPARq>K4 zWT^CgRlKN*uQ{fwB62*f3Nfl+yn<`*tjD$WRgk^Va&)n0p=0mv`2fK&doO$MCHCI> zv2m^QjRWBME-aEz5Q>3A`!i8P_-3EZaKw5E8YmS?z2G}I*1`8|oRzLh|5&WBf0S)$ zVQFvaZ7JmuXV}tQX;}*a?@gA?mai?_EZZ%+EPE{nAToBya>R1n@{{EZe3!-r_$G~C zEH|yhDp*a{y4EmjyfxFB$G=Cz+TB_N-pRx9){m{9SiiJxvwm+q zVm;%t)#qEE?LIqwcKhu0+3)kc&q1FT8=--uD)*2wm#t*NcK zt);Dvt-Y<2t-#jJ*3;I<*55Y3=CTd84YifqM%b!sqiy4C6KtAol5L9ZIotELnYKB$ zxwd(>S8WSzZ`hXER@mOLt+K7LeQ5jG_Ni@yZIf-Y?Q7dM+jiS7+g{rN+dYwqI@6Y&UFw+WwZ!vRw|8gXK^;Ty7$_06%Ro_*~<_o0e1&l~_xhI=hn!2`kIeTd*~M1b#*0lq*t_`VJod{;*)d<(}j@NFA& z;hQu*hHu9B62AT7r1GmB!S_x$;5#Sk!uL&N!*@p1gYS!I1m6|Wr23m6df0p0hug>6 z=i6VkziWTbzQ+E6{UiJL_Jj7L_T%=G_EYvV_H*`Y_UjJW5$=d|L_1;~@s5^`){eH0 z_KuE@&W-}dAjdGrM2F^h+A-NN#j(QiwqvDZm1DKzeb7l89N#-mInFrFIWDLc)kl?8 zyQ->nR6jLZjZ+iUWHnuNstwdf)yLHKYDcxRTA)^`qtr3#IQ2<&qN=G=)T!!hb)LFF zU7^0Mu2fg4yVO1EKJ|e5gZiU-SUszrSFftK)Z4yRUz@Mu>+sF=&Gyapt>@dow~=pS z-+bTZzU_Sre7pJ%@GbEj=sVc=Ip68NFZj;%o$dRg?_A#{zRP`A_`c)2&i7N_t-e3{ z9`-%zd))V=??vCszQ6eXSqIm#)=}#u)@e|uQJuzhn$&4p=cPLD)%mW@(K=V^{9RY5 ztJF=a+n{b?-63_KuRFi)^1AQW{i5!Hy2t9Cs(YsHxw;qX{!;f^-QVlpsQX9Vf9l@x zLw>|h@H6>IepWx5pW>(b#riq@dis_4Rro#WH^pz3-yFY}{9g8(=eNM`HNS;^i~W}R zE%#gF_od&re%t+a`t9-C=XcTXn%^ydi@(D^)IZKY(LdQg)xW3zVE>W+n*UV)x&F)i z-}m3(zt#U+|Ly)e{rCAF^grZ(*#C(CG5=HkXZ(K-umt!8LwgO(2($u$dKre*pT>;l#sNLjF8Nbwjn)2ib95jxI;#S zJRLGQWJ<`?kZB<=hP)QCFl2Gal8|K~Z-#6S*%`7sWN*m+kOLtHLk@);2{{&WA>_AE zbLeBCT|!-y=-;9L zgx(4B2@4Dh4hszn56cN_9M&YPRaimT6Jh0Hi^5iheH8XZ*sic6VaLKwg#8qDI_zxN z`LIi2KZjijyBc;aTntyj{lWvngTh0?!@}dklfqNN)57z@n}oLs9~xd2J~8~+@aMv( zhrbX$GkkXV%i;6F*Mxr_{!RGa@T1}9B77p`2z!JYQ76JLA|N6(B0QpDM3;!(5hW2L zB3_PI60s^`b;SD-A4Yr>u`c4%i1iVlM{JDP8gU@vhln2|4o4h~I395_;#9<)$gIeM z$l;MwBbP<4k31TACi3UVKO*l&;V2R%L|LMgsF0|zsEDYjsPw3MQIAEni|QFQAZl3D z*rTI+rT8g$r`$Pvu z2SXSp=JS|6F+atejyW51KIUSqHP#lZ#5!VqW9!EH$Hv6Q$0o+6#5RlV96KPkBz9oz z;MgIt(_>$Vof$hj_Qlw_v9H9giv2Y9yVxDEyJGjm?u-2+_IB*uI2=dg#5i-DB`!EF zG%h?YGA=qUF)lZ*MO>@6HgWCZI>c4Rjf@)|H#Tm3+=RHN;%3Cni+ek6W!$Q`)p75~ zeIB`tc3pABlf7{;~M{ z_=5PZ@!jKl#`lhYGJayb7XNhon~TC`{;<&_AIhVOYY%1TEp| zgvkk05>_UxN?4une!_|iCq#46T2n$NGwY%PaK;#E%EupnTfL#Urc;0aaH2##P<_F zO#C?U)5Hyln-afF{3`K6;-$o&6R#v*O}v(PJ@HmjWKw#PGbt-6Cn+zfep17vMoCX3 z4M=h&4N59a8k#gLsVZrH(yK`elNKi}Nm`clX40og$CFMbok}{BbS~*a(xs%!$+l!A zSxv5!?3Wyn9F&}zTtB&Wa@*t%$(@qBB==5!B6&b^N%Fwts$`ZtIeAL*bII={uS#B% z{6X^CUr2p9b$;q= zsf$vVq%KR{nR+nwaO$ztlc}dt&!nD9y^wl2^=_Jy7Lpd87MT{4mYUWwtxa0{v`%RS zY2DI#ru9kdpEe-Pl{PqSXj*yN@U+=!FQvVbHb3pvwAa%XrM;c@UE0pHJ!$*W4y65% z_G8-R^t$O$>9OhY>51t{=_%=H=^5$H^v>yp>D|+NruR8 z{l)aT>9416O#d={OZqqI+tR;F-;sVG{YLtq>9^8vr{B%M88pKuBQ+xy-pqI_V@<~1i~|`5GY(}O$vBpA zBIAP7;E{f91l6X_=FXPR*3P!h_RfyZ9!}<*?0nWa&H21@hI5v4j&rVa zrSlW#dgtfPFPz^x&p6LJFFAj4UUmNNyy^VQ`H%B%Cdm{trA(hpIWrx0WpXm}GV5nH z%zPxXZ{`!3#hI?mL7AnQLo;8>d?j;!=Bt^nWiHHIoVg@(Y37#9t(o6t?#SGgxhHd9 z=I@y|GylrGm3ce!ZWhjp&Wg)Q%u3Em%}UR5W_8Xg%<7)iGpl!2->m*wTGphjDOppq zre!^!H6v?v)(2T@v({yOnzcUb^Q_}pKV_ZCI+t}J>r&Rw*>bicyH2)Wc0hJec1ZRk z*-f(ZvzuqP$ZnP0CVOahdG?6x%IuNZqqE0mFUek>y(0VV?02%?&3-R?P4@fQhqI4m zpUgg;eKz}i_QmYW*;jH*IdyXUa{_Zha$<8D7LUw zXI##N94+VRoXI&;a;E0Y&G|Uz)0_=C8*{$M*_^W_=f_-}E99DTrCdv{Pp+J6&voQx z=H}$q%WaU`D7SHLlicRHuH3=7Lvx4ax^qY5R_2b$ouB(!?xNf`a+l^V&s~xGZtl+9 zJ-PdHzt26Gdnorv?#VoyC*+y)EO|b8a-Kb}ZeDI){k%qbjq{r1HO*_5*D9|xuPo1< zHzKbxZ)D!+yeIQm-kiLb@?OcCpZ8kc=Xsm*Hs@{0+nV=n-uAp>c_;GzPfh3j9!1%3 zVL%W>Ab|AVTcir^?(EELuT0&UOxa|fC(O(S4 z@`5z!RX}+CF0b#GbN-2Q-{-O8Jx4i51xH0kB}Y9+YezfB$BvE;&XI6rIAn+F$aH9q zUXF2&nU2|xxsC;nJ&vy(`yBfnC60rR!;U-7O3sGPCeG&0md@7Bs59=Qovf303eF6t z?(FXz@0{fP%sI_D-MP)V!B+x4kScB!r`7jR{}beHKG=$h!7?3(KO+%?m+!?nw`+x3;}Yu8>^vFjJt zIoAWM6jlZ+hn2@FV(C~1tTXlr_9^DXFf4+_F$!Zb9@8-sv$397Z)_$u8=HqMz!qam zvE|qbY$ukF6<~X?BJ2Wo8M}&I!){<#wLUD{pN-O}C0o$hY$?&R*`?&=P? zBks7Ha?qc@=_d)kz_c8Ys_e1w%_cQkk_bdEEyfR)D zua4KmTj6c+bi6&@3HRXvJd8*2?zoN*!UyBS@DccEJP)6Z&%+nsi}B6)R(uD(3*U_& z!H?l5@RRr{{0ja%ejWb~z=-YyO>jhl z$RI2tMdT2Di2lTQVj?kxm`Y41mJ=(8)x=t215rp65yiv-;vn%8afUcYoF^_3_lO6? zW8x|Cf~-JRBrB6?WOcGR*^+ESwj-BZ(3+f&bz?rHDoB;d7^-T3l_vCqId**spdGb94o^8V(%>%H%N=zZd=;j87V>#Of;*@R4 zH^Vo}H^(>6x4^f^x5anB_oMH$?~L!P@4WAh?@!+Y-y`2se>s17e?@;Kf11CEzq!Aa zzm310KjM%3X+P)Z{i0v?C;k2W1O0>j!~7%tqy6*!U-`fG@AVh^OZkP(mrxq+d95rNTxF@f=cNr7d7;y_8@VBm1z zSl~q9WZ-<@PT*ePVc>D#X|P(bMzD6UUa)?!QLt&SMGy;S20<`8s0UFn73>up9Go6p z9$XPz9b6k+AIuLP3LXs}4}KT?K6pF$Eci0`I{0^}RH#g-T&O~*TBt^-cBpQM31x=* zgocMEhUSEpg;s=Cht`EQhPH&ZhjxVWLj|Gzp>INmLq|iWLKj27g?FhyMsajMR+OiPVoYiZqTii?oQej`cnO=LDUdxI5mnIOHH6AQ&XwwR30^(nnx|9mQc&7mDCz)9kqelOl_lf zQ2A5=RY(<4#Z(D(h&nb%nY{U8nw_Zc~3!52(k~GwKEP ziu#)_MVFz=(&g!jbR{~Cu1?pa>(KS-hIA9U8Qqd@L#NXn=+1Ok+CgJ9L3?N)9iYQ> zjHYOo=4pYJXqC>QA+6JhPSL&SK6HP2Ae~DOp@-2U=+X2zdLliAo<`50^XNJBJbEF$ zgkDCkpjXrD=#BIidON*~-c9eJi|AsyguX@JrSH>^=qL0u`UU+L{f4Q`RAoM5YBF`0 zW=uMRGakmzgqSGPonaWB5gCaY%S>P{a#}d!4<(-eI3`rMNO&Ij%fc zk*ma|an(4C!#R@kaRDyGMYtG8aSGRiGq~PdKW+dwh?~KE#T9Zz+&-?DJHUOz9pVmi ze{%P^N8D5HIrox##l7L)@fG;Gd;`8Q-;{5`x92593GhqxjMMSbjV| zk)OoR`R z@l)bV;%wsA#QDU<#O1`5#MQ(-p_Wirs4p}Unh4E=7D6kbt&k8h1X)N5SppEU1zkWw zFJX`{N*E)I6DA0ggek&K;Y*=FC=`l>eZqdBL^vee748d?igY2a37k5OJuuN?a?h7dMKV#4X}Bafi55 z{8hXtUKX#4*Tn1MAL1?XuJ};=OMIJADx*wB*^H_gbu$`ew3aw2A!SIil$10HO1gw3 zTk0kCk@`ymrCe!9BN6Iw75uevp2Yev*EX&Pf-f%hFZpnsi;dDczR-leBigG16O|B-_kZa3z<@$0%xry9dZY8&s)8!6wXZaJko9vKX zGA@&{PY%ivIWAK&EAz4_OR_3w$x!YgoB!u2mviL4@&Gwk9x9KJN6BO5@$y7@vizAm zO`b02$#dlS@*;Vu{Dr(yUL&uQH_Dskt?~|em%LlvBNxfVa*2FMJ}MuVzmtEE&nn#% zhvHIj#iRI?pb}PMN_T}(I7Lt-MNyJUmI9O>im6yiO6jHaQTi)`l)=g{Wu!7%8LNy} zCMuJa&y;D(3?)yQt;|*CD~psR%5r6;vRYZIY*2QpRn%%~4YjsfPi?3+QJbr+)VAu! zYDcw;+D&z;Zk1GhYEX@+ag|m%RZt~WRkKv6>MBxGYL41h9iZl_L)8)LXmy-AQJtbr zQ)j5N)Vb;cb+Nik-J}+%$JCSR8TG9CtNOe8U-fzNy<}RlPO@IId9r1)LlRF$lY9~+ zvy;7(Ba@SoQwrV@Hd~LV3M=R3yX$Q1}+7azr?SytxJEfi0&S>Yf^V%it zigr!Aq21K(X!o>-+GFjR_ELMTy#=Mgd*FTW0jLDhKsE3Ys0HeR2A~mW3R-|xpe^_q zbO4<}SMVut0yiLl2lznz*N90W(ex8OVQ1Naa48T2UktO~2cny?P62OGdfuqkW- zTf=s+J?sR#z^>2%T@Z&P^uhoP!x*F>3lmU;GE71ZW0}WS7gXko{qHmF#NS_4HPHTm56b zquxdDraN`FPU=2As7Lg;PV1a5=#sALSvu5p9qB1ONAIf-&~x>n`UrirK2D#gPtm98 zGxS;dTz!GQSYM{E&{ym0^o{x!eY?I(->vV_i}Yf>L_ee-)sO2Z^;7z3{fvH2zo1{% zuj>ER|Ilyif9enP$NDqsB1JZ8XL`wmPQ*R-RNL+ zHo6)P12YK2YXpq25i=-*H4;XKp%|G4FnSoKVH>@SK1P3IkTJv?<{OKQrN$S=Dr2p&!PsnUGj3E@)-mgwjm)NI3$wM^&TMaX zGCwgtHC-lddQ86=GNWd9lQDTyG-WesYG$@+n3mbo>}~cl2bzP;VdhA4j5*$%WPWCT zZq77koAbq{MEc@ z{$~DeUN>)=cg%a{L-UFG-2BUYW4=RWP&rfqeTb@{YN!UPjq0I>s0nJ0TA{Y+W7H9K zLEVr8xe$&#$d5uOg5rom4C0Z9WRyf2%KisiLMVlDP+v6QAFy-?8jePxF=!l`fF`4< z=yNm^%|dh00<;({Lo3i~v<_`VThMm23w?mETictwVhz_G;=mh#6okFM48FUU^ zK$p=~^j~xX-9mTJJ@gPgLC?`k^cuajN?T>E_pJ}CN>&xCnpMN9ZPl|HT1~9xRx7KG z)y`^fb+o!z-7Kf&wn)oo1+9n`w`hyA1WU41E6akGZXqjW-&lvOW7Y}ld+U^S z+WOf#Yn`_)Sy!xU)(z{Hb=SIQJ+vNM&#af$YwN9D+AeFCw=3F}?KHc(UDK{(*S8zl zP3;zTYrCD@-tJ_7Vt2Ehw%aCcpB=O#cFgW>Gd6Dvwq&bzmJRG4wrN{-PrJAM&-aBr z*dAt&w8z-v?TPjjdzwANo@LLq7ubvKrS=#0DtoQH!QO0dvv=D0c7eUeF0za568n&S z)IM&Xv`^Wm?KAc{`+|MRzG7dqZ`il&yY_wik^R(uVZXB9*zZ!MQ)N@-Q&m&dQXi!n iq#CB0q}rz1rP`-HO}YQQLMl_{-%iW=xBov=@&5sA{1{3A literal 35983 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 28 - 347 472 462 212 0 0 1152 842 + 345 472 462 212 0 0 1152 842 41 - 345 461 462 234 0 0 1152 842 + 345 423 462 310 0 0 1152 842 66 347 526 462 104 0 0 1152 842 IBFramework Version 446.1 + IBOpenObjects + + 41 + IBSystem Version 8I127 diff --git a/macosx/English.lproj/PrefsWindow.nib/keyedobjects.nib b/macosx/English.lproj/PrefsWindow.nib/keyedobjects.nib index 6d2dfa9571197016c5aeae488b0a7439682940ab..b8ee8a903380a52b5f5fec7f98fab27f5c7feed4 100644 GIT binary patch literal 18148 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 Xf&Ya60!e=qC4aJ2@@LaK|I_~gXnfg0 literal 16847 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 z%0A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 diff --git a/macosx/PrefsController.h b/macosx/PrefsController.h index 141207200..c185975ce 100644 --- a/macosx/PrefsController.h +++ b/macosx/PrefsController.h @@ -36,7 +36,7 @@ IBOutlet NSPopUpButton * fFolderPopUp; IBOutlet NSButton * fQuitCheck, * fRemoveCheck, * fBadgeDownloadRateCheck, * fBadgeUploadRateCheck, - * fAutoStartCheck; + * fAutoStartCheck, * fCopyTorrentCheck, * fDeleteOriginalTorrentCheck; IBOutlet NSPopUpButton * fUpdatePopUp; IBOutlet NSTextField * fPortField, * fUploadField, * fDownloadField; @@ -58,6 +58,7 @@ - (void) setUpdate: (id) sender; - (void) checkUpdate; - (void) setAutoStart: (id) sender; +- (void) setMoveTorrent: (id) sender; - (void) setDownloadLocation: (id) sender; - (void) folderSheetShow: (id) sender; diff --git a/macosx/PrefsController.m b/macosx/PrefsController.m index 10bf7c5d7..83249b922 100644 --- a/macosx/PrefsController.m +++ b/macosx/PrefsController.m @@ -116,7 +116,7 @@ BOOL checkUpload = [fDefaults boolForKey: @"CheckUpload"]; int uploadLimit = [fDefaults integerForKey: @"UploadLimit"]; - [fUploadCheck setState: checkUpload ? NSOnState : NSOffState]; + [fUploadCheck setState: checkUpload]; [fUploadField setIntValue: uploadLimit]; [fUploadField setEnabled: checkUpload]; @@ -126,7 +126,7 @@ BOOL checkDownload = [fDefaults boolForKey: @"CheckDownload"]; int downloadLimit = [fDefaults integerForKey: @"DownloadLimit"]; - [fDownloadCheck setState: checkDownload ? NSOnState : NSOffState]; + [fDownloadCheck setState: checkDownload]; [fDownloadField setIntValue: downloadLimit]; [fDownloadField setEnabled: checkDownload]; @@ -134,15 +134,13 @@ //set ratio limit BOOL ratioCheck = [fDefaults boolForKey: @"RatioCheck"]; - [fRatioCheck setState: ratioCheck ? NSOnState : NSOffState]; + [fRatioCheck setState: ratioCheck]; [fRatioField setEnabled: ratioCheck]; [fRatioField setFloatValue: [fDefaults floatForKey: @"RatioLimit"]]; //set remove and quit prompts - [fQuitCheck setState: [fDefaults boolForKey: @"CheckQuit"] ? - NSOnState : NSOffState]; - [fRemoveCheck setState: [fDefaults boolForKey: @"CheckRemove"] ? - NSOnState : NSOffState]; + [fQuitCheck setState: [fDefaults boolForKey: @"CheckQuit"]]; + [fRemoveCheck setState: [fDefaults boolForKey: @"CheckRemove"]]; //set dock badging [fBadgeDownloadRateCheck setState: [fDefaults boolForKey: @"BadgeDownloadRate"]]; @@ -150,6 +148,13 @@ //set auto start [fAutoStartCheck setState: [fDefaults boolForKey: @"AutoStartDownload"]]; + + //set private torrents + BOOL copyTorrents = [fDefaults boolForKey: @"SavePrivateTorrent"]; + [fCopyTorrentCheck setState: copyTorrents]; + + [fDeleteOriginalTorrentCheck setEnabled: copyTorrents]; + [fDeleteOriginalTorrentCheck setState: [fDefaults boolForKey: @"DeleteOriginalTorrent"]]; //set update check NSString * updateCheck = [fDefaults stringForKey: @"UpdateCheck"]; @@ -419,6 +424,24 @@ [fDefaults setBool: [sender state] forKey: @"AutoStartDownload"]; } +- (void) setMoveTorrent: (id) sender +{ + int state = [sender state]; + if (sender == fCopyTorrentCheck) + { + [fDefaults setBool: state forKey: @"SavePrivateTorrent"]; + + [fDeleteOriginalTorrentCheck setEnabled: state]; + if (state == NSOffState) + { + [fDeleteOriginalTorrentCheck setState: NSOffState]; + [fDefaults setBool: NO forKey: @"DeleteOriginalTorrent"]; + } + } + else + [fDefaults setBool: state forKey: @"DeleteOriginalTorrent"]; +} + - (void) setDownloadLocation: (id) sender { //Download folder diff --git a/macosx/Torrent.h b/macosx/Torrent.h index 2a0aa7f59..0026b2888 100644 --- a/macosx/Torrent.h +++ b/macosx/Torrent.h @@ -35,8 +35,11 @@ tr_torrent_t * fHandle; tr_info_t * fInfo; tr_stat_t * fStat; + BOOL fResumeOnWake; NSDate * fDate; + + BOOL fPrivateTorrent; NSUserDefaults * fDefaults; @@ -55,11 +58,12 @@ - (NSString *) downloadFolder; - (void) getAvailability: (int8_t *) tab size: (int) size; -- (void) update; -- (void) start; -- (void) stop; -- (void) sleep; -- (void) wakeUp; +- (void) update; +- (void) start; +- (void) stop; +- (void) removeForever; +- (void) sleep; +- (void) wakeUp; - (float) ratio; - (int) stopRatioSetting; @@ -68,7 +72,6 @@ - (void) setRatioLimit: (float) limit; - (void) reveal; -- (void) trashTorrent; - (void) trashData; - (NSImage *) icon; diff --git a/macosx/Torrent.m b/macosx/Torrent.m index d028cbb4c..6476122ef 100644 --- a/macosx/Torrent.m +++ b/macosx/Torrent.m @@ -28,9 +28,14 @@ @interface Torrent (Private) -- (void) trashPath: (NSString *) path; - (id) initWithPath: (NSString *) path lib: (tr_handle_t *) lib date: (NSDate *) date stopRatioSetting: (NSNumber *) stopRatioSetting ratioLimit: (NSNumber *) ratioLimit; +- (id) initWithHash: (NSString *) hashString lib: (tr_handle_t *) lib date: (NSDate *) date + stopRatioSetting: (NSNumber *) stopRatioSetting ratioLimit: (NSNumber *) ratioLimit; +- (id) initForSuccessWithDate: (NSDate *) date stopRatioSetting: (NSNumber *) + stopRatioSetting ratioLimit: (NSNumber *) ratioLimit; + +- (void) trashPath: (NSString *) path; @end @@ -39,14 +44,29 @@ - (id) initWithPath: (NSString *) path lib: (tr_handle_t *) lib { - return [self initWithPath: path lib: lib - date: nil stopRatioSetting: nil - ratioLimit: nil]; + id torrent = [self initWithPath: path lib: lib date: nil + stopRatioSetting: nil ratioLimit: nil]; + + if (!torrent) + return nil; + + if (fPrivateTorrent && [fDefaults boolForKey: @"DeleteOriginalTorrent"]) + [self trashPath: path]; + + return torrent; } - (id) initWithHistory: (NSDictionary *) history lib: (tr_handle_t *) lib { - self = [self initWithPath: [history objectForKey: @"TorrentPath"] + //load from saved torrent file if set to, otherwise try to load from where torrent file should be + NSNumber * privateCopy; + if ((privateCopy = [history objectForKey: @"PrivateCopy"]) && [privateCopy boolValue]) + self = [self initWithHash: [history objectForKey: @"TorrentHash"] + lib: lib date: [history objectForKey: @"Date"] + stopRatioSetting: [history objectForKey: @"StopRatioSetting"] + ratioLimit: [history objectForKey: @"RatioLimit"]]; + else + self = [self initWithPath: [history objectForKey: @"TorrentPath"] lib: lib date: [history objectForKey: @"Date"] stopRatioSetting: [history objectForKey: @"StopRatioSetting"] ratioLimit: [history objectForKey: @"RatioLimit"]]; @@ -68,13 +88,20 @@ - (NSDictionary *) history { - return [NSDictionary dictionaryWithObjectsAndKeys: - [self torrentLocation], @"TorrentPath", - [self downloadFolder], @"DownloadFolder", - [self isActive] ? @"NO" : @"YES", @"Paused", - [self date], @"Date", - [NSNumber numberWithInt: fStopRatioSetting], @"StopRatioSetting", - [NSNumber numberWithFloat: fRatioLimit], @"RatioLimit", nil]; + NSMutableDictionary * history = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool: fPrivateTorrent], @"PrivateCopy", + [self downloadFolder], @"DownloadFolder", + [self isActive] ? @"NO" : @"YES", @"Paused", + [self date], @"Date", + [NSNumber numberWithInt: fStopRatioSetting], @"StopRatioSetting", + [NSNumber numberWithFloat: fRatioLimit], @"RatioLimit", nil]; + + if (fPrivateTorrent) + [history setObject: [self hashString] forKey: @"TorrentHash"]; + else + [history setObject: [self torrentLocation] forKey: @"TorrentPath"]; + + return history; } - (void) dealloc @@ -127,7 +154,7 @@ [fProgressString setString: @""]; if ([self progress] < 1.0) - [fProgressString appendFormat: @"%@ of %@ completed (%.2f%%)", [NSString stringForFileSize: + [fProgressString appendFormat: @"%@ of %@ (%.2f%%)", [NSString stringForFileSize: [self downloaded]], [NSString stringForFileSize: [self size]], 100 * [self progress]]; else [fProgressString appendFormat: @"%@, uploaded %@ (ratio: %@)", [NSString stringForFileSize: @@ -212,6 +239,12 @@ } } +- (void) removeForever +{ + if (fInfo->flags & TR_FSAVEPRIVATE) + tr_torrentRemoveSaved(fHandle); +} + - (void) sleep { if( ( fResumeOnWake = ( fStat->status & TR_STATUS_ACTIVE ) ) ) @@ -261,11 +294,6 @@ inFileViewerRootedAtPath: nil]; } -- (void) trashTorrent -{ - [self trashPath: [self torrentLocation]]; -} - - (void) trashData { [self trashPath: [self dataLocation]]; @@ -314,19 +342,12 @@ - (NSString *) hashString { - NSMutableString * string = [NSMutableString - stringWithCapacity: SHA_DIGEST_LENGTH]; - int i; - for( i = 0; i < SHA_DIGEST_LENGTH; i++ ) - { - [string appendFormat: @"%02x", fInfo->hash[i]]; - } - return string; + return [NSString stringWithUTF8String: fInfo->hashString]; } - (NSString *) torrentLocation { - return [NSString stringWithUTF8String: fInfo->torrent];; + return [NSString stringWithUTF8String: fInfo->torrent]; } - (NSString *) dataLocation @@ -487,17 +508,46 @@ return nil; fLib = lib; + fDefaults = [NSUserDefaults standardUserDefaults]; + + fPrivateTorrent = [fDefaults boolForKey: @"SavePrivateTorrent"]; int error; - if (!path || !(fHandle = tr_torrentInit(fLib, [path UTF8String], &error))) + if (!path || !(fHandle = tr_torrentInit(fLib, [path UTF8String], + fPrivateTorrent ? TR_FSAVEPRIVATE : 0, & error))) + { + [self release]; + return nil; + } + + return [self initForSuccessWithDate: date stopRatioSetting: stopRatioSetting ratioLimit: ratioLimit]; +} + +- (id) initWithHash: (NSString *) hashString lib: (tr_handle_t *) lib date: (NSDate *) date + stopRatioSetting: (NSNumber *) stopRatioSetting ratioLimit: (NSNumber *) ratioLimit +{ + if (!(self = [super init])) + return nil; + + fLib = lib; + fDefaults = [NSUserDefaults standardUserDefaults]; + + fPrivateTorrent = YES; + + int error; + if (!hashString || !(fHandle = tr_torrentInitSaved(fLib, [hashString UTF8String], TR_FSAVEPRIVATE, & error))) { [self release]; return nil; } + return [self initForSuccessWithDate: date stopRatioSetting: stopRatioSetting ratioLimit: ratioLimit]; +} + +- (id) initForSuccessWithDate: (NSDate *) date stopRatioSetting: (NSNumber *) + stopRatioSetting ratioLimit: (NSNumber *) ratioLimit +{ fInfo = tr_torrentInfo( fHandle ); - - fDefaults = [NSUserDefaults standardUserDefaults]; fDate = date ? [date retain] : [[NSDate alloc] init]; fStopRatioSetting = stopRatioSetting ? [stopRatioSetting intValue] : -1; @@ -518,6 +568,7 @@ return self; } + - (void) trashPath: (NSString *) path { if( ![[NSWorkspace sharedWorkspace] performFileOperation: