diff options
| -rw-r--r-- | altoslib/AltosLib.java | 1 | ||||
| -rw-r--r-- | altosuilib/AltosDevice.java | 30 | ||||
| -rw-r--r-- | altosuilib/AltosDeviceDialog.java | 163 | ||||
| -rw-r--r-- | altosuilib/AltosUSBDevice.java | 112 | ||||
| -rw-r--r-- | altosuilib/Makefile.am | 3 | ||||
| -rw-r--r-- | libaltos/libaltos.c | 4 | ||||
| -rw-r--r-- | micropeak/Makefile.am | 3 | ||||
| -rw-r--r-- | micropeak/MicroData.java | 15 | ||||
| -rw-r--r-- | micropeak/MicroDeviceDialog.java | 50 | ||||
| -rw-r--r-- | micropeak/MicroDownload.java | 139 | ||||
| -rw-r--r-- | micropeak/MicroGraph.java | 5 | ||||
| -rw-r--r-- | micropeak/MicroPeak.java | 81 | ||||
| -rw-r--r-- | micropeak/MicroSave.java | 102 | ||||
| -rw-r--r-- | micropeak/MicroSerial.java | 12 | ||||
| -rw-r--r-- | micropeak/MicroUSB.java | 19 | 
15 files changed, 708 insertions, 31 deletions
| diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 07516aeb..67138450 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -97,6 +97,7 @@ public class AltosLib {  	public final static int product_any = 0x10000;  	public final static int product_basestation = 0x10000 + 1;  	public final static int product_altimeter = 0x10000 + 2; +	public final static int product_micropeak_serial = 0x10000 + 3;  	/* Bluetooth "identifier" (bluetooth sucks) */  	public final static String bt_product_telebt = "TeleBT"; diff --git a/altosuilib/AltosDevice.java b/altosuilib/AltosDevice.java new file mode 100644 index 00000000..69b025ba --- /dev/null +++ b/altosuilib/AltosDevice.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib; + +import libaltosJNI.*; + +public interface AltosDevice { +	public abstract String toString(); +	public abstract String toShortString(); +	public abstract int getSerial(); +	public abstract String getPath(); +	public abstract boolean matchProduct(int product); +	public abstract String getErrorString(); +	public SWIGTYPE_p_altos_file open(); +} diff --git a/altosuilib/AltosDeviceDialog.java b/altosuilib/AltosDeviceDialog.java new file mode 100644 index 00000000..82620b8b --- /dev/null +++ b/altosuilib/AltosDeviceDialog.java @@ -0,0 +1,163 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public abstract class AltosDeviceDialog extends AltosUIDialog implements ActionListener { + +	private AltosDevice	value; +	private JList		list; +	private JButton		cancel_button; +	private JButton		select_button; +	private JButton		manage_bluetooth_button; +	private Frame		frame; +	private int		product; + +	public AltosDevice getValue() { +		return value; +	} + +	public abstract AltosDevice[] devices(); + +	private void update_devices() { +		AltosDevice[] devices = devices(); +		list.setListData(devices); +		select_button.setEnabled(devices.length > 0); +	} + +	public AltosDeviceDialog (Frame in_frame, Component location, int in_product) { +		super(in_frame, "Device Selection", true); + +		product = in_product; +		frame = in_frame; +		value = null; + +		AltosDevice[]	devices = devices(); + +		cancel_button = new JButton("Cancel"); +		cancel_button.setActionCommand("cancel"); +		cancel_button.addActionListener(this); + +//		manage_bluetooth_button = new JButton("Manage Bluetooth"); +//		manage_bluetooth_button.setActionCommand("manage"); +//		manage_bluetooth_button.addActionListener(this); + +		select_button = new JButton("Select"); +		select_button.setActionCommand("select"); +		select_button.addActionListener(this); +		if (devices.length == 0) +			select_button.setEnabled(false); +		getRootPane().setDefaultButton(select_button); + +		list = new JList(devices) { +				//Subclass JList to workaround bug 4832765, which can cause the +				//scroll pane to not let the user easily scroll up to the beginning +				//of the list.  An alternative would be to set the unitIncrement +				//of the JScrollBar to a fixed value. You wouldn't get the nice +				//aligned scrolling, but it should work. +				public int getScrollableUnitIncrement(Rectangle visibleRect, +								      int orientation, +								      int direction) { +					int row; +					if (orientation == SwingConstants.VERTICAL && +					    direction < 0 && (row = getFirstVisibleIndex()) != -1) { +						Rectangle r = getCellBounds(row, row); +						if ((r.y == visibleRect.y) && (row != 0))  { +							Point loc = r.getLocation(); +							loc.y--; +							int prevIndex = locationToIndex(loc); +							Rectangle prevR = getCellBounds(prevIndex, prevIndex); + +							if (prevR == null || prevR.y >= r.y) { +								return 0; +							} +							return prevR.height; +						} +					} +					return super.getScrollableUnitIncrement( +						visibleRect, orientation, direction); +				} +			}; + +		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); +		list.setLayoutOrientation(JList.HORIZONTAL_WRAP); +		list.setVisibleRowCount(-1); +		list.addMouseListener(new MouseAdapter() { +				 public void mouseClicked(MouseEvent e) { +					 if (e.getClickCount() == 2) { +						 select_button.doClick(); //emulate button click +					 } +				 } +			}); +		JScrollPane listScroller = new JScrollPane(list); +		listScroller.setPreferredSize(new Dimension(400, 80)); +		listScroller.setAlignmentX(LEFT_ALIGNMENT); + +		//Create a container so that we can add a title around +		//the scroll pane.  Can't add a title directly to the +		//scroll pane because its background would be white. +		//Lay out the label and scroll pane from top to bottom. +		JPanel listPane = new JPanel(); +		listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS)); + +		JLabel label = new JLabel("Select Device"); +		label.setLabelFor(list); +		listPane.add(label); +		listPane.add(Box.createRigidArea(new Dimension(0,5))); +		listPane.add(listScroller); +		listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); + +		//Lay out the buttons from left to right. +		JPanel buttonPane = new JPanel(); +		buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); +		buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); +		buttonPane.add(Box.createHorizontalGlue()); +		buttonPane.add(cancel_button); +		buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); +//		buttonPane.add(manage_bluetooth_button); +//		buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); +		buttonPane.add(select_button); + +		//Put everything together, using the content pane's BorderLayout. +		Container contentPane = getContentPane(); +		contentPane.add(listPane, BorderLayout.CENTER); +		contentPane.add(buttonPane, BorderLayout.PAGE_END); + +		//Initialize values. +		if (devices != null && devices.length != 0) +			list.setSelectedValue(devices[0], true); +		pack(); +		setLocationRelativeTo(location); +	} + +	//Handle clicks on the Set and Cancel buttons. +	public void actionPerformed(ActionEvent e) { +		if ("select".equals(e.getActionCommand())) +			value = (AltosDevice)(list.getSelectedValue()); +//		if ("manage".equals(e.getActionCommand())) { +//			AltosBTManage.show(frame, AltosBTKnown.bt_known()); +//			update_devices(); +//			return; +//		} +		setVisible(false); +	} + +} diff --git a/altosuilib/AltosUSBDevice.java b/altosuilib/AltosUSBDevice.java new file mode 100644 index 00000000..2f4e0dc6 --- /dev/null +++ b/altosuilib/AltosUSBDevice.java @@ -0,0 +1,112 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib; + +import java.util.*; +import libaltosJNI.*; + +public class AltosUSBDevice  extends altos_device implements AltosDevice { + +	public String toString() { +		String	name = getName(); +		if (name == null) +			name = "Altus Metrum"; +		return String.format("%-20.20s %4d %s", +				     name, getSerial(), getPath()); +	} + +	public String toShortString() { +		String	name = getName(); +		if (name == null) +			name = "Altus Metrum"; +		return String.format("%s %d %s", +				     name, getSerial(), getPath()); + +	} + +	public String getErrorString() { +		altos_error	error = new altos_error(); + +		libaltos.altos_get_last_error(error); +		return String.format("%s (%d)", error.getString(), error.getCode()); +	} + +	public SWIGTYPE_p_altos_file open() { +		return libaltos.altos_open(this); +	} + +	private boolean isAltusMetrum() { +		if (getVendor() != AltosUILib.vendor_altusmetrum) +			return false; +		if (getProduct() < AltosUILib.product_altusmetrum_min) +			return false; +		if (getProduct() > AltosUILib.product_altusmetrum_max) +			return false; +		return true; +	} + +	public boolean matchProduct(int want_product) { + +		if (!isAltusMetrum()) +			return false; + +		if (want_product == AltosUILib.product_any) +			return true; + +		if (want_product == AltosUILib.product_basestation) +			return matchProduct(AltosUILib.product_teledongle) || +				matchProduct(AltosUILib.product_teleterra) || +				matchProduct(AltosUILib.product_telebt) || +				matchProduct(AltosUILib.product_megadongle); + +		if (want_product == AltosUILib.product_altimeter) +			return matchProduct(AltosUILib.product_telemetrum) || +				matchProduct(AltosUILib.product_megametrum); + +		int have_product = getProduct(); + +		if (have_product == AltosUILib.product_altusmetrum)	/* old devices match any request */ +			return true; + +		if (want_product == have_product) +			return true; + +		return false; +	} + +	static java.util.List<AltosDevice> list(int product) { +		if (!AltosUILib.load_library()) +			return null; + +		SWIGTYPE_p_altos_list list = libaltos.altos_list_start(); + +		ArrayList<AltosDevice> device_list = new ArrayList<AltosDevice>(); +		if (list != null) { +			for (;;) { +				AltosUSBDevice device = new AltosUSBDevice(); +				if (libaltos.altos_list_next(list, device) == 0) +					break; +				if (device.matchProduct(product)) +					device_list.add(device); +			} +			libaltos.altos_list_finish(list); +		} + +		return device_list; +	} +}
\ No newline at end of file diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am index 26aee7c4..e2ff8cb5 100644 --- a/altosuilib/Makefile.am +++ b/altosuilib/Makefile.am @@ -11,6 +11,9 @@ AltosUILibdir = $(datadir)/java  AltosUILib_JAVA = \  	AltosConfigureUI.java \ +	AltosDevice.java \ +	AltosDeviceDialog.java \ +	AltosUSBDevice.java \  	AltosFontListener.java \  	AltosUIDialog.java \  	AltosUIFrame.java \ diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index d7b266cf..6e884c80 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -116,6 +116,7 @@ altos_open(struct altos_device *device)  		return NULL;  	} +	printf ("open\n");  //	altos_set_last_error(12, "yeah yeah, failed again");  //	free(file);  //	return NULL; @@ -148,6 +149,8 @@ altos_open(struct altos_device *device)  		return NULL;  	}  	cfmakeraw(&term); +	cfsetospeed(&term, B9600); +	cfsetispeed(&term, B9600);  #ifdef USE_POLL  	term.c_cc[VMIN] = 1;  	term.c_cc[VTIME] = 0; @@ -609,6 +612,7 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  {  	struct altos_usbdev *dev;  	if (list->current >= list->ndev) { +		printf ("end\n");  		return 0;  	}  	dev = list->dev[list->current]; diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index e0de690c..a54b78a5 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -10,12 +10,15 @@ micropeakdir=$(datadir)/java  micropeak_JAVA= \  	MicroPeak.java \  	MicroData.java \ +	MicroDownload.java \  	MicroFrame.java \  	MicroGraph.java \ +	MicroSave.java \  	MicroSerial.java \  	MicroStats.java \  	MicroStatsTable.java \  	MicroFileChooser.java \ +	MicroDeviceDialog.java \  	MicroUSB.java  JFREECHART_CLASS= \ diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java index ec9b83d8..8ccd5fd8 100644 --- a/micropeak/MicroData.java +++ b/micropeak/MicroData.java @@ -110,6 +110,7 @@ public class MicroData {  	private double		time_step;  	private double		ground_altitude;  	private ArrayList<Integer>	bytes; +	String			name;  	class FileEndedException extends Exception { @@ -310,12 +311,18 @@ public class MicroData {  	public void save (OutputStream f) throws IOException {  		for (int c : bytes)  			f.write(c); +		f.write('\n');  	} -	public MicroData (InputStream f) throws IOException { +	public void set_name(String name) { +		this.name = name; +	} + +	public MicroData (InputStream f, String name) throws IOException, InterruptedException { +		this.name = name;  		bytes = new ArrayList<Integer>();  		if (!find_header(f)) -			throw new IOException(); +			throw new IOException("No MicroPeak data header found");  		try {  			file_crc = 0xffff;  			ground_pressure = get_32(f); @@ -354,9 +361,9 @@ public class MicroData {  			time_step = 0.192;  		} catch (FileEndedException fe) { -			throw new IOException(); +			throw new IOException("File Ended Unexpectedly");  		} catch (NonHexcharException ne) { -			throw new IOException(); +			throw new IOException("Non hexadecimal character found");  		}  	} diff --git a/micropeak/MicroDeviceDialog.java b/micropeak/MicroDeviceDialog.java new file mode 100644 index 00000000..7b8a630c --- /dev/null +++ b/micropeak/MicroDeviceDialog.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import org.altusmetrum.altosuilib.*; + +public class MicroDeviceDialog extends AltosDeviceDialog { + +	public AltosDevice[] devices() { +		java.util.List<MicroUSB>	list = MicroUSB.list(); +		int		num_devices = list.size(); +		AltosDevice[]	devices = new AltosDevice[num_devices]; + +		for (int i = 0; i < num_devices; i++) +			devices[i] = list.get(i); +		return devices; +	} + +	public MicroDeviceDialog (Frame in_frame, Component location) { +		super(in_frame, location, 0); +	} + +	public static AltosDevice show (Component frameComp) { +		Frame			frame = JOptionPane.getFrameForComponent(frameComp); +		MicroDeviceDialog	dialog; + +		dialog = new MicroDeviceDialog (frame, frameComp); +		dialog.setVisible(true); +		return dialog.getValue(); +	} +} diff --git a/micropeak/MicroDownload.java b/micropeak/MicroDownload.java new file mode 100644 index 00000000..2e328b4a --- /dev/null +++ b/micropeak/MicroDownload.java @@ -0,0 +1,139 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener { +	MicroPeak	owner; +	Container	pane; +	AltosDevice	device; +	JButton		cancel; +	MicroData	data; +	MicroSerial	serial; + +	private void done_internal() { +		setVisible(false); +		if (data != null) { +			owner = owner.SetData(data); +			MicroSave save = new MicroSave(owner, data); +			if (save.runDialog()) +				owner.SetName(data.name); +		} +		dispose(); +	} + +	public void done() { +		Runnable r = new Runnable() { +				public void run() { +					try { +						done_internal(); +					} catch (Exception ex) { +					} +				} +			}; +		SwingUtilities.invokeLater(r); +	} + +	public void run() { +		try { +			data = new MicroData(serial, device.toShortString()); +			serial.close(); +		} catch (FileNotFoundException fe) { +		} catch (IOException ioe) { +		} catch (InterruptedException ie) { +		} +		done(); +	} + +	Thread	serial_thread; + +	public void start() { +		try { +			serial = new MicroSerial(device); +		} catch (FileNotFoundException fe) { +			return; +		} +		serial_thread = new Thread(this); +		serial_thread.start(); +	} + +	public void actionPerformed(ActionEvent ae) { +		System.out.printf ("command %s\n", ae.getActionCommand()); +		if (serial_thread != null) { +			System.out.printf ("Interrupting serial_thread\n"); +			serial.close(); +			serial_thread.interrupt(); +		} +	} + +	public MicroDownload(MicroPeak owner, AltosDevice device) { +		super (owner, "Download MicroPeak Data", false); + +		GridBagConstraints c; +		Insets il = new Insets(4,4,4,4); +		Insets ir = new Insets(4,4,4,4); + +		this.owner = owner; +		this.device = device; + +		pane = getContentPane(); +		pane.setLayout(new GridBagLayout()); + +		c = new GridBagConstraints(); +		c.gridx = 0; c.gridy = 0; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		JLabel device_label = new JLabel("Device:"); +		pane.add(device_label, c); + +		c = new GridBagConstraints(); +		c.gridx = 1; c.gridy = 0; +		c.fill = GridBagConstraints.HORIZONTAL; +		c.weightx = 1; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = ir; +		JLabel device_value = new JLabel(device.toString()); +		pane.add(device_value, c); + +		cancel = new JButton("Cancel"); +		c = new GridBagConstraints(); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.gridx = 0; c.gridy = 1; +		c.gridwidth = GridBagConstraints.REMAINDER; +		Insets ic = new Insets(4,4,4,4); +		c.insets = ic; +		pane.add(cancel, c); + +		cancel.addActionListener(this); + +		pack(); +		setLocationRelativeTo(owner); +		setVisible(true); +		this.start(); +	} +} diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index 38f54fe0..b9b084f8 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -111,8 +111,13 @@ public class MicroGraph implements AltosUnitsListener {  		}  	} +	public void setName (String name) { +		chart.setTitle(name); +	} +  	public void setData (MicroData data) {  		this.data = data; +		chart.setTitle(data.name);  		resetData();  	} diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index c69f7167..5e375057 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -34,13 +34,36 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  	MicroData	data;  	Container	container;  	JTabbedPane	pane; +	static int	number_of_windows; -	private void RunFile(InputStream input) { +	MicroPeak SetData(MicroData data) { +		MicroPeak	mp = this; +		if (this.data != null) { +			mp = new MicroPeak(); +			return mp.SetData(data); +		} +		this.data = data; +		graph.setData(data); +		stats.setData(data); +		setTitle(data.name); +		return this; +	} + +	void SetName(String name) { +		graph.setName(name); +		setTitle(name); +	} + +	private void RunFile(InputStream input, String name) {  		try { -			data = new MicroData(input); -			graph.setData(data); -			stats.setData(data); +			MicroData data = new MicroData(input, name); +			SetData(data);  		} catch (IOException ioe) { +			JOptionPane.showMessageDialog(this, +						      ioe.getMessage(), +						      "File Read Error", +						      JOptionPane.ERROR_MESSAGE); +		} catch (InterruptedException ie) {  		}  		try {  			input.close(); @@ -50,8 +73,12 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  	private void OpenFile(File filename) {  		try { -			RunFile (new FileInputStream(filename)); +			RunFile (new FileInputStream(filename), filename.getName());  		} catch (FileNotFoundException fne) { +			JOptionPane.showMessageDialog(this, +						      fne.getMessage(), +						      "Cannot open file", +						      JOptionPane.ERROR_MESSAGE);  		}  	} @@ -60,30 +87,44 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  		InputStream		input = chooser.runDialog();  		if (input != null) -			RunFile(input); +			RunFile(input, chooser.filename);  	}  	private void Preferences() {  		new AltosConfigureUI(this);  	} -		 +  	private void DownloadData() { -		java.util.List<MicroUSB>	devices = MicroUSB.list(); -		for (MicroUSB device : devices) -			System.out.printf("device %s\n", device.toString()); +		AltosDevice	device = MicroDeviceDialog.show(this); +		 +		if (device != null) +			new MicroDownload(this, device);  	} +	private void Save() { +		if (data == null) { +			JOptionPane.showMessageDialog(this, +						      "No data available", +						      "No data", +						      JOptionPane.INFORMATION_MESSAGE); +			return; +		} +		MicroSave	save = new MicroSave (this, data); +		if (save.runDialog()) +			SetName(data.name); +	} +	  	public void actionPerformed(ActionEvent ev) {  		if ("Exit".equals(ev.getActionCommand()))  			System.exit(0);  		else if ("Open".equals(ev.getActionCommand()))  			SelectFile(); -		else if ("New".equals(ev.getActionCommand())) -			new MicroPeak();  		else if ("Download".equals(ev.getActionCommand()))  			DownloadData();  		else if ("Preferences".equals(ev.getActionCommand()))  			Preferences(); +		else if ("Save a Copy".equals(ev.getActionCommand())) +			Save();  	}  	public void itemStateChanged(ItemEvent e) { @@ -91,6 +132,8 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  	public MicroPeak() { +		++number_of_windows; +  		AltosUIPreferences.set_component(this);  		container = getContentPane(); @@ -104,10 +147,6 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  		JMenu fileMenu = new JMenu("File");  		menuBar.add(fileMenu); -		JMenuItem newAction = new JMenuItem("New"); -		fileMenu.add(newAction); -		newAction.addActionListener(this); -  		JMenuItem openAction = new JMenuItem("Open");  		fileMenu.add(openAction);  		openAction.addActionListener(this); @@ -116,6 +155,10 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  		fileMenu.add(downloadAction);  		downloadAction.addActionListener(this); +		JMenuItem saveAction = new JMenuItem("Save a Copy"); +		fileMenu.add(saveAction); +		saveAction.addActionListener(this); +  		JMenuItem preferencesAction = new JMenuItem("Preferences");  		fileMenu.add(preferencesAction);  		preferencesAction.addActionListener(this); @@ -128,7 +171,11 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene  		addWindowListener(new WindowAdapter() {  			@Override  			public void windowClosing(WindowEvent e) { -				System.exit(0); +				setVisible(false); +				dispose(); +				--number_of_windows; +				if (number_of_windows == 0) +					System.exit(0);  			}  		}); diff --git a/micropeak/MicroSave.java b/micropeak/MicroSave.java new file mode 100644 index 00000000..cb4b4221 --- /dev/null +++ b/micropeak/MicroSave.java @@ -0,0 +1,102 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; +import org.altusmetrum.altosuilib.*; + +public class MicroSave extends JFileChooser { + +	JFrame		frame; +	MicroData	data; + +	public boolean runDialog() { +		int	ret; + +		for (;;) { +			ret = showSaveDialog(frame); +			if (ret != APPROVE_OPTION) +				return false; +			File	file; +			String	filename; +			file = getSelectedFile(); +			if (file == null) +				continue; +			if (!file.getName().contains(".")) { +				String fullname = file.getPath(); +				file = new File(fullname.concat(".mpd")); +			} +			filename = file.getName(); +			if (file.exists()) { +				if (file.isDirectory()) { +					JOptionPane.showMessageDialog(frame, +								      String.format("\"%s\" is a directory", +										    filename), +								      "Directory", +								      JOptionPane.ERROR_MESSAGE); +					continue; +				} +				int r = JOptionPane.showConfirmDialog(frame, +								      String.format("\"%s\" already exists. Overwrite?", +										    filename), +								      "Overwrite file?", +								      JOptionPane.YES_NO_OPTION); +				if (r != JOptionPane.YES_OPTION) +					continue; +							       +				if (!file.canWrite()) { +					JOptionPane.showMessageDialog(frame, +								      String.format("\"%s\" is not writable", +										    filename), +								      "File not writable", +								      JOptionPane.ERROR_MESSAGE); +					continue; +				} +			} +			try { +				FileOutputStream fos = new FileOutputStream(file); +				data.save(fos); +				fos.close(); +				data.set_name(filename); +				return true; +			} catch (FileNotFoundException fe) { +				JOptionPane.showMessageDialog(frame, +							      fe.getMessage(), +							      "Cannot create file", +							      JOptionPane.ERROR_MESSAGE); +			} catch (IOException ioe) { +			} +		} +	} + +	public MicroSave(JFrame frame, MicroData data) { +		this.frame = frame; +		this.data = data; +		setDialogTitle("Save MicroPeak Data File"); +		setFileFilter(new FileNameExtensionFilter("MicroPeak data file", +							  "mpd")); +		setCurrentDirectory(AltosUIPreferences.logdir()); +	} +} diff --git a/micropeak/MicroSerial.java b/micropeak/MicroSerial.java index a1a77a1d..15ef8582 100644 --- a/micropeak/MicroSerial.java +++ b/micropeak/MicroSerial.java @@ -27,6 +27,10 @@ public class MicroSerial extends InputStream {  	public int read() {  		int	c = libaltos.altos_getchar(file, 0); +		if (Thread.interrupted()) +			return -1; +		if (c == -1) +			return -1;  		if (AltosUIPreferences.serial_debug)  			System.out.printf("%c", c);  		return c; @@ -39,12 +43,12 @@ public class MicroSerial extends InputStream {  		}  	} -	public MicroSerial(MicroUSB usb) throws FileNotFoundException { -		file = usb.open(); +	public MicroSerial(AltosDevice device) throws FileNotFoundException { +		file = device.open();  		if (file == null) { -			final String message = usb.getErrorString(); +			final String message = device.getErrorString();  			throw new FileNotFoundException(String.format("%s (%s)", -								      usb.toShortString(), +								      device.toShortString(),  								      message));  		}  	} diff --git a/micropeak/MicroUSB.java b/micropeak/MicroUSB.java index d48610fe..244f7bc0 100644 --- a/micropeak/MicroUSB.java +++ b/micropeak/MicroUSB.java @@ -16,10 +16,12 @@   */  package org.altusmetrum.micropeak; +  import java.util.*;  import libaltosJNI.*; +import org.altusmetrum.altosuilib.*; -public class MicroUSB extends altos_device { +public class MicroUSB extends altos_device implements AltosDevice {  	static boolean	initialized = false;  	static boolean	loaded_library = false; @@ -48,16 +50,16 @@ public class MicroUSB extends altos_device {  		String	name = getName();  		if (name == null)  			name = "Altus Metrum"; -		return String.format("%-20.20s %4d %s", -				     name, getSerial(), getPath()); +		return String.format("%-20.20s %s", +				     name, getPath());  	}  	public String toShortString() {  		String	name = getName();  		if (name == null)  			name = "Altus Metrum"; -		return String.format("%s %d %s", -				     name, getSerial(), getPath()); +		return String.format("%s %s", +				     name, getPath());  	} @@ -75,11 +77,15 @@ public class MicroUSB extends altos_device {  	private boolean isMicro() {  		if (getVendor() != 0x0403)  			return false; -		if (getProduct() != 0x6001) +		if (getProduct() != 0x6015)  			return false;  		return true;  	} +	public boolean matchProduct(int product) { +		return isMicro(); +	} +  	static java.util.List<MicroUSB> list() {  		if (!load_library())  			return null; @@ -92,6 +98,7 @@ public class MicroUSB extends altos_device {  				MicroUSB device = new MicroUSB();  				if (libaltos.altos_list_next(list, device) == 0)  					break; +				System.out.printf("Device %s\n", device.toString());  				if (device.isMicro())  					device_list.add(device);  			} | 
