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 {
46 [mainWindow setTitleBarHeight:22.0];
47 [mainWindow setBottomBarHeight:18.0];
48 [mainWindow setMidBarHeight: 32.0 origin:40.0];
51 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 >";
52 [self setCurrentPath:@"\\"];
53 [currentlyField setStringValue:NSLocalizedString(@"IDLE", @"Idle")];
54 [currentlyField displayIfNeeded];
55 [tableView setDoubleAction: @selector(doubleClick:)];
56 [tableView setTarget: self];
57 [tableView registerForDraggedTypes: [NSArray arrayWithObjects: @"NSFilenamesPboardType", @"NSFilenamesPboardType", nil]];
58 tfusbc = [[TFUSBController alloc] init];
59 [tfusbc setDH:dh tableView:tableView]; //send needed items to tfusbc
62 [turboCB setEnabled:NO];
63 [versionField setStringValue:[[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleVersion"]];
64 [pathBar setEnabled:YES];
65 [[pathBar cell] setSegmentCount:1];
66 [[pathBar cell] setLabel:@"Path:" forSegment:0];
67 [[pathBar cell] setWidth:0 forSegment:0];
69 [[dh fileList] addObject:[NSDictionary dictionaryWithObject:NSLocalizedString(@"NOT_CONNECTED_ENTRY", @"Not connected") forKey:@"name"]];
70 [tableView reloadData];
71 prefs = [[NSUserDefaults standardUserDefaults] retain];
72 if ([prefs boolForKey:@"auto-connect"]) {
78 - (BOOL)validateMenuItem:(NSMenuItem*)anItem {
79 if ([[anItem title] isEqualToString:NSLocalizedString(@"DL_MENUITEM", @"Download")] && (1 > [tableView numberOfSelectedRows])) {
82 if ([[anItem title] isEqualToString:NSLocalizedString(@"DEL_MENUITEM", @"Delete")] && (1 > [tableView numberOfSelectedRows])) {
85 if ([[anItem title] isEqualToString:NSLocalizedString(@"RN_MENUITEM", @"Rename")] && (1 != [tableView numberOfSelectedRows])) {
88 if ([[anItem title] isEqualToString:NSLocalizedString(@"UL_MENUITEM", @"Upload")] && (! connected)) {
91 if ([[anItem title] isEqualToString:NSLocalizedString(@"NF_MENUITEM", @"NewFolder")] && (! connected)) {
97 - (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem {
98 if ([[toolbarItem itemIdentifier] isEqual:@"ConnectTBIcon"]) {
100 [toolbarItem setLabel:NSLocalizedString(@"DC_BUTTON", @"Disconnect")];
102 [toolbarItem setLabel:NSLocalizedString(@"CON_BUTTON", @"Connect")];
105 if ([[toolbarItem itemIdentifier] isEqual:@"UploadTBIcon"] && (! connected)) {
108 if ([[toolbarItem itemIdentifier] isEqual:@"NewFolderTBIcon"] && (! connected)) {
111 if ([[toolbarItem itemIdentifier] isEqual:@"TurboTBIcon"] && (! connected)) {
114 if ([[toolbarItem itemIdentifier] isEqual:@"DownloadTBIcon"] && (1 > [tableView numberOfSelectedRows] || !connected)) {
117 if ([[toolbarItem itemIdentifier] isEqual:@"DeleteTBIcon"] && (1 > [tableView numberOfSelectedRows] || !connected)) {
120 if ([[toolbarItem itemIdentifier] isEqual:@"RenameTBIcon"] && (1 != [tableView numberOfSelectedRows] || !connected)) {
127 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
129 [preview setString:@""];
130 if ([previewDrawer state] == NSDrawerClosedState) return; // don't bother getting previews if closed
131 if ([tableView numberOfSelectedRows] != 1 || !connected)
133 if ([tfusbc hasCurrentTransfer]) return; //for now, change to a priority transfer later?
134 id currentSelectedItem = [[dh displayedList] objectAtIndex:[tableView selectedRow]];
135 int type = [[currentSelectedItem objectForKey:@"type"] intValue];
136 if (type == 2) { //file
137 NSString* nameOnToppy = [currentSelectedItem objectForKey:@"name"];
138 if (([nameOnToppy hasSuffix:@".ini"] || [nameOnToppy hasSuffix:@".txt"] || [nameOnToppy hasSuffix:@".tgd"] || [nameOnToppy hasSuffix:@".tsv"] || [nameOnToppy hasSuffix:@".dat"] || [nameOnToppy hasSuffix:@".tap"])) {
139 [drawerTabView selectTabViewItemAtIndex:0];
140 NSString* tempFile = NSTemporaryDirectory(); // download preview to temp folder
141 tempFile = [tempFile stringByAppendingPathComponent:@"MacTFTemp"];
142 [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];
143 while ([tfusbc hasCurrentTransfer]) {
146 [preview setString:[NSString stringWithContentsOfFile:tempFile]];
147 } else if ([nameOnToppy hasSuffix:@".rec"]) { //display headers
148 [drawerTabView selectTabViewItemAtIndex:1];
149 NSString* tempFile = NSTemporaryDirectory(); // download first 64k to temp folder
150 tempFile = [tempFile stringByAppendingPathComponent:@"MacTFTemp"];
151 [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];
152 while ([tfusbc hasCurrentTransfer]) {
155 NSDictionary* recData = [dh extractDataFromRecHeader:tempFile forModel:[prefs objectForKey:@"modelType"]]; //then parse and display headers
156 [recStart setObjectValue:[recData objectForKey:@"startTime"]];
157 [recDuration setObjectValue:[recData objectForKey:@"duration"]];
158 [recDescription setStringValue:[recData objectForKey:@"description"]];
159 [recName setStringValue:[recData objectForKey:@"name"]];
160 [recExtInfo setStringValue:[recData objectForKey:@"extInfo"]];
161 [recChannel setStringValue:[recData objectForKey:@"channel"]];
164 [drawerTabView selectTabViewItemAtIndex:0];
167 } else if (type == 1) { //folder
168 [drawerTabView selectTabViewItemAtIndex:0];
171 [statusField setStringValue:NSLocalizedString(@"SEL_ERROR", @"Selection error...")];
176 - (void) setAvailableSpace:(NSData*)input {
177 [availSpaceField setStringValue:[self prepForSizeDisplay:input]];
180 - (void) setFreeSpace:(NSData*) input {
181 [freeSpaceField setStringValue:[self prepForSizeDisplay:input]];
184 - (NSString*) prepForSizeDisplay:(NSData*) input {
185 UInt32 size_bigendian;
186 [input getBytes:&size_bigendian];
187 unsigned size = EndianU32_BtoN(size_bigendian);
189 if( size == 0. ) ret = NSLocalizedString( @" - ", "no file size" );
190 else if( size > 0. && size < 1024. ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.0f KB", "file size measured in kilobytes" ), size];
191 else if( size >= 1024. && size < pow( 1024., 2. ) ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.1f MB", "file size measured in megabytes" ), ( size / 1024. )];
192 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. ) )];
193 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. ) )];
194 else if( size >= pow( 1024., 4. ) ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.4f PB", "file size measured in pentabytes" ), ( size / pow( 1024., 4. ) )];
198 - (IBAction) connect: (id) sender {
200 context = [tfusbc initializeUSB];
201 if (context == nil) {
202 [statusField setStringValue:NSLocalizedString(@"INIT_PROBLEM", @"Message when initialization fails.")];
205 // add a check here to see if really connected...
207 [[dh fileList] removeAllObjects];
208 [[dh fileList] addObject:[NSDictionary dictionaryWithObject:NSLocalizedString(@"FETCHING", @"Fetching") forKey:@"name"]];
209 [tableView reloadData];
210 [tfusbc clearQueues];
212 [turboCB setState:0];
213 [turboCB setEnabled:YES];
214 [[pathBar cell] setSegmentCount:2];
215 [[pathBar cell] setLabel:@"Path:" forSegment:0];
216 [[pathBar cell] setLabel:@"\\" forSegment:1];
217 [[pathBar cell] setWidth:0 forSegment:0];
218 [[pathBar cell] setWidth:0 forSegment:1];
220 [pathBar setHidden:NO];
221 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
222 [connectButton setTitle:NSLocalizedString(@"DC_BUTTON", @"Disconnect.")];
223 [statusField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"CONNECTED_MESSAGE", @"Message giving connection speed."), [tfusbc getSpeed]]];
224 [NSThread detachNewThreadSelector:@selector(transfer:) toTarget:tfusbc withObject:nil];
225 } else { // already connected
227 if ([tfusbc hasCurrentTransfer]) { //gives a few seconds for busy thread to notice it should not be connected before cutting the device off
230 [tfusbc closeDevice:context];
231 [connectButton setTitle:NSLocalizedString(@"CON_BUTTON", @"Connect.")];
232 [statusField setStringValue:NSLocalizedString(@"NO_CONNECT", @"No connection.")];
233 [[dh fileList] removeAllObjects];
234 [tableView reloadData];
235 [turboCB setState:0];
236 [turboCB setEnabled:NO];
237 [connectLight setImage:[NSImage imageNamed:@"red.tiff"]];
238 [self setCurrentPath:@"\\"];
241 int ret = [self goToPath:@"\\"];
243 sleep (5); //error, wait a few secs for HDD to start if need be then try again
244 [self goToPath:@"\\"];
246 [self setCurrentPath:@"\\"];
249 - (int) goToPath:(NSString*) path {
250 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:path,@"path",@"fileList",@"transferType",nil]];
251 // FIXME: The caller would like to know whether the operation succeeded.
252 // But it has not even finished yet. So goToPath should somehow notify
253 // the caller on completion.
257 - (void)doubleClick:(id)sender
259 if ([tableView numberOfSelectedRows] != 1)
261 id currentSelectedItem = [[dh displayedList] objectAtIndex:[tableView selectedRow]];
262 int type = [[currentSelectedItem objectForKey:@"type"] intValue];
263 if (type == 2) { //file
264 [self downloadFileDoubleClickThread:nil];
265 } else if (type == 1) { //folder
266 NSString* currentName = [currentSelectedItem objectForKey:@"name"];
267 if ([currentName isEqualToString:@".. (Parent folder)"]) { // move up
268 NSMutableArray* array = [NSMutableArray arrayWithArray:[currentPath componentsSeparatedByString:@"\\"]];
269 if ([array count] > 1){ // not going to root
270 [array removeLastObject];
271 NSString* temp = [NSString stringWithString:[array componentsJoinedByString:@"\\"]];
272 if ([self goToPath:temp]) {// if error
273 [self goToPath:temp]; // hackish workaround
275 int segCount = [pathBar segmentCount]; //remember count starts at 1, not zero!
276 NSRect r = [pathBar frame];
277 [[pathBar cell] setSegmentCount:segCount-1];
278 [pathBar setNeedsDisplayInRect:r];
279 [pathBar displayIfNeeded];
280 [self setCurrentPath:temp];
281 [statusField setStringValue:NSLocalizedString(@"CONNECTED_OK", @"Connection OK")];
283 [self setCurrentPath:@"\\"];
284 [[pathBar cell] setSegmentCount:1];
287 NSMutableString* temp = [NSMutableString stringWithString:currentPath];
288 if (![temp isEqualToString:@"\\"])
289 [temp appendString:@"\\"];
290 [temp appendString:currentName];
291 if ([self goToPath:temp]) { // if error, try again
292 [self goToPath:temp]; // hackish workaround
294 [self setCurrentPath:temp];
295 int segCount = [pathBar segmentCount]; //remember count starts at 1, not zero!
296 NSRect r = [pathBar frame];
297 [[pathBar cell] setSegmentCount:segCount+1];
298 [[pathBar cell] setLabel:currentName forSegment:segCount];
299 [[pathBar cell] setWidth:0 forSegment:segCount];
301 [pathBar displayIfNeededInRect:r];
302 [statusField setStringValue:NSLocalizedString(@"CONNECTED_OK", @"Connection OK")];
305 [statusField setStringValue:NSLocalizedString(@"SEL_ERROR", @"Selection error...")];
310 - (void) downloadFileDoubleClickThread:(NSDictionary*)fileInfo {
311 if (! connected) return;
312 [self downloadSelectedFile:nil];
313 // [self updateHDDSize];
316 /*- (void) updateHDDSize {
317 if (! connected) return;
318 NSData* hddSizeString = [tfusbc getHDDSize:context];
319 if (hddSizeString != nil) {
320 [self setAvailableSpace:[hddSizeString subdataWithRange:(NSRange) {8,4}]];
321 [self setFreeSpace:[hddSizeString subdataWithRange:(NSRange) {12,4}]];
325 - (void)tableView:(NSTableView *)tView didClickTableColumn:(NSTableColumn *)tableColumn
327 // Either reverse the sort or change the sorting column
328 NSString* columnIdentifier = [tableColumn identifier];
329 BOOL newSortAscending = !(sortAscending && [tableColumn isEqualTo:selectedColumn]);
331 NSString* sortKey = nil;
332 SEL sortSelector = @selector(compare:);
333 if ([columnIdentifier isEqualToString:@"name"]) {
335 sortSelector = @selector(caseInsensitiveCompare:);
336 } else if ([columnIdentifier isEqualToString:@"date"]) {
337 sortKey = @"sortdate";
338 } else if ([columnIdentifier isEqualToString:@"size"]) {
339 sortKey = @"fileSize";
340 } else if ([columnIdentifier isEqualToString:@"icon"]) {
346 NSSortDescriptor* descriptor = [[[NSSortDescriptor alloc]
347 initWithKey:sortKey ascending:newSortAscending selector:sortSelector]
349 NSArray* sortedArray = [[dh fileList] sortedArrayUsingDescriptors:
350 [NSArray arrayWithObject:descriptor]];
351 NSImage* indicatorImage = [NSImage imageNamed:
352 newSortAscending ? @"NSAscendingSortIndicator" : @"NSDescendingSortIndicator"];
354 sortAscending = newSortAscending;
355 selectedColumn = tableColumn;
356 [tView setIndicatorImage: indicatorImage inTableColumn: tableColumn];
357 // remove other indicators
358 NSMutableArray* otherColumns = [NSMutableArray arrayWithArray:[tView tableColumns]];
359 [otherColumns removeObject:tableColumn];
360 NSEnumerator* cols = [otherColumns objectEnumerator];
362 while (currentCol = [cols nextObject]) {
363 [tView setIndicatorImage: nil inTableColumn: currentCol];
365 [dh setFileList:sortedArray];
366 [dh search:searchField];
371 - (IBAction) downloadSelectedFile:(id)sender{
374 NSLog(@"Download file starting...");
375 NSEnumerator* selected = [tableView selectedRowEnumerator];
377 while (currentSelected = [selected nextObject]) {
378 id currentSelectedItem = [[dh displayedList] objectAtIndex:[currentSelected intValue]];
379 int type = [[currentSelectedItem objectForKey:@"type"] intValue];
380 if (type == 1) {[statusField setStringValue:NSLocalizedString(@"NO_FOLDER_DL", @"Folder download not supported yet")];}
381 else if (type == 2) {
382 NSString* nameOnToppy = [currentSelectedItem objectForKey:@"name"];
383 NSSavePanel *nssave = [[NSSavePanel savePanel]retain];
384 int retButton = [nssave runModalForDirectory:nil file:nameOnToppy];
386 NSString* savePath= [nssave filename];
388 unsigned long long offset = 0;
389 NSFileHandle *newFileHandle = [NSFileHandle fileHandleForReadingAtPath:savePath];
390 if (!(newFileHandle==nil)) { // there is a file there, ask if want to resume
391 NSLog(@"existing file length: %qu", [newFileHandle seekToEndOfFile]);
392 //ask to resume, save offset if yes
393 //offset = [newFileHandle seekToEndOfFile];
395 [tfusbc setProgressBar:progressBar time:progressTime turbo:turboCB];
396 [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];
400 // [self updateHDDSize];
403 - (void) finishTransfer {
404 [currentlyField setStringValue:@""];
405 [progressBar setDoubleValue:0];
406 [[NSSound soundNamed:@"Ping"] play];
407 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
408 [currentlyField setStringValue:NSLocalizedString(@"IDLE", @"Idle")];
409 [currentlyField display];
412 - (IBAction) uploadFile: (id) sender {
415 NSOpenPanel *nsop = [[NSOpenPanel openPanel]retain];
416 [nsop setAllowsMultipleSelection:YES];
417 [nsop setCanChooseFiles:YES];
418 [nsop setCanChooseDirectories:YES];
419 int retButton = [nsop runModal];
420 NSArray *returnedNames = [nsop filenames];
421 if (retButton == NSFileHandlingPanelCancelButton) {
422 NSLog(@"Upload cancelled");
425 //get info about the chosen file - later if do folders check here and do recursive all things in folder???
426 NSEnumerator *enumerator = [returnedNames objectEnumerator];
428 // [statusField setStringValue:[NSLocalizedString(@"CONNECTED_OK", @"Connection OK") stringByAppendingString:NSLocalizedString(@"DOWNLOAD", @"Download")];
429 [connectLight setImage:[NSImage imageNamed:@"blink.tiff"]];
430 while (returnedName = [enumerator nextObject]) {
432 [self uploadPath:returnedName toPath:[NSString stringWithString:currentPath]];
438 - (void) uploadPath:(NSString*) path toPath:(NSString*) toPath {
441 NSFileManager* fm = [NSFileManager defaultManager];
442 NSDictionary *fattrs = [fm fileAttributesAtPath:path traverseLink:NO];
444 NSLog(@"Path of file to upload is incorrect!");
446 NSString* type = [fattrs fileType];
447 if ([type isEqualToString:@"NSFileTypeDirectory"]) {
448 // should look to create folder on Toppy, or add stuff if already there (maybe it does this automatically?), and place in subfolders etc
449 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[path lastPathComponent],@"newName",toPath,@"path",@"newFolder",@"transferType", nil]];
450 NSArray* subPaths = [fm directoryContentsAtPath:path];
451 NSEnumerator* e = [subPaths objectEnumerator];
453 while (object = [e nextObject]) {
454 NSString* subPath = [NSString stringWithFormat:@"%@/%@", path, object];
455 NSString* subToPath = [NSString stringWithFormat:@"%@\\%@", toPath, [path lastPathComponent]];
456 // NSLog(@"subdir: %@, %@", subPath, subToPath);
457 if (![object isEqualToString:@".DS_Store"]) {
458 [self uploadPath:subPath toPath:subToPath];
461 if (connected) { //may have disconnected during threaded upload (although not actually threaded here!)
462 // [self updateHDDSize];
463 [self goToPath:currentPath];
467 NSDictionary* fileAttr = [dh extractAttributes:fattrs]; // turn Dict into a new TypeFile dict
468 NSMutableArray* array = [NSMutableArray arrayWithArray:[path componentsSeparatedByString:@"/"]]; // cut down name
469 NSString* fileName = [NSString stringWithString:[array lastObject]];
470 NSData* typeFile = [dh getDataFromTFFile:fileAttr withName:fileName];
471 [progressBar setDoubleValue:0];
472 [currentlyField setStringValue:[NSLocalizedString(@"UPLOADING", @"Uploading") stringByAppendingString:fileName]];
473 [currentlyField displayIfNeeded];
474 [tfusbc setProgressBar:progressBar time:progressTime turbo:turboCB];
475 [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];
479 -(IBAction)deleteFile:(id)sender
483 if ( [tableView numberOfSelectedRows] == 0 )
485 NSString *title = NSLocalizedString(@"WARNING", @"Warning!");
486 NSString *defaultButton = NSLocalizedString(@"DEL", @"Delete");
487 NSString *alternateButton = NSLocalizedString(@"NO_DEL", @"Don't Delete");
488 NSString *otherButton = nil;
489 NSString *message = NSLocalizedString(@"DEL_MESSAGE", @"Are you sure you want to delete the selected file(s)?");
492 NSBeginAlertSheet(title, defaultButton, alternateButton, otherButton, mainWindow, self, @selector(sheetDidEnd:returnCode:contextInfo:), nil, nil, message);
495 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
497 if ( returnCode == NSAlertDefaultReturn ) {
498 NSLog(@"Deleting file(s) starting...");
499 NSEnumerator* selected = [tableView selectedRowEnumerator];
501 while (currentSelected = [selected nextObject]) {
502 id currentSelectedItem = [[dh displayedList] objectAtIndex:[currentSelected intValue]];
503 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:currentSelectedItem,@"file",currentPath,@"path",@"delete",@"transferType", nil]];
505 // [self updateHDDSize];
506 [self goToPath:currentPath];
507 //should check so don't delete root folders?
511 - (IBAction)openPrefsSheet:(id)sender
513 [NSApp beginSheet:prefsWindow
514 modalForWindow:mainWindow
516 didEndSelector:@selector(mySheetDidEnd:returnCode:contextInfo:)
518 return; // leave without doing anything else
521 - (IBAction) mySheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode
522 contextInfo:(void *)contextInfo {
524 [sheet orderOut:self];
525 if(returnCode == 0) return;
526 // continue with application
529 - (IBAction)closePrefsSheet:(id)sender
531 //do changes to prefs here
533 [tfusbc setDebug:[debugCB state]];
535 NSLog(@"auto: %i", [autoCB state]);
536 [prefs setBool:[autoCB state] forKey:@"auto-connect"];
537 // [prefs setBool:[epgCB state] forKey:@"epgSync"];
539 [NSApp endSheet:prefsWindow returnCode:1];
542 - (IBAction)openRenameSheet:(id)sender
544 if ( [tableView numberOfSelectedRows] != 1 )
546 [renameOld setStringValue:[[[dh displayedList] objectAtIndex:[tableView selectedRow]] objectForKey:@"name"]];
547 [renameNew setStringValue:[renameOld stringValue]];
548 // [renameWindow setTitleBarHeight:0.0];
549 [NSApp beginSheet: renameWindow
550 modalForWindow: mainWindow
554 [NSApp runModalForWindow: renameWindow];
558 - (IBAction)cancelRename:(id)sender{
559 [NSApp endSheet: renameWindow];
560 [renameWindow orderOut: self];
564 - (IBAction)closeRenameSheet:(id)sender
566 //do changes to rename here
568 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[renameOld stringValue],@"oldName",[renameNew stringValue],@"newName", currentPath,@"path",@"rename",@"transferType",nil]];
569 [self goToPath:currentPath];
572 [self cancelRename:sender];
576 - (IBAction)openNewFolderSheet:(id)sender
578 [NSApp beginSheet: newFolderWindow
579 modalForWindow: mainWindow
583 [NSApp runModalForWindow: newFolderWindow];
588 - (IBAction)cancelNewFolder:(id)sender{
589 [NSApp endSheet: newFolderWindow];
590 [newFolderWindow orderOut: self];
594 - (IBAction)closeNewFolderSheet:(id)sender
596 //do changes to make new folder here
598 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[newFolderNew stringValue],@"newName",currentPath,@"path",@"newFolder",@"transferType", nil]];
599 [self goToPath:currentPath];
602 [self cancelNewFolder:sender];
605 - (IBAction)pathBarClick:(id)sender {
606 int segCount = [pathBar segmentCount]; //remember count starts at 1, not zero!
607 int selectedSegment = [sender selectedSegment];
608 if (selectedSegment == segCount - 1) return; //no need to move anywhere
609 int i = 1; // remember have "path" there too
610 NSMutableArray* pathArray = [NSMutableArray arrayWithCapacity:selectedSegment];
611 while (i<=selectedSegment) {
612 [pathArray addObject:[[pathBar cell] labelForSegment:i]];
615 NSString* pathString = [pathArray componentsJoinedByString:@"\\"];
616 if ([pathString hasPrefix:@"\\\\"]) pathString = [pathString substringFromIndex:1];
617 [self goToPath:pathString];
618 [self setCurrentPath:pathString];
619 NSRect r = [pathBar frame];
620 [[pathBar cell] setSegmentCount:selectedSegment+1];
621 [pathBar displayIfNeededInRect:r];
628 - (USBDeviceContext*) getContext {
632 - (NSNumber*) isConnected {
633 return [NSNumber numberWithBool:connected];
637 - (NSString*) currentPath {
641 - (IBAction) toggleTurbo:(id)sender {
642 if ([tfusbc hasCurrentTransfer]) { //have a current transfer, lets toggle it
643 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"turbo",@"transferType",[NSNumber numberWithBool:[turboCB state]],@"turboOn",nil]];
647 - (IBAction) toggleTurboCB:(id)sender {
650 if ([turboCB state]) { // currently on, want off
651 [turboCB setState:0];
653 [turboCB setState:1];
655 if ([tfusbc hasCurrentTransfer]) { //have a current transfer, lets toggle it
656 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"turbo",@"transferType",[NSNumber numberWithBool:[turboCB state]],@"turboOn",nil]];
660 - (IBAction) togglePreview:(id)sender {
661 [previewDrawer toggle:sender];
664 /*- (IBAction) snapshot:(id) sender {
665 NSArray* snapshotData = [self snapshotOfPath:@"\\"];
666 [dh setSnapShot:snapshotData];
667 // show snapshot window
668 [snapshotWindow makeKeyAndOrderFront:sender];
669 [outlineView reloadData];
672 - (NSArray*) snapshotOfPath:(NSString*)path {
674 NSData* hddFileData = [tfusbc getFileList:context forPath:path];
675 NSData* checkForError = [hddFileData subdataWithRange:(NSRange){4,4}];
676 const UInt32 check_bigendian = EndianU32_NtoB(USB_Fail);
677 const UInt32 check2_bigendian = EndianU32_NtoB(USB_DataHddDir);
678 if ([checkForError isEqualToData:[NSData dataWithBytes:&check_bigendian length:4]]) {
679 [statusField setStringValue:@"Connected - error on last command"];
681 if (! [checkForError isEqualToData:[NSData dataWithBytes:&check2_bigendian length:4]]) {
682 hddFileData = [tfusbc getFileList:context forPath:path]; //try again
683 if ([checkForError isEqualToData:[NSData dataWithBytes:&check_bigendian length:4]]) {
684 [statusField setStringValue:@"Connected - error on last command"];
687 hddFileData = [hddFileData subdataWithRange:(NSRange) {8, [hddFileData length]-8}]; // cut off header and cmd
689 NSMutableArray* paths = [[NSMutableArray alloc] init];
690 for (i=0; i*114 < [hddFileData length]-4; i++) { // 4 is there cause swapping sometimes adds a byte of padding
691 NSData* temp = [hddFileData subdataWithRange:(NSRange) {i*114,114}];
692 NSMutableDictionary* tfFile = [dh newTFFileFromSwappedHexData:temp];
693 [dh convertRawDataToUseful:tfFile];
694 if (!([[tfFile objectForKey:@"name"] isEqualToString:@".."])) {
695 if ([[tfFile objectForKey:@"type"] intValue] == 1) { //folder
696 NSMutableString* temp = [NSMutableString stringWithString:path];
697 if (![temp isEqualToString:@"\\"])
698 [temp appendString:@"\\"];
699 [temp appendString:[tfFile objectForKey:@"name"]];
700 [paths addObject:tfFile];
701 [paths addObject:[self snapshotOfPath:temp]];
703 [paths addObject:tfFile];
713 /*- (IBAction) epg:(id) sender {
714 XMLToEPG *xmlConv = [[XMLToEPG alloc] init];
715 NSOpenPanel *nsop = [[NSOpenPanel openPanel]retain];
716 NSArray *fileType = [NSArray arrayWithObject:@"xml"];
717 [nsop setAllowsMultipleSelection:NO];
718 [nsop setCanChooseFiles:YES];
719 [nsop setCanChooseDirectories:NO];
720 [nsop runModalForTypes:fileType];
721 NSMutableArray* importedXML = [xmlConv importXML:[nsop URL]];
722 [xmlConv fixData:importedXML];
723 [xmlConv exportFixedXML:importedXML toFile:@"/Volumes/Tyr/nathan/Desktop/TV/Guides/test.tgd"];
728 /* if ([prefs boolForKey:@"epgSync"]) {
730 XMLToEPG *xmlConv = [[XMLToEPG alloc] init];
731 NSString* path = @"/Volumes/Tyr/nathan/Desktop/TV/Guides/tv.xml";
732 NSString* tempFile = @"/Volumes/Tyr/nathan/Desktop/TV/Guides/test.epg";
733 NSMutableArray* importedXML = [xmlConv importXML:[NSURL fileURLWithPath:path]];
734 [xmlConv fixData:importedXML];
735 [xmlConv exportFixedXML:importedXML toFile:tempFile];
738 NSFileManager* fm = [NSFileManager defaultManager];
739 NSDictionary *fattrs = [fm fileAttributesAtPath:tempFile traverseLink:NO];
741 NSLog(@"Path of file to upload is incorrect!");
744 NSDictionary* fileAttr = [dh extractAttributes:fattrs];
745 NSMutableArray* array = [NSMutableArray arrayWithArray:[tempFile componentsSeparatedByString:@"/"]];
746 NSString* fileName = [NSString stringWithString:[array lastObject]];
747 NSData* typeFile = [dh getDataFromTFFile:fileAttr withName:fileName];
748 [tfusbc uploadFile:tempFile ofSize:[fattrs fileSize] fromPath:@"\\Program Files\\TimerKey\\" withAttributes:typeFile toDevice:context];
749 [self goToPath:currentPath];
755 /*- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
757 if ([prefs objectForKey:@"NoRollover"] != nil) return;
758 if ([aTableView mouseOverRow] == rowIndex && ([aTableView selectedRow] != rowIndex))
759 if ([aTableView lockFocusIfCanDraw]) {
760 NSRect rowRect = [aTableView rectOfRow:rowIndex];
761 NSRect columnRect = [aTableView rectOfColumn:[[aTableView tableColumns] indexOfObject:aTableColumn]];
763 if (!highlightImage) {
764 highlightImage = [[NSImage alloc] initWithData:[highlightImageData propertyList]];
765 [highlightImage setDataRetained:YES]; //?
766 [highlightImage setCacheMode:NSImageCacheAlways]; //?
769 [highlightImage drawInRect:NSIntersectionRect(rowRect, columnRect) fromRect:NSMakeRect(0,0,1,[highlightImage size].height) operation:NSCompositeSourceOver fraction:0.3];
770 [aTableView unlockFocus];
777 if (highlightImage) [highlightImage release];
781 - (IBAction)pauseCurrentTransfer:(id)sender {
783 [pauseButton setImage:[NSImage imageNamed:@"DownloadResume.tif"]];
784 [pauseButton setAlternateImage:[NSImage imageNamed:@"DownloadResumePressed.tif"]];
785 //add priority "halt" to queue naming file
786 id current = [tfusbc currentTransferInfo];
787 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"pause",@"transferType",[current objectForKey:@"filename"],@"filename",nil]];
789 [currentlyField setStringValue:[NSLocalizedString(@"PAUSED", @"Paused: ") stringByAppendingString:[[current objectForKey:@"filename"]objectForKey:@"name"]]];
790 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
791 [currentlyField displayIfNeeded];
793 //change image to pause
794 //add priority "resume" to queue naming file
795 [pauseButton setImage:[NSImage imageNamed:@"DownloadStop.tif"]];
796 [pauseButton setAlternateImage:[NSImage imageNamed:@"DownloadStopPressed.tif"]];
797 id current = [tfusbc firstPausedTransferInfo];//temp as for now only have 1 paused
798 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"resume",@"transferType",[current objectForKey:@"filename"],@"filename",nil]];
800 [currentlyField setStringValue:[NSLocalizedString(@"DOWNLOADING", @"Downloading: ") stringByAppendingString:[[current objectForKey:@"filename"]objectForKey:@"name"]]];
801 [connectLight setImage:[NSImage imageNamed:@"blink.tiff"]];
802 [currentlyField displayIfNeeded];
806 - (id) selectedColumn {
807 return selectedColumn;
809 - (id) currentlyField {
810 return currentlyField;
812 - (id) connectLight {
818 @implementation UIElements (PrivateMethods)
820 // To ensure proper maintenance of reference counts, all updates of currentPath
821 // go via this method.
822 - (void) setCurrentPath:(NSString*)path {
823 // Retain first, in case it's the same or a related object.
825 [currentPath release];