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; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 package org.altusmetrum.altoslib_14;
25 public class AltosPreferences {
26 public static AltosPreferencesBackend backend = null;
28 /* logdir preference name */
29 public final static String logdirPreference = "LOGDIR";
31 /* channel preference name */
32 public final static String channelPreferenceFormat = "CHANNEL-%d";
34 /* frequency preference name */
35 public final static String frequencyPreferenceFormat = "FREQUENCY-%d";
37 /* telemetry format preference name */
38 public final static String telemetryPreferenceFormat = "TELEMETRY-%d";
40 /* telemetry rate format preference name */
41 public final static String telemetryRatePreferenceFormat = "RATE-%d";
43 /* log file format preference name */
44 public final static String logfilePreferenceFormat = "LOGFILE-%d";
46 /* state preference name */
47 public final static String statePreferenceHead = "STATE-";
48 public final static String statePreferenceFormat = "STATE-%d";
49 public final static String statePreferenceLatest = "STATE-LATEST";
51 /* voice preference name */
52 public final static String voicePreference = "VOICE";
54 /* callsign preference name */
55 public final static String callsignPreference = "CALLSIGN";
57 /* firmware directory preference name */
58 public final static String firmwaredirPreference = "FIRMWARE";
60 /* serial debug preference name */
61 public final static String serialDebugPreference = "SERIAL-DEBUG";
63 /* scanning telemetry preferences name */
64 public final static String scanningTelemetryPreference = "SCANNING-TELEMETRY";
66 /* scanning telemetry rate preferences name */
67 public final static String scanningTelemetryRatePreference = "SCANNING-RATE";
69 /* Launcher serial preference name */
70 public final static String launcherSerialPreference = "LAUNCHER-SERIAL";
72 /* Launcher channel preference name */
73 public final static String launcherChannelPreference = "LAUNCHER-CHANNEL";
75 /* Default logdir is ~/AltusMetrum */
76 public final static String logdirName = "AltusMetrum";
79 public static File logdir;
81 /* Last log directory - use this next time we open or save something */
82 public static File last_logdir;
84 /* Map directory -- hangs of logdir */
85 public static File mapdir;
87 /* Frequency (map serial to frequency) */
88 public static Hashtable<Integer, Double> frequencies;
90 /* Telemetry (map serial to telemetry format) */
91 public static Hashtable<Integer, Integer> telemetries;
93 /* Telemetry rate (map serial to telemetry format) */
94 public static Hashtable<Integer, Integer> telemetry_rates;
96 /* Log file (map serial to logfile name) */
97 public static Hashtable<Integer, File> logfiles;
99 /* Voice preference */
100 public static boolean voice;
102 /* Callsign preference */
103 public static String callsign;
105 /* Firmware directory */
106 public static File firmwaredir;
108 /* Scanning telemetry */
109 public static int scanning_telemetry;
111 public static int scanning_telemetry_rate;
113 /* List of frequencies */
114 public final static String common_frequencies_node_name = "COMMON-FREQUENCIES";
115 public static AltosFrequency[] common_frequencies;
117 public final static String frequency_count = "COUNT";
118 public final static String frequency_format = "FREQUENCY-%d";
119 public final static String description_format = "DESCRIPTION-%d";
120 public final static String frequenciesPreference = "FREQUENCIES-1";
122 /* Units preference */
124 public final static String unitsPreference = "IMPERIAL-UNITS";
126 /* Maps cache size preference name */
127 final static String mapCachePreference = "MAP-CACHE";
129 static LinkedList<AltosMapCacheListener> map_cache_listeners;
131 public static int map_cache = 9;
133 final static String mapTypePreference = "MAP-TYPE";
136 public static AltosFrequency[] load_common_frequencies() {
137 AltosFrequency[] frequencies = null;
140 AltosJson json = AltosJson.fromString(backend.getString(frequenciesPreference,
142 frequencies = (AltosFrequency[]) json.make((new AltosFrequency[1]).getClass());
143 } catch (Exception e) {
146 if (frequencies == null) {
147 if (backend.nodeExists(common_frequencies_node_name)) {
148 AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
149 int count = node.getInt(frequency_count, 0);
152 frequencies = new AltosFrequency[count];
153 for (int i = 0; i < count; i++) {
157 frequency = node.getDouble(String.format(frequency_format, i), 0.0);
158 description = node.getString(String.format(description_format, i), null);
159 frequencies[i] = new AltosFrequency(frequency, description);
165 if (frequencies == null) {
166 frequencies = new AltosFrequency[10];
167 for (int i = 0; i < 10; i++) {
168 frequencies[i] = new AltosFrequency(434.550 + i * .1,
169 String.format("Channel %d", i));
175 public static void save_common_frequencies() {
176 AltosJson json = new AltosJson(common_frequencies);
177 backend.putString(frequenciesPreference, json.toString());
181 public static int launcher_serial;
183 public static int launcher_channel;
185 public static void init(AltosPreferencesBackend in_backend) {
190 backend = in_backend;
192 /* Initialize logdir from preferences */
193 String logdir_string = backend.getString(logdirPreference, null);
194 if (logdir_string != null)
195 logdir = new File(logdir_string);
197 logdir = new File(backend.homeDirectory(), logdirName);
198 if (!logdir.exists())
201 mapdir = new File(logdir, "maps");
202 if (!mapdir.exists())
205 frequencies = new Hashtable<Integer, Double>();
207 telemetries = new Hashtable<Integer,Integer>();
209 telemetry_rates = new Hashtable<Integer,Integer>();
211 logfiles = new Hashtable<Integer,File>();
213 voice = backend.getBoolean(voicePreference, true);
215 callsign = backend.getString(callsignPreference,"N0CALL");
217 scanning_telemetry = backend.getInt(scanningTelemetryPreference,(1 << AltosLib.ao_telemetry_standard));
219 scanning_telemetry_rate = backend.getInt(scanningTelemetryRatePreference,(1 << AltosLib.ao_telemetry_rate_38400));
221 launcher_serial = backend.getInt(launcherSerialPreference, 0);
223 launcher_channel = backend.getInt(launcherChannelPreference, 0);
225 String firmwaredir_string = backend.getString(firmwaredirPreference, null);
226 if (firmwaredir_string != null)
227 firmwaredir = new File(firmwaredir_string);
231 common_frequencies = load_common_frequencies();
233 AltosConvert.imperial_units = backend.getBoolean(unitsPreference, false);
235 map_cache = backend.getInt(mapCachePreference, 9);
236 map_cache_listeners = new LinkedList<AltosMapCacheListener>();
237 map_type = backend.getInt(mapTypePreference, AltosMap.maptype_hybrid);
240 public static void flush_preferences() {
244 public static void set_logdir(File new_logdir) {
245 synchronized (backend) {
247 mapdir = new File(logdir, "maps");
248 if (!mapdir.exists())
250 backend.putString(logdirPreference, logdir.getPath());
255 public static File logdir() {
256 synchronized (backend) {
261 public static File last_logdir() {
262 synchronized (backend) {
263 if (last_logdir == null)
264 last_logdir = logdir;
269 public static void set_last_logdir(File file) {
270 synchronized(backend) {
271 if (file != null && !file.isDirectory())
272 file = file.getParentFile();
274 file = new File(".");
279 public static File mapdir() {
280 synchronized (backend) {
285 public static void set_frequency(int serial, double new_frequency) {
286 synchronized (backend) {
287 frequencies.put(serial, new_frequency);
288 backend.putDouble(String.format(frequencyPreferenceFormat, serial), new_frequency);
293 public static double frequency(int serial) {
294 synchronized (backend) {
295 if (frequencies.containsKey(serial))
296 return frequencies.get(serial);
297 double frequency = backend.getDouble(String.format(frequencyPreferenceFormat, serial), 0);
298 if (frequency == 0.0) {
299 int channel = backend.getInt(String.format(channelPreferenceFormat, serial), 0);
300 frequency = AltosConvert.radio_channel_to_frequency(channel);
302 frequencies.put(serial, frequency);
307 public static void set_telemetry(int serial, int new_telemetry) {
308 synchronized (backend) {
309 telemetries.put(serial, new_telemetry);
310 backend.putInt(String.format(telemetryPreferenceFormat, serial), new_telemetry);
315 public static int telemetry(int serial) {
316 synchronized (backend) {
317 if (telemetries.containsKey(serial))
318 return telemetries.get(serial);
319 int telemetry = backend.getInt(String.format(telemetryPreferenceFormat, serial),
320 AltosLib.ao_telemetry_standard);
321 telemetries.put(serial, telemetry);
326 public static void set_telemetry_rate(int serial, int new_telemetry_rate) {
327 synchronized (backend) {
328 telemetry_rates.put(serial, new_telemetry_rate);
329 backend.putInt(String.format(telemetryRatePreferenceFormat, serial), new_telemetry_rate);
334 public static int telemetry_rate(int serial) {
335 synchronized (backend) {
336 if (telemetry_rates.containsKey(serial))
337 return telemetry_rates.get(serial);
338 int telemetry_rate = backend.getInt(String.format(telemetryRatePreferenceFormat, serial),
339 AltosLib.ao_telemetry_rate_38400);
340 telemetry_rates.put(serial, telemetry_rate);
341 return telemetry_rate;
345 public static void set_logfile(int serial, File new_logfile) {
346 synchronized(backend) {
347 logfiles.put(serial, new_logfile);
348 backend.putString(String.format(logfilePreferenceFormat, serial), new_logfile.getPath());
353 public static File logfile(int serial) {
354 synchronized(backend) {
355 if (logfiles.containsKey(serial))
356 return logfiles.get(serial);
357 String logfile_string = backend.getString(String.format(logfilePreferenceFormat, serial), null);
358 if (logfile_string == null)
360 File logfile = new File(logfile_string);
361 logfiles.put(serial, logfile);
366 public static void set_state(AltosState state, int serial) {
368 synchronized(backend) {
369 backend.putJson(String.format(statePreferenceFormat, serial), new AltosJson(state));
370 backend.putInt(statePreferenceLatest, serial);
375 public static ArrayList<Integer> list_states() {
376 String[] keys = backend.keys();
377 ArrayList<Integer> states = new ArrayList<Integer>();
379 for (String key : keys) {
380 if (key.startsWith(statePreferenceHead)) {
382 int serial = AltosParse.parse_int(key.substring(statePreferenceHead.length()));
384 } catch (ParseException pe) {
391 public static void remove_state(int serial) {
392 synchronized(backend) {
393 backend.remove(String.format(statePreferenceFormat, serial));
398 public static int latest_state() {
400 synchronized (backend) {
401 latest = backend.getInt(statePreferenceLatest, 0);
406 public static AltosState state(int serial) {
407 synchronized(backend) {
409 AltosJson json = backend.getJson(String.format(statePreferenceFormat, serial));
411 return (AltosState) (json.make(AltosState.class));
412 } catch (Exception e) {
418 public static void set_scanning_telemetry(int new_scanning_telemetry) {
419 synchronized (backend) {
420 scanning_telemetry = new_scanning_telemetry;
421 backend.putInt(scanningTelemetryPreference, scanning_telemetry);
426 public static int scanning_telemetry() {
427 synchronized (backend) {
428 return scanning_telemetry;
432 public static void set_scanning_telemetry_rate(int new_scanning_telemetry_rate) {
433 synchronized (backend) {
434 scanning_telemetry_rate = new_scanning_telemetry_rate;
435 backend.putInt(scanningTelemetryRatePreference, scanning_telemetry_rate);
440 public static int scanning_telemetry_rate() {
441 synchronized(backend) {
442 return scanning_telemetry_rate;
446 public static void set_voice(boolean new_voice) {
447 synchronized (backend) {
449 backend.putBoolean(voicePreference, voice);
454 public static boolean voice() {
455 synchronized (backend) {
460 public static void set_callsign(String new_callsign) {
461 synchronized(backend) {
462 callsign = new_callsign;
463 backend.putString(callsignPreference, callsign);
468 public static String callsign() {
469 synchronized(backend) {
474 public static void set_firmwaredir(File new_firmwaredir) {
475 synchronized (backend) {
476 firmwaredir = new_firmwaredir;
477 backend.putString(firmwaredirPreference, firmwaredir.getPath());
482 public static File firmwaredir() {
483 synchronized (backend) {
488 public static void set_launcher_serial(int new_launcher_serial) {
489 synchronized (backend) {
490 launcher_serial = new_launcher_serial;
491 backend.putInt(launcherSerialPreference, launcher_serial);
496 public static int launcher_serial() {
497 synchronized (backend) {
498 return launcher_serial;
502 public static void set_launcher_channel(int new_launcher_channel) {
503 synchronized (backend) {
504 launcher_channel = new_launcher_channel;
505 backend.putInt(launcherChannelPreference, launcher_channel);
510 public static int launcher_channel() {
511 synchronized (backend) {
512 return launcher_channel;
516 public static AltosPreferencesBackend bt_devices() {
517 synchronized (backend) {
518 return backend.node("bt_devices");
522 public static AltosFrequency[] common_frequencies() {
523 synchronized (backend) {
524 return common_frequencies;
528 public static void set_common_frequencies(AltosFrequency[] frequencies) {
529 synchronized(backend) {
530 common_frequencies = frequencies;
532 save_common_frequencies();
536 public static void add_common_frequency(AltosFrequency frequency) {
537 AltosFrequency[] old_frequencies = common_frequencies();
538 AltosFrequency[] new_frequencies = new AltosFrequency[old_frequencies.length + 1];
541 for (i = 0; i < old_frequencies.length; i++) {
542 if (frequency.frequency == old_frequencies[i].frequency)
544 if (frequency.frequency < old_frequencies[i].frequency)
546 new_frequencies[i] = old_frequencies[i];
548 new_frequencies[i] = frequency;
549 for (; i < old_frequencies.length; i++)
550 new_frequencies[i+1] = old_frequencies[i];
551 set_common_frequencies(new_frequencies);
554 static LinkedList<AltosUnitsListener> units_listeners;
556 public static boolean imperial_units() {
557 synchronized(backend) {
558 return AltosConvert.imperial_units;
562 public static void set_imperial_units(boolean imperial_units) {
563 synchronized (backend) {
564 AltosConvert.imperial_units = imperial_units;
565 backend.putBoolean(unitsPreference, imperial_units);
568 if (units_listeners != null) {
569 for (AltosUnitsListener l : units_listeners) {
570 l.units_changed(imperial_units);
575 public static void register_units_listener(AltosUnitsListener l) {
576 synchronized(backend) {
577 if (units_listeners == null)
578 units_listeners = new LinkedList<AltosUnitsListener>();
579 units_listeners.add(l);
583 public static void unregister_units_listener(AltosUnitsListener l) {
584 synchronized(backend) {
585 units_listeners.remove(l);
590 public static void register_map_cache_listener(AltosMapCacheListener l) {
591 synchronized(backend) {
592 map_cache_listeners.add(l);
596 public static void unregister_map_cache_listener(AltosMapCacheListener l) {
597 synchronized (backend) {
598 map_cache_listeners.remove(l);
602 public static void set_map_cache(int new_map_cache) {
603 synchronized(backend) {
604 map_cache = new_map_cache;
605 backend.putInt(mapCachePreference, map_cache);
607 for (AltosMapCacheListener l: map_cache_listeners)
608 l.map_cache_changed(map_cache);
612 public static int map_cache() {
613 synchronized(backend) {
618 static LinkedList<AltosMapTypeListener> map_type_listeners;
620 public static void set_map_type(int map_type) {
621 synchronized(backend) {
622 AltosPreferences.map_type = map_type;
623 backend.putInt(mapTypePreference, map_type);
626 if (map_type_listeners != null) {
627 for (AltosMapTypeListener l : map_type_listeners) {
628 l.map_type_changed(map_type);
633 public static int map_type() {
634 synchronized(backend) {
639 public static void register_map_type_listener(AltosMapTypeListener l) {
640 synchronized(backend) {
641 if (map_type_listeners == null)
642 map_type_listeners = new LinkedList<AltosMapTypeListener>();
643 map_type_listeners.add(l);
647 public static void unregister_map_type_listener(AltosMapTypeListener l) {
648 synchronized(backend) {
649 map_type_listeners.remove(l);