use libtransmission for moving, incomplete directory, and directory controlling in general (still rough around the edges)

This commit is contained in:
Mitchell Livingston 2009-10-21 13:01:14 +00:00
parent 0c53f3fa62
commit 581afef25a
13 changed files with 257 additions and 297 deletions

View File

@ -254,7 +254,7 @@
[fDestination release];
fDestination = [destination retain];
[fTorrent changeDownloadFolder: fDestination];
[fTorrent changeDownloadFolderBeforeUsing: fDestination];
}
[fLocationField setStringValue: [fDestination stringByAbbreviatingWithTildeInPath]];

View File

@ -263,7 +263,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
}
tr_benc settings;
tr_bencInitDict(&settings, 34);
tr_bencInitDict(&settings, 36);
const char * configDir = tr_getDefaultConfigDir("Transmission");
tr_sessionGetDefaultSettings(configDir, &settings);
@ -290,6 +290,9 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
tr_bencDictAddBool(&settings, TR_PREFS_KEY_DHT_ENABLED, [fDefaults boolForKey: @"DHTGlobal"]);
tr_bencDictAddStr(&settings, TR_PREFS_KEY_DOWNLOAD_DIR, [[[fDefaults stringForKey: @"DownloadFolder"]
stringByExpandingTildeInPath] UTF8String]);
tr_bencDictAddStr(&settings, TR_PREFS_KEY_INCOMPLETE_DIR, [[[fDefaults stringForKey: @"IncompleteDownloadFolder"]
stringByExpandingTildeInPath] UTF8String]);
tr_bencDictAddBool(&settings, TR_PREFS_KEY_INCOMPLETE_DIR_ENABLED, [fDefaults boolForKey: @"UseIncompleteDownloadFolder"]);
tr_bencDictAddInt(&settings, TR_PREFS_KEY_MSGLEVEL, [fDefaults integerForKey: @"MessageLevel"]);
tr_bencDictAddInt(&settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, [fDefaults integerForKey: @"PeersTotal"]);
@ -940,11 +943,11 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
deleteTorrentFile: showWindow ? NO : deleteTorrentFile lib: fLib]))
continue;
//change the location if the group calls for it (this has to wait until after the torrent is create)
//change the location if the group calls for it (this has to wait until after the torrent is created)
if (!lockDestination && [[GroupsController groups] usesCustomDownloadLocationForIndex: [torrent groupValue]])
{
location = [[GroupsController groups] customDownloadLocationForIndex: [torrent groupValue]];
[torrent changeDownloadFolder: location];
[torrent changeDownloadFolderBeforeUsing: location];
}
//verify the data right away if it was newly created
@ -1464,14 +1467,22 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
{
NSMutableArray * paths = [NSMutableArray arrayWithCapacity: [selected count]];
for (Torrent * torrent in [fTableView selectedTorrents])
[paths addObject: [NSURL fileURLWithPath: [torrent dataLocation]]];
{
NSString * location = [torrent dataLocation];
if (location)
[paths addObject: [NSURL fileURLWithPath: location]];
}
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs: paths];
}
else
{
for (Torrent * torrent in selected)
[[NSWorkspace sharedWorkspace] selectFile: [torrent dataLocation] inFileViewerRootedAtPath: nil];
{
NSString * location = [torrent dataLocation];
if (location)
[[NSWorkspace sharedWorkspace] selectFile: location inFileViewerRootedAtPath: nil];
}
}
}
@ -1769,6 +1780,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
}
}
#warning dataLocation could return nil
NSDictionary * clickContext = [NSDictionary dictionaryWithObjectsAndKeys: GROWL_DOWNLOAD_COMPLETE, @"Type",
[torrent dataLocation] , @"Location", nil];
[GrowlApplicationBridge notifyWithTitle: NSLocalizedString(@"Download Complete", "Growl notification title")
@ -1780,7 +1792,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
//bounce download stack
[[NSDistributedNotificationCenter defaultCenter] postNotificationName: @"com.apple.DownloadFileFinished"
object: [[torrent downloadFolder] stringByAppendingPathComponent: [torrent name]]];
object: [torrent dataLocation]];
if ([fDefaults boolForKey: @"QueueSeed"] && [self numToStartFromQueue: NO] == 0)
{
@ -1830,6 +1842,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
}
}
#warning dataLocation could return nil
NSDictionary * clickContext = [NSDictionary dictionaryWithObjectsAndKeys: GROWL_SEEDING_COMPLETE, @"Type",
[torrent dataLocation], @"Location", nil];
[GrowlApplicationBridge notifyWithTitle: NSLocalizedString(@"Seeding Complete", "Growl notification title")
@ -3142,7 +3155,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
NSMutableArray * qlArray = [NSMutableArray arrayWithCapacity: [selectedTorrents count]];
for (Torrent * torrent in selectedTorrents)
if (([torrent isFolder] || [torrent isComplete]) && [[NSFileManager defaultManager] fileExistsAtPath: [torrent dataLocation]])
if (([torrent isFolder] || [torrent isComplete]) && [torrent dataLocation])
[qlArray addObject: torrent];
return qlArray;

View File

@ -44,7 +44,7 @@
- (BOOL) isFolder;
- (NSString *) name;
- (NSString *) fullPath;
- (NSString *) path;
- (NSIndexSet *) indexes;
- (uint64_t) size;

View File

@ -98,7 +98,7 @@
return fName;
}
- (NSString *) fullPath
- (NSString *) path
{
return fPath;
}
@ -137,7 +137,7 @@
{
fIsFolder = isFolder;
fName = [name retain];
fPath = [[path stringByAppendingPathComponent: name] retain];
fPath = [path retain];
fIndexes = [[NSMutableIndexSet alloc] init];
}

View File

@ -211,7 +211,7 @@ typedef enum
{
NSString * ident = [tableColumn identifier];
if ([ident isEqualToString: @"Name"])
return [[fTorrent downloadFolder] stringByAppendingPathComponent: [(FileListNode *)item fullPath]];
return [fTorrent fileLocation: item];
else if ([ident isEqualToString: @"Check"])
{
switch ([cell state])
@ -314,21 +314,27 @@ typedef enum
- (void) revealFile: (id) sender
{
NSString * folder = [fTorrent downloadFolder];
NSIndexSet * indexes = [fOutline selectedRowIndexes];
if ([NSApp isOnSnowLeopardOrBetter])
{
NSMutableArray * paths = [NSMutableArray arrayWithCapacity: [indexes count]];
for (NSUInteger i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i])
[paths addObject: [NSURL fileURLWithPath: [folder stringByAppendingPathComponent: [[fOutline itemAtRow: i] fullPath]]]];
{
NSString * path = [fTorrent fileLocation: [fOutline itemAtRow: i]];
if (path)
[paths addObject: [NSURL fileURLWithPath: path]];
}
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs: paths];
}
else
{
for (NSUInteger i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i])
[[NSWorkspace sharedWorkspace] selectFile: [folder stringByAppendingPathComponent: [[fOutline itemAtRow: i] fullPath]]
inFileViewerRootedAtPath: nil];
{
NSString * path = [fTorrent fileLocation: [fOutline itemAtRow: i]];
if (path)
[[NSWorkspace sharedWorkspace] selectFile: path inFileViewerRootedAtPath: nil];
}
}
}
@ -342,11 +348,9 @@ typedef enum
if (action == @selector(revealFile:))
{
NSString * downloadFolder = [fTorrent downloadFolder];
NSIndexSet * indexSet = [fOutline selectedRowIndexes];
for (NSInteger i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
if ([[NSFileManager defaultManager] fileExistsAtPath:
[downloadFolder stringByAppendingPathComponent: [[fFileList objectAtIndex: i] fullPath]]])
if ([fTorrent fileLocation: [fFileList objectAtIndex: i]] != nil)
return YES;
return NO;
}

View File

@ -1129,7 +1129,6 @@ typedef enum
{
FileOutlineView * fileOutlineView = [fFileController outlineView];
Torrent * torrent = [fTorrents objectAtIndex: 0];
NSString * folder = [torrent downloadFolder];
NSIndexSet * indexes = [fileOutlineView selectedRowIndexes];
NSMutableArray * urlArray = [NSMutableArray arrayWithCapacity: [indexes count]];
@ -1137,7 +1136,7 @@ typedef enum
{
FileListNode * item = [fileOutlineView itemAtRow: i];
if ([self canQuickLookFile: item])
[urlArray addObject: [NSURL fileURLWithPath: [folder stringByAppendingPathComponent: [item fullPath]]]];
[urlArray addObject: [torrent fileLocation: item]];
}
return urlArray;
@ -1167,14 +1166,14 @@ typedef enum
{
FileOutlineView * fileOutlineView = [fFileController outlineView];
NSString * fullPath = [(NSURL *) item path];
NSString * folder = [[fTorrents objectAtIndex: 0] downloadFolder];
NSString * fullPath = [(NSURL *)item path];
Torrent * torrent = [fTorrents objectAtIndex: 0];
NSRange visibleRows = [fileOutlineView rowsInRect: [fileOutlineView bounds]];
for (NSUInteger row = visibleRows.location; row < NSMaxRange(visibleRows); row++)
{
FileListNode * rowItem = [fileOutlineView itemAtRow: row];
if ([[folder stringByAppendingPathComponent: [rowItem fullPath]] isEqualToString: fullPath])
if ([[torrent fileLocation: rowItem] isEqualToString: fullPath])
{
NSRect frame = [fileOutlineView iconRectForRow: row];
@ -1372,8 +1371,8 @@ typedef enum
Torrent * torrent = [fTorrents objectAtIndex: 0];
NSString * location = [torrent dataLocation];
[fDataLocationField setStringValue: [location stringByAbbreviatingWithTildeInPath]];
[fDataLocationField setToolTip: location];
[fDataLocationField setStringValue: location ? [location stringByAbbreviatingWithTildeInPath] : @""];
[fDataLocationField setToolTip: location ? location : @""];
}
- (void) updateInfoActivity
@ -1662,11 +1661,7 @@ typedef enum
- (BOOL) canQuickLookFile: (FileListNode *) item
{
Torrent * torrent = [fTorrents objectAtIndex: 0];
if (![[NSFileManager defaultManager] fileExistsAtPath: [[torrent downloadFolder] stringByAppendingPathComponent: [item fullPath]]])
return NO;
return [item isFolder] || [torrent fileProgress: item] >= 1.0;
return [torrent fileLocation: item] != nil && ([item isFolder] || [torrent fileProgress: item] >= 1.0);
}
#warning doesn't like blank addresses

View File

@ -23,6 +23,7 @@
*****************************************************************************/
#import "MessageWindowController.h"
#import "NSApplicationAdditions.h"
#import "NSStringAdditions.h"
#import <transmission.h>

View File

@ -104,6 +104,7 @@
- (void) setDownloadLocation: (id) sender;
- (void) folderSheetShow: (id) sender;
- (void) incompleteFolderSheetShow: (id) sender;
- (void) setUseIncompleteFolder: (id) sender;
- (void) applyRatioSetting: (id) sender;
- (void) updateRatioStopField;

View File

@ -741,6 +741,11 @@ tr_session * fHandle;
@selector(incompleteFolderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
}
- (void) setUseIncompleteFolder: (id) sender
{
tr_sessionSetIncompleteDirEnabled(fHandle, [fDefaults boolForKey: @"UseIncompleteDownloadFolder"]);
}
- (void) setAutoImport: (id) sender
{
NSString * path;
@ -1091,6 +1096,12 @@ tr_session * fHandle;
NSString * downloadLocation = [[NSString stringWithUTF8String: tr_sessionGetDownloadDir(fHandle)] stringByStandardizingPath];
[fDefaults setObject: downloadLocation forKey: @"DownloadFolder"];
NSString * incompleteLocation = [[NSString stringWithUTF8String: tr_sessionGetIncompleteDir(fHandle)] stringByStandardizingPath];
[fDefaults setObject: incompleteLocation forKey: @"IncompleteDownloadFolder"];
const BOOL useIncomplete = tr_sessionIsIncompleteDirEnabled(fHandle);
[fDefaults setBool: useIncomplete forKey: @"UseIncompleteDownloadFolder"];
//peers
const uint16_t peersTotal = tr_sessionGetPeerLimit(fHandle);
[fDefaults setInteger: peersTotal forKey: @"PeersTotal"];
@ -1299,7 +1310,12 @@ tr_session * fHandle;
- (void) incompleteFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
{
if (code == NSOKButton)
[fDefaults setObject: [[openPanel filenames] objectAtIndex: 0] forKey: @"IncompleteDownloadFolder"];
{
NSString * folder = [[openPanel filenames] objectAtIndex: 0];
[fDefaults setObject: folder forKey: @"IncompleteDownloadFolder"];
tr_sessionSetIncompleteDir(fHandle, [folder UTF8String]);
}
[fIncompleteFolderPopUp selectItemAtIndex: 0];
}

View File

@ -34,11 +34,6 @@
tr_torrent * fHandle;
const tr_info * fInfo;
const tr_stat * fStat;
BOOL fResumeOnWake;
BOOL fUseIncompleteFolder;
NSString * fDownloadFolder, * fIncompleteFolder;
NSUserDefaults * fDefaults;
@ -56,7 +51,9 @@
NSInteger fGroupValue;
NSDictionary * fQuickPauseDict;
BOOL fResumeOnWake;
NSString * fTimeMachineExclude;
}
- (id) initWithPath: (NSString *) path location: (NSString *) location deleteTorrentFile: (BOOL) torrentDelete
@ -68,9 +65,9 @@
- (void) closeRemoveTorrent;
- (void) changeIncompleteDownloadFolder: (NSString *) folder;
- (void) changeDownloadFolder: (NSString *) folder;
- (NSString *) downloadFolder;
- (void) changeDownloadFolderBeforeUsing: (NSString *) folder;
- (NSString *) currentDirectory;
- (void) getAvailability: (int8_t *) tab size: (NSInteger) size;
- (void) getAmountFinished: (float *) tab size: (NSInteger) size;
@ -119,8 +116,6 @@
- (void) copyTorrentFileTo: (NSString *) path;
- (BOOL) alertForRemainingDiskSpace;
- (BOOL) alertForFolderAvailable;
- (BOOL) alertForMoveFolderAvailable;
- (NSImage *) icon;
@ -144,7 +139,9 @@
- (BOOL) privateTorrent;
- (NSString *) torrentLocation;
#warning needed?
- (NSString *) dataLocation;
- (NSString *) fileLocation: (FileListNode *) node;
- (CGFloat) progress;
- (CGFloat) progressDone;

View File

@ -32,14 +32,10 @@
@interface Torrent (Private)
- (id) initWithPath: (NSString *) path hash: (NSString *) hashString torrentStruct: (tr_torrent *) torrentStruct lib: (tr_session *) lib
downloadFolder: (NSString *) downloadFolder
useIncompleteFolder: (NSNumber *) useIncompleteFolder incompleteFolder: (NSString *) incompleteFolder
downloadFolder: (NSString *) downloadFolder incompleteFolder: (NSString *) incompleteFolder
waitToStart: (NSNumber *) waitToStart
groupValue: (NSNumber *) groupValue;
- (BOOL) shouldUseIncompleteFolderForName: (NSString *) name;
- (void) updateDownloadFolder;
- (void) createFileList;
- (void) insertPath: (NSMutableArray *) components forParent: (FileListNode *) parent fileSize: (uint64_t) size
index: (NSInteger) index flatList: (NSMutableArray *) flatFileList;
@ -48,11 +44,9 @@
- (void) ratioLimitHit;
- (void) quickPause;
- (void) endQuickPause;
- (NSString *) etaString;
- (void) updateTimeMachineExclude;
- (void) setTimeMachineExclude: (BOOL) exclude forPath: (NSString *) path;
@end
@ -80,8 +74,7 @@ int trashDataFile(const char * filename)
lib: (tr_session *) lib
{
self = [self initWithPath: path hash: nil torrentStruct: NULL lib: lib
downloadFolder: location
useIncompleteFolder: nil incompleteFolder: nil
downloadFolder: location incompleteFolder: nil
waitToStart: nil groupValue: nil];
if (self)
@ -95,8 +88,7 @@ int trashDataFile(const char * filename)
- (id) initWithTorrentStruct: (tr_torrent *) torrentStruct location: (NSString *) location lib: (tr_session *) lib
{
self = [self initWithPath: nil hash: nil torrentStruct: torrentStruct lib: lib
downloadFolder: location
useIncompleteFolder: nil incompleteFolder: nil
downloadFolder: location incompleteFolder: nil
waitToStart: nil groupValue: nil];
return self;
@ -107,9 +99,9 @@ int trashDataFile(const char * filename)
self = [self initWithPath: [history objectForKey: @"InternalTorrentPath"]
hash: [history objectForKey: @"TorrentHash"]
torrentStruct: NULL lib: lib
downloadFolder: [history objectForKey: @"DownloadFolder"]
useIncompleteFolder: [history objectForKey: @"UseIncompleteFolder"]
incompleteFolder: [history objectForKey: @"IncompleteFolder"]
downloadFolder: [history objectForKey: @"DownloadFolder"] //upgrading from versions < 1.80
incompleteFolder: [[history objectForKey: @"UseIncompleteFolder"] boolValue] //upgrading from versions < 1.80
? [history objectForKey: @"IncompleteFolder"] : nil
waitToStart: [history objectForKey: @"WaitToStart"]
groupValue: [history objectForKey: @"GroupValue"]];
@ -152,19 +144,12 @@ int trashDataFile(const char * filename)
- (NSDictionary *) history
{
NSMutableDictionary * history = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[self torrentLocation], @"InternalTorrentPath",
[self hashString], @"TorrentHash",
fDownloadFolder, @"DownloadFolder",
[NSNumber numberWithBool: fUseIncompleteFolder], @"UseIncompleteFolder",
[NSNumber numberWithBool: [self isActive]], @"Active",
[NSNumber numberWithBool: fWaitToStart], @"WaitToStart",
[NSNumber numberWithInt: fGroupValue], @"GroupValue", nil];
if (fIncompleteFolder)
[history setObject: fIncompleteFolder forKey: @"IncompleteFolder"];
return history;
return [NSDictionary dictionaryWithObjectsAndKeys:
[self torrentLocation], @"InternalTorrentPath",
[self hashString], @"TorrentHash",
[NSNumber numberWithBool: [self isActive]], @"Active",
[NSNumber numberWithBool: fWaitToStart], @"WaitToStart",
[NSNumber numberWithInt: fGroupValue], @"GroupValue", nil];
}
- (void) dealloc
@ -180,15 +165,12 @@ int trashDataFile(const char * filename)
[fNameString release];
[fHashString release];
[fDownloadFolder release];
[fIncompleteFolder release];
[fIcon release];
[fFileList release];
[fFlatFileList release];
[fQuickPauseDict release];
[fTimeMachineExclude release];
[super dealloc];
}
@ -201,35 +183,21 @@ int trashDataFile(const char * filename)
- (void) closeRemoveTorrent
{
//allow the file to be index by Time Machine
[self setTimeMachineExclude: NO forPath: [[self downloadFolder] stringByAppendingPathComponent: [self name]]];
if (fTimeMachineExclude)
[self setTimeMachineExclude: NO forPath: fTimeMachineExclude];
tr_torrentRemove(fHandle);
}
- (void) changeIncompleteDownloadFolder: (NSString *) folder
- (void) changeDownloadFolderBeforeUsing: (NSString *) folder
{
fUseIncompleteFolder = folder != nil;
[fIncompleteFolder release];
fIncompleteFolder = fUseIncompleteFolder ? [folder retain] : nil;
[self updateDownloadFolder];
tr_torrentSetDownloadDir(fHandle, [folder UTF8String]);
[self updateTimeMachineExclude];
}
- (void) changeDownloadFolder: (NSString *) folder
- (NSString *) currentDirectory
{
if (fDownloadFolder && [folder isEqualToString: fDownloadFolder])
return;
[fDownloadFolder release];
fDownloadFolder = [folder retain];
[self updateDownloadFolder];
}
- (NSString *) downloadFolder
{
return [NSString stringWithUTF8String: tr_torrentGetDownloadDir(fHandle)];
return [NSString stringWithUTF8String: tr_torrentGetCurrentDir(fHandle)];
}
- (void) getAvailability: (int8_t *) tab size: (NSInteger) size
@ -280,6 +248,11 @@ int trashDataFile(const char * filename)
//update queue for checking (from downloading to seeding), stalled, or error
if ((wasChecking && ![self isChecking]) || (wasStalled != fStalled) || (!wasError && [self isError] && [self isActive]))
[[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateQueue" object: self];
//when the data first appears, update time machine exclusion
#warning perhaps always check to get if the file is moved through rpc
if (!fTimeMachineExclude)
[self updateTimeMachineExclude];
}
- (void) startTransfer
@ -287,7 +260,7 @@ int trashDataFile(const char * filename)
fWaitToStart = NO;
fFinishedSeeding = NO;
if (![self isActive] && [self alertForFolderAvailable] && [self alertForRemainingDiskSpace])
if (![self isActive] && /*[self alertForFolderAvailable] &&*/ [self alertForRemainingDiskSpace])
{
tr_torrentStart(fHandle);
[self update];
@ -455,67 +428,53 @@ int trashDataFile(const char * filename)
- (void) moveTorrentDataFileTo: (NSString *) folder
{
NSString * oldFolder = [self downloadFolder];
if (![oldFolder isEqualToString: folder] || ![fDownloadFolder isEqualToString: folder])
#warning fix
/*NSString * oldFolder = [self downloadFolder];
if ([oldFolder isEqualToString: folder])
return;
//check if moving inside itself
NSArray * oldComponents = [oldFolder pathComponents],
* newComponents = [folder pathComponents];
NSInteger count;
if ((count = [oldComponents count]) < [newComponents count]
&& [[newComponents objectAtIndex: count] isEqualToString: [self name]]
&& [oldComponents isEqualToArray:
[newComponents objectsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, count)]]])
{
//check if moving inside itself
NSArray * oldComponents = [oldFolder pathComponents],
* newComponents = [folder pathComponents];
NSInteger count;
NSAlert * alert = [[NSAlert alloc] init];
[alert setMessageText: NSLocalizedString(@"A folder cannot be moved to inside itself.",
"Move inside itself alert -> title")];
[alert setInformativeText: [NSString stringWithFormat:
NSLocalizedString(@"The move operation of \"%@\" cannot be done.",
"Move inside itself alert -> message"), [self name]]];
[alert addButtonWithTitle: NSLocalizedString(@"OK", "Move inside itself alert -> button")];
if ((count = [oldComponents count]) < [newComponents count]
&& [[newComponents objectAtIndex: count] isEqualToString: [self name]]
&& [oldComponents isEqualToArray:
[newComponents objectsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, count)]]])
{
NSAlert * alert = [[NSAlert alloc] init];
[alert setMessageText: NSLocalizedString(@"A folder cannot be moved to inside itself.",
"Move inside itself alert -> title")];
[alert setInformativeText: [NSString stringWithFormat:
NSLocalizedString(@"The move operation of \"%@\" cannot be done.",
"Move inside itself alert -> message"), [self name]]];
[alert addButtonWithTitle: NSLocalizedString(@"OK", "Move inside itself alert -> button")];
[alert runModal];
[alert release];
return;
}
[alert runModal];
[alert release];
[self quickPause];
return;
}*/
#warning doesn't block?
int status;
tr_torrentSetLocation(fHandle, [folder UTF8String], YES, NULL, &status);
if (status == TR_LOC_DONE)
[[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil];
else
{
return;
NSAlert * alert = [[NSAlert alloc] init];
[alert setMessageText: NSLocalizedString(@"There was an error moving the data file.", "Move error alert -> title")];
[alert setInformativeText: [NSString stringWithFormat:
NSLocalizedString(@"The move operation of \"%@\" cannot be done.",
"Move error alert -> message"), [self name]]];
[alert addButtonWithTitle: NSLocalizedString(@"OK", "Move error alert -> button")];
//allow if file can be moved or does not exist
if ([[NSFileManager defaultManager] moveItemAtPath: [oldFolder stringByAppendingPathComponent: [self name]]
toPath: [folder stringByAppendingPathComponent: [self name]] error: NULL]
|| ![[NSFileManager defaultManager] fileExistsAtPath: [oldFolder stringByAppendingPathComponent: [self name]]])
{
//get rid of both incomplete folder and old download folder, even if move failed
fUseIncompleteFolder = NO;
if (fIncompleteFolder)
{
[fIncompleteFolder release];
fIncompleteFolder = nil;
}
[self changeDownloadFolder: folder];
[[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil];
[self endQuickPause];
}
else
{
[self endQuickPause];
NSAlert * alert = [[NSAlert alloc] init];
[alert setMessageText: NSLocalizedString(@"There was an error moving the data file.", "Move error alert -> title")];
[alert setInformativeText: [NSString stringWithFormat:
NSLocalizedString(@"The move operation of \"%@\" cannot be done.",
"Move error alert -> message"), [self name]]];
[alert addButtonWithTitle: NSLocalizedString(@"OK", "Move error alert -> button")];
[alert runModal];
[alert release];
}
[alert runModal];
[alert release];
}
}
@ -529,6 +488,8 @@ int trashDataFile(const char * filename)
if ([self allDownloaded] || ![fDefaults boolForKey: @"WarningRemainingSpace"])
return YES;
#warning fix
return YES;
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * downloadFolder = [self downloadFolder];
@ -566,7 +527,8 @@ int trashDataFile(const char * filename)
return YES;
}
- (BOOL) alertForFolderAvailable
#warning is this needed?
/*- (BOOL) alertForFolderAvailable
{
#warning check for change from incomplete to download folder first
if (access(tr_torrentGetDownloadDir(fHandle), 0))
@ -618,35 +580,13 @@ int trashDataFile(const char * filename)
[self update];
[[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil];
}
- (BOOL) alertForMoveFolderAvailable
{
if (access([fDownloadFolder UTF8String], 0))
{
NSAlert * alert = [[NSAlert alloc] init];
[alert setMessageText: [NSString stringWithFormat:
NSLocalizedString(@"The folder for moving the completed \"%@\" cannot be used.",
"Move folder cannot be used alert -> title"), [self name]]];
[alert setInformativeText: [NSString stringWithFormat:
NSLocalizedString(@"\"%@\" cannot be used. The file will remain in its current location.",
"Move folder cannot be used alert -> message"), fDownloadFolder]];
[alert addButtonWithTitle: NSLocalizedString(@"OK", "Move folder cannot be used alert -> button")];
[alert runModal];
[alert release];
return NO;
}
return YES;
}
}*/
- (NSImage *) icon
{
if (!fIcon)
fIcon = [[[NSWorkspace sharedWorkspace] iconForFileType: [self isFolder] ? NSFileTypeForHFSTypeCode('fldr')
: [[self name] pathExtension]] retain];
: [[self name] pathExtension]] retain];
return fIcon;
}
@ -789,9 +729,54 @@ int trashDataFile(const char * filename)
return [NSString stringWithUTF8String: fInfo->torrent];
}
#warning returning nil causes the info field to not change - check all uses of data location
- (NSString *) dataLocation
{
return [[self downloadFolder] stringByAppendingPathComponent: [self name]];
if ([self isFolder])
{
NSString * dataLocation = [[self currentDirectory] stringByAppendingPathComponent: [self name]];
if (![[NSFileManager defaultManager] fileExistsAtPath: dataLocation])
return nil;
return dataLocation;
}
else
{
char * location = tr_torrentFindFile(fHandle, 0);
if (location == NULL)
return nil;
NSString * dataLocation = [NSString stringWithUTF8String: location];
free(location);
return dataLocation;
}
}
- (NSString *) fileLocation: (FileListNode *) node
{
if ([node isFolder])
{
NSString * basePath = [[node path] stringByAppendingPathComponent: [node name]];
NSString * dataLocation = [[self currentDirectory] stringByAppendingPathComponent: basePath];
if (![[NSFileManager defaultManager] fileExistsAtPath: dataLocation])
return nil;
return dataLocation;
}
else
{
char * location = tr_torrentFindFile(fHandle, [[node indexes] firstIndex]);
if (location == NULL)
return nil;
NSString * dataLocation = [NSString stringWithUTF8String: location];
free(location);
return dataLocation;
}
}
- (CGFloat) progress
@ -1508,7 +1493,8 @@ int trashDataFile(const char * filename)
- (NSURL *) previewItemURL
{
return [NSURL fileURLWithPath: [self dataLocation]];
NSString * location = [self dataLocation];
return location ? [NSURL fileURLWithPath: location] : nil;
}
@end
@ -1516,8 +1502,7 @@ int trashDataFile(const char * filename)
@implementation Torrent (Private)
- (id) initWithPath: (NSString *) path hash: (NSString *) hashString torrentStruct: (tr_torrent *) torrentStruct lib: (tr_session *) lib
downloadFolder: (NSString *) downloadFolder
useIncompleteFolder: (NSNumber *) useIncompleteFolder incompleteFolder: (NSString *) incompleteFolder
downloadFolder: (NSString *) downloadFolder incompleteFolder: (NSString *) incompleteFolder
waitToStart: (NSNumber *) waitToStart
groupValue: (NSNumber *) groupValue
{
@ -1526,25 +1511,10 @@ int trashDataFile(const char * filename)
fDefaults = [NSUserDefaults standardUserDefaults];
fDownloadFolder = downloadFolder ? downloadFolder : [fDefaults stringForKey: @"DownloadFolder"];
fDownloadFolder = [[fDownloadFolder stringByExpandingTildeInPath] retain];
fUseIncompleteFolder = useIncompleteFolder ? [useIncompleteFolder boolValue]
: [fDefaults boolForKey: @"UseIncompleteDownloadFolder"];
if (fUseIncompleteFolder)
{
fIncompleteFolder = incompleteFolder ? incompleteFolder : [fDefaults stringForKey: @"IncompleteDownloadFolder"];
fIncompleteFolder = [[fIncompleteFolder stringByExpandingTildeInPath] retain];
}
if (torrentStruct)
{
fHandle = torrentStruct;
fInfo = tr_torrentInfo(fHandle);
NSString * currentDownloadFolder = [self shouldUseIncompleteFolderForName: [NSString stringWithUTF8String: fInfo->name]]
? fIncompleteFolder : fDownloadFolder;
tr_torrentSetDownloadDir(fHandle, [currentDownloadFolder UTF8String]);
}
else
{
@ -1568,9 +1538,10 @@ int trashDataFile(const char * filename)
if (result == TR_PARSE_OK)
{
NSString * currentDownloadFolder = [self shouldUseIncompleteFolderForName: [NSString stringWithUTF8String: info.name]]
? fIncompleteFolder : fDownloadFolder;
tr_ctorSetDownloadDir(ctor, TR_FORCE, [currentDownloadFolder UTF8String]);
if (downloadFolder)
tr_ctorSetDownloadDir(ctor, TR_FORCE, [downloadFolder UTF8String]);
if (incompleteFolder)
tr_ctorSetIncompleteDir(ctor, [incompleteFolder UTF8String]);
fHandle = tr_torrentNew(ctor, NULL);
}
@ -1607,11 +1578,9 @@ int trashDataFile(const char * filename)
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(checkGroupValueForRemoval:)
name: @"GroupValueRemoved" object: nil];
fTimeMachineExclude = nil;
[self update];
//mark incomplete files to be ignored by Time Machine
[self setTimeMachineExclude: ![self allDownloaded] forPath: [[self downloadFolder] stringByAppendingPathComponent: [self name]]];
return self;
}
@ -1693,11 +1662,12 @@ int trashDataFile(const char * filename)
//create new folder or file if it doesn't already exist
if (!node)
{
NSString * path = [[parent path] stringByAppendingPathComponent: [parent name]];
if (isFolder)
node = [[FileListNode alloc] initWithFolderName: name path: [parent fullPath]];
node = [[FileListNode alloc] initWithFolderName: name path: path];
else
{
node = [[FileListNode alloc] initWithFileName: name path: [parent fullPath] size: size index: index];
node = [[FileListNode alloc] initWithFileName: name path: path size: size index: index];
[flatFileList addObject: node];
}
@ -1714,23 +1684,6 @@ int trashDataFile(const char * filename)
}
}
- (BOOL) shouldUseIncompleteFolderForName: (NSString *) name
{
return fUseIncompleteFolder &&
![[NSFileManager defaultManager] fileExistsAtPath: [fDownloadFolder stringByAppendingPathComponent: name]];
}
- (void) updateDownloadFolder
{
//remove old Time Machine location
[self setTimeMachineExclude: NO forPath: [[self downloadFolder] stringByAppendingPathComponent: [self name]]];
NSString * folder = [self shouldUseIncompleteFolderForName: [self name]] ? fIncompleteFolder : fDownloadFolder;
tr_torrentSetDownloadDir(fHandle, [folder UTF8String]);
[self setTimeMachineExclude: ![self allDownloaded] forPath: [folder stringByAppendingPathComponent: [self name]]];
}
//status has been retained
- (void) completenessChange: (NSNumber *) status
{
@ -1741,48 +1694,17 @@ int trashDataFile(const char * filename)
{
case TR_SEED:
case TR_PARTIAL_SEED:
canMove = YES;
//move file from incomplete folder to download folder
if (fUseIncompleteFolder && ![[self downloadFolder] isEqualToString: fDownloadFolder]
&& (canMove = [self alertForMoveFolderAvailable]))
{
[self quickPause];
if ([[NSFileManager defaultManager] moveItemAtPath: [[self downloadFolder] stringByAppendingPathComponent: [self name]]
toPath: [fDownloadFolder stringByAppendingPathComponent: [self name]] error: NULL])
[self updateDownloadFolder];
else
canMove = NO;
[self endQuickPause];
}
if (!canMove)
{
fUseIncompleteFolder = NO;
[fDownloadFolder release];
fDownloadFolder = fIncompleteFolder;
fIncompleteFolder = nil;
}
//allow to be backed up by Time Machine
[self setTimeMachineExclude: NO forPath: [[self downloadFolder] stringByAppendingPathComponent: [self name]]];
[[NSNotificationCenter defaultCenter] postNotificationName: @"TorrentFinishedDownloading" object: self];
break;
case TR_LEECH:
//do not allow to be backed up by Time Machine
[self setTimeMachineExclude: YES forPath: [[self downloadFolder] stringByAppendingPathComponent: [self name]]];
[[NSNotificationCenter defaultCenter] postNotificationName: @"TorrentRestartedDownloading" object: self];
break;
}
[status release];
[self update];
[self updateTimeMachineExclude];
}
- (void) ratioLimitHit
@ -1794,37 +1716,6 @@ int trashDataFile(const char * filename)
fFinishedSeeding = YES;
}
- (void) quickPause
{
if (fQuickPauseDict)
return;
fQuickPauseDict = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithInt: [self usesSpeedLimit: YES]], @"UploadUsesSpeedLimit",
[NSNumber numberWithInt: [self speedLimit: YES]], @"UploadSpeedLimit",
[NSNumber numberWithInt: [self usesSpeedLimit: NO]], @"DownloadUsesSpeedLimit",
[NSNumber numberWithInt: [self speedLimit: NO]], @"DownloadSpeedLimit", nil];
[self setUseSpeedLimit: YES upload: YES];
[self setSpeedLimit: 0 upload: YES];
[self setUseSpeedLimit: YES upload: NO];
[self setSpeedLimit: 0 upload: NO];
}
- (void) endQuickPause
{
if (!fQuickPauseDict)
return;
[self setUseSpeedLimit: [[fQuickPauseDict objectForKey: @"UploadUsesSpeedLimit"] intValue] upload: YES];
[self setSpeedLimit: [[fQuickPauseDict objectForKey: @"UploadSpeedLimit"] intValue] upload: YES];
[self setUseSpeedLimit: [[fQuickPauseDict objectForKey: @"DownloadUsesSpeedLimit"] intValue] upload: NO];
[self setSpeedLimit: [[fQuickPauseDict objectForKey: @"DownloadSpeedLimit"] intValue] upload: NO];
[fQuickPauseDict release];
fQuickPauseDict = nil;
}
- (NSString *) etaString
{
const NSInteger eta = [self eta];
@ -1839,6 +1730,26 @@ int trashDataFile(const char * filename)
}
}
- (void) updateTimeMachineExclude
{
NSString * newLocation = [self dataLocation];
if (fTimeMachineExclude && newLocation && [fTimeMachineExclude isEqualToString: newLocation] && ![self allDownloaded])
return;
if (fTimeMachineExclude)
{
[self setTimeMachineExclude: NO forPath: fTimeMachineExclude];
fTimeMachineExclude = nil;
}
if (newLocation && ![self allDownloaded])
{
[self setTimeMachineExclude: YES forPath: newLocation];
fTimeMachineExclude = [newLocation retain];
}
}
- (void) setTimeMachineExclude: (BOOL) exclude forPath: (NSString *) path
{
CSBackupSetItemExcluded((CFURLRef)[NSURL fileURLWithPath: path], exclude, true);

View File

@ -298,11 +298,19 @@
if ([NSApp isOnSnowLeopardOrBetter])
{
NSURL * file = [NSURL fileURLWithPath: [[self representedObject] dataLocation]];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs: [NSArray arrayWithObject: file]];
NSString * location = [[self representedObject] dataLocation];
if (location)
{
NSURL * file = [NSURL fileURLWithPath: location];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs: [NSArray arrayWithObject: file]];
}
}
else
[[NSWorkspace sharedWorkspace] selectFile: [[self representedObject] dataLocation] inFileViewerRootedAtPath: nil];
{
NSString * location = [[self representedObject] dataLocation];
if (location)
[[NSWorkspace sharedWorkspace] selectFile: location inFileViewerRootedAtPath: nil];
}
}
else;

