1/****************************************************************************** 2 * Copyright (c) 2007-2012 Transmission authors and contributors 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 *****************************************************************************/ 22 23#import "DragOverlayWindow.h" 24#import "DragOverlayView.h" 25#import "NSStringAdditions.h" 26 27@interface DragOverlayWindow (Private) 28 29- (void) resizeWindow; 30 31@end 32 33@implementation DragOverlayWindow 34 35- (id) initWithLib: (tr_session *) lib forWindow: (NSWindow *) window 36{ 37 if ((self = ([super initWithContentRect: [window frame] styleMask: NSBorderlessWindowMask 38 backing: NSBackingStoreBuffered defer: NO]))) 39 { 40 fLib = lib; 41 42 [self setBackgroundColor: [NSColor colorWithCalibratedWhite: 0.0 alpha: 0.5]]; 43 [self setAlphaValue: 0.0]; 44 [self setOpaque: NO]; 45 [self setHasShadow: NO]; 46 47 DragOverlayView * view = [[DragOverlayView alloc] initWithFrame: [self frame]]; 48 [self setContentView: view]; 49 50 [self setReleasedWhenClosed: NO]; 51 [self setIgnoresMouseEvents: YES]; 52 53 fFadeInAnimation = [[NSViewAnimation alloc] initWithViewAnimations: @[ 54 @{NSViewAnimationTargetKey: self, 55 NSViewAnimationEffectKey: NSViewAnimationFadeInEffect} 56 ]]; 57 [fFadeInAnimation setDuration: 0.15]; 58 [fFadeInAnimation setAnimationBlockingMode: NSAnimationNonblockingThreaded]; 59 60 fFadeOutAnimation = [[NSViewAnimation alloc] initWithViewAnimations: @[ 61 @{NSViewAnimationTargetKey: self, 62 NSViewAnimationEffectKey: NSViewAnimationFadeOutEffect} 63 ]]; 64 [fFadeOutAnimation setDuration: 0.5]; 65 [fFadeOutAnimation setAnimationBlockingMode: NSAnimationNonblockingThreaded]; 66 67 [window addChildWindow: self ordered: NSWindowAbove]; 68 69 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resizeWindow) 70 name: NSWindowDidResizeNotification object: window]; 71 } 72 return self; 73} 74 75- (void) dealloc 76{ 77 [[NSNotificationCenter defaultCenter] removeObserver: self]; 78} 79 80- (void) setTorrents: (NSArray *) files 81{ 82 uint64_t size = 0; 83 NSInteger count = 0; 84 85 NSString * name; 86 BOOL folder; 87 NSInteger fileCount = 0; 88 89 for (NSString * file in files) 90 { 91 if ([[[NSWorkspace sharedWorkspace] typeOfFile: file error: NULL] isEqualToString: @"org.bittorrent.torrent"] 92 || [[file pathExtension] caseInsensitiveCompare: @"torrent"] == NSOrderedSame) 93 { 94 tr_ctor * ctor = tr_ctorNew(fLib); 95 tr_ctorSetMetainfoFromFile(ctor, [file UTF8String]); 96 tr_info info; 97 if (tr_torrentParse(ctor, &info) == TR_PARSE_OK) 98 { 99 count++; 100 size += info.totalSize; 101 fileCount += info.fileCount; 102 103 //only useful when one torrent 104 if (count == 1) 105 { 106 name = @(info.name); 107 folder = info.isFolder; 108 } 109 } 110 tr_metainfoFree(&info); 111 tr_ctorFree(ctor); 112 } 113 } 114 115 if (count <= 0) 116 return; 117 118 //set strings and icon 119 NSString * secondString = [NSString stringForFileSize: size]; 120 if (count > 1 || folder) 121 { 122 NSString * fileString; 123 if (fileCount == 1) 124 fileString = NSLocalizedString(@"1 file", "Drag overlay -> torrents"); 125 else 126 fileString= [NSString stringWithFormat: NSLocalizedString(@"%@ files", "Drag overlay -> torrents"), 127 [NSString formattedUInteger: fileCount]]; 128 secondString = [NSString stringWithFormat: @"%@, %@", fileString, secondString]; 129 } 130 131 NSImage * icon; 132 if (count == 1) 133 icon = [[NSWorkspace sharedWorkspace] iconForFileType: folder ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [name pathExtension]]; 134 else 135 { 136 name = [NSString stringWithFormat: NSLocalizedString(@"%@ Torrent Files", "Drag overlay -> torrents"), 137 [NSString formattedUInteger: count]]; 138 secondString = [secondString stringByAppendingString: @" total"]; 139 icon = [NSImage imageNamed: @"TransmissionDocument.icns"]; 140 } 141 142 [[self contentView] setOverlay: icon mainLine: name subLine: secondString]; 143 [self fadeIn]; 144} 145 146- (void) setFile: (NSString *) file 147{ 148 [[self contentView] setOverlay: [NSImage imageNamed: @"CreateLarge"] 149 mainLine: NSLocalizedString(@"Create a Torrent File", "Drag overlay -> file") subLine: file]; 150 [self fadeIn]; 151} 152 153- (void) setURL: (NSString *) url 154{ 155 [[self contentView] setOverlay: [NSImage imageNamed: @"Globe"] 156 mainLine: NSLocalizedString(@"Web Address", "Drag overlay -> url") subLine: url]; 157 [self fadeIn]; 158} 159 160- (void) fadeIn 161{ 162 //stop other animation and set to same progress 163 if ([fFadeOutAnimation isAnimating]) 164 { 165 [fFadeOutAnimation stopAnimation]; 166 [fFadeInAnimation setCurrentProgress: 1.0 - [fFadeOutAnimation currentProgress]]; 167 } 168 [fFadeInAnimation startAnimation]; 169} 170 171- (void) fadeOut 172{ 173 //stop other animation and set to same progress 174 if ([fFadeInAnimation isAnimating]) 175 { 176 [fFadeInAnimation stopAnimation]; 177 [fFadeOutAnimation setCurrentProgress: 1.0 - [fFadeInAnimation currentProgress]]; 178 } 179 if ([self alphaValue] > 0.0) 180 [fFadeOutAnimation startAnimation]; 181} 182 183@end 184 185@implementation DragOverlayWindow (Private) 186 187- (void) resizeWindow 188{ 189 [self setFrame: [[self parentWindow] frame] display: NO]; 190} 191 192@end 193