use a custom class instead of a dictionary for holding a torrent's file structure

This commit is contained in:
Mitchell Livingston 2008-05-22 18:39:49 +00:00
parent dd6fc41ef3
commit b89071685f
11 changed files with 332 additions and 97 deletions

56
FileListNode.h Normal file
View File

@ -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

148
FileListNode.m Normal file
View File

@ -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

View File

@ -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;
};

View File

@ -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];
}

View File

@ -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])

View File

@ -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)
{

View File

@ -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)

View File

@ -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];

View File

@ -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"),

View File

@ -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

View File

@ -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];
}
}