View File

@ -3,18 +3,20 @@
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10B504</string>
<string key="IBDocument.InterfaceBuilderVersion">732</string>
<string key="IBDocument.InterfaceBuilderVersion">740</string>
<string key="IBDocument.AppKitVersion">1038.2</string>
<string key="IBDocument.HIToolboxVersion">437.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">732</string>
<string key="NS.object.0">740</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="153"/>
<integer value="1760"/>
<integer value="255"/>
<integer value="1361"/>
<integer value="1760"/>
<integer value="28"/>
<integer value="153"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -60,7 +62,7 @@
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
</object>
<object class="NSCustomView" id="249126185">
<nil key="NSNextResponder"/>
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -392,11 +394,12 @@
</object>
</object>
<string key="NSFrameSize">{542, 291}</string>
<reference key="NSSuperview"/>
<string key="NSClassName">NSView</string>
<string key="NSExtension">NSResponder</string>
</object>
<object class="NSCustomView" id="314557528">
<nil key="NSNextResponder"/>
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -1542,6 +1545,7 @@
</object>
</object>
<string key="NSFrameSize">{542, 288}</string>
<reference key="NSSuperview"/>
<string key="NSClassName">NSView</string>
<string key="NSExtension">NSResponder</string>
</object>
@ -7781,6 +7785,14 @@ AAABAAAAAQ</bytes>
</object>
<int key="connectionID">1928</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">setUseIncompleteFolder:</string>
<reference key="source" ref="511492310"/>
<reference key="destination" ref="615763784"/>
</object>
<int key="connectionID">1929</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@ -11611,7 +11623,7 @@ AAABAAAAAQ</bytes>
<real value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<real value="1"/>
<string>{{189, 274}, {542, 288}}</string>
<string>{{333, 406}, {542, 288}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<real value="1"/>
<string>{{429, 310}, {539, 288}}</string>
@ -11729,7 +11741,7 @@ AAABAAAAAQ</bytes>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">1928</int>
<int key="maxID">1929</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@ -11928,6 +11940,7 @@ AAABAAAAAQ</bytes>
<string>setSpeedLimit:</string>
<string>setStalled:</string>
<string>setStalledMinutes:</string>
<string>setUseIncompleteFolder:</string>
<string>updateBlocklist:</string>
</object>
<object class="NSMutableArray" key="dict.values">
@ -11985,6 +11998,7 @@ AAABAAAAAQ</bytes>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">