1/****************************************************************************** 2 * $Id: InfoFileViewController.m 13309 2012-05-20 00:19:55Z livings124 $ 3 * 4 * Copyright (c) 2010-2012 Transmission authors and contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 *****************************************************************************/ 24 25#import "InfoFileViewController.h" 26#import "FileListNode.h" 27#import "FileOutlineController.h" 28#import "FileOutlineView.h" 29#import "Torrent.h" 30 31@interface InfoFileViewController (Private) 32 33- (void) setupInfo; 34 35- (BOOL) canQuickLookFile: (FileListNode *) item; 36 37@end 38 39@implementation InfoFileViewController 40 41- (id) init 42{ 43 if ((self = [super initWithNibName: @"InfoFileView" bundle: nil])) 44 { 45 [self setTitle: NSLocalizedString(@"Files", "Inspector view -> title")]; 46 } 47 48 return self; 49} 50 51- (void) awakeFromNib 52{ 53 const CGFloat height = [[NSUserDefaults standardUserDefaults] floatForKey: @"InspectorContentHeightFiles"]; 54 if (height != 0.0) 55 { 56 NSRect viewRect = [[self view] frame]; 57 viewRect.size.height = height; 58 [[self view] setFrame: viewRect]; 59 } 60 61 [[fFileFilterField cell] setPlaceholderString: NSLocalizedString(@"Filter", "inspector -> file filter")]; 62 63 //localize and place all and none buttons 64 [fCheckAllButton setTitle: NSLocalizedString(@"All", "inspector -> check all")]; 65 [fUncheckAllButton setTitle: NSLocalizedString(@"None", "inspector -> check all")]; 66 67 NSRect checkAllFrame = [fCheckAllButton frame]; 68 NSRect uncheckAllFrame = [fUncheckAllButton frame]; 69 const CGFloat oldAllWidth = checkAllFrame.size.width; 70 const CGFloat oldNoneWidth = uncheckAllFrame.size.width; 71 72 [fCheckAllButton sizeToFit]; 73 [fUncheckAllButton sizeToFit]; 74 const CGFloat newWidth = MAX([fCheckAllButton bounds].size.width, [fUncheckAllButton bounds].size.width); 75 76 const CGFloat uncheckAllChange = newWidth - oldNoneWidth; 77 uncheckAllFrame.size.width = newWidth; 78 uncheckAllFrame.origin.x -= uncheckAllChange; 79 [fUncheckAllButton setFrame: uncheckAllFrame]; 80 81 const CGFloat checkAllChange = newWidth - oldAllWidth; 82 checkAllFrame.size.width = newWidth; 83 checkAllFrame.origin.x -= (checkAllChange + uncheckAllChange); 84 [fCheckAllButton setFrame: checkAllFrame]; 85} 86 87- (void) dealloc 88{ 89 [fTorrents release]; 90 91 [super dealloc]; 92} 93 94- (void) setInfoForTorrents: (NSArray *) torrents 95{ 96 //don't check if it's the same in case the metadata changed 97 [fTorrents release]; 98 fTorrents = [torrents retain]; 99 100 fSet = NO; 101} 102 103- (void) updateInfo 104{ 105 if (!fSet) 106 [self setupInfo]; 107 108 if ([fTorrents count] == 1) 109 { 110 [fFileController refresh]; 111 112 #warning use TorrentFileCheckChange notification as well 113 Torrent * torrent = [fTorrents objectAtIndex: 0]; 114 if ([torrent isFolder]) 115 { 116 const NSInteger filesCheckState = [torrent checkForFiles: [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [torrent fileCount])]]; 117 [fCheckAllButton setEnabled: filesCheckState != NSOnState]; //if anything is unchecked 118 [fUncheckAllButton setEnabled: ![torrent allDownloaded]]; //if there are any checked files that aren't finished 119 } 120 } 121} 122 123- (void) saveViewSize 124{ 125 [[NSUserDefaults standardUserDefaults] setFloat: NSHeight([[self view] frame]) forKey: @"InspectorContentHeightFiles"]; 126} 127 128- (void) setFileFilterText: (id) sender 129{ 130 [fFileController setFilterText: [sender stringValue]]; 131} 132 133- (IBAction) checkAll: (id) sender 134{ 135 [fFileController checkAll]; 136} 137 138- (IBAction) uncheckAll: (id) sender 139{ 140 [fFileController uncheckAll]; 141} 142 143- (NSArray *) quickLookURLs 144{ 145 FileOutlineView * fileOutlineView = [fFileController outlineView]; 146 Torrent * torrent = [fTorrents objectAtIndex: 0]; 147 NSIndexSet * indexes = [fileOutlineView selectedRowIndexes]; 148 NSMutableArray * urlArray = [NSMutableArray arrayWithCapacity: [indexes count]]; 149 150 for (NSUInteger i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i]) 151 { 152 FileListNode * item = [fileOutlineView itemAtRow: i]; 153 if ([self canQuickLookFile: item]) 154 [urlArray addObject: [NSURL fileURLWithPath: [torrent fileLocation: item]]]; 155 } 156 157 return urlArray; 158} 159 160- (BOOL) canQuickLook 161{ 162 if ([fTorrents count] != 1) 163 return NO; 164 165 Torrent * torrent = [fTorrents objectAtIndex: 0]; 166 if (![torrent isFolder]) 167 return NO; 168 169 FileOutlineView * fileOutlineView = [fFileController outlineView]; 170 NSIndexSet * indexes = [fileOutlineView selectedRowIndexes]; 171 172 for (NSUInteger i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i]) 173 if ([self canQuickLookFile: [fileOutlineView itemAtRow: i]]) 174 return YES; 175 176 return NO; 177} 178 179- (NSRect) quickLookSourceFrameForPreviewItem: (id <QLPreviewItem>) item 180{ 181 FileOutlineView * fileOutlineView = [fFileController outlineView]; 182 183 NSString * fullPath = [(NSURL *)item path]; 184 Torrent * torrent = [fTorrents objectAtIndex: 0]; 185 NSRange visibleRows = [fileOutlineView rowsInRect: [fileOutlineView bounds]]; 186 187 for (NSUInteger row = visibleRows.location; row < NSMaxRange(visibleRows); row++) 188 { 189 FileListNode * rowItem = [fileOutlineView itemAtRow: row]; 190 if ([[torrent fileLocation: rowItem] isEqualToString: fullPath]) 191 { 192 NSRect frame = [fileOutlineView iconRectForRow: row]; 193 194 if (!NSIntersectsRect([fileOutlineView visibleRect], frame)) 195 return NSZeroRect; 196 197 frame.origin = [fileOutlineView convertPoint: frame.origin toView: nil]; 198 frame.origin = [[[self view] window] convertBaseToScreen: frame.origin]; 199 frame.origin.y -= frame.size.height; 200 return frame; 201 } 202 } 203 204 return NSZeroRect; 205} 206 207@end 208 209@implementation InfoFileViewController (Private) 210 211- (void) setupInfo 212{ 213 [fFileFilterField setStringValue: @""]; 214 215 if ([fTorrents count] == 1) 216 { 217 Torrent * torrent = [fTorrents objectAtIndex: 0]; 218 219 [fFileController setTorrent: torrent]; 220 221 const BOOL isFolder = [torrent isFolder]; 222 [fFileFilterField setEnabled: isFolder]; 223 224 if (!isFolder) 225 { 226 [fCheckAllButton setEnabled: NO]; 227 [fUncheckAllButton setEnabled: NO]; 228 } 229 } 230 else 231 { 232 [fFileController setTorrent: nil]; 233 234 [fFileFilterField setEnabled: NO]; 235 236 [fCheckAllButton setEnabled: NO]; 237 [fUncheckAllButton setEnabled: NO]; 238 } 239 240 fSet = YES; 241} 242 243- (BOOL) canQuickLookFile: (FileListNode *) item 244{ 245 Torrent * torrent = [fTorrents objectAtIndex: 0]; 246 return ([item isFolder] || [torrent fileProgress: item] >= 1.0) && [torrent fileLocation: item]; 247} 248 249@end 250