use a custom class instead of a dictionary for holding a torrent's file structure
This commit is contained in:
parent
dd6fc41ef3
commit
b89071685f
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2008 Transmission authors and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface FileListNode : NSObject <NSCopying>
|
||||
{
|
||||
NSString * fName, * fPath;
|
||||
BOOL fIsFolder;
|
||||
NSMutableIndexSet * fIndexes;
|
||||
|
||||
uint64_t fSize;
|
||||
NSImage * fIcon;
|
||||
|
||||
NSMutableArray * fChildren;
|
||||
}
|
||||
|
||||
- (id) initWithFolderName: (NSString *) name path: (NSString *) path;
|
||||
- (id) initWithFileName: (NSString *) name path: (NSString *) path size: (uint64_t) size index: (int) index;
|
||||
|
||||
- (void) insertChild: (FileListNode *) child;
|
||||
- (void) insertIndex: (NSUInteger) index;
|
||||
|
||||
- (BOOL) isFolder;
|
||||
- (NSString *) name;
|
||||
- (NSString *) fullPath;
|
||||
- (NSIndexSet *) indexes;
|
||||
|
||||
- (uint64_t) size;
|
||||
- (NSImage *) icon;
|
||||
|
||||
- (NSArray *) children;
|
||||
|
||||
@end
|
|
@ -0,0 +1,148 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2008 Transmission authors and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#import "FileListNode.h"
|
||||
|
||||
@interface FileListNode (Private)
|
||||
|
||||
- (id) initWithFolder: (BOOL) isFolder name: (NSString *) name path: (NSString *) path;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FileListNode
|
||||
|
||||
- (id) initWithFolderName: (NSString *) name path: (NSString *) path
|
||||
{
|
||||
if ((self = [self initWithFolder: YES name: name path: path]))
|
||||
{
|
||||
fChildren = [[NSMutableArray alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithFileName: (NSString *) name path: (NSString *) path size: (uint64_t) size index: (int) index
|
||||
{
|
||||
if ((self = [self initWithFolder: NO name: name path: path]))
|
||||
{
|
||||
fSize = size;
|
||||
[fIndexes addIndex: index];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) insertChild: (FileListNode *) child
|
||||
{
|
||||
[fChildren addObject: child];
|
||||
}
|
||||
|
||||
- (void) insertIndex: (NSUInteger) index
|
||||
{
|
||||
[fIndexes addIndex: index];
|
||||
}
|
||||
|
||||
- (id) copyWithZone: (NSZone *) zone
|
||||
{
|
||||
return [self retain];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[fName release];
|
||||
[fPath release];
|
||||
[fIndexes release];
|
||||
|
||||
[fIcon release];
|
||||
|
||||
[fChildren release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL) isFolder
|
||||
{
|
||||
return fIsFolder;
|
||||
}
|
||||
|
||||
- (NSString *) name
|
||||
{
|
||||
return fName;
|
||||
}
|
||||
|
||||
- (NSString *) fullPath
|
||||
{
|
||||
return fPath;
|
||||
}
|
||||
|
||||
- (NSIndexSet *) indexes
|
||||
{
|
||||
return fIndexes;
|
||||
}
|
||||
|
||||
- (uint64_t) size
|
||||
{
|
||||
NSAssert(!fIsFolder, @"method can only be invoked on files currently");
|
||||
|
||||
return fSize;
|
||||
}
|
||||
|
||||
- (NSImage *) icon
|
||||
{
|
||||
NSAssert(!fIsFolder, @"method can only be invoked on files currently");
|
||||
|
||||
if (!fIcon)
|
||||
{
|
||||
fIcon = [[[NSWorkspace sharedWorkspace] iconForFileType: [fName pathExtension]] retain];
|
||||
[fIcon setFlipped: YES];
|
||||
}
|
||||
return fIcon;
|
||||
}
|
||||
|
||||
- (NSArray *) children
|
||||
{
|
||||
NSAssert(fIsFolder, @"method can only be invoked on folders");
|
||||
|
||||
return fChildren;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation FileListNode (Private)
|
||||
|
||||
- (id) initWithFolder: (BOOL) isFolder name: (NSString *) name path: (NSString *) path
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
fIsFolder = isFolder;
|
||||
fName = [name retain];
|
||||
fPath = [[path stringByAppendingPathComponent: name] retain];
|
||||
|
||||
fIndexes = [[NSMutableIndexSet alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -142,6 +142,7 @@
|
|||
A26E75880CB6AA7500226674 /* InfoOptions.png in Resources */ = {isa = PBXBuildFile; fileRef = A26E75870CB6AA7500226674 /* InfoOptions.png */; };
|
||||
A26E75960CB6AB4800226674 /* InfoGeneral.png in Resources */ = {isa = PBXBuildFile; fileRef = A26E75950CB6AB4800226674 /* InfoGeneral.png */; };
|
||||
A2710E770A86796000CE4F7D /* PrefsWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A2710E750A86796000CE4F7D /* PrefsWindow.m */; };
|
||||
A2725B6E0DE5C4F5003445E7 /* FileListNode.m in Sources */ = {isa = PBXBuildFile; fileRef = A2725B6D0DE5C4F5003445E7 /* FileListNode.m */; };
|
||||
A277DA0B0C693D9C00DA2CD4 /* ActionOn.png in Resources */ = {isa = PBXBuildFile; fileRef = A277DA090C693D9C00DA2CD4 /* ActionOn.png */; };
|
||||
A29576030D11D63C0093B167 /* Creator.xib in Resources */ = {isa = PBXBuildFile; fileRef = A29576010D11D63C0093B167 /* Creator.xib */; };
|
||||
A29576130D11D8DD0093B167 /* InfoWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = A29576110D11D8DD0093B167 /* InfoWindow.xib */; };
|
||||
|
@ -581,6 +582,8 @@
|
|||
A26E75950CB6AB4800226674 /* InfoGeneral.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = InfoGeneral.png; path = macosx/Images/InfoGeneral.png; sourceTree = "<group>"; };
|
||||
A2710E740A86796000CE4F7D /* PrefsWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PrefsWindow.h; path = macosx/PrefsWindow.h; sourceTree = "<group>"; };
|
||||
A2710E750A86796000CE4F7D /* PrefsWindow.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PrefsWindow.m; path = macosx/PrefsWindow.m; sourceTree = "<group>"; };
|
||||
A2725B6C0DE5C4F5003445E7 /* FileListNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileListNode.h; sourceTree = "<group>"; };
|
||||
A2725B6D0DE5C4F5003445E7 /* FileListNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileListNode.m; sourceTree = "<group>"; };
|
||||
A27476FF0CC38EE6003CC76D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = macosx/es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
A27477010CC38EE6003CC76D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = macosx/es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
A277DA090C693D9C00DA2CD4 /* ActionOn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ActionOn.png; path = macosx/Images/ActionOn.png; sourceTree = "<group>"; };
|
||||
|
@ -905,6 +908,8 @@
|
|||
4D364D9F091FBB2C00377D12 /* TorrentTableView.m */,
|
||||
4DCCBB3D09C3D71100D3CABF /* TorrentCell.h */,
|
||||
4DCCBB3C09C3D71100D3CABF /* TorrentCell.m */,
|
||||
A2725B6C0DE5C4F5003445E7 /* FileListNode.h */,
|
||||
A2725B6D0DE5C4F5003445E7 /* FileListNode.m */,
|
||||
A25AFDE70D1038AD0092A1BA /* MenuLabel.h */,
|
||||
A25AFDE80D1038AD0092A1BA /* MenuLabel.m */,
|
||||
A26AF2820D2DC27C00FF7140 /* AddWindowController.h */,
|
||||
|
@ -1997,6 +2002,7 @@
|
|||
A2FB701C0D95CAEA0001F331 /* GroupsController.m in Sources */,
|
||||
A2D307A40D9EC6870051FD27 /* BlocklistDownloader.m in Sources */,
|
||||
A2DF57740DE46A6A000795D5 /* QuickLookController.m in Sources */,
|
||||
A2725B6E0DE5C4F5003445E7 /* FileListNode.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import "FileNameCell.h"
|
||||
#import "FileOutlineView.h"
|
||||
#import "Torrent.h"
|
||||
#import "FileListNode.h"
|
||||
#import "NSApplicationAdditions.h"
|
||||
#import "NSStringAdditions.h"
|
||||
|
||||
|
@ -91,8 +92,9 @@
|
|||
|
||||
- (NSImage *) image
|
||||
{
|
||||
NSImage * image = [[self objectValue] objectForKey: @"Icon"];
|
||||
if (!image)
|
||||
FileListNode * node = (FileListNode *)[self objectValue];
|
||||
NSImage * image;
|
||||
if ([node isFolder])
|
||||
{
|
||||
if (!fFolderImage)
|
||||
{
|
||||
|
@ -101,6 +103,9 @@
|
|||
}
|
||||
image = fFolderImage;
|
||||
}
|
||||
else
|
||||
image = [node icon];
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
@ -110,7 +115,7 @@
|
|||
|
||||
result.origin.x += PADDING_HORIZONAL;
|
||||
|
||||
const float IMAGE_SIZE = [[[self objectValue] objectForKey: @"IsFolder"] boolValue] ? IMAGE_FOLDER_SIZE : IMAGE_ICON_SIZE;
|
||||
const float IMAGE_SIZE = [(FileListNode *)[self objectValue] isFolder] ? IMAGE_FOLDER_SIZE : IMAGE_ICON_SIZE;
|
||||
result.origin.y += (result.size.height - IMAGE_SIZE) * 0.5;
|
||||
result.size = NSMakeSize(IMAGE_SIZE, IMAGE_SIZE);
|
||||
|
||||
|
@ -138,7 +143,7 @@
|
|||
&& [[self highlightColorWithFrame: cellFrame inView: controlView] isEqual: [NSColor alternateSelectedControlColor]])
|
||||
specialColor = [NSColor whiteColor];
|
||||
else if ([[(FileOutlineView *)[self controlView] torrent] checkForFiles:
|
||||
[[self objectValue] objectForKey: @"Indexes"]] == NSOffState)
|
||||
[(FileListNode *)[self objectValue] indexes]] == NSOffState)
|
||||
specialColor = [NSColor disabledControlTextColor];
|
||||
else;
|
||||
|
||||
|
@ -147,7 +152,7 @@
|
|||
[titleString drawInRect: titleRect];
|
||||
|
||||
//status
|
||||
if (![[[self objectValue] objectForKey: @"IsFolder"] boolValue])
|
||||
if (![(FileListNode *)[self objectValue] isFolder])
|
||||
{
|
||||
NSAttributedString * statusString = [self attributedStatusWithColor: specialColor ? specialColor : [NSColor darkGrayColor]];
|
||||
NSRect statusRect = [self rectForStatusWithString: statusString inBounds: cellFrame];
|
||||
|
@ -165,7 +170,7 @@
|
|||
|
||||
NSRect result = bounds;
|
||||
|
||||
if (![[[self objectValue] objectForKey: @"IsFolder"] boolValue])
|
||||
if (![(FileListNode *)[self objectValue] isFolder])
|
||||
{
|
||||
result.origin.x += PADDING_HORIZONAL + IMAGE_ICON_SIZE + PADDING_BETWEEN_IMAGE_AND_TITLE;
|
||||
result.origin.y += PADDING_ABOVE_TITLE_FILE;
|
||||
|
@ -183,7 +188,7 @@
|
|||
|
||||
- (NSRect) rectForStatusWithString: (NSAttributedString *) string inBounds: (NSRect) bounds
|
||||
{
|
||||
if ([[[self objectValue] objectForKey: @"IsFolder"] boolValue])
|
||||
if ([(FileListNode *)[self objectValue] isFolder])
|
||||
return NSZeroRect;
|
||||
|
||||
NSSize statusSize = [string size];
|
||||
|
@ -204,7 +209,7 @@
|
|||
if (color)
|
||||
[fTitleAttributes setObject: color forKey: NSForegroundColorAttributeName];
|
||||
|
||||
NSString * title = [[self objectValue] objectForKey: @"Name"];
|
||||
NSString * title = [(FileListNode *)[self objectValue] name];
|
||||
return [[[NSAttributedString alloc] initWithString: title attributes: fTitleAttributes] autorelease];
|
||||
}
|
||||
|
||||
|
@ -214,11 +219,11 @@
|
|||
[fStatusAttributes setObject: color forKey: NSForegroundColorAttributeName];
|
||||
|
||||
Torrent * torrent = [(FileOutlineView *)[self controlView] torrent];
|
||||
float percent = [torrent fileProgress: [[[self objectValue] objectForKey: @"Indexes"] firstIndex]] * 100.0;
|
||||
FileListNode * node = (FileListNode *)[self objectValue];
|
||||
float percent = [torrent fileProgress: [[node indexes] firstIndex]] * 100.0;
|
||||
|
||||
NSString * status = [NSString localizedStringWithFormat: NSLocalizedString(@"%.2f%% of %@",
|
||||
"Inspector -> Files tab -> file status string"), percent,
|
||||
[NSString stringForFileSize: [[[self objectValue] objectForKey: @"Size"] unsignedLongLongValue]]];
|
||||
"Inspector -> Files tab -> file status string"), percent, [NSString stringForFileSize: [node size]]];
|
||||
|
||||
return [[[NSAttributedString alloc] initWithString: status attributes: fStatusAttributes] autorelease];
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#import "Torrent.h"
|
||||
#import "FileOutlineView.h"
|
||||
#import "FilePriorityCell.h"
|
||||
#import "FileListNode.h"
|
||||
#import "QuickLookController.h"
|
||||
#import "NSApplicationAdditions.h"
|
||||
|
||||
|
@ -101,23 +102,26 @@ typedef enum
|
|||
if (!item)
|
||||
return fTorrent ? [[fTorrent fileList] count] : 0;
|
||||
else
|
||||
return [[item objectForKey: @"IsFolder"] boolValue] ? [[item objectForKey: @"Children"] count] : 0;
|
||||
{
|
||||
FileListNode * node = (FileListNode *)item;
|
||||
return [node isFolder] ? [[node children] count] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) outlineView: (NSOutlineView *) outlineView isItemExpandable: (id) item
|
||||
{
|
||||
return [[item objectForKey: @"IsFolder"] boolValue];
|
||||
return [(FileListNode *)item isFolder];
|
||||
}
|
||||
|
||||
- (id) outlineView: (NSOutlineView *) outlineView child: (int) index ofItem: (id) item
|
||||
{
|
||||
return [(item ? [item objectForKey: @"Children"] : [fTorrent fileList]) objectAtIndex: index];
|
||||
return [(item ? [(FileListNode *)item children] : [fTorrent fileList]) objectAtIndex: index];
|
||||
}
|
||||
|
||||
- (id) outlineView: (NSOutlineView *) outlineView objectValueForTableColumn: (NSTableColumn *) tableColumn byItem: (id) item
|
||||
{
|
||||
if ([[tableColumn identifier] isEqualToString: @"Check"])
|
||||
return [NSNumber numberWithInt: [fTorrent checkForFiles: [item objectForKey: @"Indexes"]]];
|
||||
return [NSNumber numberWithInt: [fTorrent checkForFiles: [(FileListNode *)item indexes]]];
|
||||
else
|
||||
return item;
|
||||
}
|
||||
|
@ -127,7 +131,7 @@ typedef enum
|
|||
{
|
||||
NSString * identifier = [tableColumn identifier];
|
||||
if ([identifier isEqualToString: @"Check"])
|
||||
[cell setEnabled: [fTorrent canChangeDownloadCheckForFiles: [item objectForKey: @"Indexes"]]];
|
||||
[cell setEnabled: [fTorrent canChangeDownloadCheckForFiles: [(FileListNode *)item indexes]]];
|
||||
else if ([identifier isEqualToString: @"Priority"])
|
||||
{
|
||||
[cell setRepresentedObject: item];
|
||||
|
@ -148,7 +152,7 @@ typedef enum
|
|||
if ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask)
|
||||
indexSet = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTorrent fileCount])];
|
||||
else
|
||||
indexSet = [item objectForKey: @"Indexes"];
|
||||
indexSet = [(FileListNode *)item indexes];
|
||||
|
||||
[fTorrent setFileCheckState: [object intValue] != NSOffState ? NSOnState : NSOffState forIndexes: indexSet];
|
||||
[fOutline reloadData];
|
||||
|
@ -159,7 +163,7 @@ typedef enum
|
|||
|
||||
- (NSString *) outlineView: (NSOutlineView *) outlineView typeSelectStringForTableColumn: (NSTableColumn *) tableColumn item: (id) item
|
||||
{
|
||||
return [item objectForKey: @"Name"];
|
||||
return [(FileListNode *)item name];
|
||||
}
|
||||
|
||||
- (NSString *) outlineView: (NSOutlineView *) outlineView toolTipForCell: (NSCell *) cell rect: (NSRectPointer) rect
|
||||
|
@ -167,7 +171,7 @@ typedef enum
|
|||
{
|
||||
NSString * ident = [tableColumn identifier];
|
||||
if ([ident isEqualToString: @"Name"])
|
||||
return [[fTorrent downloadFolder] stringByAppendingPathComponent: [item objectForKey: @"Path"]];
|
||||
return [[fTorrent downloadFolder] stringByAppendingPathComponent: [(FileListNode *)item fullPath]];
|
||||
else if ([ident isEqualToString: @"Check"])
|
||||
{
|
||||
switch ([cell state])
|
||||
|
@ -182,7 +186,7 @@ typedef enum
|
|||
}
|
||||
else if ([ident isEqualToString: @"Priority"])
|
||||
{
|
||||
NSSet * priorities = [fTorrent filePrioritiesForIndexes: [item objectForKey: @"Indexes"]];
|
||||
NSSet * priorities = [fTorrent filePrioritiesForIndexes: [(FileListNode *)item indexes]];
|
||||
switch ([priorities count])
|
||||
{
|
||||
case 0:
|
||||
|
@ -209,7 +213,7 @@ typedef enum
|
|||
|
||||
- (float) outlineView: (NSOutlineView *) outlineView heightOfRowByItem: (id) item
|
||||
{
|
||||
if ([[item objectForKey: @"IsFolder"] boolValue])
|
||||
if ([(FileListNode *)item isFolder])
|
||||
return ROW_SMALL_HEIGHT;
|
||||
else
|
||||
return [outlineView rowHeight];
|
||||
|
@ -223,7 +227,7 @@ typedef enum
|
|||
NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
|
||||
int i;
|
||||
for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]];
|
||||
|
||||
[fTorrent setFileCheckState: state forIndexes: itemIndexes];
|
||||
[fOutline reloadData];
|
||||
|
@ -235,7 +239,7 @@ typedef enum
|
|||
NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
|
||||
int i;
|
||||
for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]];
|
||||
|
||||
[fTorrent setFileCheckState: NSOnState forIndexes: itemIndexes];
|
||||
|
||||
|
@ -265,7 +269,7 @@ typedef enum
|
|||
NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
|
||||
int i;
|
||||
for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]];
|
||||
|
||||
[fTorrent setFilePriority: priority forIndexes: itemIndexes];
|
||||
[fOutline reloadData];
|
||||
|
@ -278,7 +282,7 @@ typedef enum
|
|||
int i;
|
||||
for (i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i])
|
||||
[[NSWorkspace sharedWorkspace] selectFile: [folder stringByAppendingPathComponent:
|
||||
[[fOutline itemAtRow: i] objectForKey: @"Path"]] inFileViewerRootedAtPath: nil];
|
||||
[[fOutline itemAtRow: i] fullPath]] inFileViewerRootedAtPath: nil];
|
||||
}
|
||||
|
||||
#warning make real view controller (Leopard-only) so that Command-R will work
|
||||
|
@ -296,7 +300,7 @@ typedef enum
|
|||
int i;
|
||||
for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:
|
||||
[downloadFolder stringByAppendingPathComponent: [[[fTorrent fileList] objectAtIndex: i] objectForKey: @"Path"]]])
|
||||
[downloadFolder stringByAppendingPathComponent: [[[fTorrent fileList] objectAtIndex: i] fullPath]]])
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
@ -310,7 +314,7 @@ typedef enum
|
|||
NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
|
||||
int i, state = ([menuItem tag] == FILE_CHECK_TAG) ? NSOnState : NSOffState;
|
||||
for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]];
|
||||
|
||||
return [fTorrent checkForFiles: itemIndexes] != state && [fTorrent canChangeDownloadCheckForFiles: itemIndexes];
|
||||
}
|
||||
|
@ -324,7 +328,7 @@ typedef enum
|
|||
NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
|
||||
int i;
|
||||
for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
|
||||
[itemIndexes addIndexes: [[fOutline itemAtRow: i] indexes]];
|
||||
|
||||
return [fTorrent canChangeDownloadCheckForFiles: itemIndexes];
|
||||
}
|
||||
|
@ -357,7 +361,7 @@ typedef enum
|
|||
NSIndexSet * fileIndexSet;
|
||||
for (i = [indexSet firstIndex]; i != NSNotFound && (!current || !other); i = [indexSet indexGreaterThanIndex: i])
|
||||
{
|
||||
fileIndexSet = [[fOutline itemAtRow: i] objectForKey: @"Indexes"];
|
||||
fileIndexSet = [[fOutline itemAtRow: i] indexes];
|
||||
if (![fTorrent canChangeDownloadCheckForFiles: fileIndexSet])
|
||||
continue;
|
||||
else if ([fTorrent hasFilePriority: priority forIndexes: fileIndexSet])
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#import "FileNameCell.h"
|
||||
#import "FilePriorityCell.h"
|
||||
#import "Torrent.h"
|
||||
#import "FileListNode.h"
|
||||
#import "QuickLookController.h"
|
||||
#import "CTGradient.h"
|
||||
|
||||
|
@ -179,7 +180,7 @@
|
|||
if (![self isRowSelected: row])
|
||||
{
|
||||
NSDictionary * item = [self itemAtRow: row];
|
||||
NSIndexSet * indexes = [item objectForKey: @"Indexes"];
|
||||
NSIndexSet * indexes = [(FileListNode *)item indexes];
|
||||
|
||||
if ([fTorrent checkForFiles: indexes] != NSOffState)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#import "FilePriorityCell.h"
|
||||
#import "FileOutlineView.h"
|
||||
#import "FileListNode.h"
|
||||
#import "Torrent.h"
|
||||
|
||||
@implementation FilePriorityCell
|
||||
|
@ -73,7 +74,7 @@
|
|||
|
||||
FileOutlineView * controlView = (FileOutlineView *)[self controlView];
|
||||
Torrent * torrent = [controlView torrent];
|
||||
[torrent setFilePriority: priority forIndexes: [[self representedObject] objectForKey: @"Indexes"]];
|
||||
[torrent setFilePriority: priority forIndexes: [(FileListNode *)[self representedObject] indexes]];
|
||||
[controlView reloadData];
|
||||
}
|
||||
|
||||
|
@ -101,8 +102,8 @@
|
|||
- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) controlView
|
||||
{
|
||||
Torrent * torrent = [(FileOutlineView *)controlView torrent];
|
||||
NSDictionary * dict = [self representedObject];
|
||||
NSSet * priorities = [torrent filePrioritiesForIndexes: [dict objectForKey: @"Indexes"]];
|
||||
FileListNode * node = [self representedObject];
|
||||
NSSet * priorities = [torrent filePrioritiesForIndexes: [node indexes]];
|
||||
|
||||
int count = [priorities count];
|
||||
if (fHoverRow && count > 0)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import "InfoWindowController.h"
|
||||
#import "InfoTabButtonCell.h"
|
||||
#import "FileOutlineView.h"
|
||||
#import "FileListNode.h"
|
||||
#import "QuickLookController.h"
|
||||
#import "NSApplicationAdditions.h"
|
||||
#import "NSStringAdditions.h"
|
||||
|
@ -907,9 +908,9 @@ typedef enum
|
|||
int i;
|
||||
for (i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i])
|
||||
{
|
||||
NSDictionary * item = [fileOutlineView itemAtRow: i];
|
||||
if ([[item objectForKey: @"IsFolder"] boolValue] || [torrent fileProgress: [[item objectForKey: @"Indexes"] firstIndex]] == 1.0)
|
||||
[urlArray addObject: [NSURL fileURLWithPath: [folder stringByAppendingPathComponent: [item objectForKey: @"Path"]]]];
|
||||
FileListNode * item = [fileOutlineView itemAtRow: i];
|
||||
if ([item isFolder] || [torrent fileProgress: [[item indexes] firstIndex]] == 1.0)
|
||||
[urlArray addObject: [NSURL fileURLWithPath: [folder stringByAppendingPathComponent: [item fullPath]]]];
|
||||
}
|
||||
|
||||
return urlArray;
|
||||
|
@ -924,8 +925,8 @@ typedef enum
|
|||
int i;
|
||||
for (i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i])
|
||||
{
|
||||
NSDictionary * item = [fileOutlineView itemAtRow: i];
|
||||
if ([[item objectForKey: @"IsFolder"] boolValue] || [torrent fileProgress: [[item objectForKey: @"Indexes"] firstIndex]] == 1.0)
|
||||
FileListNode * item = [fileOutlineView itemAtRow: i];
|
||||
if ([item isFolder] || [torrent fileProgress: [[item indexes] firstIndex]] == 1.0)
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -943,8 +944,8 @@ typedef enum
|
|||
int row;
|
||||
for (row = visibleRows.location; row < NSMaxRange(visibleRows); row++)
|
||||
{
|
||||
id rowItem = [fileOutlineView itemAtRow: row];
|
||||
if ([[folder stringByAppendingPathComponent: [rowItem objectForKey: @"Path"]] isEqualToString: fullPath])
|
||||
FileListNode * rowItem = [fileOutlineView itemAtRow: row];
|
||||
if ([[folder stringByAppendingPathComponent: [rowItem fullPath]] isEqualToString: fullPath])
|
||||
{
|
||||
NSRect frame = [fileOutlineView iconRectForRow: row];
|
||||
frame.origin = [fileOutlineView convertPoint: frame.origin toView: nil];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2007-2008 Transmission authors and contributors
|
||||
* Copyright (c) 2008 Transmission authors and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2007-2008 Transmission authors and contributors
|
||||
* Copyright (c) 2008 Transmission authors and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -49,9 +49,8 @@ QuickLookController * fQuickLookInstance = nil;
|
|||
return fQuickLookInstance;
|
||||
}
|
||||
|
||||
// This is the QuickLook delegate method
|
||||
// It should return the frame for the item represented by the URL
|
||||
// If an empty frame is returned then the panel will fade in/out instead
|
||||
//QuickLook delegate method
|
||||
//returns the frame for the item represented by the URL, or an empty frame to fade in/out instead
|
||||
- (NSRect) previewPanel: (NSPanel *) panel frameForURL: (NSURL *) url
|
||||
{
|
||||
if ([fInfoController shouldQuickLookFileView])
|
||||
|
@ -65,8 +64,7 @@ QuickLookController * fQuickLookInstance = nil;
|
|||
if (!fQuickLookAvailable)
|
||||
return NO;
|
||||
|
||||
NSArray * urlArray = nil;
|
||||
|
||||
NSArray * urlArray;
|
||||
if ([fInfoController shouldQuickLookFileView])
|
||||
urlArray = [fInfoController quickLookURLs];
|
||||
else
|
||||
|
@ -74,7 +72,7 @@ QuickLookController * fQuickLookInstance = nil;
|
|||
|
||||
if (urlArray && [urlArray count] > 0)
|
||||
{
|
||||
[[QLPreviewPanel sharedPreviewPanel] setURLs: urlArray currentIndex: 0 preservingDisplayState: YES];
|
||||
[[QLPreviewPanel sharedPreviewPanel] setURLs: urlArray];
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
|
@ -83,6 +81,9 @@ QuickLookController * fQuickLookInstance = nil;
|
|||
|
||||
- (BOOL) canQuickLook
|
||||
{
|
||||
if (!fQuickLookAvailable)
|
||||
return NO;
|
||||
|
||||
if ([fInfoController shouldQuickLookFileView])
|
||||
return [fInfoController canQuickLook];
|
||||
else
|
||||
|
|
110
macosx/Torrent.m
110
macosx/Torrent.m
|
@ -24,6 +24,7 @@
|
|||
|
||||
#import "Torrent.h"
|
||||
#import "GroupsController.h"
|
||||
#import "FileListNode.h"
|
||||
#import "NSApplicationAdditions.h"
|
||||
#import "NSStringAdditions.h"
|
||||
|
||||
|
@ -43,8 +44,7 @@
|
|||
- (void) updateDownloadFolder;
|
||||
|
||||
- (void) createFileList;
|
||||
- (void) insertPath: (NSMutableArray *) components forSiblings: (NSMutableArray *) siblings previousPath: (NSString *) previousPath
|
||||
fileSize: (uint64_t) size index: (int) index;
|
||||
- (void) insertPath: (NSMutableArray *) components forParent: (FileListNode *) parent fileSize: (uint64_t) size index: (int) index;
|
||||
|
||||
- (void) completenessChange: (NSNumber *) status;
|
||||
|
||||
|
@ -1648,78 +1648,90 @@ void completenessChangeCallback(tr_torrent * torrent, cp_status_t status, void *
|
|||
|
||||
- (void) createFileList
|
||||
{
|
||||
int count = [self fileCount], i;
|
||||
NSMutableArray * fileList = [[NSMutableArray alloc] initWithCapacity: count];
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if ([self folder])
|
||||
{
|
||||
tr_file * file = &fInfo->files[i];
|
||||
int count = [self fileCount], i;
|
||||
NSMutableArray * fileList = [[NSMutableArray alloc] initWithCapacity: count];
|
||||
|
||||
NSMutableArray * pathComponents = [[[NSString stringWithUTF8String: file->name] pathComponents] mutableCopy];
|
||||
NSString * path;
|
||||
if ([self folder])
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
path = [pathComponents objectAtIndex: 0];
|
||||
[pathComponents removeObjectAtIndex: 0];
|
||||
tr_file * file = &fInfo->files[i];
|
||||
|
||||
NSMutableArray * pathComponents = [[[NSString stringWithUTF8String: file->name] pathComponents] mutableCopy];
|
||||
NSString * path = [pathComponents objectAtIndex: 0];
|
||||
NSString * name = [pathComponents objectAtIndex: 1];
|
||||
[pathComponents removeObjectsAtIndexes: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, 2)]];
|
||||
|
||||
if ([pathComponents count] > 0)
|
||||
{
|
||||
//determine if node already exists
|
||||
NSEnumerator * enumerator = [fileList objectEnumerator];
|
||||
FileListNode * node;
|
||||
while ((node = [enumerator nextObject]))
|
||||
if ([[node name] isEqualToString: name])
|
||||
break;
|
||||
|
||||
if (!node)
|
||||
{
|
||||
node = [[FileListNode alloc] initWithFolderName: name path: path];
|
||||
[fileList addObject: node];
|
||||
[node release];
|
||||
}
|
||||
|
||||
[self insertPath: pathComponents forParent: node fileSize: file->length index: i];
|
||||
}
|
||||
else
|
||||
{
|
||||
FileListNode * node = [[FileListNode alloc] initWithFileName: name path: path size: file->length index: i];
|
||||
[fileList addObject: node];
|
||||
[node release];
|
||||
}
|
||||
|
||||
[pathComponents release];
|
||||
}
|
||||
else
|
||||
path = @"";
|
||||
|
||||
[self insertPath: pathComponents forSiblings: fileList previousPath: path fileSize: file->length index: i];
|
||||
[pathComponents release];
|
||||
fFileList = [[NSArray alloc] initWithArray: fileList];
|
||||
[fileList release];
|
||||
}
|
||||
else
|
||||
{
|
||||
FileListNode * node = [[FileListNode alloc] initWithFileName: [self name] path: @"" size: [self size] index: 0];
|
||||
fFileList = [[NSArray arrayWithObject: node] retain];
|
||||
[node release];
|
||||
}
|
||||
|
||||
fFileList = [[NSArray alloc] initWithArray: fileList];
|
||||
[fileList release];
|
||||
}
|
||||
|
||||
- (void) insertPath: (NSMutableArray *) components forSiblings: (NSMutableArray *) siblings previousPath: (NSString *) previousPath
|
||||
fileSize: (uint64_t) size index: (int) index
|
||||
- (void) insertPath: (NSMutableArray *) components forParent: (FileListNode *) parent fileSize: (uint64_t) size index: (int) index
|
||||
{
|
||||
NSString * name = [components objectAtIndex: 0];
|
||||
BOOL isFolder = [components count] > 1;
|
||||
|
||||
NSMutableDictionary * dict = nil;
|
||||
FileListNode * node = nil;
|
||||
if (isFolder)
|
||||
{
|
||||
NSEnumerator * enumerator = [siblings objectEnumerator];
|
||||
while ((dict = [enumerator nextObject]))
|
||||
if ([[dict objectForKey: @"Name"] isEqualToString: name] && [[dict objectForKey: @"IsFolder"] boolValue])
|
||||
NSEnumerator * enumerator = [[parent children] objectEnumerator];
|
||||
while ((node = [enumerator nextObject]))
|
||||
if ([[node name] isEqualToString: name] && [node isFolder])
|
||||
break;
|
||||
}
|
||||
|
||||
NSString * currentPath = [previousPath stringByAppendingPathComponent: name];
|
||||
|
||||
//create new folder or item if it doesn't already exist
|
||||
if (!dict)
|
||||
//create new folder or file if it doesn't already exist
|
||||
if (!node)
|
||||
{
|
||||
dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: name, @"Name",
|
||||
[NSNumber numberWithBool: isFolder], @"IsFolder", currentPath, @"Path", nil];
|
||||
[siblings addObject: dict];
|
||||
|
||||
if (isFolder)
|
||||
{
|
||||
[dict setObject: [NSMutableArray array] forKey: @"Children"];
|
||||
[dict setObject: [NSMutableIndexSet indexSetWithIndex: index] forKey: @"Indexes"];
|
||||
}
|
||||
node = [[FileListNode alloc] initWithFolderName: name path: [parent fullPath]];
|
||||
else
|
||||
{
|
||||
[dict setObject: [NSIndexSet indexSetWithIndex: index] forKey: @"Indexes"];
|
||||
[dict setObject: [NSNumber numberWithUnsignedLongLong: size] forKey: @"Size"];
|
||||
|
||||
NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFileType: [name pathExtension]];
|
||||
[icon setFlipped: YES];
|
||||
[dict setObject: icon forKey: @"Icon"];
|
||||
}
|
||||
node = [[FileListNode alloc] initWithFileName: name path: [parent fullPath] size: size index: index];
|
||||
|
||||
[parent insertChild: node];
|
||||
}
|
||||
else
|
||||
[[dict objectForKey: @"Indexes"] addIndex: index];
|
||||
|
||||
if (isFolder)
|
||||
{
|
||||
[node insertIndex: index];
|
||||
|
||||
[components removeObjectAtIndex: 0];
|
||||
[self insertPath: components forSiblings: [dict objectForKey: @"Children"] previousPath: currentPath fileSize: size
|
||||
index: index];
|
||||
[self insertPath: components forParent: node fileSize: size index: index];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue