Source code: com/barteo/emulator/app/ui/swt/SwtSelectDeviceDialog.java
1 /*
2 * MicroEmulator
3 * Copyright (C) 2002-2003 Bartek Teodorczyk <barteo@it.pl>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library 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. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 package com.barteo.emulator.app.ui.swt;
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.util.Enumeration;
27 import java.util.Vector;
28 import java.util.jar.Attributes;
29 import java.util.jar.JarFile;
30 import java.util.jar.Manifest;
31
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.events.SelectionAdapter;
34 import org.eclipse.swt.events.SelectionEvent;
35 import org.eclipse.swt.graphics.Rectangle;
36 import org.eclipse.swt.layout.GridData;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.widgets.Button;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Control;
41 import org.eclipse.swt.widgets.Event;
42 import org.eclipse.swt.widgets.FileDialog;
43 import org.eclipse.swt.widgets.Group;
44 import org.eclipse.swt.widgets.List;
45 import org.eclipse.swt.widgets.Listener;
46 import org.eclipse.swt.widgets.Shell;
47
48 import com.barteo.emulator.app.Config;
49 import com.barteo.emulator.app.util.DeviceEntry;
50 import com.barteo.emulator.app.util.ProgressJarClassLoader;
51 import com.barteo.emulator.device.swt.SwtDevice;
52
53
54 public class SwtSelectDeviceDialog extends SwtDialog
55 {
56 private Button btAdd;
57 private Button btRemove;
58 private Button btDefault;
59 private List lsDevices;
60 private Vector deviceModel;
61 private DeviceEntry selectedEntry;
62
63 private Listener btAddListener = new Listener()
64 {
65 private FileDialog fileDialog = null;
66
67 public void handleEvent(Event event)
68 {
69 if (fileDialog == null) {
70 fileDialog = new FileDialog(getShell(), SWT.OPEN);
71 fileDialog.setText("Open device profile file...");
72 fileDialog.setFilterNames(new String[] {"Device profile (*.dev)"});
73 fileDialog.setFilterExtensions(new String[] {"*.dev"});
74 }
75
76 ProgressJarClassLoader loader = new ProgressJarClassLoader();
77
78 fileDialog.open();
79
80 if (fileDialog.getFileName() != null) {
81 String deviceClassName = null;
82 String deviceName = null;
83 try {
84 JarFile jar = new JarFile(
85 new File(fileDialog.getFilterPath(), fileDialog.getFileName()));
86 Manifest manifest = jar.getManifest();
87 if (manifest == null) {
88 SwtMessageDialog.openError(getShell(),
89 "Error", "Missing manifest in dev file.");
90 return;
91 }
92 Attributes attrs = manifest.getMainAttributes();
93
94 deviceName = attrs.getValue("Device-Name");
95 if (deviceName == null) {
96 SwtMessageDialog.openError(getShell(),
97 "Error", "Missing Device-Name entry in jar manifest.");
98 return;
99 }
100
101 deviceClassName = attrs.getValue("Device-Class");
102 if (deviceClassName == null) {
103 SwtMessageDialog.openError(getShell(),
104 "Error", "Missing Device-Class entry in jar manifest.");
105 return;
106 }
107
108 jar.close();
109 deviceClassName = deviceClassName.replace('.', '/');
110 if (deviceClassName.charAt(0) == '/') {
111 deviceClassName = deviceClassName.substring(1);
112 }
113 for (Enumeration e = deviceModel.elements(); e.hasMoreElements(); ) {
114 DeviceEntry entry = (DeviceEntry) e.nextElement();
115 if (deviceClassName.equals(entry.getClassName())) {
116 SwtMessageDialog.openInformation(getShell(),
117 "Info", "Device is already added.");
118 return;
119 }
120 }
121
122 loader.addRepository(new File(fileDialog.getFilterPath(), fileDialog.getFileName()).toURL());
123 } catch (IOException ex) {
124 SwtMessageDialog.openError(getShell(),
125 "Error", "Error reading " + fileDialog.getFileName() + " file.");
126 return;
127 }
128
129 Class deviceClass = null;
130 try {
131 deviceClass = loader.findClass(deviceClassName);
132 } catch (ClassNotFoundException ex) {
133 SwtMessageDialog.openError(getShell(),
134 "Error", "Cannot find class defined in Device-Class entry in jar manifest.");
135 return;
136 }
137
138 if (!SwtDevice.class.isAssignableFrom(deviceClass)) {
139 SwtMessageDialog.openError(getShell(),
140 "Error", "Cannot find class defined in Device-Class entry in jar manifest.");
141 return;
142 }
143
144 try {
145 File deviceFile = File.createTempFile("dev", ".dev", Config.getConfigPath());
146 FileInputStream fis = new FileInputStream(
147 new File(fileDialog.getFilterPath(), fileDialog.getFileName()));
148 FileOutputStream fos = new FileOutputStream(deviceFile);
149 byte[] buf = new byte[1024];
150 int i = 0;
151 while((i=fis.read(buf))!=-1) {
152 fos.write(buf, 0, i);
153 }
154 fis.close();
155 fos.close();
156
157 DeviceEntry entry =
158 new DeviceEntry(deviceName, deviceFile.getName(), deviceClassName, false);
159 deviceModel.addElement(entry);
160 for (i = 0; i < deviceModel.size(); i++) {
161 if (deviceModel.elementAt(i) == entry) {
162 lsDevices.add(entry.getName());
163 lsDevices.select(i);
164 }
165 }
166 lsDevicesListener.widgetSelected(null);
167 } catch (IOException ex) {
168 System.err.println(ex);
169 }
170 }
171 }
172 };
173
174 private Listener btRemoveListener = new Listener()
175 {
176 public void handleEvent(Event event)
177 {
178 DeviceEntry entry = (DeviceEntry) deviceModel.elementAt(lsDevices.getSelectionIndex());
179 File deviceFile = new File(Config.getConfigPath(), entry.getFileName());
180 deviceFile.delete();
181 if (entry.isDefaultDevice()) {
182 for (int i = 0; i < deviceModel.size(); i++) {
183 DeviceEntry tmp = (DeviceEntry) deviceModel.elementAt(i);
184 if (!tmp.canRemove()) {
185 tmp.setDefaultDevice(true);
186 lsDevices.setItem(i, tmp.getName() + " (default)");
187 break;
188 }
189 }
190 }
191 for (int i = 0; i < deviceModel.size(); i++) {
192 if (deviceModel.elementAt(i) == entry) {
193 deviceModel.removeElementAt(i);
194 lsDevices.remove(i);
195 break;
196 }
197 }
198 lsDevicesListener.widgetSelected(null);
199 }
200 };
201
202 private Listener btDefaultListener = new Listener()
203 {
204 public void handleEvent(Event event)
205 {
206 DeviceEntry entry = (DeviceEntry) deviceModel.elementAt(lsDevices.getSelectionIndex());
207 for (int i = 0; i < deviceModel.size(); i++) {
208 DeviceEntry tmp = (DeviceEntry) deviceModel.elementAt(i);
209 if (tmp == entry) {
210 tmp.setDefaultDevice(true);
211 lsDevices.setItem(i, tmp.getName() + " (default)");
212 } else {
213 tmp.setDefaultDevice(false);
214 lsDevices.setItem(i, tmp.getName());
215 }
216 }
217 btDefault.setEnabled(false);
218 }
219 };
220
221 SelectionAdapter lsDevicesListener = new SelectionAdapter()
222 {
223 public void widgetSelected(SelectionEvent e)
224 {
225 int index = lsDevices.getSelectionIndex();
226 if (index != -1) {
227 selectedEntry = (DeviceEntry) deviceModel.elementAt(index);
228 if (selectedEntry.isDefaultDevice()) {
229 btDefault.setEnabled(false);
230 } else {
231 btDefault.setEnabled(true);
232 }
233 if (selectedEntry.canRemove()) {
234 btRemove.setEnabled(true);
235 } else {
236 btRemove.setEnabled(false);
237 }
238 btOk.setEnabled(true);
239 } else {
240 selectedEntry = null;
241 btDefault.setEnabled(false);
242 btRemove.setEnabled(false);
243 btOk.setEnabled(false);
244 }
245 }
246 };
247
248
249 public SwtSelectDeviceDialog(Shell parent)
250 {
251 super(parent);
252
253 Vector devs = Config.getDevices();
254 for (int i = 0; i < devs.size(); i++) {
255 DeviceEntry entry = (DeviceEntry) devs.elementAt(i);
256 if (entry.isDefaultDevice()) {
257 selectedEntry = entry;
258 }
259 }
260 }
261
262
263 protected void configureShell(Shell shell)
264 {
265 super.configureShell(shell);
266
267 shell.setText("Select device...");
268 }
269
270
271 protected Control createDialogArea(Composite composite)
272 {
273 GridLayout gridLayout = new GridLayout();
274 gridLayout.numColumns = 1;
275 composite.setLayout(gridLayout);
276
277 Group gpDevices = new Group(composite, SWT.NONE);
278 gpDevices.setText("Installed devices");
279 gridLayout = new GridLayout();
280 gridLayout.numColumns = 1;
281 gpDevices.setLayout(gridLayout);
282 gpDevices.setLayoutData(new GridData(GridData.FILL_BOTH));
283
284 lsDevices = new List(gpDevices, SWT.SINGLE | SWT.V_SCROLL);
285 GridData gridData = new GridData(GridData.FILL_BOTH);
286 gridData.horizontalSpan = 3;
287 gridData.grabExcessVerticalSpace = true;
288 Rectangle trim = lsDevices.computeTrim(0, 0, 0, lsDevices.getItemHeight() * 5);
289 gridData.heightHint = trim.height;
290 lsDevices.setLayoutData(gridData);
291 lsDevices.addSelectionListener(lsDevicesListener);
292
293 Composite btDevices = new Composite(gpDevices, SWT.NONE);
294 gridLayout = new GridLayout();
295 gridLayout.numColumns = 3;
296 btDevices.setLayout(gridLayout);
297 btDevices.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
298
299 btAdd = new Button(btDevices, SWT.PUSH);
300 btAdd.setText("Add...");
301 btAdd.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
302 btAdd.addListener(SWT.Selection, btAddListener);
303
304 btRemove = new Button(btDevices, SWT.PUSH);
305 btRemove.setText("Remove");
306 btRemove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
307 btRemove.addListener(SWT.Selection, btRemoveListener);
308
309 btDefault = new Button(btDevices, SWT.PUSH);
310 btDefault.setText("Set as default");
311 btDefault.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
312 btDefault.addListener(SWT.Selection, btDefaultListener);
313
314 Vector devs = Config.getDevices();
315 deviceModel = new Vector();
316 for (int i = 0; i < devs.size(); i++) {
317 DeviceEntry entry = (DeviceEntry) devs.elementAt(i);
318 deviceModel.addElement(entry);
319 if (entry.isDefaultDevice()) {
320 lsDevices.add(entry.getName() + " (default)");
321 lsDevices.select(i);
322 } else {
323 lsDevices.add(entry.getName());
324 }
325 }
326
327 return composite;
328 }
329
330
331 protected Control createButtonBar(Composite parent)
332 {
333 Control control = super.createButtonBar(parent);
334
335 lsDevicesListener.widgetSelected(null);
336
337 return control;
338 }
339
340
341 public DeviceEntry getSelectedDeviceEntry()
342 {
343 return selectedEntry;
344 }
345
346
347 public boolean close()
348 {
349 super.close();
350
351 Vector devices = Config.getDevices();
352 devices.removeAllElements();
353
354 for (Enumeration e = deviceModel.elements(); e.hasMoreElements(); ) {
355 devices.add(e.nextElement());
356 }
357
358 Config.saveConfig("config-swt.xml");
359
360 return true;
361 }
362
363 }