2 * Copyright © 2010 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 import java.util.prefs.*;
23 import java.util.concurrent.LinkedBlockingQueue;
24 import java.awt.Component;
26 import javax.swing.filechooser.FileSystemView;
28 class AltosPreferences {
29 static Preferences preferences;
31 /* logdir preference name */
32 final static String logdirPreference = "LOGDIR";
34 /* channel preference name */
35 final static String channelPreferenceFormat = "CHANNEL-%d";
37 /* frequency preference name */
38 final static String frequencyPreferenceFormat = "FREQUENCY-%d";
40 /* telemetry format preference name */
41 final static String telemetryPreferenceFormat = "TELEMETRY-%d";
43 /* voice preference name */
44 final static String voicePreference = "VOICE";
46 /* callsign preference name */
47 final static String callsignPreference = "CALLSIGN";
49 /* firmware directory preference name */
50 final static String firmwaredirPreference = "FIRMWARE";
52 /* serial debug preference name */
53 final static String serialDebugPreference = "SERIAL-DEBUG";
55 /* scanning telemetry preferences name */
56 final static String scanningTelemetryPreference = "SCANNING-TELEMETRY";
58 /* font size preferences name */
59 final static String fontSizePreference = "FONT-SIZE";
61 /* Launcher serial preference name */
62 final static String launcherSerialPreference = "LAUNCHER-SERIAL";
64 /* Launcher channel preference name */
65 final static String launcherChannelPreference = "LAUNCHER-CHANNEL";
67 /* Look&Feel preference name */
68 final static String lookAndFeelPreference = "LOOK-AND-FEEL";
70 /* Default logdir is ~/TeleMetrum */
71 final static String logdirName = "TeleMetrum";
73 /* UI Component to pop dialogs up */
74 static Component component;
79 /* Map directory -- hangs of logdir */
82 /* Frequency (map serial to frequency) */
83 static Hashtable<Integer, Double> frequencies;
85 /* Telemetry (map serial to telemetry format) */
86 static Hashtable<Integer, Integer> telemetries;
88 /* Voice preference */
91 /* Callsign preference */
92 static String callsign;
94 /* Firmware directory */
95 static File firmwaredir;
98 static boolean serial_debug;
100 /* Scanning telemetry */
101 static int scanning_telemetry;
103 static LinkedList<AltosFontListener> font_listeners;
105 static int font_size = Altos.font_size_medium;
107 static LinkedList<AltosUIListener> ui_listeners;
109 static String look_and_feel = null;
111 /* List of frequencies */
112 final static String common_frequencies_node_name = "COMMON-FREQUENCIES";
113 static AltosFrequency[] common_frequencies;
115 final static String frequency_count = "COUNT";
116 final static String frequency_format = "FREQUENCY-%d";
117 final static String description_format = "DESCRIPTION-%d";
119 static AltosFrequency[] load_common_frequencies() {
120 AltosFrequency[] frequencies = null;
121 boolean existing = false;
123 existing = preferences.nodeExists(common_frequencies_node_name);
124 } catch (BackingStoreException be) {
128 Preferences node = preferences.node(common_frequencies_node_name);
129 int count = node.getInt(frequency_count, 0);
131 frequencies = new AltosFrequency[count];
132 for (int i = 0; i < count; i++) {
136 frequency = node.getDouble(String.format(frequency_format, i), 0.0);
137 description = node.get(String.format(description_format, i), null);
138 frequencies[i] = new AltosFrequency(frequency, description);
141 frequencies = new AltosFrequency[10];
142 for (int i = 0; i < 10; i++) {
143 frequencies[i] = new AltosFrequency(434.550 + i * .1,
144 String.format("Channel %d", i));
150 static void save_common_frequencies(AltosFrequency[] frequencies) {
151 Preferences node = preferences.node(common_frequencies_node_name);
153 node.putInt(frequency_count, frequencies.length);
154 for (int i = 0; i < frequencies.length; i++) {
155 node.putDouble(String.format(frequency_format, i), frequencies[i].frequency);
156 node.put(String.format(description_format, i), frequencies[i].description);
159 static int launcher_serial;
161 static int launcher_channel;
163 public static void init() {
164 preferences = Preferences.userRoot().node("/org/altusmetrum/altosui");
166 /* Initialize logdir from preferences */
167 String logdir_string = preferences.get(logdirPreference, null);
168 if (logdir_string != null)
169 logdir = new File(logdir_string);
171 /* Use the file system view default directory */
172 logdir = new File(FileSystemView.getFileSystemView().getDefaultDirectory(), logdirName);
173 if (!logdir.exists())
176 mapdir = new File(logdir, "maps");
177 if (!mapdir.exists())
180 frequencies = new Hashtable<Integer, Double>();
182 telemetries = new Hashtable<Integer,Integer>();
184 voice = preferences.getBoolean(voicePreference, true);
186 callsign = preferences.get(callsignPreference,"N0CALL");
188 scanning_telemetry = preferences.getInt(scanningTelemetryPreference,(1 << Altos.ao_telemetry_standard));
190 font_listeners = new LinkedList<AltosFontListener>();
192 font_size = preferences.getInt(fontSizePreference, Altos.font_size_medium);
193 Altos.set_fonts(font_size);
195 launcher_serial = preferences.getInt(launcherSerialPreference, 0);
197 launcher_channel = preferences.getInt(launcherChannelPreference, 0);
199 String firmwaredir_string = preferences.get(firmwaredirPreference, null);
200 if (firmwaredir_string != null)
201 firmwaredir = new File(firmwaredir_string);
205 serial_debug = preferences.getBoolean(serialDebugPreference, false);
206 AltosSerial.set_debug(serial_debug);
208 common_frequencies = load_common_frequencies();
210 look_and_feel = preferences.get(lookAndFeelPreference, UIManager.getSystemLookAndFeelClassName());
212 ui_listeners = new LinkedList<AltosUIListener>();
217 static void set_component(Component in_component) {
218 component = in_component;
221 static void flush_preferences() {
224 } catch (BackingStoreException ee) {
225 if (component != null)
226 JOptionPane.showMessageDialog(component,
227 preferences.absolutePath(),
228 "Cannot save prefernces",
229 JOptionPane.ERROR_MESSAGE);
231 System.err.printf("Cannot save preferences\n");
235 public static void set_logdir(File new_logdir) {
237 mapdir = new File(logdir, "maps");
238 if (!mapdir.exists())
240 synchronized (preferences) {
241 preferences.put(logdirPreference, logdir.getPath());
246 private static boolean check_dir(File dir) {
249 JOptionPane.showMessageDialog(component,
251 "Cannot create directory",
252 JOptionPane.ERROR_MESSAGE);
255 } else if (!dir.isDirectory()) {
256 JOptionPane.showMessageDialog(component,
258 "Is not a directory",
259 JOptionPane.ERROR_MESSAGE);
265 /* Configure the log directory. This is where all telemetry and eeprom files
266 * will be written to, and where replay will look for telemetry files
268 public static void ConfigureLog() {
269 JFileChooser logdir_chooser = new JFileChooser(logdir.getParentFile());
271 logdir_chooser.setDialogTitle("Configure Data Logging Directory");
272 logdir_chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
274 if (logdir_chooser.showDialog(component, "Select Directory") == JFileChooser.APPROVE_OPTION) {
275 File dir = logdir_chooser.getSelectedFile();
281 public static File logdir() {
285 public static File mapdir() {
289 public static void set_frequency(int serial, double new_frequency) {
290 frequencies.put(serial, new_frequency);
291 synchronized (preferences) {
292 preferences.putDouble(String.format(frequencyPreferenceFormat, serial), new_frequency);
297 public static double frequency(int serial) {
298 if (frequencies.containsKey(serial))
299 return frequencies.get(serial);
300 double frequency = preferences.getDouble(String.format(frequencyPreferenceFormat, serial), 0);
301 if (frequency == 0.0) {
302 int channel = preferences.getInt(String.format(channelPreferenceFormat, serial), 0);
303 frequency = AltosConvert.radio_channel_to_frequency(channel);
305 frequencies.put(serial, frequency);
309 public static void set_telemetry(int serial, int new_telemetry) {
310 telemetries.put(serial, new_telemetry);
311 synchronized (preferences) {
312 preferences.putInt(String.format(telemetryPreferenceFormat, serial), new_telemetry);
317 public static int telemetry(int serial) {
318 if (telemetries.containsKey(serial))
319 return telemetries.get(serial);
320 int telemetry = preferences.getInt(String.format(telemetryPreferenceFormat, serial),
321 Altos.ao_telemetry_standard);
322 telemetries.put(serial, telemetry);
326 public static void set_scanning_telemetry(int new_scanning_telemetry) {
327 scanning_telemetry = new_scanning_telemetry;
328 synchronized (preferences) {
329 preferences.putInt(scanningTelemetryPreference, scanning_telemetry);
334 public static int scanning_telemetry() {
335 return scanning_telemetry;
338 public static void set_voice(boolean new_voice) {
340 synchronized (preferences) {
341 preferences.putBoolean(voicePreference, voice);
346 public static boolean voice() {
350 public static void set_callsign(String new_callsign) {
351 callsign = new_callsign;
352 synchronized(preferences) {
353 preferences.put(callsignPreference, callsign);
358 public static String callsign() {
362 public static void set_firmwaredir(File new_firmwaredir) {
363 firmwaredir = new_firmwaredir;
364 synchronized (preferences) {
365 preferences.put(firmwaredirPreference, firmwaredir.getPath());
370 public static File firmwaredir() {
374 public static int font_size() {
378 static void set_fonts() {
381 public static void set_font_size(int new_font_size) {
382 font_size = new_font_size;
383 synchronized (preferences) {
384 preferences.putInt(fontSizePreference, font_size);
386 Altos.set_fonts(font_size);
387 for (AltosFontListener l : font_listeners)
388 l.font_size_changed(font_size);
392 public static void register_font_listener(AltosFontListener l) {
393 synchronized (preferences) {
394 font_listeners.add(l);
398 public static void unregister_font_listener(AltosFontListener l) {
399 synchronized (preferences) {
400 font_listeners.remove(l);
404 public static void set_look_and_feel(String new_look_and_feel) {
405 look_and_feel = new_look_and_feel;
407 UIManager.setLookAndFeel(look_and_feel);
408 } catch (Exception e) {
410 synchronized(preferences) {
411 preferences.put(lookAndFeelPreference, look_and_feel);
413 for (AltosUIListener l : ui_listeners)
414 l.ui_changed(look_and_feel);
418 public static String look_and_feel() {
419 return look_and_feel;
422 public static void register_ui_listener(AltosUIListener l) {
423 synchronized(preferences) {
428 public static void unregister_ui_listener(AltosUIListener l) {
429 synchronized (preferences) {
430 ui_listeners.remove(l);
433 public static void set_serial_debug(boolean new_serial_debug) {
434 serial_debug = new_serial_debug;
435 AltosSerial.set_debug(serial_debug);
436 synchronized (preferences) {
437 preferences.putBoolean(serialDebugPreference, serial_debug);
442 public static boolean serial_debug() {
446 public static void set_launcher_serial(int new_launcher_serial) {
447 launcher_serial = new_launcher_serial;
448 System.out.printf("set launcher serial to %d\n", new_launcher_serial);
449 synchronized (preferences) {
450 preferences.putInt(launcherSerialPreference, launcher_serial);
455 public static int launcher_serial() {
456 return launcher_serial;
459 public static void set_launcher_channel(int new_launcher_channel) {
460 launcher_channel = new_launcher_channel;
461 System.out.printf("set launcher channel to %d\n", new_launcher_channel);
462 synchronized (preferences) {
463 preferences.putInt(launcherChannelPreference, launcher_channel);
468 public static int launcher_channel() {
469 return launcher_channel;
472 public static Preferences bt_devices() {
473 return preferences.node("bt_devices");
476 public static AltosFrequency[] common_frequencies() {
477 return common_frequencies;
480 public static void set_common_frequencies(AltosFrequency[] frequencies) {
481 common_frequencies = frequencies;
482 synchronized(preferences) {
483 save_common_frequencies(frequencies);
488 public static void add_common_frequency(AltosFrequency frequency) {
489 AltosFrequency[] new_frequencies = new AltosFrequency[common_frequencies.length + 1];
492 for (i = 0; i < common_frequencies.length; i++) {
493 if (frequency.frequency == common_frequencies[i].frequency)
495 if (frequency.frequency < common_frequencies[i].frequency)
497 new_frequencies[i] = common_frequencies[i];
499 new_frequencies[i] = frequency;
500 for (; i < common_frequencies.length; i++)
501 new_frequencies[i+1] = common_frequencies[i];
502 set_common_frequencies(new_frequencies);