1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
5 * Copyright (C) 2013, Rob Norris <rw_norris@hotmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Sort of like the globals file, but values are automatically saved via program use.
24 * Some settings are *not* intended to have any GUI controls.
25 * Other settings be can used to set other GUI elements.
27 * ATM This is implemented using the simple (for me!) GKeyFile API - AKA an .ini file
28 * One might wish to consider the more modern alternative such as:
29 * http://developer.gnome.org/gio/2.26/GSettings.html
30 * Since these settings are 'internal' I have no problem with them *not* being supported
31 * between various Viking versions, should one switch to different API/storage methods.
32 * Indeed even the internal settings themselves can be liable to change.
37 static GKeyFile *keyfile;
39 #define VIKING_INI_FILE "viking.ini"
41 static gboolean settings_load_from_file()
43 GKeyFileFlags flags = G_KEY_FILE_KEEP_COMMENTS;
47 gchar *fn = g_build_filename ( a_get_viking_dir(), VIKING_INI_FILE, NULL );
49 if ( !g_key_file_load_from_file ( keyfile, fn, flags, &error ) ) {
50 g_warning ( "%s: %s", error->message, fn );
52 g_error_free ( error );
61 void a_settings_init()
63 keyfile = g_key_file_new();
64 settings_load_from_file();
70 * ATM: The only time settings are saved is on program exit
71 * Could change this to occur on window exit or dialog exit or have memory hash of values...?
73 void a_settings_uninit()
76 gchar *fn = g_build_filename ( a_get_viking_dir(), VIKING_INI_FILE, NULL );
79 gchar *keyfilestr = g_key_file_to_data ( keyfile, &size, &error );
82 g_warning ( "%s", error->message );
83 g_error_free ( error );
87 g_file_set_contents ( fn, keyfilestr, size, &error );
89 g_warning ( "%s: %s", error->message, fn );
90 g_error_free ( error );
93 g_key_file_free ( keyfile );
95 g_free ( keyfilestr );
99 // ATM, can't see a point in having any more than one group for various settings
100 #define VIKING_SETTINGS_GROUP "viking"
102 static gboolean settings_get_boolean ( const gchar *group, const gchar *name, gboolean *val )
104 GError *error = NULL;
105 gboolean success = TRUE;
106 gboolean bb = g_key_file_get_boolean ( keyfile, group, name, &error );
108 // Only print on debug - as often may have requests for keys not in the file
109 g_debug ( "%s", error->message );
110 g_error_free ( error );
117 gboolean a_settings_get_boolean ( const gchar *name, gboolean *val )
119 return settings_get_boolean ( VIKING_SETTINGS_GROUP, name, val );
122 void a_settings_set_boolean ( const gchar *name, gboolean val )
124 g_key_file_set_boolean ( keyfile, VIKING_SETTINGS_GROUP, name, val );
127 static gboolean settings_get_string ( const gchar *group, const gchar *name, gchar **val )
129 GError *error = NULL;
130 gboolean success = TRUE;
131 gchar *str = g_key_file_get_string ( keyfile, group, name, &error );
133 // Only print on debug - as often may have requests for keys not in the file
134 g_debug ( "%s", error->message );
135 g_error_free ( error );
142 gboolean a_settings_get_string ( const gchar *name, gchar **val )
144 return settings_get_string ( VIKING_SETTINGS_GROUP, name, val );
147 void a_settings_set_string ( const gchar *name, const gchar *val )
149 g_key_file_set_string ( keyfile, VIKING_SETTINGS_GROUP, name, val );
152 static gboolean settings_get_integer ( const gchar *group, const gchar *name, gint *val )
154 GError *error = NULL;
155 gboolean success = TRUE;
156 gint ii = g_key_file_get_integer ( keyfile, group, name, &error );
158 // Only print on debug - as often may have requests for keys not in the file
159 g_debug ( "%s", error->message );
160 g_error_free ( error );
167 gboolean a_settings_get_integer ( const gchar *name, gint *val )
169 return settings_get_integer ( VIKING_SETTINGS_GROUP, name, val );
172 void a_settings_set_integer ( const gchar *name, gint val )
174 g_key_file_set_integer ( keyfile, VIKING_SETTINGS_GROUP, name, val );
177 static gboolean settings_get_double ( const gchar *group, const gchar *name, gdouble *val )
179 GError *error = NULL;
180 gboolean success = TRUE;
181 gdouble dd = g_key_file_get_double ( keyfile, group, name, &error );
183 // Only print on debug - as often may have requests for keys not in the file
184 g_debug ( "%s", error->message );
185 g_error_free ( error );
192 gboolean a_settings_get_double ( const gchar *name, gdouble *val )
194 return settings_get_double ( VIKING_SETTINGS_GROUP, name, val );
197 void a_settings_set_double ( const gchar *name, gdouble val )
199 g_key_file_set_double ( keyfile, VIKING_SETTINGS_GROUP, name, val );
202 static gboolean settings_get_integer_list ( const gchar *group, const gchar *name, gint **vals, gsize *length )
204 GError *error = NULL;
205 gboolean success = TRUE;
206 gint *ints = g_key_file_get_integer_list ( keyfile, group, name, length, &error );
208 // Only print on debug - as often may have requests for keys not in the file
209 g_debug ( "%s", error->message );
210 g_error_free ( error );
218 * The returned list of integers should be freed when no longer needed
220 static gboolean a_settings_get_integer_list ( const gchar *name, gint **vals, gsize* length )
222 return settings_get_integer_list ( VIKING_SETTINGS_GROUP, name, vals, length );
225 static void a_settings_set_integer_list ( const gchar *name, gint vals[], gsize length )
227 g_key_file_set_integer_list ( keyfile, VIKING_SETTINGS_GROUP, name, vals, length );
230 gboolean a_settings_get_integer_list_contains ( const gchar *name, gint val )
234 // Get current list and see if the value supplied is in the list
235 gboolean contains = FALSE;
237 if ( a_settings_get_integer_list ( name, &vals, &length ) ) {
238 // See if it's not already there
240 if ( vals && length ) {
241 while ( ii < length ) {
242 if ( vals[ii] == val ) {
255 void a_settings_set_integer_list_containing ( const gchar *name, gint val )
259 gboolean need_to_add = TRUE;
262 if ( a_settings_get_integer_list ( name, &vals, &length ) ) {
263 // See if it's not already there
264 if ( vals && length ) {
265 while ( ii < length ) {
266 if ( vals[ii] == val ) {
274 // Add value into array if necessary
276 // NB not bothering to sort this 'list' ATM as there is not much to be gained
277 guint new_length = length + 1;
278 gint new_vals[new_length];
280 for ( ii = 0; ii < length; ii++ ) {
281 new_vals[ii] = vals[ii];
283 new_vals[length] = val; // Set the new value
285 a_settings_set_integer_list ( name, new_vals, new_length );