[PATCH 1/2] Update preference saving for numeric values

Linus Torvalds torvalds at linux-foundation.org
Fri Jan 11 11:49:40 PST 2013


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Fri, 11 Jan 2013 10:14:10 -0800
Subject: [PATCH 1/2] Update preference saving for numeric values

This does the "don't save defaults" for numeric values too.

Also, move the preferences loading/saving to a new "prefs.c" file.

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---

This continues the series from yesterday. The next patch fixes a problem 
that I noticed that happens when you have no nickname entries in the 
system config, but then load an XML file that has dive computers listed, 
and without a new nickname.

That was an independent bug, but is related to this patch in the sense 
that I noticed that as I was testing this one: if you clear all the system 
config data (to test this whole default loading/saving logic) and have 
dive computer entries without nicknames in your xml file, you can easily 
see that. 

 Makefile      |   6 ++-
 display-gtk.h |   1 -
 gtk-gui.c     | 118 +------------------------------------------
 pref.h        |   6 +++
 prefs.c       | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 173 insertions(+), 118 deletions(-)
 create mode 100644 prefs.c

diff --git a/Makefile b/Makefile
index aade639f2cdd..1a7543556ae8 100644
--- a/Makefile
+++ b/Makefile
@@ -132,7 +132,8 @@ MSGOBJS=$(addprefix share/locale/,$(MSGLANGS:.po=.UTF-8/LC_MESSAGES/subsurface.m
 
 OBJS =	main.o dive.o time.o profile.o info.o equipment.o divelist.o deco.o planner.o \
 	parse-xml.o save-xml.o libdivecomputer.o print.o uemis.o uemis-downloader.o \
-	gtk-gui.o statistics.o file.o cochran.o device.o download-dialog.o $(OSSUPPORT).o $(RESFILE)
+	gtk-gui.o statistics.o file.o cochran.o device.o download-dialog.o prefs.o \
+	$(OSSUPPORT).o $(RESFILE)
 
 $(NAME): $(OBJS) $(MSGOBJS)
 	$(CC) $(LDFLAGS) -o $(NAME) $(OBJS) $(LIBS)
@@ -273,6 +274,9 @@ uemis-downloader.o: uemis-downloader.c dive.h uemis.h
 device.o: device.c device.h dive.h
 	$(CC) $(CFLAGS) $(GLIB2CFLAGS) -c device.c
 
+prefs.o: prefs.c dive.h pref.h
+	$(CC) $(CFLAGS) $(GLIB2CFLAGS) -c prefs.c
+
 $(OSSUPPORT).o: $(OSSUPPORT).c display-gtk.h
 	$(CC) $(CFLAGS) $(OSSUPPORT_CFLAGS) -c $(OSSUPPORT).c
 
diff --git a/display-gtk.h b/display-gtk.h
index e083a3e961f3..b889ff1a2c99 100644
--- a/display-gtk.h
+++ b/display-gtk.h
@@ -32,7 +32,6 @@ extern void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar,
 extern void quit(GtkWidget *w, gpointer data);
 extern gboolean on_delete(GtkWidget* w, gpointer data);
 
-extern const char *divelist_font;
 extern void set_divelist_font(const char *);
 
 extern void import_files(GtkWidget *, gpointer);
diff --git a/gtk-gui.c b/gtk-gui.c
index 4dbd367992b5..60dde03990a5 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -528,19 +528,6 @@ static void pick_default_file(GtkWidget *w, GtkButton *button)
 	gtk_widget_set_sensitive(parent, TRUE);
 }
 
-static void set_bool_conf(char *name, gboolean value, gboolean def)
-{
-	if (value == def) {
-		subsurface_unset_conf(name);
-		return;
-	}
-	subsurface_set_conf_bool(name, value);
-}
-#define __SAVE_BOOLEAN(name, field, value) \
-	set_bool_conf(name, prefs.field == value, default_prefs.field == value)
-#define SAVE_UNIT(name, field, value) __SAVE_BOOLEAN(name, units.field, value)
-#define SAVE_BOOL(name, field) __SAVE_BOOLEAN(name, field, TRUE)
-
 static void preferences_dialog(GtkWidget *w, gpointer data)
 {
 	int result;
@@ -806,40 +793,6 @@ static void preferences_dialog(GtkWidget *w, gpointer data)
 
 		update_screen();
 
-		SAVE_UNIT("feet", length, FEET);
-		SAVE_UNIT("psi", pressure, PSI);
-		SAVE_UNIT("cuft", volume, CUFT);
-		SAVE_UNIT("fahrenheit", temperature, FAHRENHEIT);
-		SAVE_UNIT("lbs", weight, LBS);
-
-		SAVE_BOOL("TEMPERATURE", visible_cols.temperature);
-		SAVE_BOOL("TOTALWEIGHT", visible_cols.totalweight);
-		SAVE_BOOL("SUIT", visible_cols.suit);
-		SAVE_BOOL("CYLINDER", visible_cols.cylinder);
-		SAVE_BOOL("NITROX", visible_cols.nitrox);
-		SAVE_BOOL("SAC", visible_cols.sac);
-		SAVE_BOOL("OTU", visible_cols.otu);
-		SAVE_BOOL("MAXCNS", visible_cols.maxcns);
-
-		subsurface_set_conf("divelist_font", divelist_font);
-
-		SAVE_BOOL("po2graph", pp_graphs.po2);
-		SAVE_BOOL("pn2graph", pp_graphs.pn2);
-		SAVE_BOOL("phegraph", pp_graphs.phe);
-
-		/* Fixme! Only save if different-from-default. unset if default */
-		subsurface_set_conf("po2threshold", po2_threshold_text);
-		subsurface_set_conf("pn2threshold", pn2_threshold_text);
-		subsurface_set_conf("phethreshold", phe_threshold_text);
-
-		SAVE_BOOL("redceiling", profile_red_ceiling);
-		SAVE_BOOL("calcceiling", profile_calc_ceiling);
-		SAVE_BOOL("calcceiling3m", calc_ceiling_3m_incr);
-
-		/* Fixme! Only save if different-from-default. unset if default */
-		subsurface_set_conf("gflow", gflow_text);
-		subsurface_set_conf("gfhigh", gfhigh_text);
-
 		new_default = strdup(gtk_button_get_label(GTK_BUTTON(xmlfile_button)));
 
 		/* if we opened the default file and are changing its name,
@@ -852,13 +805,11 @@ static void preferences_dialog(GtkWidget *w, gpointer data)
 		}
 
 		if (strcmp(current_default, new_default)) {
-			subsurface_set_conf("default_filename", new_default);
 			free((void *)default_filename);
 			default_filename = new_default;
 		}
 
-		/* Flush the changes out to the system */
-		subsurface_flush_conf();
+		save_preferences();
 	} else if (result == GTK_RESPONSE_CANCEL) {
 		prefs = oldprefs;
 		set_gf(prefs.gflow, prefs.gfhigh);
@@ -1195,18 +1146,6 @@ static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, GtkWidget *diveli
 	return FALSE;
 }
 
-static gboolean get_bool(char *name, gboolean def)
-{
-	int val = subsurface_get_conf_bool(name);
-	if (val < 0)
-		return def;
-	return val;
-}
-#define GET_UNIT(name, field, f, t) \
-	prefs.units.field = get_bool(name, default_prefs.units.field) ? (t) : (f)
-#define GET_BOOL(name, field) \
-	prefs.field = get_bool(name, default_prefs.field)
-
 void init_ui(int *argcp, char ***argvp)
 {
 	GtkWidget *win;
@@ -1240,60 +1179,7 @@ void init_ui(int *argcp, char ***argvp)
 
 	subsurface_open_conf();
 
-	GET_UNIT("feet", length, METERS, FEET);
-	GET_UNIT("psi", pressure, BAR, PSI);
-	GET_UNIT("cuft", volume, LITER, CUFT);
-	GET_UNIT("fahrenheit", temperature, CELSIUS, FAHRENHEIT);
-	GET_UNIT("lbs", weight, KG, LBS);
-
-	/* an unset key is 'default' */
-	GET_BOOL("CYLINDER", visible_cols.cylinder);
-	GET_BOOL("TEMPERATURE", visible_cols.temperature);
-	GET_BOOL("TOTALWEIGHT", visible_cols.totalweight);
-	GET_BOOL("SUIT", visible_cols.suit);
-	GET_BOOL("NITROX", visible_cols.nitrox);
-	GET_BOOL("OTU", visible_cols.otu);
-	GET_BOOL("MAXCNS", visible_cols.maxcns);
-	GET_BOOL("SAC", visible_cols.sac);
-	GET_BOOL("po2graph", pp_graphs.po2);
-	GET_BOOL("pn2graph", pp_graphs.pn2);
-	GET_BOOL("phegraph", pp_graphs.phe);
-
-	conf_value = subsurface_get_conf("po2threshold");
-	if (conf_value) {
-		sscanf(conf_value, "%lf", &prefs.pp_graphs.po2_threshold);
-		free((void *)conf_value);
-	}
-	conf_value = subsurface_get_conf("pn2threshold");
-	if (conf_value) {
-		sscanf(conf_value, "%lf", &prefs.pp_graphs.pn2_threshold);
-		free((void *)conf_value);
-	}
-	conf_value = subsurface_get_conf("phethreshold");
-	if (conf_value) {
-		sscanf(conf_value, "%lf", &prefs.pp_graphs.phe_threshold);
-		free((void *)conf_value);
-	}
-	GET_BOOL("redceiling", profile_red_ceiling);
-	GET_BOOL("calcceiling", profile_calc_ceiling);
-	GET_BOOL("calcceiling3m", calc_ceiling_3m_incr);
-	conf_value = subsurface_get_conf("gflow");
-	if (conf_value) {
-		sscanf(conf_value, "%lf", &prefs.gflow);
-		prefs.gflow /= 100.0;
-		set_gf(prefs.gflow, -1.0);
-		free((void *)conf_value);
-	}
-	conf_value = subsurface_get_conf("gfhigh");
-	if (conf_value) {
-		sscanf(conf_value, "%lf", &prefs.gfhigh);
-		prefs.gfhigh /= 100.0;
-		set_gf(-1.0, prefs.gfhigh);
-		free((void *)conf_value);
-	}
-	divelist_font = subsurface_get_conf("divelist_font");
-
-	default_filename = subsurface_get_conf("default_filename");
+	load_preferences();
 
 	default_dive_computer_vendor = subsurface_get_conf("dive_computer_vendor");
 	default_dive_computer_product = subsurface_get_conf("dive_computer_product");
diff --git a/pref.h b/pref.h
index 1804b3e5ded3..18a6480322f7 100644
--- a/pref.h
+++ b/pref.h
@@ -45,4 +45,10 @@ extern int subsurface_get_conf_bool(char *name);
 extern void subsurface_flush_conf(void);
 extern void subsurface_close_conf(void);
 
+/* Misc preferences - should we have defaults for these too? */
+extern const char *divelist_font;
+
+extern void load_preferences(void);
+extern void save_preferences(void);
+
 #endif /* PREF_H */
diff --git a/prefs.c b/prefs.c
new file mode 100644
index 000000000000..9dbb9ed4a87c
--- /dev/null
+++ b/prefs.c
@@ -0,0 +1,160 @@
+#include "dive.h"
+
+static void set_bool_conf(char *name, gboolean value, gboolean def)
+{
+	if (value == def) {
+		subsurface_unset_conf(name);
+		return;
+	}
+	subsurface_set_conf_bool(name, value);
+}
+#define __SAVE_BOOLEAN(name, field, value) \
+	set_bool_conf(name, prefs.field == value, default_prefs.field == value)
+#define SAVE_UNIT(name, field, value) __SAVE_BOOLEAN(name, units.field, value)
+#define SAVE_BOOL(name, field) __SAVE_BOOLEAN(name, field, TRUE)
+
+/* We don't really save doubles */
+static void save_double_conf(char *name, double _val, double _def)
+{
+	int val = rint(_val * 100), neg, len;
+	int def = rint(_def * 100);
+	char string[16];
+
+	if (val == def) {
+		subsurface_unset_conf(name);
+		return;
+	}
+	neg = 0;
+	if (val < 0) {
+		neg = 1;
+		val = -val;
+	}
+	len = snprintf(string, sizeof(string), "%s%d.%02d",
+		neg ? "-" : "", val / 100, val % 100);
+
+	/* Save with 0-2 decimals */
+	if (string[len-1] == '0') {
+		len--;
+		if (string[len-1] == '0')
+			len -= 2;	/* Remove decimal point too */
+		string[len] = 0;
+	}
+
+	subsurface_set_conf(name, string);
+}
+
+#define SAVE_DOUBLE(name, field) save_double_conf(name, prefs.field, default_prefs.field)
+#define SAVE_PERCENT(name, field) save_double_conf(name, prefs.field*100, default_prefs.field*100)
+
+void save_preferences(void)
+{
+	SAVE_UNIT("feet", length, FEET);
+	SAVE_UNIT("psi", pressure, PSI);
+	SAVE_UNIT("cuft", volume, CUFT);
+	SAVE_UNIT("fahrenheit", temperature, FAHRENHEIT);
+	SAVE_UNIT("lbs", weight, LBS);
+
+	SAVE_BOOL("TEMPERATURE", visible_cols.temperature);
+	SAVE_BOOL("TOTALWEIGHT", visible_cols.totalweight);
+	SAVE_BOOL("SUIT", visible_cols.suit);
+	SAVE_BOOL("CYLINDER", visible_cols.cylinder);
+	SAVE_BOOL("NITROX", visible_cols.nitrox);
+	SAVE_BOOL("SAC", visible_cols.sac);
+	SAVE_BOOL("OTU", visible_cols.otu);
+	SAVE_BOOL("MAXCNS", visible_cols.maxcns);
+
+	subsurface_set_conf("divelist_font", divelist_font);
+
+	SAVE_BOOL("po2graph", pp_graphs.po2);
+	SAVE_BOOL("pn2graph", pp_graphs.pn2);
+	SAVE_BOOL("phegraph", pp_graphs.phe);
+
+	SAVE_DOUBLE("po2threshold", pp_graphs.po2_threshold);
+	SAVE_DOUBLE("pn2threshold", pp_graphs.pn2_threshold);
+	SAVE_DOUBLE("phethreshold", pp_graphs.phe_threshold);
+
+	SAVE_BOOL("redceiling", profile_red_ceiling);
+	SAVE_BOOL("calcceiling", profile_calc_ceiling);
+	SAVE_BOOL("calcceiling3m", calc_ceiling_3m_incr);
+
+	SAVE_PERCENT("gflow", gflow);
+	SAVE_PERCENT("gfhigh", gfhigh);
+
+	subsurface_set_conf("default_filename", default_filename);
+
+	/* Flush the changes out to the system */
+	subsurface_flush_conf();
+}
+
+static gboolean get_bool(char *name, gboolean def)
+{
+	int val = subsurface_get_conf_bool(name);
+	if (val < 0)
+		return def;
+	return val;
+}
+#define GET_UNIT(name, field, f, t) \
+	prefs.units.field = get_bool(name, default_prefs.units.field) ? (t) : (f)
+#define GET_BOOL(name, field) \
+	prefs.field = get_bool(name, default_prefs.field)
+
+
+void load_preferences(void)
+{
+	const char *conf_value;
+
+	GET_UNIT("feet", length, METERS, FEET);
+	GET_UNIT("psi", pressure, BAR, PSI);
+	GET_UNIT("cuft", volume, LITER, CUFT);
+	GET_UNIT("fahrenheit", temperature, CELSIUS, FAHRENHEIT);
+	GET_UNIT("lbs", weight, KG, LBS);
+
+	/* an unset key is 'default' */
+	GET_BOOL("CYLINDER", visible_cols.cylinder);
+	GET_BOOL("TEMPERATURE", visible_cols.temperature);
+	GET_BOOL("TOTALWEIGHT", visible_cols.totalweight);
+	GET_BOOL("SUIT", visible_cols.suit);
+	GET_BOOL("NITROX", visible_cols.nitrox);
+	GET_BOOL("OTU", visible_cols.otu);
+	GET_BOOL("MAXCNS", visible_cols.maxcns);
+	GET_BOOL("SAC", visible_cols.sac);
+	GET_BOOL("po2graph", pp_graphs.po2);
+	GET_BOOL("pn2graph", pp_graphs.pn2);
+	GET_BOOL("phegraph", pp_graphs.phe);
+
+	conf_value = subsurface_get_conf("po2threshold");
+	if (conf_value) {
+		sscanf(conf_value, "%lf", &prefs.pp_graphs.po2_threshold);
+		free((void *)conf_value);
+	}
+	conf_value = subsurface_get_conf("pn2threshold");
+	if (conf_value) {
+		sscanf(conf_value, "%lf", &prefs.pp_graphs.pn2_threshold);
+		free((void *)conf_value);
+	}
+	conf_value = subsurface_get_conf("phethreshold");
+	if (conf_value) {
+		sscanf(conf_value, "%lf", &prefs.pp_graphs.phe_threshold);
+		free((void *)conf_value);
+	}
+	GET_BOOL("redceiling", profile_red_ceiling);
+	GET_BOOL("calcceiling", profile_calc_ceiling);
+	GET_BOOL("calcceiling3m", calc_ceiling_3m_incr);
+	conf_value = subsurface_get_conf("gflow");
+	if (conf_value) {
+		sscanf(conf_value, "%lf", &prefs.gflow);
+		prefs.gflow /= 100.0;
+		set_gf(prefs.gflow, -1.0);
+		free((void *)conf_value);
+	}
+	conf_value = subsurface_get_conf("gfhigh");
+	if (conf_value) {
+		sscanf(conf_value, "%lf", &prefs.gfhigh);
+		prefs.gfhigh /= 100.0;
+		set_gf(-1.0, prefs.gfhigh);
+		free((void *)conf_value);
+	}
+	divelist_font = subsurface_get_conf("divelist_font");
+
+	default_filename = subsurface_get_conf("default_filename");
+}
-- 
1.8.1.rc2.6.g18499ba



More information about the subsurface mailing list