ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/MacOSX/Launcher/VMListController.mm
(Generate patch)

Comparing SheepShaver/src/MacOSX/Launcher/VMListController.mm (file contents):
Revision 1.5 by asvitkine, 2009-08-02T23:17:18Z vs.
Revision 1.10 by asvitkine, 2009-08-31T05:08:21Z

# Line 25 | Line 25
25  
26   TODO:
27  
28 Verify if VM exists
29 Create Disk on New VM
30 Keep track of VMs that are running and disallow editing settings, re-launching, etc..
31 Drag-drop to re-arrange order of VMs
28   Drag VM from Finder to import
29 < Don't show Preferences menu in spawned SheepShaver instances - or make them
30 < use the same nib file as this app!
29 > When choosing things like rom file and keycode files - have a checkbox to copy
30 > selected file into the bundle.
31 > Copy path!
32  
33   */
34  
35 + @interface NSObject (TableViewContextMenu)
36 + - (NSMenu *) tableView: (NSTableView *) tableView menuForEvent: (NSEvent *) event;
37 + @end
38 +
39 + @implementation NSTableView (ContextMenu)
40 + - (NSMenu *) menuForEvent: (NSEvent *) event
41 + {
42 +        if ([[self delegate] respondsToSelector:@selector(tableView:menuForEvent:)])
43 +                return [[self delegate] tableView:self menuForEvent:event];
44 +        return nil;
45 + }
46 + @end
47 +
48 + #define VM_DRAG_TYPE @"sheepvm"
49 +
50   @implementation VMListController
51  
52   + (id) sharedInstance
# Line 54 | Line 66 | use the same nib file as this app!
66          vmArray = [[NSMutableArray alloc] initWithCapacity:[vms count]];
67          [vmArray addObjectsFromArray:vms];
68  
69 +        tasks = [[NSMutableDictionary alloc] init];
70 +
71 +        [[NSNotificationCenter defaultCenter] addObserver:self
72 +                selector:@selector(onTaskTerminated:)
73 +                name:NSTaskDidTerminateNotification
74 +                object:nil];
75 +
76          return self;
77   }
78  
79   - (void) awakeFromNib
80   {
81 +        [[[vmList tableColumns] objectAtIndex:0] setEditable:YES];
82          [vmList setDataSource: self];
83          [vmList setDelegate: self];
84          [vmList reloadData];
85 +        [vmList registerForDraggedTypes:[NSArray arrayWithObjects:VM_DRAG_TYPE, nil]];
86 + }
87 +
88 + - (void) _showNotFoundAlert
89 + {
90 +        NSAlert *alert = [[[NSAlert alloc] init] autorelease];
91 +        [alert setMessageText:@"The virtual machine cannot be found."];
92 +        [alert setAlertStyle:NSWarningAlertStyle];
93 +        [alert beginSheetModalForWindow:[self window]
94 +                    modalDelegate:self
95 +                   didEndSelector:nil
96 +                      contextInfo:nil];
97 + }
98 +
99 + - (void) reloadDataAndSave
100 + {
101 +        [vmList reloadData];
102 +        [[NSUserDefaults standardUserDefaults] setObject:vmArray forKey:@"vm_list"];
103   }
104  
105   - (void) keyDown: (NSEvent *) event
# Line 81 | Line 119 | use the same nib file as this app!
119  
120   - (id) tableView: (NSTableView *) table objectValueForTableColumn: (NSTableColumn *) c row: (int) r
121   {
122 <        return [vmArray objectAtIndex: r]; // [[vmArray objectAtIndex: r] lastPathComponent];
122 >        return [[[vmArray objectAtIndex: r] lastPathComponent] stringByDeletingPathExtension];
123 > }
124 >
125 > - (void) tableView: (NSTableView *) table setObjectValue: (id) value forTableColumn: (NSTableColumn *) c row: (int) r
126 > {
127 >        NSString *currentPath = [vmArray objectAtIndex: r];
128 >        NSString *newPath = [[NSString stringWithFormat:@"%@/%@.sheepvm",
129 >                [currentPath stringByDeletingLastPathComponent], value] retain];
130 >        if (![currentPath isEqual:newPath]) {
131 >                if ([[NSFileManager defaultManager] fileExistsAtPath:currentPath]) {
132 >                        NSFileManager *manager = [NSFileManager defaultManager];
133 >                        if ([manager movePath: currentPath toPath: newPath handler:nil]) {
134 >                                [vmArray replaceObjectAtIndex: r withObject: newPath];
135 >                                [currentPath release];
136 >                        }
137 >                } else {
138 >                        [self _showNotFoundAlert];
139 >                }
140 >        }
141   }
142  
143   - (void) tableViewSelectionDidChange: (NSNotification *) notification
# Line 95 | Line 151 | use the same nib file as this app!
151          }
152   }
153  
154 < //- (NSString *) tableView: (NSTableView *) table toolTipForCell: (NSCell *) cell rect: (NSRectPointer) rect
155 < //             tableColumn: (NSTableColumn *) c row: (int) r mouseLocation: (NSPoint) loc
156 < //{
157 < //      return [vmArray objectAtIndex: r];
158 < //}
154 > - (BOOL) tableView: (NSTableView *) table writeRowsWithIndexes: (NSIndexSet *) rows toPasteboard: (NSPasteboard *) pboard
155 > {
156 >        vmBeingDragged = [vmArray objectAtIndex:[rows firstIndex]];
157 >        [pboard declareTypes:[NSArray arrayWithObject:VM_DRAG_TYPE] owner:self];
158 >        [pboard setString:VM_DRAG_TYPE forType:VM_DRAG_TYPE];
159 >        return YES;
160 > }
161 >
162 > - (NSDragOperation) tableView: (NSTableView *) table validateDrop: (id <NSDraggingInfo>) info proposedRow: (int) row proposedDropOperation: (NSTableViewDropOperation) op
163 > {
164 >        if (op == NSTableViewDropAbove && row != -1) {
165 >                return NSDragOperationPrivate;
166 >        } else {
167 >                return NSDragOperationNone;
168 >        }
169 > }
170 >
171 > - (BOOL) tableView: (NSTableView *) table acceptDrop: (id <NSDraggingInfo>) info row: (int) row dropOperation: (NSTableViewDropOperation) op
172 > {      
173 >        if ([[[info draggingPasteboard] availableTypeFromArray:[NSArray arrayWithObject:VM_DRAG_TYPE]] isEqualToString:VM_DRAG_TYPE]) {
174 >                [vmList deselectAll:nil];
175 >                int index = [vmArray indexOfObject:vmBeingDragged];
176 >                if (index != row) {
177 >                        [vmArray insertObject:vmBeingDragged atIndex:row];
178 >                        if (row <= index) {
179 >                                index += 1;
180 >                        } else {
181 >                                row -= 1;
182 >                        }
183 >                        [vmArray removeObjectAtIndex: index];
184 >                }
185 >                [self reloadDataAndSave];
186 >                [vmList selectRow:row byExtendingSelection:NO];
187 >                return YES;
188 >        }
189 >
190 >        return NO;
191 > }
192 >
193 > - (NSMenu *) tableView: (NSTableView *) table menuForEvent: (NSEvent *) event
194 > {
195 >        NSMenu *menu = nil;
196 >        int row = [table rowAtPoint:[table convertPoint:[event locationInWindow] fromView:nil]];
197 >        if (row >= 0) {
198 >                [table selectRow:row byExtendingSelection:NO];
199 >                menu = [[[NSMenu alloc] initWithTitle: @"Contextual Menu"] autorelease];
200 >                [menu addItemWithTitle: @"Launch Virtual Machine"
201 >                                action: @selector(launchVirtualMachine:) keyEquivalent: @""];
202 >                [menu addItemWithTitle: @"Edit VM Settings..."
203 >                                action: @selector(editVirtualMachineSettings:) keyEquivalent: @""];
204 >                [menu addItemWithTitle: @"Reveal VM in Finder"
205 >                                action: @selector(revealVirtualMachineInFinder:) keyEquivalent: @""];
206 >                [menu addItemWithTitle: @"Remove VM from List"
207 >                                action: @selector(deleteVirtualMachine:) keyEquivalent: @""];
208 >        }
209 >        return menu;
210 > }
211 >
212 > - (NSString *) tableView: (NSTableView *) table toolTipForCell: (NSCell *) cell rect: (NSRectPointer) rect
213 >             tableColumn: (NSTableColumn *) c row: (int) r mouseLocation: (NSPoint) loc
214 > {
215 >        return [vmArray objectAtIndex: r];
216 > }
217  
218   - (IBAction) newVirtualMachine: (id) sender
219   {
# Line 124 | Line 238 | use the same nib file as this app!
238                  [manager createFileAtPath:[[save filename] stringByAppendingPathComponent:@"prefs"] contents:nil attributes:nil];
239                  [vmArray addObject:[save filename]];
240                  [vmList reloadData];
127                [[NSUserDefaults standardUserDefaults] setObject:vmArray forKey:@"vm_list"];
241                  [vmList selectRow:([vmArray count] - 1) byExtendingSelection:NO];
242 <                [self editVirtualMachineSettings:self];
242 >                [[VMSettingsController sharedInstance] editSettingsForNewVM:[save filename] sender:self];
243                  if ([[VMSettingsController sharedInstance] cancelWasClicked]) {
244                          [manager removeFileAtPath:[save filename] handler:nil];
245                          [vmArray removeObjectAtIndex:([vmArray count] - 1)];
133                        [vmList reloadData];
246                  }
247 <                // TODO advanced: show sub-panel in save dialog that says "Create Disk:"
247 >                [self reloadDataAndSave];
248          }
249   }
250  
# Line 158 | Line 270 | use the same nib file as this app!
270   {
271          if (returnCode == NSOKButton) {
272                  [vmArray addObject:[open filename]];
273 <                [vmList reloadData];
162 <                [[NSUserDefaults standardUserDefaults] setObject:vmArray forKey:@"vm_list"];
273 >                [self reloadDataAndSave];
274          }
275   }
276  
# Line 167 | Line 278 | use the same nib file as this app!
278   {
279          int selectedRow = [vmList selectedRow];
280          if (selectedRow >= 0) {
281 <                [[VMSettingsController sharedInstance] editSettingsFor:[vmArray objectAtIndex:selectedRow] sender:sender];
281 >                NSString *path = [vmArray objectAtIndex:selectedRow];
282 >                if ([tasks objectForKey:path]) {
283 >                        NSAlert *alert = [[[NSAlert alloc] init] autorelease];
284 >                        [alert setMessageText:@"Cannot edit virtual machine settings while it's running."];
285 >                        [alert setAlertStyle:NSWarningAlertStyle];
286 >                        [alert beginSheetModalForWindow:[self window]
287 >                                    modalDelegate:self
288 >                                   didEndSelector:nil
289 >                                      contextInfo:nil];
290 >                } else if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
291 >                        [[VMSettingsController sharedInstance] editSettingsFor:path sender:sender];
292 >                } else {
293 >                        [self _showNotFoundAlert];
294 >                }
295          }
296   }
297  
# Line 175 | Line 299 | use the same nib file as this app!
299   {
300          int selectedRow = [vmList selectedRow];
301          if (selectedRow >= 0) {
302 <                NSTask *sheep = [[NSTask alloc] init];
303 <                [sheep setLaunchPath:[[NSBundle mainBundle] pathForAuxiliaryExecutable:@"SheepShaver"]];
304 <                [sheep setArguments:[NSArray arrayWithObject:[vmArray objectAtIndex:selectedRow]]];
305 <                [sheep launch];
302 >                NSString *path = [vmArray objectAtIndex:selectedRow];
303 >                if ([tasks objectForKey:path]) {
304 >                        NSAlert *alert = [[[NSAlert alloc] init] autorelease];
305 >                        [alert setMessageText:@"The selected virtual machine is already running."];
306 >                        [alert setAlertStyle:NSWarningAlertStyle];
307 >                        [alert beginSheetModalForWindow:[self window]
308 >                                    modalDelegate:self
309 >                                   didEndSelector:nil
310 >                                      contextInfo:nil];
311 >                } else if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
312 >                        NSTask *sheep = [[NSTask alloc] init];
313 >                        [sheep setLaunchPath:[[NSBundle mainBundle] pathForAuxiliaryExecutable:@"SheepShaver"]];
314 >                        [sheep setArguments:[NSArray arrayWithObject:path]];
315 >                        [sheep launch];
316 >                        [tasks setObject:sheep forKey:path];
317 >                } else {
318 >                        [self _showNotFoundAlert];
319 >                }
320 >        }
321 > }
322 >
323 > - (void) onTaskTerminated: (NSNotification *) notification
324 > {
325 >        NSArray *paths = [tasks allKeys];
326 >        NSEnumerator *enumerator = [paths objectEnumerator];
327 >        NSString *path;
328 >        while ((path = [enumerator nextObject])) {
329 >                NSTask *task = [tasks objectForKey:path];
330 >                if (![task isRunning]) {
331 >                        [tasks removeObjectForKey:path];
332 >                        [task release];
333 >                }
334          }
335   }
336  
# Line 195 | Line 347 | use the same nib file as this app!
347                                    modalDelegate:self
348                                   didEndSelector:@selector(_deleteVirtualMachineDone: returnCode: contextInfo:)
349                                      contextInfo:nil];
350 <
199 <                        }
350 >        }
351   }
352  
353   - (void) _deleteVirtualMachineDone: (NSAlert *) alert returnCode: (int) returnCode contextInfo: (void *) contextInfo
# Line 204 | Line 355 | use the same nib file as this app!
355          if (returnCode == NSAlertFirstButtonReturn) {
356                  [vmArray removeObjectAtIndex:[vmList selectedRow]];
357                  [vmList deselectAll:self];
358 <                [vmList reloadData];
359 <                [[NSUserDefaults standardUserDefaults] setObject:vmArray forKey:@"vm_list"];
358 >                [self reloadDataAndSave];
359 >        }
360 > }
361 >
362 > - (IBAction) revealVirtualMachineInFinder: (id) sender
363 > {
364 >        int selectedRow = [vmList selectedRow];
365 >        if (selectedRow >= 0) {
366 >                NSString *path = [vmArray objectAtIndex:selectedRow];
367 >                if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
368 >                        [[NSWorkspace sharedWorkspace] selectFile: path inFileViewerRootedAtPath: @""];
369 >                } else {
370 >                        [self _showNotFoundAlert];
371 >                }
372          }
373   }
374  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines