mirror of
https://github.com/transmission/transmission
synced 2024-12-30 19:46:56 +00:00
b8c01a581e
* Replace Deprecated constants pt.1 - `NSOnState` -> `NSControlStateValueOn` - `NSOffState` -> `NSControlStateValueOff` - `MSMixedState` -> `NSControlStateValueMixed` * Replace Deprecated constants pt.2 - `NS(\w+)AlertStyle` -> `NSAlertStyle$1` * Replace Deprecated constants pt.3 - `NSFileHandlingPanel(\w+)Button` -> `NSModalResponse$1` * Replace Deprecated constants pt.4 - `NSMouse(Entered|Exited)Mask` -> `NSEventMaskMouse$1` - `NS(Left|Right)Mouse(Down|Up|Dragged)Mask` -> `NSEventMask$1Mouse$2` - `NSMouse(Entered|Exited)` -> `NSEventTypeMouse$1` - `NS(Left|Right)Mouse(Up|Down)` -> `NSEventType$1Mouse$2` * Replace Deprecated constants pt.5 - `NSComposite(\w+)` -> `NSCompositingOperation$1` * Replace Deprecated constants pt.6 - `NSAlternateKeyMask` -> `NSEventModifierFlagOption` - `NSCommandKeyMask` -> `NSEventModifierFlagCommand` * Replace Deprecated constants pt.7 - `NS(\w+)TextAlignment` -> `NSTextAlignment$1` - `NSBackgroundStyleDark` -> `NSBackgroundStyleEmphasized` * Replace Deprecated constants pt.8 - `NSTexturedRoundedBezelStyle` -> `NSBezelStyleTexturedRounded` - `NSBorderlessWindowMask` -> `NSWindowStyleMaskBorderless` - `NS(OK|Cancel)Button` -> `NSModalResponse$1`
254 lines
7.3 KiB
Text
254 lines
7.3 KiB
Text
/******************************************************************************
|
|
* Copyright (c) 2010-2012 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 "InfoFileViewController.h"
|
|
#import "FileListNode.h"
|
|
#import "FileOutlineController.h"
|
|
#import "FileOutlineView.h"
|
|
#import "Torrent.h"
|
|
|
|
@interface InfoFileViewController (Private)
|
|
|
|
- (void)setupInfo;
|
|
|
|
- (BOOL)canQuickLookFile:(FileListNode*)item;
|
|
|
|
@end
|
|
|
|
@implementation InfoFileViewController
|
|
|
|
- (instancetype)init
|
|
{
|
|
if ((self = [super initWithNibName:@"InfoFileView" bundle:nil]))
|
|
{
|
|
self.title = NSLocalizedString(@"Files", "Inspector view -> title");
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)awakeFromNib
|
|
{
|
|
CGFloat const height = [NSUserDefaults.standardUserDefaults floatForKey:@"InspectorContentHeightFiles"];
|
|
if (height != 0.0)
|
|
{
|
|
NSRect viewRect = self.view.frame;
|
|
viewRect.size.height = height;
|
|
self.view.frame = viewRect;
|
|
}
|
|
|
|
[fFileFilterField.cell setPlaceholderString:NSLocalizedString(@"Filter", "inspector -> file filter")];
|
|
|
|
//localize and place all and none buttons
|
|
fCheckAllButton.title = NSLocalizedString(@"All", "inspector -> check all");
|
|
fUncheckAllButton.title = NSLocalizedString(@"None", "inspector -> check all");
|
|
|
|
NSRect checkAllFrame = fCheckAllButton.frame;
|
|
NSRect uncheckAllFrame = fUncheckAllButton.frame;
|
|
CGFloat const oldAllWidth = checkAllFrame.size.width;
|
|
CGFloat const oldNoneWidth = uncheckAllFrame.size.width;
|
|
|
|
[fCheckAllButton sizeToFit];
|
|
[fUncheckAllButton sizeToFit];
|
|
CGFloat const newWidth = MAX(fCheckAllButton.bounds.size.width, fUncheckAllButton.bounds.size.width);
|
|
|
|
CGFloat const uncheckAllChange = newWidth - oldNoneWidth;
|
|
uncheckAllFrame.size.width = newWidth;
|
|
uncheckAllFrame.origin.x -= uncheckAllChange;
|
|
fUncheckAllButton.frame = uncheckAllFrame;
|
|
|
|
CGFloat const checkAllChange = newWidth - oldAllWidth;
|
|
checkAllFrame.size.width = newWidth;
|
|
checkAllFrame.origin.x -= (checkAllChange + uncheckAllChange);
|
|
fCheckAllButton.frame = checkAllFrame;
|
|
}
|
|
|
|
- (void)setInfoForTorrents:(NSArray*)torrents
|
|
{
|
|
//don't check if it's the same in case the metadata changed
|
|
fTorrents = torrents;
|
|
|
|
fSet = NO;
|
|
}
|
|
|
|
- (void)updateInfo
|
|
{
|
|
if (!fSet)
|
|
{
|
|
[self setupInfo];
|
|
}
|
|
|
|
if (fTorrents.count == 1)
|
|
{
|
|
[fFileController refresh];
|
|
|
|
#warning use TorrentFileCheckChange notification as well
|
|
Torrent* torrent = fTorrents[0];
|
|
if (torrent.folder)
|
|
{
|
|
NSInteger const filesCheckState = [torrent
|
|
checkForFiles:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, torrent.fileCount)]];
|
|
fCheckAllButton.enabled = filesCheckState != NSControlStateValueOn; //if anything is unchecked
|
|
fUncheckAllButton.enabled = !torrent.allDownloaded; //if there are any checked files that aren't finished
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)saveViewSize
|
|
{
|
|
[NSUserDefaults.standardUserDefaults setFloat:NSHeight(self.view.frame) forKey:@"InspectorContentHeightFiles"];
|
|
}
|
|
|
|
- (void)setFileFilterText:(id)sender
|
|
{
|
|
[fFileController setFilterText:[sender stringValue]];
|
|
}
|
|
|
|
- (IBAction)checkAll:(id)sender
|
|
{
|
|
[fFileController checkAll];
|
|
}
|
|
|
|
- (IBAction)uncheckAll:(id)sender
|
|
{
|
|
[fFileController uncheckAll];
|
|
}
|
|
|
|
- (NSArray*)quickLookURLs
|
|
{
|
|
FileOutlineView* fileOutlineView = fFileController.outlineView;
|
|
Torrent* torrent = fTorrents[0];
|
|
NSIndexSet* indexes = fileOutlineView.selectedRowIndexes;
|
|
NSMutableArray* urlArray = [NSMutableArray arrayWithCapacity:indexes.count];
|
|
|
|
for (NSUInteger i = indexes.firstIndex; i != NSNotFound; i = [indexes indexGreaterThanIndex:i])
|
|
{
|
|
FileListNode* item = [fileOutlineView itemAtRow:i];
|
|
if ([self canQuickLookFile:item])
|
|
{
|
|
[urlArray addObject:[NSURL fileURLWithPath:[torrent fileLocation:item]]];
|
|
}
|
|
}
|
|
|
|
return urlArray;
|
|
}
|
|
|
|
- (BOOL)canQuickLook
|
|
{
|
|
if (fTorrents.count != 1)
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
Torrent* torrent = fTorrents[0];
|
|
if (!torrent.folder)
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
FileOutlineView* fileOutlineView = fFileController.outlineView;
|
|
NSIndexSet* indexes = fileOutlineView.selectedRowIndexes;
|
|
|
|
for (NSUInteger i = indexes.firstIndex; i != NSNotFound; i = [indexes indexGreaterThanIndex:i])
|
|
{
|
|
if ([self canQuickLookFile:[fileOutlineView itemAtRow:i]])
|
|
{
|
|
return YES;
|
|
}
|
|
}
|
|
|
|
return NO;
|
|
}
|
|
|
|
- (NSRect)quickLookSourceFrameForPreviewItem:(id<QLPreviewItem>)item
|
|
{
|
|
FileOutlineView* fileOutlineView = fFileController.outlineView;
|
|
|
|
NSString* fullPath = ((NSURL*)item).path;
|
|
Torrent* torrent = fTorrents[0];
|
|
NSRange visibleRows = [fileOutlineView rowsInRect:fileOutlineView.bounds];
|
|
|
|
for (NSUInteger row = visibleRows.location; row < NSMaxRange(visibleRows); row++)
|
|
{
|
|
FileListNode* rowItem = [fileOutlineView itemAtRow:row];
|
|
if ([[torrent fileLocation:rowItem] isEqualToString:fullPath])
|
|
{
|
|
NSRect frame = [fileOutlineView iconRectForRow:row];
|
|
|
|
if (!NSIntersectsRect(fileOutlineView.visibleRect, frame))
|
|
{
|
|
return NSZeroRect;
|
|
}
|
|
|
|
frame.origin = [fileOutlineView convertPoint:frame.origin toView:nil];
|
|
frame = [self.view.window convertRectToScreen:frame];
|
|
frame.origin.y -= frame.size.height;
|
|
return frame;
|
|
}
|
|
}
|
|
|
|
return NSZeroRect;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation InfoFileViewController (Private)
|
|
|
|
- (void)setupInfo
|
|
{
|
|
fFileFilterField.stringValue = @"";
|
|
|
|
if (fTorrents.count == 1)
|
|
{
|
|
Torrent* torrent = fTorrents[0];
|
|
|
|
[fFileController setTorrent:torrent];
|
|
|
|
BOOL const isFolder = torrent.folder;
|
|
fFileFilterField.enabled = isFolder;
|
|
|
|
if (!isFolder)
|
|
{
|
|
fCheckAllButton.enabled = NO;
|
|
fUncheckAllButton.enabled = NO;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
[fFileController setTorrent:nil];
|
|
|
|
fFileFilterField.enabled = NO;
|
|
|
|
fCheckAllButton.enabled = NO;
|
|
fUncheckAllButton.enabled = NO;
|
|
}
|
|
|
|
fSet = YES;
|
|
}
|
|
|
|
- (BOOL)canQuickLookFile:(FileListNode*)item
|
|
{
|
|
Torrent* torrent = fTorrents[0];
|
|
return (item.isFolder || [torrent fileProgress:item] >= 1.0) && [torrent fileLocation:item];
|
|
}
|
|
|
|
@end
|