ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/MacOSX/Launcher/VMListController.mm
Revision: 1.6
Committed: 2009-08-02T23:46:44Z (15 years, 2 months ago) by asvitkine
Branch: MAIN
Changes since 1.5: +50 -7 lines
Log Message:
keep track of running VMs

File Contents

# User Rev Content
1 asvitkine 1.1 /*
2     * VMListController.mm - SheepShaver VM manager in Cocoa on Mac OS X
3     *
4     * Copyright (C) 2009 Alexei Svitkine
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #import "VMListController.h"
22     #import "VMSettingsController.h"
23    
24 asvitkine 1.4 /*
25    
26     TODO:
27    
28     Verify if VM exists
29     Create Disk on New VM
30     Drag-drop to re-arrange order of VMs
31     Drag VM from Finder to import
32     Don't show Preferences menu in spawned SheepShaver instances - or make them
33     use the same nib file as this app!
34    
35     */
36    
37 asvitkine 1.1 @implementation VMListController
38    
39     + (id) sharedInstance
40     {
41     static VMListController *_sharedInstance = nil;
42     if (!_sharedInstance) {
43     _sharedInstance = [[VMListController allocWithZone:[self zone]] init];
44     }
45     return _sharedInstance;
46     }
47    
48     - (id) init
49     {
50     self = [super initWithWindowNibName:@"VMListWindow"];
51    
52     NSArray *vms = [[NSUserDefaults standardUserDefaults] stringArrayForKey:@"vm_list"];
53     vmArray = [[NSMutableArray alloc] initWithCapacity:[vms count]];
54     [vmArray addObjectsFromArray:vms];
55    
56 asvitkine 1.6 tasks = [[NSMutableDictionary alloc] init];
57    
58     [[NSNotificationCenter defaultCenter] addObserver:self
59     selector:@selector(onTaskTerminated:)
60     name:NSTaskDidTerminateNotification
61     object:nil];
62    
63 asvitkine 1.1 return self;
64     }
65    
66     - (void) awakeFromNib
67     {
68 asvitkine 1.2 [vmList setDataSource: self];
69 asvitkine 1.4 [vmList setDelegate: self];
70 asvitkine 1.2 [vmList reloadData];
71 asvitkine 1.1 }
72    
73 asvitkine 1.4 - (void) keyDown: (NSEvent *) event
74     {
75     if ([event type] == NSKeyDown && [[event characters] length] > 0) {
76     unichar key = [[event characters] characterAtIndex:0];
77     if (key == NSDeleteFunctionKey || key == NSDeleteCharacter) {
78     [self deleteVirtualMachine:self];
79     }
80     }
81     }
82    
83 asvitkine 1.1 - (int) numberOfRowsInTableView: (NSTableView *) table
84     {
85 asvitkine 1.2 return [vmArray count];
86 asvitkine 1.1 }
87    
88     - (id) tableView: (NSTableView *) table objectValueForTableColumn: (NSTableColumn *) c row: (int) r
89     {
90 asvitkine 1.2 return [vmArray objectAtIndex: r]; // [[vmArray objectAtIndex: r] lastPathComponent];
91 asvitkine 1.1 }
92    
93 asvitkine 1.5 - (void) tableViewSelectionDidChange: (NSNotification *) notification
94     {
95     if ([vmList selectedRow] >= 0) {
96     [settingsButton setEnabled:YES];
97     [launchButton setEnabled:YES];
98     } else {
99     [settingsButton setEnabled:NO];
100     [launchButton setEnabled:NO];
101     }
102     }
103    
104 asvitkine 1.1 //- (NSString *) tableView: (NSTableView *) table toolTipForCell: (NSCell *) cell rect: (NSRectPointer) rect
105     // tableColumn: (NSTableColumn *) c row: (int) r mouseLocation: (NSPoint) loc
106     //{
107     // return [vmArray objectAtIndex: r];
108     //}
109    
110     - (IBAction) newVirtualMachine: (id) sender
111     {
112     NSSavePanel *save = [NSSavePanel savePanel];
113     [save setMessage: @"New SheepShaver Virtual Machine:"];
114     [save setRequiredFileType: @"sheepvm"];
115     [save setCanSelectHiddenExtension: YES];
116     [save setExtensionHidden: NO];
117     [save beginSheetForDirectory: nil
118     file: @"New.sheepvm"
119     modalForWindow: [self window]
120     modalDelegate: self
121     didEndSelector: @selector(_newVirtualMachineDone: returnCode: contextInfo:)
122     contextInfo: nil];
123     }
124    
125     - (IBAction) _newVirtualMachineDone: (NSSavePanel *) save returnCode: (int) returnCode contextInfo: (void *) contextInfo
126     {
127     if (returnCode == NSOKButton) {
128 asvitkine 1.3 NSFileManager *manager = [NSFileManager defaultManager];
129     [manager createDirectoryAtPath:[save filename] attributes:nil];
130     [manager createFileAtPath:[[save filename] stringByAppendingPathComponent:@"prefs"] contents:nil attributes:nil];
131     [vmArray addObject:[save filename]];
132     [vmList reloadData];
133     [[NSUserDefaults standardUserDefaults] setObject:vmArray forKey:@"vm_list"];
134     [vmList selectRow:([vmArray count] - 1) byExtendingSelection:NO];
135     [self editVirtualMachineSettings:self];
136     if ([[VMSettingsController sharedInstance] cancelWasClicked]) {
137     [manager removeFileAtPath:[save filename] handler:nil];
138     [vmArray removeObjectAtIndex:([vmArray count] - 1)];
139     [vmList reloadData];
140     }
141     // TODO advanced: show sub-panel in save dialog that says "Create Disk:"
142 asvitkine 1.1 }
143     }
144    
145     - (IBAction) importVirtualMachine: (id) sender
146     {
147     NSOpenPanel *open = [NSOpenPanel openPanel];
148     [open setMessage:@"Import SheepShaver Virtual Machine:"];
149     [open setResolvesAliases:YES];
150     // Curiously, bundles are treated as "files" not "directories" by NSOpenPanel.
151     [open setCanChooseDirectories:NO];
152     [open setCanChooseFiles:YES];
153     [open setAllowsMultipleSelection:NO];
154     [open beginSheetForDirectory: nil
155     file: nil
156     types: [NSArray arrayWithObject:@"sheepvm"]
157     modalForWindow: [self window]
158     modalDelegate: self
159     didEndSelector: @selector(_importVirtualMachineDone: returnCode: contextInfo:)
160     contextInfo: nil];
161     }
162    
163     - (void) _importVirtualMachineDone: (NSOpenPanel *) open returnCode: (int) returnCode contextInfo: (void *) contextInfo
164     {
165     if (returnCode == NSOKButton) {
166     [vmArray addObject:[open filename]];
167     [vmList reloadData];
168     [[NSUserDefaults standardUserDefaults] setObject:vmArray forKey:@"vm_list"];
169     }
170     }
171    
172 asvitkine 1.4 - (IBAction) editVirtualMachineSettings: (id) sender
173 asvitkine 1.1 {
174     int selectedRow = [vmList selectedRow];
175 asvitkine 1.2 if (selectedRow >= 0) {
176 asvitkine 1.6 NSString *path = [vmArray objectAtIndex:selectedRow];
177     if ([tasks objectForKey:path]) {
178     NSAlert *alert = [[[NSAlert alloc] init] autorelease];
179     [alert setMessageText:@"Cannot edit virtual machine settings while it's running."];
180     [alert setAlertStyle:NSWarningAlertStyle];
181     [alert beginSheetModalForWindow:[self window]
182     modalDelegate:self
183     didEndSelector:nil
184     contextInfo:nil];
185     } else {
186     [[VMSettingsController sharedInstance] editSettingsFor:path sender:sender];
187     }
188 asvitkine 1.2 }
189 asvitkine 1.1 }
190    
191 asvitkine 1.4 - (IBAction) launchVirtualMachine: (id) sender
192 asvitkine 1.1 {
193 asvitkine 1.2 int selectedRow = [vmList selectedRow];
194     if (selectedRow >= 0) {
195 asvitkine 1.6 NSString *path = [vmArray objectAtIndex:selectedRow];
196     if ([tasks objectForKey:path]) {
197     NSAlert *alert = [[[NSAlert alloc] init] autorelease];
198     [alert setMessageText:@"The selected virtual machine is already running."];
199     [alert setAlertStyle:NSWarningAlertStyle];
200     [alert beginSheetModalForWindow:[self window]
201     modalDelegate:self
202     didEndSelector:nil
203     contextInfo:nil];
204     } else {
205     NSTask *sheep = [[NSTask alloc] init];
206     [sheep setLaunchPath:[[NSBundle mainBundle] pathForAuxiliaryExecutable:@"SheepShaver"]];
207     [sheep setArguments:[NSArray arrayWithObject:path]];
208     [sheep launch];
209     [tasks setObject:sheep forKey:path];
210     }
211     }
212     }
213    
214     - (void) onTaskTerminated: (NSNotification *) notification
215     {
216     NSArray *paths = [tasks allKeys];
217     NSEnumerator *enumerator = [paths objectEnumerator];
218     NSString *path;
219     while ((path = [enumerator nextObject])) {
220     NSTask *task = [tasks objectForKey:path];
221     if (![task isRunning]) {
222     [tasks removeObjectForKey:path];
223     [task release];
224     }
225 asvitkine 1.2 }
226 asvitkine 1.1 }
227    
228 asvitkine 1.4 - (IBAction) deleteVirtualMachine: (id) sender
229     {
230     int selectedRow = [vmList selectedRow];
231     if (selectedRow >= 0) {
232     NSAlert *alert = [[[NSAlert alloc] init] autorelease];
233     [alert setMessageText:@"Do you wish to remove the selected virtual machine from the list?"];
234     [alert addButtonWithTitle:@"Remove"];
235     [alert addButtonWithTitle:@"Cancel"];
236     [alert setAlertStyle:NSWarningAlertStyle];
237     [alert beginSheetModalForWindow:[self window]
238     modalDelegate:self
239     didEndSelector:@selector(_deleteVirtualMachineDone: returnCode: contextInfo:)
240     contextInfo:nil];
241    
242 asvitkine 1.6 }
243 asvitkine 1.4 }
244    
245     - (void) _deleteVirtualMachineDone: (NSAlert *) alert returnCode: (int) returnCode contextInfo: (void *) contextInfo
246     {
247     if (returnCode == NSAlertFirstButtonReturn) {
248     [vmArray removeObjectAtIndex:[vmList selectedRow]];
249     [vmList deselectAll:self];
250     [vmList reloadData];
251     [[NSUserDefaults standardUserDefaults] setObject:vmArray forKey:@"vm_list"];
252     }
253     }
254    
255 asvitkine 1.1 @end