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"
24 @implementation UIElements
26 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:
27 (NSApplication *)theApplication {
31 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)path
35 [self uploadPath:path toPath:[NSString stringWithString:currentPath]];
36 NSLog(@"DockUpload:%@", path);
40 -(void) awakeFromNib {
41 [mainWindow setTitleBarHeight:22.0];
42 [mainWindow setBottomBarHeight:18.0];
43 [mainWindow setMidBarHeight: 32.0 origin:40.0];
46 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 >";
47 currentPath = [[NSString stringWithString:@"\\"] retain];
48 [currentlyField setStringValue:NSLocalizedString(@"IDLE", @"Idle")];
49 [currentlyField displayIfNeeded];
50 [tableView setDoubleAction: @selector(doubleClick:)];
51 [tableView setTarget: self];
52 [tableView registerForDraggedTypes: [NSArray arrayWithObjects: @"NSFilenamesPboardType", @"NSFilenamesPboardType", nil]];
53 tfusbc = [[TFUSBController alloc] init];
54 [tfusbc setDH:dh tableView:tableView]; //send needed items to tfusbc
57 [turboCB setEnabled:NO];
58 [versionField setStringValue:[[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleVersion"]];
59 [pathBar setEnabled:YES];
60 [[pathBar cell] setSegmentCount:1];
61 [[pathBar cell] setLabel:@"Path:" forSegment:0];
62 [[pathBar cell] setWidth:0 forSegment:0];
64 [[dh fileList] addObject:[NSDictionary dictionaryWithObject:NSLocalizedString(@"NOT_CONNECTED_ENTRY", @"Not connected") forKey:@"name"]];
65 [tableView reloadData];
66 prefs = [[NSUserDefaults standardUserDefaults] retain];
67 if ([prefs boolForKey:@"auto-connect"]) {
72 if ([NSEvent isShiftKeyDown] && [NSEvent isControlKeyDown]) { NSLog(@"Testmode activated");
73 unsigned long long offset = 512*2000;
74 NSLog(@"%qu", offset);
75 const UInt64 offset_bigendian = EndianU64_NtoB(offset);
76 NSData* dat = [NSData dataWithBytes:&offset_bigendian length:8];
77 NSLog([dat description]);
82 - (BOOL)validateMenuItem:(NSMenuItem*)anItem {
83 if ([[anItem title] isEqualToString:NSLocalizedString(@"DL_MENUITEM", @"Download")] && (1 > [tableView numberOfSelectedRows])) {
86 if ([[anItem title] isEqualToString:NSLocalizedString(@"DEL_MENUITEM", @"Delete")] && (1 > [tableView numberOfSelectedRows])) {
89 if ([[anItem title] isEqualToString:NSLocalizedString(@"RN_MENUITEM", @"Rename")] && (1 != [tableView numberOfSelectedRows])) {
92 if ([[anItem title] isEqualToString:NSLocalizedString(@"UL_MENUITEM", @"Upload")] && (! connected)) {
95 if ([[anItem title] isEqualToString:NSLocalizedString(@"NF_MENUITEM", @"NewFolder")] && (! connected)) {
101 - (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem {
102 if ([[toolbarItem itemIdentifier] isEqual:@"ConnectTBIcon"]) {
104 [toolbarItem setLabel:NSLocalizedString(@"DC_BUTTON", @"Disconnect")];
106 [toolbarItem setLabel:NSLocalizedString(@"CON_BUTTON", @"Connect")];
109 if ([[toolbarItem itemIdentifier] isEqual:@"UploadTBIcon"] && (! connected)) {
112 if ([[toolbarItem itemIdentifier] isEqual:@"NewFolderTBIcon"] && (! connected)) {
115 if ([[toolbarItem itemIdentifier] isEqual:@"TurboTBIcon"] && (! connected)) {
118 if ([[toolbarItem itemIdentifier] isEqual:@"DownloadTBIcon"] && (1 > [tableView numberOfSelectedRows] || !connected)) {
121 if ([[toolbarItem itemIdentifier] isEqual:@"DeleteTBIcon"] && (1 > [tableView numberOfSelectedRows] || !connected)) {
124 if ([[toolbarItem itemIdentifier] isEqual:@"RenameTBIcon"] && (1 != [tableView numberOfSelectedRows] || !connected)) {
131 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
133 [preview setString:@""];
134 if ([previewDrawer state] == NSDrawerClosedState) return; // don't bother getting previews if closed
135 if ([tableView numberOfSelectedRows] != 1 || !connected)
137 if ([[tfusbc transferQueue] count] > 0) return; //for now, change to a priority transfer later?
138 id currentSelectedItem = [[dh displayedList] objectAtIndex:[tableView selectedRow]];
139 int type = [[currentSelectedItem objectForKey:@"type"] intValue];
140 if (type == 2) { //file
141 NSString* nameOnToppy = [currentSelectedItem objectForKey:@"name"];
142 if (([nameOnToppy hasSuffix:@".ini"] || [nameOnToppy hasSuffix:@".txt"] || [nameOnToppy hasSuffix:@".tgd"] || [nameOnToppy hasSuffix:@".tsv"] || [nameOnToppy hasSuffix:@".dat"] || [nameOnToppy hasSuffix:@".tap"])) {
143 [drawerTabView selectTabViewItemAtIndex:0];
144 NSString* tempFile = NSTemporaryDirectory(); // download preview to temp folder
145 tempFile = [tempFile stringByAppendingPathComponent:@"MacTFTemp"];
146 [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];
147 while ([[tfusbc transferQueue] count] > 0) {
150 [preview setString:[NSString stringWithContentsOfFile:tempFile]];
151 } else if ([nameOnToppy hasSuffix:@".rec"]) { //display headers
152 [drawerTabView selectTabViewItemAtIndex:1];
153 NSString* tempFile = NSTemporaryDirectory(); // download first 64k to temp folder
154 tempFile = [tempFile stringByAppendingPathComponent:@"MacTFTemp"];
155 [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];
156 while ([[tfusbc transferQueue] count] > 0) {
159 NSDictionary* recData = [dh extractDataFromRecHeader:tempFile forModel:[prefs objectForKey:@"modelType"]]; //then parse and display headers
160 [recStart setObjectValue:[recData objectForKey:@"startTime"]];
161 [recDuration setObjectValue:[recData objectForKey:@"duration"]];
162 [recDescription setStringValue:[recData objectForKey:@"description"]];
163 [recName setStringValue:[recData objectForKey:@"name"]];
164 [recExtInfo setStringValue:[recData objectForKey:@"extInfo"]];
165 [recChannel setStringValue:[recData objectForKey:@"channel"]];
168 [drawerTabView selectTabViewItemAtIndex:0];
171 } else if (type == 1) { //folder
172 [drawerTabView selectTabViewItemAtIndex:0];
175 [statusField setStringValue:NSLocalizedString(@"SEL_ERROR", @"Selection error...")];
180 - (void) setAvailableSpace:(NSData*)input {
181 [availSpaceField setStringValue:[self prepForSizeDisplay:input]];
184 - (void) setFreeSpace:(NSData*) input {
185 [freeSpaceField setStringValue:[self prepForSizeDisplay:input]];
188 - (NSString*) prepForSizeDisplay:(NSData*) input {
189 UInt32 size_bigendian;
190 [input getBytes:&size_bigendian];
191 unsigned size = EndianU32_BtoN(size_bigendian);
193 if( size == 0. ) ret = NSLocalizedString( @" - ", "no file size" );
194 else if( size > 0. && size < 1024. ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.0f KB", "file size measured in kilobytes" ), size];
195 else if( size >= 1024. && size < pow( 1024., 2. ) ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.1f MB", "file size measured in megabytes" ), ( size / 1024. )];
196 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. ) )];
197 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. ) )];
198 else if( size >= pow( 1024., 4. ) ) ret = [NSString stringWithFormat:NSLocalizedString( @"%.4f PB", "file size measured in pentabytes" ), ( size / pow( 1024., 4. ) )];
202 - (IBAction) connect: (id) sender {
204 context = [tfusbc initializeUSB];
205 if (context == nil) {
206 [statusField setStringValue:NSLocalizedString(@"INIT_PROBLEM", @"Message when initialization fails.")];
209 // add a check here to see if really connected...
211 [[dh fileList] removeAllObjects];
212 [[dh fileList] addObject:[NSDictionary dictionaryWithObject:NSLocalizedString(@"FETCHING", @"Fetching") forKey:@"name"]];
213 [tableView reloadData];
214 [tfusbc clearQueues];
216 [turboCB setState:0];
217 [turboCB setEnabled:YES];
218 [[pathBar cell] setSegmentCount:2];
219 [[pathBar cell] setLabel:@"Path:" forSegment:0];
220 [[pathBar cell] setLabel:@"\\" forSegment:1];
221 [[pathBar cell] setWidth:0 forSegment:0];
222 [[pathBar cell] setWidth:0 forSegment:1];
224 [pathBar setHidden:NO];
225 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
226 [connectButton setTitle:NSLocalizedString(@"DC_BUTTON", @"Disconnect.")];
227 [statusField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"CONNECTED_MESSAGE", @"Message giving connection speed."), [tfusbc getSpeed]]];
228 [NSThread detachNewThreadSelector:@selector(transfer:) toTarget:tfusbc withObject:nil];
229 } else { // already connected
231 if ([[tfusbc transferQueue] count] != 0) { //gives a few seconds for busy thread to notice it should not be connected before cutting the device off
234 [tfusbc closeDevice:context];
235 [connectButton setTitle:NSLocalizedString(@"CON_BUTTON", @"Connect.")];
236 [statusField setStringValue:NSLocalizedString(@"NO_CONNECT", @"No connection.")];
237 [[dh fileList] removeAllObjects];
238 [tableView reloadData];
239 [turboCB setState:0];
240 [turboCB setEnabled:NO];
241 [connectLight setImage:[NSImage imageNamed:@"red.tiff"]];
245 int ret = [self goToPath:@"\\"];
247 sleep (5); //error, wait a few secs for HDD to start if need be then try again
248 [self goToPath:@"\\"];
253 - (int) goToPath:(NSString*) path {
254 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:path,@"path",@"fileList",@"transferType",nil]];
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 currentPath = [[NSString stringWithString:temp] retain];
281 [statusField setStringValue:NSLocalizedString(@"CONNECTED_OK", @"Connection OK")];
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 currentPath = [[NSString stringWithString:temp] retain];
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 NSArray* sortDescriptors = [[NSArray alloc] init];
329 NSArray* sortedArray;
330 NSImage *indicatorImage;
331 if (sortAscending || ![tableColumn isEqualTo:selectedColumn]) {
332 if ([[tableColumn identifier] isEqualToString:@"name"]) {
333 NSSortDescriptor* nameDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)] autorelease];
334 sortDescriptors=[NSArray arrayWithObject:nameDescriptor];
336 if ([[tableColumn identifier] isEqualToString:@"date"]) {
337 NSSortDescriptor* dateDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"sortdate" ascending:YES] autorelease];
338 sortDescriptors=[NSArray arrayWithObject:dateDescriptor];
340 if ([[tableColumn identifier] isEqualToString:@"size"]) {
341 NSSortDescriptor* sizeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"fileSize" ascending:YES] autorelease];
342 sortDescriptors=[NSArray arrayWithObject:sizeDescriptor];
344 if ([[tableColumn identifier] isEqualToString:@"icon"]) {
345 NSSortDescriptor* sizeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"suffix" ascending:YES] autorelease];
346 sortDescriptors=[NSArray arrayWithObject:sizeDescriptor];
348 sortedArray=[[dh fileList] sortedArrayUsingDescriptors:sortDescriptors];
349 indicatorImage = [NSImage imageNamed: @"NSAscendingSortIndicator"];
351 if ([[tableColumn identifier] isEqualToString:@"name"]) {
352 NSSortDescriptor* nameDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO selector:@selector(caseInsensitiveCompare:)] autorelease];
353 sortDescriptors=[NSArray arrayWithObject:nameDescriptor];
355 if ([[tableColumn identifier] isEqualToString:@"date"]) {
356 NSSortDescriptor* dateDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"sortdate" ascending:NO] autorelease];
357 sortDescriptors=[NSArray arrayWithObject:dateDescriptor];
359 if ([[tableColumn identifier] isEqualToString:@"size"]) {
360 NSSortDescriptor* sizeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"fileSize" ascending:NO] autorelease];
361 sortDescriptors=[NSArray arrayWithObject:sizeDescriptor];
363 if ([[tableColumn identifier] isEqualToString:@"icon"]) {
364 NSSortDescriptor* sizeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"suffix" ascending:NO] autorelease];
365 sortDescriptors=[NSArray arrayWithObject:sizeDescriptor];
368 sortedArray=[[dh fileList] sortedArrayUsingDescriptors:sortDescriptors];
369 indicatorImage = [NSImage imageNamed: @"NSDescendingSortIndicator"];
371 sortAscending = !sortAscending;
372 selectedColumn = tableColumn;
373 [tView setIndicatorImage: indicatorImage inTableColumn: tableColumn];
374 // remove other indicators
375 NSMutableArray* otherColumns = [NSMutableArray arrayWithArray:[tView tableColumns]];
376 [otherColumns removeObject:tableColumn];
377 NSEnumerator* cols = [otherColumns objectEnumerator];
379 while (currentCol = [cols nextObject]) {
380 [tView setIndicatorImage: nil inTableColumn: currentCol];
382 [dh setFileList:sortedArray];
383 [dh search:searchField];
388 - (IBAction) downloadSelectedFile:(id)sender{
391 NSLog(@"Download file starting...");
392 NSEnumerator* selected = [tableView selectedRowEnumerator];
394 while (currentSelected = [selected nextObject]) {
395 id currentSelectedItem = [[dh displayedList] objectAtIndex:[currentSelected intValue]];
396 int type = [[currentSelectedItem objectForKey:@"type"] intValue];
397 if (type == 1) {[statusField setStringValue:NSLocalizedString(@"NO_FOLDER_DL", @"Folder download not supported yet")];}
398 else if (type == 2) {
399 NSString* nameOnToppy = [currentSelectedItem objectForKey:@"name"];
400 NSSavePanel *nssave = [[NSSavePanel savePanel]retain];
401 int retButton = [nssave runModalForDirectory:nil file:nameOnToppy];
403 NSString* savePath= [nssave filename];
405 unsigned long long offset = 0;
406 NSFileHandle *newFileHandle = [NSFileHandle fileHandleForReadingAtPath:savePath];
407 if (!(newFileHandle==nil)) { // there is a file there, ask if want to resume
408 NSLog(@"existing file length: %qu", [newFileHandle seekToEndOfFile]);
409 //ask to resume, save offset if yes
410 //offset = [newFileHandle seekToEndOfFile];
412 [tfusbc setProgressBar:progressBar time:progressTime turbo:turboCB];
413 [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];
417 // [self updateHDDSize];
420 - (void) finishTransfer {
421 [currentlyField setStringValue:@""];
422 [progressBar setDoubleValue:0];
423 [[NSSound soundNamed:@"Ping"] play];
424 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
425 [currentlyField setStringValue:NSLocalizedString(@"IDLE", @"Idle")];
426 [currentlyField display];
429 - (IBAction) uploadFile: (id) sender {
432 NSOpenPanel *nsop = [[NSOpenPanel openPanel]retain];
433 [nsop setAllowsMultipleSelection:YES];
434 [nsop setCanChooseFiles:YES];
435 [nsop setCanChooseDirectories:YES];
436 int retButton = [nsop runModal];
437 NSArray *returnedNames = [nsop filenames];
438 if (retButton == NSFileHandlingPanelCancelButton) {
439 NSLog(@"Upload cancelled");
442 //get info about the chosen file - later if do folders check here and do recursive all things in folder???
443 NSEnumerator *enumerator = [returnedNames objectEnumerator];
445 // [statusField setStringValue:[NSLocalizedString(@"CONNECTED_OK", @"Connection OK") stringByAppendingString:NSLocalizedString(@"DOWNLOAD", @"Download")];
446 [connectLight setImage:[NSImage imageNamed:@"blink.tiff"]];
447 while (returnedName = [enumerator nextObject]) {
449 [self uploadPath:returnedName toPath:[NSString stringWithString:currentPath]];
455 - (void) uploadPath:(NSString*) path toPath:(NSString*) toPath {
458 NSFileManager* fm = [NSFileManager defaultManager];
459 NSDictionary *fattrs = [fm fileAttributesAtPath:path traverseLink:NO];
461 NSLog(@"Path of file to upload is incorrect!");
463 NSString* type = [fattrs fileType];
464 if ([type isEqualToString:@"NSFileTypeDirectory"]) {
465 // should look to create folder on Toppy, or add stuff if already there (maybe it does this automatically?), and place in subfolders etc
466 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[path lastPathComponent],@"newName",toPath,@"path",@"newFolder",@"transferType", nil]];
467 NSArray* subPaths = [fm directoryContentsAtPath:path];
468 NSEnumerator* e = [subPaths objectEnumerator];
470 while (object = [e nextObject]) {
471 NSString* subPath = [NSString stringWithFormat:@"%@/%@", path, object];
472 NSString* subToPath = [NSString stringWithFormat:@"%@\\%@", toPath, [path lastPathComponent]];
473 // NSLog(@"subdir: %@, %@", subPath, subToPath);
474 if (![object isEqualToString:@".DS_Store"]) {
475 [self uploadPath:subPath toPath:subToPath];
478 if (connected) { //may have disconnected during threaded upload (although not actually threaded here!)
479 // [self updateHDDSize];
480 [self goToPath:currentPath];
484 NSDictionary* fileAttr = [dh extractAttributes:fattrs]; // turn Dict into a new TypeFile dict
485 NSMutableArray* array = [NSMutableArray arrayWithArray:[path componentsSeparatedByString:@"/"]]; // cut down name
486 NSString* fileName = [NSString stringWithString:[array lastObject]];
487 NSData* typeFile = [dh getDataFromTFFile:fileAttr withName:fileName];
488 [progressBar setDoubleValue:0];
489 [currentlyField setStringValue:[NSLocalizedString(@"UPLOADING", @"Uploading") stringByAppendingString:fileName]];
490 [currentlyField displayIfNeeded];
491 [tfusbc setProgressBar:progressBar time:progressTime turbo:turboCB];
492 [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];
496 -(IBAction)deleteFile:(id)sender
500 if ( [tableView numberOfSelectedRows] == 0 )
502 NSString *title = NSLocalizedString(@"WARNING", @"Warning!");
503 NSString *defaultButton = NSLocalizedString(@"DEL", @"Delete");
504 NSString *alternateButton = NSLocalizedString(@"NO_DEL", @"Don't Delete");
505 NSString *otherButton = nil;
506 NSString *message = NSLocalizedString(@"DEL_MESSAGE", @"Are you sure you want to delete the selected file(s)?");
509 NSBeginAlertSheet(title, defaultButton, alternateButton, otherButton, mainWindow, self, @selector(sheetDidEnd:returnCode:contextInfo:), nil, nil, message);
512 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
514 if ( returnCode == NSAlertDefaultReturn ) {
515 NSLog(@"Deleting file(s) starting...");
516 NSEnumerator* selected = [tableView selectedRowEnumerator];
518 while (currentSelected = [selected nextObject]) {
519 id currentSelectedItem = [[dh displayedList] objectAtIndex:[currentSelected intValue]];
520 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:currentSelectedItem,@"file",currentPath,@"path",@"delete",@"transferType", nil]];
522 // [self updateHDDSize];
523 [self goToPath:currentPath];
524 //should check so don't delete root folders?
528 - (IBAction)openPrefsSheet:(id)sender
530 [NSApp beginSheet:prefsWindow
531 modalForWindow:mainWindow
533 didEndSelector:@selector(mySheetDidEnd:returnCode:contextInfo:)
535 return; // leave without doing anything else
538 - (IBAction) mySheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode
539 contextInfo:(void *)contextInfo {
541 [sheet orderOut:self];
542 if(returnCode == 0) return;
543 // continue with application
546 - (IBAction)closePrefsSheet:(id)sender
548 //do changes to prefs here
550 [tfusbc setDebug:[debugCB state]];
552 NSLog(@"auto: %i", [autoCB state]);
553 [prefs setBool:[autoCB state] forKey:@"auto-connect"];
554 // [prefs setBool:[epgCB state] forKey:@"epgSync"];
556 [NSApp endSheet:prefsWindow returnCode:1];
559 - (IBAction)openRenameSheet:(id)sender
561 if ( [tableView numberOfSelectedRows] != 1 )
563 [renameOld setStringValue:[[[dh displayedList] objectAtIndex:[tableView selectedRow]] objectForKey:@"name"]];
564 [renameNew setStringValue:[renameOld stringValue]];
565 // [renameWindow setTitleBarHeight:0.0];
566 [NSApp beginSheet: renameWindow
567 modalForWindow: mainWindow
571 [NSApp runModalForWindow: renameWindow];
575 - (IBAction)cancelRename:(id)sender{
576 [NSApp endSheet: renameWindow];
577 [renameWindow orderOut: self];
581 - (IBAction)closeRenameSheet:(id)sender
583 //do changes to rename here
585 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[renameOld stringValue],@"oldName",[renameNew stringValue],@"newName", currentPath,@"path",@"rename",@"transferType",nil]];
586 [self goToPath:currentPath];
589 [self cancelRename:sender];
593 - (IBAction)openNewFolderSheet:(id)sender
595 [NSApp beginSheet: newFolderWindow
596 modalForWindow: mainWindow
600 [NSApp runModalForWindow: newFolderWindow];
605 - (IBAction)cancelNewFolder:(id)sender{
606 [NSApp endSheet: newFolderWindow];
607 [newFolderWindow orderOut: self];
611 - (IBAction)closeNewFolderSheet:(id)sender
613 //do changes to make new folder here
615 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[newFolderNew stringValue],@"newName",currentPath,@"path",@"newFolder",@"transferType", nil]];
616 [self goToPath:currentPath];
619 [self cancelNewFolder:sender];
622 - (IBAction)pathBarClick:(id)sender {
623 int segCount = [pathBar segmentCount]; //remember count starts at 1, not zero!
624 int selectedSegment = [sender selectedSegment];
625 if (selectedSegment == segCount - 1) return; //no need to move anywhere
626 int i = 1; // remember have "path" there too
627 NSMutableArray* pathArray = [NSMutableArray arrayWithCapacity:selectedSegment];
628 while (i<=selectedSegment) {
629 [pathArray addObject:[[pathBar cell] labelForSegment:i]];
632 NSString* pathString = [pathArray componentsJoinedByString:@"\\"];
633 if ([pathString hasPrefix:@"\\\\"]) pathString = [pathString substringFromIndex:1];
634 [self goToPath:pathString];
635 currentPath = [[NSString stringWithString:pathString] retain];
636 NSRect r = [pathBar frame];
637 [[pathBar cell] setSegmentCount:selectedSegment+1];
638 [pathBar displayIfNeededInRect:r];
645 - (USBDeviceContext*) getContext {
649 - (NSNumber*) isConnected {
650 return [NSNumber numberWithBool:connected];
654 - (NSString*) currentPath {
658 - (IBAction) toggleTurbo:(id)sender {
659 if ([[tfusbc transferQueue] count] > 0) { //have a current transfer, lets toggle it
660 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"turbo",@"transferType",[NSNumber numberWithBool:[turboCB state]],@"turboOn",nil]];
664 - (IBAction) toggleTurboCB:(id)sender {
667 if ([turboCB state]) { // currently on, want off
668 [turboCB setState:0];
670 [turboCB setState:1];
672 if ([[tfusbc transferQueue] count] > 0) { //have a current transfer, lets toggle it
673 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"turbo",@"transferType",[NSNumber numberWithBool:[turboCB state]],@"turboOn",nil]];
677 - (IBAction) togglePreview:(id)sender {
678 [previewDrawer toggle:sender];
681 /*- (IBAction) snapshot:(id) sender {
682 NSArray* snapshotData = [self snapshotOfPath:@"\\"];
683 [dh setSnapShot:snapshotData];
684 // show snapshot window
685 [snapshotWindow makeKeyAndOrderFront:sender];
686 [outlineView reloadData];
689 - (NSArray*) snapshotOfPath:(NSString*)path {
691 NSData* hddFileData = [tfusbc getFileList:context forPath:path];
692 NSData* checkForError = [hddFileData subdataWithRange:(NSRange){4,4}];
693 const UInt32 check_bigendian = EndianU32_NtoB(USB_Fail);
694 const UInt32 check2_bigendian = EndianU32_NtoB(USB_DataHddDir);
695 if ([checkForError isEqualToData:[NSData dataWithBytes:&check_bigendian length:4]]) {
696 [statusField setStringValue:@"Connected - error on last command"];
698 if (! [checkForError isEqualToData:[NSData dataWithBytes:&check2_bigendian length:4]]) {
699 hddFileData = [tfusbc getFileList:context forPath:path]; //try again
700 if ([checkForError isEqualToData:[NSData dataWithBytes:&check_bigendian length:4]]) {
701 [statusField setStringValue:@"Connected - error on last command"];
704 hddFileData = [hddFileData subdataWithRange:(NSRange) {8, [hddFileData length]-8}]; // cut off header and cmd
706 NSMutableArray* paths = [[NSMutableArray alloc] init];
707 for (i=0; i*114 < [hddFileData length]-4; i++) { // 4 is there cause swapping sometimes adds a byte of padding
708 NSData* temp = [hddFileData subdataWithRange:(NSRange) {i*114,114}];
709 NSMutableDictionary* tfFile = [dh getTFFileFromSwappedHexData:temp];
710 [dh convertRawDataToUseful:tfFile];
711 if (!([[tfFile objectForKey:@"name"] isEqualToString:@".."])) {
712 if ([[tfFile objectForKey:@"type"] intValue] == 1) { //folder
713 NSMutableString* temp = [NSMutableString stringWithString:path];
714 if (![temp isEqualToString:@"\\"])
715 [temp appendString:@"\\"];
716 [temp appendString:[tfFile objectForKey:@"name"]];
717 [paths addObject:tfFile];
718 [paths addObject:[self snapshotOfPath:temp]];
720 [paths addObject:tfFile];
729 /*- (IBAction) epg:(id) sender {
730 XMLToEPG *xmlConv = [[XMLToEPG alloc] init];
731 NSOpenPanel *nsop = [[NSOpenPanel openPanel]retain];
732 NSArray *fileType = [NSArray arrayWithObject:@"xml"];
733 [nsop setAllowsMultipleSelection:NO];
734 [nsop setCanChooseFiles:YES];
735 [nsop setCanChooseDirectories:NO];
736 [nsop runModalForTypes:fileType];
737 NSMutableArray* importedXML = [xmlConv importXML:[nsop URL]];
738 [xmlConv fixData:importedXML];
739 [xmlConv exportFixedXML:importedXML toFile:@"/Volumes/Tyr/nathan/Desktop/TV/Guides/test.tgd"];
744 /* if ([prefs boolForKey:@"epgSync"]) {
746 XMLToEPG *xmlConv = [[XMLToEPG alloc] init];
747 NSString* path = @"/Volumes/Tyr/nathan/Desktop/TV/Guides/tv.xml";
748 NSString* tempFile = @"/Volumes/Tyr/nathan/Desktop/TV/Guides/test.epg";
749 NSMutableArray* importedXML = [xmlConv importXML:[NSURL fileURLWithPath:path]];
750 [xmlConv fixData:importedXML];
751 [xmlConv exportFixedXML:importedXML toFile:tempFile];
754 NSFileManager* fm = [NSFileManager defaultManager];
755 NSDictionary *fattrs = [fm fileAttributesAtPath:tempFile traverseLink:NO];
757 NSLog(@"Path of file to upload is incorrect!");
760 NSDictionary* fileAttr = [dh extractAttributes:fattrs];
761 NSMutableArray* array = [NSMutableArray arrayWithArray:[tempFile componentsSeparatedByString:@"/"]];
762 NSString* fileName = [NSString stringWithString:[array lastObject]];
763 NSData* typeFile = [dh getDataFromTFFile:fileAttr withName:fileName];
764 [tfusbc uploadFile:tempFile ofSize:[fattrs fileSize] fromPath:@"\\Program Files\\TimerKey\\" withAttributes:typeFile toDevice:context];
765 [self goToPath:currentPath];
771 /*- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
773 if ([prefs objectForKey:@"NoRollover"] != nil) return;
774 if ([aTableView mouseOverRow] == rowIndex && ([aTableView selectedRow] != rowIndex))
775 if ([aTableView lockFocusIfCanDraw]) {
776 NSRect rowRect = [aTableView rectOfRow:rowIndex];
777 NSRect columnRect = [aTableView rectOfColumn:[[aTableView tableColumns] indexOfObject:aTableColumn]];
779 if (!highlightImage) {
780 highlightImage = [[NSImage alloc] initWithData:[highlightImageData propertyList]];
781 [highlightImage setDataRetained:YES]; //?
782 [highlightImage setCacheMode:NSImageCacheAlways]; //?
785 [highlightImage drawInRect:NSIntersectionRect(rowRect, columnRect) fromRect:NSMakeRect(0,0,1,[highlightImage size].height) operation:NSCompositeSourceOver fraction:0.3];
786 [aTableView unlockFocus];
793 if (highlightImage) [highlightImage release];
797 - (IBAction)pauseCurrentTransfer:(id)sender {
799 [pauseButton setImage:[NSImage imageNamed:@"DownloadResume.tif"]];
800 [pauseButton setAlternateImage:[NSImage imageNamed:@"DownloadResumePressed.tif"]];
801 //add priority "halt" to queue naming file
802 id current = [[tfusbc transferQueue] objectAtIndex:0];
803 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"pause",@"transferType",[current objectForKey:@"filename"],@"filename",nil]];
805 [currentlyField setStringValue:[NSLocalizedString(@"PAUSED", @"Paused: ") stringByAppendingString:[[current objectForKey:@"filename"]objectForKey:@"name"]]];
806 [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
807 [currentlyField displayIfNeeded];
809 //change image to pause
810 //add priority "resume" to queue naming file
811 [pauseButton setImage:[NSImage imageNamed:@"DownloadStop.tif"]];
812 [pauseButton setAlternateImage:[NSImage imageNamed:@"DownloadStopPressed.tif"]];
813 id current = [[tfusbc pausedQueue] objectAtIndex:0];//temp as for now only have 1 paused
814 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:@"resume",@"transferType",[current objectForKey:@"filename"],@"filename",nil]];
816 [currentlyField setStringValue:[NSLocalizedString(@"DOWNLOADING", @"Downloading: ") stringByAppendingString:[[current objectForKey:@"filename"]objectForKey:@"name"]]];
817 [connectLight setImage:[NSImage imageNamed:@"blink.tiff"]];
818 [currentlyField displayIfNeeded];
822 - (id) selectedColumn {
823 return selectedColumn;
825 - (id) currentlyField {
826 return currentlyField;
828 - (id) connectLight {