1 // MacTF Copyright 2004 Nathan Oates
5 * This source code is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Public License as published
7 * by the Free Software Foundation; either version 2 of the License,
8 * or (at your option) any later version.
10 * This source code is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * Please refer to the GNU Public License for more details.
15 * You should have received a copy of the GNU Public License along with
16 * this source code; if not, write to:
17 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* This file was modified by Kalle Olavi Niemitalo on 2007-10-18. */
22 #import "UIElements.h"
25 @interface UIElements (PrivateMethods)
26 - (void) setCurrentPath:(NSString*)path;
29 @implementation UIElements
31 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:
32 (NSApplication *)theApplication {
36 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)path
40 [self uploadPath:path toPath:[NSString stringWithString:currentPath]];
41 NSLog(@"DockUpload:%@", path);
45 -(void) awakeFromNib {
48 highlightImageData = @"<4d4d002a 00000048 800f4f6d a2ca65ca 564b390a 69371941 1ee22622 dc04743b 7c86826e 900fcdb1 d9e5b237 3ab60647 06b0b8d8 d5151a1a 82732348 46616888 4bcd00f9 719f0100 000d0100 00030000 00010001 00000101 00030000 00010012 00000102 00030000 00030000 00ea0103 00030000 00010005 00000106 00030000 00010002 00000111 00040000 00010000 00080115 00030000 00010003 00000116 00040000 00010000 2aaa0117 00040000 00010000 003f011a 00050000 00010000 00f0011b 00050000 00010000 00f8011c 00030000 00010001 00000128 00030000 00010002 00000000 00000008 00080008 000afc80 00002710 000afc80 00002710 >";
49 [self setCurrentPath:@"\\"];
50 [currentlyField setStringValue:NSLocalizedString(@"IDLE", @"Idle")];
51 [currentlyField displayIfNeeded];
52 [tableView setDoubleAction: @selector(doubleClick:)];
53 [tableView setTarget: self];
54 [tableView registerForDraggedTypes: [NSArray arrayWithObjects: @"NSFilenamesPboardType", @"NSFilenamesPboardType", nil]];
55 tfusbc = [[TFUSBController alloc] init];
56 [tfusbc setDH:dh tableView:tableView]; //send needed items to tfusbc
59 [turboCB setEnabled:NO];
60 [versionField setStringValue:[[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleVersion"]];
61 [pathBar setEnabled:YES];
62 [[pathBar cell] setSegmentCount:1];
63 [[pathBar cell] setLabel:@"Path:" forSegment:0];
64 [[pathBar cell] setWidth:0 forSegment:0];
66 [[dh fileList] addObject:[NSDictionary dictionaryWithObject:NSLocalizedString(@"NOT_CONNECTED_ENTRY", @"Not connected") forKey:@"name"]];
67 [tableView reloadData];
68 prefs = [[NSUserDefaults standardUserDefaults] retain];
69 if ([prefs boolForKey:@"auto-connect"]) {
75 - (BOOL)validateMenuItem:(NSMenuItem*)anItem {
76 if ([[anItem title] isEqualToString:NSLocalizedString(@"DL_MENUITEM", @"Download")] && (1 > [tableView numberOfSelectedRows])) {
79 if ([[anItem title] isEqualToString:NSLocalizedString(@"DEL_MENUITEM", @"Delete")] && (1 > [tableView numberOfSelectedRows])) {
82 if ([[anItem title] isEqualToString:NSLocalizedString(@"RN_MENUITEM", @"Rename")] && (1 != [tableView numberOfSelectedRows])) {
85 if ([[anItem title] isEqualToString:NSLocalizedString(@"UL_MENUITEM", @"Upload")] && (! connected)) {
88 if ([[anItem title] isEqualToString:NSLocalizedString(@"NF_MENUITEM", @"NewFolder")] && (! connected)) {
94 - (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem {
95 if ([[toolbarItem itemIdentifier] isEqual:@"ConnectTBIcon"]) {
97 [toolbarItem setLabel:NSLocalizedString(@"DC_BUTTON", @"Disconnect")];
99 [toolbarItem setLabel:NSLocalizedString(@"CON_BUTTON", @"Connect")];
102 if ([[toolbarItem itemIdentifier] isEqual:@"UploadTBIcon"] && (! connected)) {
105 if ([[toolbarItem itemIdentifier] isEqual:@"NewFolderTBIcon"] && (! connected)) {
108 if ([[toolbarItem itemIdentifier] isEqual:@"TurboTBIcon"] && (! connected)) {
111 if ([[toolbarItem itemIdentifier] isEqual:@"DownloadTBIcon"] && (1 > [tableView numberOfSelectedRows] || !connected)) {
114 if ([[toolbarItem itemIdentifier] isEqual:@"DeleteTBIcon"] && (1 > [tableView numberOfSelectedRows] || !connected)) {
117 if ([[toolbarItem itemIdentifier] isEqual:@"RenameTBIcon"] && (1 != [tableView numberOfSelectedRows] || !connected)) {
124 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
126 [preview setString:@""];
127 if ([previewDrawer state] == NSDrawerClosedState) return; // don't bother getting previews if closed
128 if ([tableView numberOfSelectedRows] != 1 || !connected)
130 if ([tfusbc hasCurrentTransfer]) return; //for now, change to a priority transfer later?
131 id currentSelectedItem = [[dh displayedList] objectAtIndex:[tableView selectedRow]];
132 int type = [[currentSelectedItem objectForKey:@"type"] intValue];
133 if (type == 2) { //file
134 NSString* nameOnToppy = [currentSelectedItem objectForKey:@"name"];
135 if (([nameOnToppy hasSuffix:@".ini"] || [nameOnToppy hasSuffix:@".txt"] || [nameOnToppy hasSuffix:@".tgd"] || [nameOnToppy hasSuffix:@".tsv"] || [nameOnToppy hasSuffix:@".dat"] || [nameOnToppy hasSuffix:@".tap"])) {
136 [drawerTabView selectTabViewItemAtIndex:0];
137 NSString* tempFile = NSTemporaryDirectory(); // download preview to temp folder
138 tempFile = [tempFile stringByAppendingPathComponent:@"MacTFTemp"];
139 [tfusbc addTransfer:[NSDictionary dictionaryWithObjectsAndKeys:currentSelectedItem,@"filename",currentPath,@"path",tempFile,@"savePath",[NSNumber numberWithUnsignedLongLong:0],@"offset",@"download",@"transferType",[NSNumber numberWithBool:NO],@"looping",[NSNumber numberWithInt:0],@"existingTime",nil] atIndex:-1];
140 while ([tfusbc hasCurrentTransfer]) {
143 [preview setString:[NSString stringWithContentsOfFile:tempFile]];
144 } else if ([nameOnToppy hasSuffix:@".rec"]) { //display headers
145 [drawerTabView selectTabViewItemAtIndex:1];
146 NSString* tempFile = NSTemporaryDirectory(); // download first 64k to temp folder
147 tempFile = [tempFile stringByAppendingPathComponent:@"MacTFTemp"];
148 [tfusbc addTransfer:[NSDictionary dictionaryWithObjectsAndKeys:currentSelectedItem,@"filename",currentPath,@"path",tempFile,@"savePath",[NSNumber numberWithUnsignedLongLong:0],@"offset",@"download",@"transferType",[NSNumber numberWithBool:NO],@"looping",[NSNumber numberWithInt:0],@"existingTime",nil] atIndex:-1];
149 while ([tfusbc hasCurrentTransfer]) {
152 NSDictionary* recData = [dh extractDataFromRecHeader:tempFile forModel:[prefs objectForKey:@"modelType"]]; //then parse and display headers
153 [recStart setObjectValue:[recData objectForKey:@"startTime"]];
154 [recDuration setObjectValue:[recData objectForKey:@"duration"]];
155 [recDescription setStringValue:[recData objectForKey:@"description"]];
156 [recName setStringValue:[recData objectForKey:@"name"]];
157 [recExtInfo setStringValue:[recData objectForKey:@"extInfo"]];
158 [recChannel setStringValue:[recData objectForKey:@"channel"]];
161 [drawerTabView selectTabViewItemAtIndex:0];
164 } else if (type == 1) { //folder
165 [drawerTabView selectTabViewItemAtIndex:0];
168 [statusField setStringValue:NSLocalizedString(@"SEL_ERROR", @"Selection error...")];
173 - (void) setAvailableSpace:(NSData*)input {
174 [availSpaceField setStringValue:[self prepForSizeDisplay:input]];
177 - (void) setFreeSpace:(NSData*) input {
178 [freeSpaceField setStringValue:[self prepForSizeDisplay:input]];
181 - (NSString*) prepForSizeDisplay:(NSData*) input {
182 UInt32 size_bigendian;
183 [input getBytes:&size_bigendian];
184 unsigned size = EndianU32_BtoN(size_bigendian);
186 if( size == 0. ) ret = NSLocalizedString( @" - ", "no file size" );
187 else if( size > 0. && size < 1024. ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.0f KB", "file size measured in kilobytes" ), size];
188 else if( size >= 1024. && size < pow( 1024., 2. ) ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.1f MB", "file size measured in megabytes" ), ( size / 1024. )];
189 else if( size >= pow( 1024., 2. ) && size < pow( 1024., 3. ) ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.2f GB", "file size measured in gigabytes" ), ( size / pow( 1024., 2. ) )];
190 else if( size >= pow( 1024., 3. ) && size < pow( 1024., 4. ) ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.3f TB", "file size measured in terabytes" ), ( size / pow( 1024., 3. ) )];
191 else if( size >= pow( 1024., 4. ) ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.4f PB", "file size measured in pentabytes" ), ( size / pow( 1024., 4. ) )];
195 - (IBAction) connect: (id) sender {
197 context = [tfusbc initializeUSB];
198 if (context == nil) {
199 [statusField setStringValue:NSLocalizedString(@"INIT_PROBLEM", @"Message when initialization fails.")];
202 // add a check here to see if really connected...
204 [[dh fileList] removeAllObjects];
205 [[dh fileList] addObject:[NSDictionary dictionaryWithObject:NSLocalizedString(@"FETCHING", @"Fetching") forKey:@"name"]];
206 [tableView reloadData];
207 [tfusbc clearQueues];
209 [turboCB setState:0];
210 [turboCB setEnabled:YES];
211 [[pathBar cell] setSegmentCount:2];
212 [[pathBar cell] setLabel:@"Path:" forSegment:0];
213 [[pathBar cell] setLabel:@"\\" forSegment:1];
214 [[pathBar cell] setWidth:0 forSegment:0];
215 [[pathBar cell] setWidth:0 forSegment:1];
217 [pathBar setHidden:NO];
218 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
219 [connectButton setTitle:NSLocalizedString(@"DC_BUTTON", @"Disconnect.")];
220 [statusField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"CONNECTED_MESSAGE", @"Message giving connection speed."), [tfusbc getSpeed]]];
221 [NSThread detachNewThreadSelector:@selector(transfer:) toTarget:tfusbc withObject:nil];
222 } else { // already connected
224 if ([tfusbc hasCurrentTransfer]) { //gives a few seconds for busy thread to notice it should not be connected before cutting the device off
227 [tfusbc closeDevice:context];
228 [connectButton setTitle:NSLocalizedString(@"CON_BUTTON", @"Connect.")];
229 [statusField setStringValue:NSLocalizedString(@"NO_CONNECT", @"No connection.")];
230 [[dh fileList] removeAllObjects];
231 [tableView reloadData];
232 [turboCB setState:0];
233 [turboCB setEnabled:NO];
234 [connectLight setImage:[NSImage imageNamed:@"red.tiff"]];
235 [self setCurrentPath:@"\\"];
238 int ret = [self goToPath:@"\\"];
240 sleep (5); //error, wait a few secs for HDD to start if need be then try again
241 [self goToPath:@"\\"];
243 [self setCurrentPath:@"\\"];
246 - (int) goToPath:(NSString*) path {
247 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:path,@"path",@"fileList",@"transferType",nil]];
248 // FIXME: The caller would like to know whether the operation succeeded.
249 // But it has not even finished yet. So goToPath should somehow notify
250 // the caller on completion.
254 - (void)doubleClick:(id)sender
256 if ([tableView numberOfSelectedRows] != 1)
258 id currentSelectedItem = [[dh displayedList] objectAtIndex:[tableView selectedRow]];
259 int type = [[currentSelectedItem objectForKey:@"type"] intValue];
260 if (type == 2) { //file
261 [self downloadFileDoubleClickThread:nil];
262 } else if (type == 1) { //folder
263 NSString* currentName = [currentSelectedItem objectForKey:@"name"];
264 if ([currentName isEqualToString:@".. (Parent folder)"]) { // move up
265 NSMutableArray* array = [NSMutableArray arrayWithArray:[currentPath componentsSeparatedByString:@"\\"]];
266 if ([array count] > 1){ // not going to root
267 [array removeLastObject];
268 NSString* temp = [NSString stringWithString:[array componentsJoinedByString:@"\\"]];
269 if ([self goToPath:temp]) {// if error
270 [self goToPath:temp]; // hackish workaround
272 int segCount = [pathBar segmentCount]; //remember count starts at 1, not zero!
273 NSRect r = [pathBar frame];
274 [[pathBar cell] setSegmentCount:segCount-1];
275 [pathBar setNeedsDisplayInRect:r];
276 [pathBar displayIfNeeded];
277 [self setCurrentPath:temp];
278 [statusField setStringValue:NSLocalizedString(@"CONNECTED_OK", @"Connection OK")];
280 [self setCurrentPath:@"\\"];
281 [[pathBar cell] setSegmentCount:1];
284 NSMutableString* temp = [NSMutableString stringWithString:currentPath];
285 if (![temp isEqualToString:@"\\"])
286 [temp appendString:@"\\"];
287 [temp appendString:currentName];
288 if ([self goToPath:temp]) { // if error, try again
289 [self goToPath:temp]; // hackish workaround
291 [self setCurrentPath:temp];
292 int segCount = [pathBar segmentCount]; //remember count starts at 1, not zero!
293 NSRect r = [pathBar frame];
294 [[pathBar cell] setSegmentCount:segCount+1];
295 [[pathBar cell] setLabel:currentName forSegment:segCount];
296 [[pathBar cell] setWidth:0 forSegment:segCount];
298 [pathBar displayIfNeededInRect:r];
299 [statusField setStringValue:NSLocalizedString(@"CONNECTED_OK", @"Connection OK")];
302 [statusField setStringValue:NSLocalizedString(@"SEL_ERROR", @"Selection error...")];
307 - (void) downloadFileDoubleClickThread:(NSDictionary*)fileInfo {
308 if (! connected) return;
309 [self downloadSelectedFile:nil];
310 // [self updateHDDSize];
313 /*- (void) updateHDDSize {
314 if (! connected) return;
315 NSData* hddSizeString = [tfusbc getHDDSize:context];
316 if (hddSizeString != nil) {
317 [self setAvailableSpace:[hddSizeString subdataWithRange:(NSRange) {8,4}]];
318 [self setFreeSpace:[hddSizeString subdataWithRange:(NSRange) {12,4}]];
322 - (void)tableView:(NSTableView *)tView didClickTableColumn:(NSTableColumn *)tableColumn
324 // Either reverse the sort or change the sorting column
325 NSString* columnIdentifier = [tableColumn identifier];
326 BOOL newSortAscending = !(sortAscending && [tableColumn isEqualTo:selectedColumn]);
328 NSString* sortKey = nil;
329 SEL sortSelector = @selector(compare:);
330 if ([columnIdentifier isEqualToString:@"name"]) {
332 sortSelector = @selector(caseInsensitiveCompare:);
333 } else if ([columnIdentifier isEqualToString:@"date"]) {
334 sortKey = @"sortdate";
335 } else if ([columnIdentifier isEqualToString:@"size"]) {
336 sortKey = @"fileSize";
337 } else if ([columnIdentifier isEqualToString:@"icon"]) {
343 NSSortDescriptor* descriptor = [[[NSSortDescriptor alloc]
344 initWithKey:sortKey ascending:newSortAscending selector:sortSelector]
346 NSArray* sortedArray = [[dh fileList] sortedArrayUsingDescriptors:
347 [NSArray arrayWithObject:descriptor]];
348 NSImage* indicatorImage = [NSImage imageNamed:
349 newSortAscending ? @"NSAscendingSortIndicator" : @"NSDescendingSortIndicator"];
351 sortAscending = newSortAscending;
352 selectedColumn = tableColumn;
353 [tView setIndicatorImage: indicatorImage inTableColumn: tableColumn];
354 // remove other indicators
355 NSMutableArray* otherColumns = [NSMutableArray arrayWithArray:[tView tableColumns]];
356 [otherColumns removeObject:tableColumn];
357 NSEnumerator* cols = [otherColumns objectEnumerator];
359 while (currentCol = [cols nextObject]) {
360 [tView setIndicatorImage: nil inTableColumn: currentCol];
362 [dh setFileList:sortedArray];
363 [dh search:searchField];
368 - (IBAction) downloadSelectedFile:(id)sender{
371 NSLog(@"Download file starting...");
372 NSEnumerator* selected = [tableView selectedRowEnumerator];
374 while (currentSelected = [selected nextObject]) {
375 id currentSelectedItem = [[dh displayedList] objectAtIndex:[currentSelected intValue]];
376 int type = [[currentSelectedItem objectForKey:@"type"] intValue];
377 if (type == 1) {[statusField setStringValue:NSLocalizedString(@"NO_FOLDER_DL", @"Folder download not supported yet")];}
378 else if (type == 2) {
379 NSString* nameOnToppy = [currentSelectedItem objectForKey:@"name"];
380 NSSavePanel *nssave = [[NSSavePanel savePanel]retain];
381 int retButton = [nssave runModalForDirectory:nil file:nameOnToppy];
383 NSString* savePath= [nssave filename];
385 unsigned long long offset = 0;
386 NSFileHandle *newFileHandle = [NSFileHandle fileHandleForReadingAtPath:savePath];
387 if (!(newFileHandle==nil)) { // there is a file there, ask if want to resume
388 NSLog(@"existing file length: %qu", [newFileHandle seekToEndOfFile]);
389 //ask to resume, save offset if yes
390 //offset = [newFileHandle seekToEndOfFile];
392 [tfusbc setProgressBar:progressBar time:progressTime turbo:turboCB];
393 [tfusbc addTransfer:[NSDictionary dictionaryWithObjectsAndKeys:currentSelectedItem,@"filename",currentPath,@"path",savePath,@"savePath",[NSNumber numberWithUnsignedLongLong:offset],@"offset",@"download",@"transferType",[NSNumber numberWithBool:YES],@"looping",[NSNumber numberWithInt:0],@"existingTime",nil] atIndex:-1];
397 // [self updateHDDSize];
400 - (void) finishTransfer {
401 [currentlyField setStringValue:@""];
402 [progressBar setDoubleValue:0];
403 [[NSSound soundNamed:@"Ping"] play];
404 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
405 [currentlyField setStringValue:NSLocalizedString(@"IDLE", @"Idle")];
406 [currentlyField display];
409 - (IBAction) uploadFile: (id) sender {
412 NSOpenPanel *nsop = [[NSOpenPanel openPanel]retain];
413 [nsop setAllowsMultipleSelection:YES];
414 [nsop setCanChooseFiles:YES];
415 [nsop setCanChooseDirectories:YES];
416 int retButton = [nsop runModal];
417 NSArray *returnedNames = [nsop filenames];
418 if (retButton == NSFileHandlingPanelCancelButton) {
419 NSLog(@"Upload cancelled");
422 //get info about the chosen file - later if do folders check here and do recursive all things in folder???
423 NSEnumerator *enumerator = [returnedNames objectEnumerator];
425 // [statusField setStringValue:[NSLocalizedString(@"CONNECTED_OK", @"Connection OK") stringByAppendingString:NSLocalizedString(@"DOWNLOAD", @"Download")];
426 [connectLight setImage:[NSImage imageNamed:@"blink.tiff"]];
427 while (returnedName = [enumerator nextObject]) {
429 [self uploadPath:returnedName toPath:[NSString stringWithString:currentPath]];
435 - (void) uploadPath:(NSString*) path toPath:(NSString*) toPath {
438 NSFileManager* fm = [NSFileManager defaultManager];
439 NSDictionary *fattrs = [fm fileAttributesAtPath:path traverseLink:NO];
441 NSLog(@"Path of file to upload is incorrect!");
443 NSString* type = [fattrs fileType];
444 if ([type isEqualToString:@"NSFileTypeDirectory"]) {
445 // should look to create folder on Toppy, or add stuff if already there (maybe it does this automatically?), and place in subfolders etc
446 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[path lastPathComponent],@"newName",toPath,@"path",@"newFolder",@"transferType", nil]];
447 NSArray* subPaths = [fm directoryContentsAtPath:path];
448 NSEnumerator* e = [subPaths objectEnumerator];
450 while (object = [e nextObject]) {
451 NSString* subPath = [NSString stringWithFormat:@"%@/%@", path, object];
452 NSString* subToPath = [NSString stringWithFormat:@"%@\\%@", toPath, [path lastPathComponent]];
453 // NSLog(@"subdir: %@, %@", subPath, subToPath);
454 if (![object isEqualToString:@".DS_Store"]) {
455 [self uploadPath:subPath toPath:subToPath];
458 if (connected) { //may have disconnected during threaded upload (although not actually threaded here!)
459 // [self updateHDDSize];
460 [self goToPath:currentPath];
464 NSDictionary* fileAttr = [dh extractAttributes:fattrs]; // turn Dict into a new TypeFile dict
465 NSMutableArray* array = [NSMutableArray arrayWithArray:[path componentsSeparatedByString:@"/"]]; // cut down name
466 NSString* fileName = [NSString stringWithString:[array lastObject]];
467 NSData* typeFile = [dh getDataFromTFFile:fileAttr withName:fileName];
468 [progressBar setDoubleValue:0];
469 [currentlyField setStringValue:[NSLocalizedString(@"UPLOADING", @"Uploading") stringByAppendingString:fileName]];
470 [currentlyField displayIfNeeded];
471 [tfusbc setProgressBar:progressBar time:progressTime turbo:turboCB];
472 [tfusbc addTransfer:[NSDictionary dictionaryWithObjectsAndKeys:path,@"filename",[NSNumber numberWithUnsignedLongLong:[fattrs fileSize]],@"fileSize",toPath,@"path",typeFile,@"attributes",@"upload",@"transferType",[NSNumber numberWithUnsignedLongLong:0],@"offset",[NSNumber numberWithInt:0],@"existingTime",nil] atIndex:-1];
476 -(IBAction)deleteFile:(id)sender
480 if ( [tableView numberOfSelectedRows] == 0 )
482 NSString *title = NSLocalizedString(@"WARNING", @"Warning!");
483 NSString *defaultButton = NSLocalizedString(@"DEL", @"Delete");
484 NSString *alternateButton = NSLocalizedString(@"NO_DEL", @"Don't Delete");
485 NSString *otherButton = nil;
486 NSString *message = NSLocalizedString(@"DEL_MESSAGE", @"Are you sure you want to delete the selected file(s)?");
489 NSBeginAlertSheet(title, defaultButton, alternateButton, otherButton, mainWindow, self, @selector(sheetDidEnd:returnCode:contextInfo:), nil, nil, message);
492 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
494 if ( returnCode == NSAlertDefaultReturn ) {
495 NSLog(@"Deleting file(s) starting...");
496 NSEnumerator* selected = [tableView selectedRowEnumerator];
498 while (currentSelected = [selected nextObject]) {
499 id currentSelectedItem = [[dh displayedList] objectAtIndex:[currentSelected intValue]];
500 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:currentSelectedItem,@"file",currentPath,@"path",@"delete",@"transferType", nil]];
502 // [self updateHDDSize];
503 [self goToPath:currentPath];
504 //should check so don't delete root folders?
508 - (IBAction)openPrefsSheet:(id)sender
510 [NSApp beginSheet:prefsWindow
511 modalForWindow:mainWindow
513 didEndSelector:@selector(mySheetDidEnd:returnCode:contextInfo:)
515 return; // leave without doing anything else
518 - (IBAction) mySheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode
519 contextInfo:(void *)contextInfo {
521 [sheet orderOut:self];
522 if(returnCode == 0) return;
523 // continue with application
526 - (IBAction)closePrefsSheet:(id)sender
528 //do changes to prefs here
530 [tfusbc setDebug:[debugCB state]];
532 NSLog(@"auto: %i", [autoCB state]);
533 [prefs setBool:[autoCB state] forKey:@"auto-connect"];
534 // [prefs setBool:[epgCB state] forKey:@"epgSync"];
536 [NSApp endSheet:prefsWindow returnCode:1];
539 - (IBAction)openRenameSheet:(id)sender
541 if ( [tableView numberOfSelectedRows] != 1 )
543 [renameOld setStringValue:[[[dh displayedList] objectAtIndex:[tableView selectedRow]] objectForKey:@"name"]];
544 [renameNew setStringValue:[renameOld stringValue]];
545 // [renameWindow setTitleBarHeight:0.0];
546 [NSApp beginSheet: renameWindow
547 modalForWindow: mainWindow
551 [NSApp runModalForWindow: renameWindow];
555 - (IBAction)cancelRename:(id)sender{
556 [NSApp endSheet: renameWindow];
557 [renameWindow orderOut: self];
561 - (IBAction)closeRenameSheet:(id)sender
563 //do changes to rename here
565 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[renameOld stringValue],@"oldName",[renameNew stringValue],@"newName", currentPath,@"path",@"rename",@"transferType",nil]];
566 [self goToPath:currentPath];
569 [self cancelRename:sender];
573 - (IBAction)openNewFolderSheet:(id)sender
575 [NSApp beginSheet: newFolderWindow
576 modalForWindow: mainWindow
580 [NSApp runModalForWindow: newFolderWindow];
585 - (IBAction)cancelNewFolder:(id)sender{
586 [NSApp endSheet: newFolderWindow];
587 [newFolderWindow orderOut: self];
591 - (IBAction)closeNewFolderSheet:(id)sender
593 //do changes to make new folder here
595 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[newFolderNew stringValue],@"newName",currentPath,@"path",@"newFolder",@"transferType", nil]];
596 [self goToPath:currentPath];
599 [self cancelNewFolder:sender];
602 - (IBAction)pathBarClick:(id)sender {
603 int segCount = [pathBar segmentCount]; //remember count starts at 1, not zero!
604 int selectedSegment = [sender selectedSegment];
605 if (selectedSegment == segCount - 1) return; //no need to move anywhere
606 int i = 1; // remember have "path" there too
607 NSMutableArray* pathArray = [NSMutableArray arrayWithCapacity:selectedSegment];
608 while (i<=selectedSegment) {
609 [pathArray addObject:[[pathBar cell] labelForSegment:i]];
612 NSString* pathString = [pathArray componentsJoinedByString:@"\\"];
613 if ([pathString hasPrefix:@"\\\\"]) pathString = [pathString substringFromIndex:1];
614 [self goToPath:pathString];
615 [self setCurrentPath:pathString];
616 NSRect r = [pathBar frame];
617 [[pathBar cell] setSegmentCount:selectedSegment+1];
618 [pathBar displayIfNeededInRect:r];
625 - (USBDeviceContext*) getContext {
629 - (NSNumber*) isConnected {
630 return [NSNumber numberWithBool:connected];
634 - (NSString*) currentPath {
638 - (IBAction) toggleTurbo:(id)sender {
639 if ([tfusbc hasCurrentTransfer]) { //have a current transfer, lets toggle it
640 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"turbo",@"transferType",[NSNumber numberWithBool:[turboCB state]],@"turboOn",nil]];
644 - (IBAction) toggleTurboCB:(id)sender {
647 if ([turboCB state]) { // currently on, want off
648 [turboCB setState:0];
650 [turboCB setState:1];
652 if ([tfusbc hasCurrentTransfer]) { //have a current transfer, lets toggle it
653 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"turbo",@"transferType",[NSNumber numberWithBool:[turboCB state]],@"turboOn",nil]];
657 - (IBAction) togglePreview:(id)sender {
658 [previewDrawer toggle:sender];
661 /*- (IBAction) snapshot:(id) sender {
662 NSArray* snapshotData = [self snapshotOfPath:@"\\"];
663 [dh setSnapShot:snapshotData];
664 // show snapshot window
665 [snapshotWindow makeKeyAndOrderFront:sender];
666 [outlineView reloadData];
669 - (NSArray*) snapshotOfPath:(NSString*)path {
671 NSData* hddFileData = [tfusbc getFileList:context forPath:path];
672 NSData* checkForError = [hddFileData subdataWithRange:(NSRange){4,4}];
673 const UInt32 check_bigendian = EndianU32_NtoB(USB_Fail);
674 const UInt32 check2_bigendian = EndianU32_NtoB(USB_DataHddDir);
675 if ([checkForError isEqualToData:[NSData dataWithBytes:&check_bigendian length:4]]) {
676 [statusField setStringValue:@"Connected - error on last command"];
678 if (! [checkForError isEqualToData:[NSData dataWithBytes:&check2_bigendian length:4]]) {
679 hddFileData = [tfusbc getFileList:context forPath:path]; //try again
680 if ([checkForError isEqualToData:[NSData dataWithBytes:&check_bigendian length:4]]) {
681 [statusField setStringValue:@"Connected - error on last command"];
684 hddFileData = [hddFileData subdataWithRange:(NSRange) {8, [hddFileData length]-8}]; // cut off header and cmd
686 NSMutableArray* paths = [[NSMutableArray alloc] init];
687 for (i=0; i*114 < [hddFileData length]-4; i++) { // 4 is there cause swapping sometimes adds a byte of padding
688 NSData* temp = [hddFileData subdataWithRange:(NSRange) {i*114,114}];
689 NSMutableDictionary* tfFile = [dh newTFFileFromSwappedHexData:temp];
690 [dh convertRawDataToUseful:tfFile];
691 if (!([[tfFile objectForKey:@"name"] isEqualToString:@".."])) {
692 if ([[tfFile objectForKey:@"type"] intValue] == 1) { //folder
693 NSMutableString* temp = [NSMutableString stringWithString:path];
694 if (![temp isEqualToString:@"\\"])
695 [temp appendString:@"\\"];
696 [temp appendString:[tfFile objectForKey:@"name"]];
697 [paths addObject:tfFile];
698 [paths addObject:[self snapshotOfPath:temp]];
700 [paths addObject:tfFile];
710 /*- (IBAction) epg:(id) sender {
711 XMLToEPG *xmlConv = [[XMLToEPG alloc] init];
712 NSOpenPanel *nsop = [[NSOpenPanel openPanel]retain];
713 NSArray *fileType = [NSArray arrayWithObject:@"xml"];
714 [nsop setAllowsMultipleSelection:NO];
715 [nsop setCanChooseFiles:YES];
716 [nsop setCanChooseDirectories:NO];
717 [nsop runModalForTypes:fileType];
718 NSMutableArray* importedXML = [xmlConv importXML:[nsop URL]];
719 [xmlConv fixData:importedXML];
720 [xmlConv exportFixedXML:importedXML toFile:@"/Volumes/Tyr/nathan/Desktop/TV/Guides/test.tgd"];
725 /* if ([prefs boolForKey:@"epgSync"]) {
727 XMLToEPG *xmlConv = [[XMLToEPG alloc] init];
728 NSString* path = @"/Volumes/Tyr/nathan/Desktop/TV/Guides/tv.xml";
729 NSString* tempFile = @"/Volumes/Tyr/nathan/Desktop/TV/Guides/test.epg";
730 NSMutableArray* importedXML = [xmlConv importXML:[NSURL fileURLWithPath:path]];
731 [xmlConv fixData:importedXML];
732 [xmlConv exportFixedXML:importedXML toFile:tempFile];
735 NSFileManager* fm = [NSFileManager defaultManager];
736 NSDictionary *fattrs = [fm fileAttributesAtPath:tempFile traverseLink:NO];
738 NSLog(@"Path of file to upload is incorrect!");
741 NSDictionary* fileAttr = [dh extractAttributes:fattrs];
742 NSMutableArray* array = [NSMutableArray arrayWithArray:[tempFile componentsSeparatedByString:@"/"]];
743 NSString* fileName = [NSString stringWithString:[array lastObject]];
744 NSData* typeFile = [dh getDataFromTFFile:fileAttr withName:fileName];
745 [tfusbc uploadFile:tempFile ofSize:[fattrs fileSize] fromPath:@"\\Program Files\\TimerKey\\" withAttributes:typeFile toDevice:context];
746 [self goToPath:currentPath];
752 /*- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
754 if ([prefs objectForKey:@"NoRollover"] != nil) return;
755 if ([aTableView mouseOverRow] == rowIndex && ([aTableView selectedRow] != rowIndex))
756 if ([aTableView lockFocusIfCanDraw]) {
757 NSRect rowRect = [aTableView rectOfRow:rowIndex];
758 NSRect columnRect = [aTableView rectOfColumn:[[aTableView tableColumns] indexOfObject:aTableColumn]];
760 if (!highlightImage) {
761 highlightImage = [[NSImage alloc] initWithData:[highlightImageData propertyList]];
762 [highlightImage setDataRetained:YES]; //?
763 [highlightImage setCacheMode:NSImageCacheAlways]; //?
766 [highlightImage drawInRect:NSIntersectionRect(rowRect, columnRect) fromRect:NSMakeRect(0,0,1,[highlightImage size].height) operation:NSCompositeSourceOver fraction:0.3];
767 [aTableView unlockFocus];
774 if (highlightImage) [highlightImage release];
778 - (IBAction)pauseCurrentTransfer:(id)sender {
780 [pauseButton setImage:[NSImage imageNamed:@"DownloadResume.tif"]];
781 [pauseButton setAlternateImage:[NSImage imageNamed:@"DownloadResumePressed.tif"]];
782 //add priority "halt" to queue naming file
783 id current = [tfusbc currentTransferInfo];
784 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"pause",@"transferType",[current objectForKey:@"filename"],@"filename",nil]];
786 [currentlyField setStringValue:[NSLocalizedString(@"PAUSED", @"Paused: ") stringByAppendingString:[[current objectForKey:@"filename"]objectForKey:@"name"]]];
787 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
788 [currentlyField displayIfNeeded];
790 //change image to pause
791 //add priority "resume" to queue naming file
792 [pauseButton setImage:[NSImage imageNamed:@"DownloadStop.tif"]];
793 [pauseButton setAlternateImage:[NSImage imageNamed:@"DownloadStopPressed.tif"]];
794 id current = [tfusbc firstPausedTransferInfo];//temp as for now only have 1 paused
795 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"resume",@"transferType",[current objectForKey:@"filename"],@"filename",nil]];
797 [currentlyField setStringValue:[NSLocalizedString(@"DOWNLOADING", @"Downloading: ") stringByAppendingString:[[current objectForKey:@"filename"]objectForKey:@"name"]]];
798 [connectLight setImage:[NSImage imageNamed:@"blink.tiff"]];
799 [currentlyField displayIfNeeded];
803 - (id) selectedColumn {
804 return selectedColumn;
806 - (id) currentlyField {
807 return currentlyField;
809 - (id) connectLight {
815 @implementation UIElements (PrivateMethods)
817 // To ensure proper maintenance of reference counts, all updates of currentPath
818 // go via this method.
819 - (void) setCurrentPath:(NSString*)path {
820 // Retain first, in case it's the same or a related object.
822 [currentPath release];