Prominent notice in DataHandler.h.
[MacTF.git] / UIElements.m
blobb5c0f6e5522b33bd41d99080a2a7752681db3af5
1 // MacTF Copyright 2004 Nathan Oates
3 /* 
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.
9  *
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.
14  *
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.
18  */
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 {
28     return YES;
31 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)path
33         if (!connected) 
34                 [self connect:nil];
35         [self uploadPath:path toPath:[NSString stringWithString:currentPath]];
36         NSLog(@"DockUpload:%@", path);
37         return YES;
40 -(void) awakeFromNib {
41         [mainWindow setTitleBarHeight:22.0];
42         [mainWindow setBottomBarHeight:18.0];
43         [mainWindow setMidBarHeight: 32.0 origin:40.0];
44         connected = NO;
45         paused = NO;
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
55         sortAscending = TRUE;
56         [turboCB setState:0];
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];
63         [pathBar sizeToFit];
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"]) {
68                 [self connect:nil];
69                 [autoCB setState:1];    
70         }
71         // test code heres
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]);
78         
79         }
82 - (BOOL)validateMenuItem:(NSMenuItem*)anItem {
83     if ([[anItem title] isEqualToString:NSLocalizedString(@"DL_MENUITEM", @"Download")] && (1 > [tableView numberOfSelectedRows])) {
84         return NO;
85     }
86         if ([[anItem title] isEqualToString:NSLocalizedString(@"DEL_MENUITEM", @"Delete")] && (1 > [tableView numberOfSelectedRows])) {
87         return NO;
88     }
89         if ([[anItem title] isEqualToString:NSLocalizedString(@"RN_MENUITEM", @"Rename")] && (1 != [tableView numberOfSelectedRows])) {
90         return NO;
91     }
92         if ([[anItem title] isEqualToString:NSLocalizedString(@"UL_MENUITEM", @"Upload")] && (! connected)) {
93         return NO;
94     }
95         if ([[anItem title] isEqualToString:NSLocalizedString(@"NF_MENUITEM", @"NewFolder")] && (! connected)) {
96         return NO;
97     }
98     return YES;
101 - (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem {
102     if ([[toolbarItem itemIdentifier] isEqual:@"ConnectTBIcon"]) {
103                 if (connected) {
104                         [toolbarItem setLabel:NSLocalizedString(@"DC_BUTTON", @"Disconnect")];
105                 } else {
106                         [toolbarItem setLabel:NSLocalizedString(@"CON_BUTTON", @"Connect")];
107                 }
108         }
109         if ([[toolbarItem itemIdentifier] isEqual:@"UploadTBIcon"] && (! connected)) {
110                 return NO;
111         }
112         if ([[toolbarItem itemIdentifier] isEqual:@"NewFolderTBIcon"] && (! connected)) {
113                 return NO;
114         }
115         if ([[toolbarItem itemIdentifier] isEqual:@"TurboTBIcon"] && (! connected)) {
116                 return NO;
117         }
118         if ([[toolbarItem itemIdentifier] isEqual:@"DownloadTBIcon"] && (1 > [tableView numberOfSelectedRows] || !connected)) {
119                 return NO;
120         }
121         if ([[toolbarItem itemIdentifier] isEqual:@"DeleteTBIcon"] && (1 > [tableView numberOfSelectedRows] || !connected)) {
122                 return NO;
123         }
124         if ([[toolbarItem itemIdentifier] isEqual:@"RenameTBIcon"] && (1 != [tableView numberOfSelectedRows] || !connected)) {
125                 return NO;
126         }
127     return YES;
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)
136                 return;
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) {
148                                 usleep(10);
149                         }
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) {
157                                 usleep(10);
158                         }
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"]];
166                 }       
167                 else {
168                         [drawerTabView selectTabViewItemAtIndex:0];
169                         return;
170                 }
171         } else if (type == 1) { //folder
172                 [drawerTabView selectTabViewItemAtIndex:0];
173                 return;
174         } else {
175                 [statusField setStringValue:NSLocalizedString(@"SEL_ERROR", @"Selection error...")];
176                 return;
177         }
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);
192         NSString *ret = nil;
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. ) )];
199         return ret;
202 - (IBAction) connect: (id) sender { 
203         if (! connected) {
204                 context = [tfusbc initializeUSB];
205                 if (context == nil) {
206                         [statusField setStringValue:NSLocalizedString(@"INIT_PROBLEM", @"Message when initialization fails.")];
207                         return;
208                 }
209                 // add a check here to see if really connected...
210                 connected = YES;
211                 [[dh fileList] removeAllObjects];
212                 [[dh fileList] addObject:[NSDictionary dictionaryWithObject:NSLocalizedString(@"FETCHING", @"Fetching") forKey:@"name"]];
213                 [tableView reloadData];
214                 [tfusbc clearQueues];
215                 paused = NO;
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];
223                 [pathBar sizeToFit];
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
230                 connected = NO;
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
232                         sleep(3);
233                 }
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"]];
242                 currentPath = @"\\";
243                 return;
244         }
245         int ret = [self goToPath:@"\\"];
246         if (ret == 1) { 
247                 sleep (5); //error, wait a few secs for HDD to start if need be then try again
248                 [self goToPath:@"\\"];
249         }
250         currentPath = @"\\";
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)
260                 return;
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
274                                 }
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")];
282                         } else {//root
283                                 currentPath = @"\\";
284                                 [[pathBar cell] setSegmentCount:1];
285                         }
286                 } else { //move down
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
293                 }
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];
300                         [pathBar sizeToFit];
301                         [pathBar displayIfNeededInRect:r];
302                         [statusField setStringValue:NSLocalizedString(@"CONNECTED_OK", @"Connection OK")];
303                 }
304         } else {
305                 [statusField setStringValue:NSLocalizedString(@"SEL_ERROR", @"Selection error...")];
306                 return; 
307         }
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}]];
322         } 
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];
335                 } else
336                         if ([[tableColumn identifier] isEqualToString:@"date"]) {
337                                 NSSortDescriptor* dateDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"sortdate" ascending:YES] autorelease];
338                                 sortDescriptors=[NSArray arrayWithObject:dateDescriptor];
339                         } else
340                                 if ([[tableColumn identifier] isEqualToString:@"size"]) {
341                                         NSSortDescriptor* sizeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"fileSize" ascending:YES] autorelease];
342                                         sortDescriptors=[NSArray arrayWithObject:sizeDescriptor];
343                                 }  else
344                                         if ([[tableColumn identifier] isEqualToString:@"icon"]) {
345                                                 NSSortDescriptor* sizeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"suffix" ascending:YES] autorelease];
346                                                 sortDescriptors=[NSArray arrayWithObject:sizeDescriptor];
347                                         }
348                 sortedArray=[[dh fileList] sortedArrayUsingDescriptors:sortDescriptors];                
349                 indicatorImage = [NSImage imageNamed: @"NSAscendingSortIndicator"];
350     } else {
351         if ([[tableColumn identifier] isEqualToString:@"name"]) {
352                         NSSortDescriptor* nameDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO selector:@selector(caseInsensitiveCompare:)] autorelease];
353                         sortDescriptors=[NSArray arrayWithObject:nameDescriptor];
354                 } else
355                         if ([[tableColumn identifier] isEqualToString:@"date"]) {
356                                 NSSortDescriptor* dateDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"sortdate" ascending:NO] autorelease];
357                                 sortDescriptors=[NSArray arrayWithObject:dateDescriptor];
358                         } else
359                                 if ([[tableColumn identifier] isEqualToString:@"size"]) {
360                                         NSSortDescriptor* sizeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"fileSize" ascending:NO] autorelease];
361                                         sortDescriptors=[NSArray arrayWithObject:sizeDescriptor];
362                                 } else
363                                 if ([[tableColumn identifier] isEqualToString:@"icon"]) {
364                                         NSSortDescriptor* sizeDescriptor=[[[NSSortDescriptor alloc] initWithKey:@"suffix" ascending:NO] autorelease];
365                                         sortDescriptors=[NSArray arrayWithObject:sizeDescriptor];
366                                 }
368                 sortedArray=[[dh fileList] sortedArrayUsingDescriptors:sortDescriptors];                
369         indicatorImage = [NSImage imageNamed: @"NSDescendingSortIndicator"];
370     }
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];
378         id currentCol;
379         while (currentCol = [cols nextObject]) {
380                 [tView setIndicatorImage: nil inTableColumn: currentCol];
381         }
382         [dh setFileList:sortedArray];
383         [dh search:searchField];
384         [dh reloadTable];
388 - (IBAction) downloadSelectedFile:(id)sender{
389         if (! connected)
390                 return;
391         NSLog(@"Download file starting...");
392         NSEnumerator* selected = [tableView selectedRowEnumerator];
393         id currentSelected;
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];
402                         if (retButton) {
403                                 NSString* savePath= [nssave filename]; 
404                                 NSLog(savePath);
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];
411                                 }
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];
414                         }
415                 }               
416         }
417         //              [self updateHDDSize];
418         }
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 {
430         if (! connected)
431                 return;
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");
440                 return;
441         }
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];
444         id returnedName;
445 //      [statusField setStringValue:[NSLocalizedString(@"CONNECTED_OK", @"Connection OK") stringByAppendingString:NSLocalizedString(@"DOWNLOAD", @"Download")]; 
446         [connectLight setImage:[NSImage imageNamed:@"blink.tiff"]];
447         while (returnedName = [enumerator nextObject]) {
448                 NSLog(returnedName);
449                 [self uploadPath:returnedName toPath:[NSString stringWithString:currentPath]];
450         }
455 - (void) uploadPath:(NSString*) path toPath:(NSString*) toPath {
456         if (! connected)
457                 return;
458         NSFileManager* fm = [NSFileManager defaultManager];
459         NSDictionary *fattrs = [fm fileAttributesAtPath:path traverseLink:NO];
460         if (!fattrs) {
461                 NSLog(@"Path of file to upload is incorrect!");
462                 return; }
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];
469                 id object;
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];
476                         }
477                 }
478                 if (connected) { //may have disconnected during threaded upload (although not actually threaded here!)
479         //              [self updateHDDSize];
480                         [self goToPath:currentPath];
481                 }
482         }
483         else {
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];
493         }
496 -(IBAction)deleteFile:(id)sender
498         if (! connected)
499                 return;
500         if ( [tableView numberOfSelectedRows] == 0 )
501         return;
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)?");
508     NSBeep();
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];
517                 id currentSelected;
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]];
521                 }
522         //      [self updateHDDSize];
523                 [self goToPath:currentPath];
524                 //should check so don't delete root folders?
525         }
528 - (IBAction)openPrefsSheet:(id)sender
530         [NSApp beginSheet:prefsWindow
531            modalForWindow:mainWindow
532                 modalDelegate:self
533            didEndSelector:@selector(mySheetDidEnd:returnCode:contextInfo:)
534           contextInfo: nil];
535         return;  // leave without doing anything else
538 - (IBAction) mySheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode
539                            contextInfo:(void *)contextInfo {
540         
541         [sheet orderOut:self];
542         if(returnCode == 0)  return;
543         // continue with application  
546 - (IBAction)closePrefsSheet:(id)sender
548         //do changes to prefs here
549         //    if (connected) {
550         [tfusbc setDebug:[debugCB state]]; 
551         //  }
552         NSLog(@"auto: %i", [autoCB state]);
553         [prefs setBool:[autoCB state] forKey:@"auto-connect"];
554 //      [prefs setBool:[epgCB state] forKey:@"epgSync"];
555         [prefs synchronize];
556         [NSApp endSheet:prefsWindow returnCode:1];
559 - (IBAction)openRenameSheet:(id)sender
561         if ( [tableView numberOfSelectedRows] != 1 )
562         return;
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
568                 modalDelegate: nil
569            didEndSelector: nil
570                   contextInfo: nil];
571     [NSApp runModalForWindow: renameWindow];
572     // Sheet is up here.
575 - (IBAction)cancelRename:(id)sender{
576         [NSApp endSheet: renameWindow];
577     [renameWindow orderOut: self];
578         [NSApp stopModal];
581 - (IBAction)closeRenameSheet:(id)sender
583         //do changes to rename here
584         if (connected) {
585                 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[renameOld stringValue],@"oldName",[renameNew stringValue],@"newName", currentPath,@"path",@"rename",@"transferType",nil]];
586                 [self goToPath:currentPath];
587         }
588                 //then close up
589         [self cancelRename:sender];
593 - (IBAction)openNewFolderSheet:(id)sender
595         [NSApp beginSheet: newFolderWindow
596            modalForWindow: mainWindow
597                 modalDelegate: nil
598            didEndSelector: nil
599                   contextInfo: nil];
600     [NSApp runModalForWindow: newFolderWindow];
601     // Sheet is up here.
602         
605 - (IBAction)cancelNewFolder:(id)sender{
606         [NSApp endSheet: newFolderWindow];
607     [newFolderWindow orderOut: self];
608         [NSApp stopModal];
611 - (IBAction)closeNewFolderSheet:(id)sender
613         //do changes to make new folder here
614         if (connected) {
615                 [tfusbc addPriorityTransfer:[NSDictionary dictionaryWithObjectsAndKeys:[newFolderNew stringValue],@"newName",currentPath,@"path",@"newFolder",@"transferType", nil]];
616                 [self goToPath:currentPath];
617         }
618         //then close up
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]];
630                 i++;
631         } 
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];      
641 - (id)getTfusbc {
642         return tfusbc;
645 - (USBDeviceContext*) getContext {
646         return context;
649 - (NSNumber*) isConnected {
650         return [NSNumber numberWithBool:connected];
654 - (NSString*) currentPath {
655         return 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]];
661         }
664 - (IBAction) toggleTurboCB:(id)sender {
665         if (! connected)
666                 return;
667         if ([turboCB state]) { // currently on, want off
668                 [turboCB setState:0];
669         } else {
670                 [turboCB setState:1];
671         }
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]];
674         }
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 {
690         
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"];
702         }
704 hddFileData = [hddFileData subdataWithRange:(NSRange) {8, [hddFileData length]-8}]; // cut off header and cmd 
705 int i;
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]];
719                 } else {
720                         [paths addObject:tfFile];
721                 }
722         }
724 return paths;
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"]) {
745                         [epgCB setState:1];
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];
752                         if (! connected)
753                                 return;
754                         NSFileManager* fm = [NSFileManager defaultManager];
755                         NSDictionary *fattrs = [fm fileAttributesAtPath:tempFile traverseLink:NO];
756                         if (!fattrs) {
757                                 NSLog(@"Path of file to upload is incorrect!");
758                                 return;
759                         }
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];
766                         [self resetTurbo];
767                 } */
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]; //?
783                                         }
785                                 [highlightImage drawInRect:NSIntersectionRect(rowRect, columnRect) fromRect:NSMakeRect(0,0,1,[highlightImage size].height) operation:NSCompositeSourceOver fraction:0.3];
786                                 [aTableView unlockFocus];
787                         }
791 - (void)dealloc
793   if (highlightImage) [highlightImage release];
794 [super dealloc];
797 - (IBAction)pauseCurrentTransfer:(id)sender {
798         if (!paused) {
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]];
804         paused = YES;
805         [currentlyField setStringValue:[NSLocalizedString(@"PAUSED", @"Paused: ") stringByAppendingString:[[current objectForKey:@"filename"]objectForKey:@"name"]]];
806         [connectLight setImage:[NSImage imageNamed:@"green.tiff"]];
807         [currentlyField displayIfNeeded];
808         } else {
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]];
815         paused = NO;
816         [currentlyField setStringValue:[NSLocalizedString(@"DOWNLOADING", @"Downloading: ") stringByAppendingString:[[current objectForKey:@"filename"]objectForKey:@"name"]]];
817         [connectLight setImage:[NSImage imageNamed:@"blink.tiff"]];
818         [currentlyField displayIfNeeded];
819         }
822 - (id) selectedColumn {
823         return selectedColumn;
825 - (id) currentlyField {
826         return currentlyField;
828 - (id) connectLight {
829         return connectLight;
832 @end