]> git.street.me.uk Git - andy/viking.git/blame - src/viklayer_defaults.c
Make simple GPSBabel filter options use the updated acquire framework options.
[andy/viking.git] / src / viklayer_defaults.c
CommitLineData
a7023a1b
RN
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2/*
3 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 *
5 * Copyright (C) 2013, Rob Norris <rw_norris@hotmail.com>
6 *
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.
11 *
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.
16 *
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
20 *
21 */
22#include <gtk/gtk.h>
23#include <glib/gi18n.h>
24#include <string.h>
25#include <stdlib.h>
26#include <stdio.h>
27#include <glib/gstdio.h>
28#include "viklayer_defaults.h"
29#include "dir.h"
30#include "file.h"
31
32#define VIKING_LAYER_DEFAULTS_INI_FILE "viking_layer_defaults.ini"
33
34// A list of the parameter types in use
35static GPtrArray *paramsVD;
36
37static GKeyFile *keyfile;
38
39static gboolean loaded;
40
6cc5daf1 41static VikLayerParamData get_default_data_answer ( const gchar *group, const gchar *name, VikLayerParamType ptype, gpointer *success )
a7023a1b
RN
42{
43 VikLayerParamData data = VIK_LPD_BOOLEAN ( FALSE );
44
45 GError *error = NULL;
46
47 switch ( ptype ) {
48 case VIK_LAYER_PARAM_DOUBLE: {
49 gdouble dd = g_key_file_get_double ( keyfile, group, name, &error );
50 if ( !error ) data.d = dd;
51 break;
52 }
53 case VIK_LAYER_PARAM_UINT: {
54 guint32 uu = g_key_file_get_integer ( keyfile, group, name, &error );
55 if ( !error ) data.u = uu;
56 break;
57 }
58 case VIK_LAYER_PARAM_INT: {
59 gint32 ii = g_key_file_get_integer ( keyfile, group, name, &error );
60 if ( !error ) data.i = ii;
61 break;
62 }
63 case VIK_LAYER_PARAM_BOOLEAN: {
64 gboolean bb = g_key_file_get_boolean ( keyfile, group, name, &error );
65 if ( !error ) data.b = bb;
66 break;
67 }
68 case VIK_LAYER_PARAM_STRING: {
69 gchar *str = g_key_file_get_string ( keyfile, group, name, &error );
70 if ( !error ) data.s = str;
71 break;
72 }
73 //case VIK_LAYER_PARAM_STRING_LIST: {
74 // gchar **str = g_key_file_get_string_list ( keyfile, group, name, &error );
75 // data.sl = str_to_glist (str); //TODO convert
76 // break;
77 //}
78 case VIK_LAYER_PARAM_COLOR: {
79 gchar *str = g_key_file_get_string ( keyfile, group, name, &error );
80 if ( !error ) {
81 memset(&(data.c), 0, sizeof(data.c));
82 gdk_color_parse ( str, &(data.c) );
83 }
84 g_free ( str );
85 break;
86 }
87 default: break;
88 }
6cc5daf1 89 *success = GINT_TO_POINTER (TRUE);
a7023a1b 90 if ( error ) {
873fc9e4 91 g_warning ( "%s", error->message );
a7023a1b 92 g_error_free ( error );
6cc5daf1 93 *success = GINT_TO_POINTER (FALSE);
a7023a1b
RN
94 }
95
96 return data;
97}
98
20144311 99static VikLayerParamData get_default_data ( const gchar *group, const gchar *name, VikLayerParamType ptype )
a7023a1b 100{
20144311
RN
101 gpointer success = GINT_TO_POINTER (TRUE);
102 // NB This should always succeed - don't worry about 'success'
6cc5daf1 103 return get_default_data_answer ( group, name, ptype, &success );
a7023a1b
RN
104}
105
106static void set_default_data ( VikLayerParamData data, const gchar *group, const gchar *name, VikLayerParamType ptype )
107{
108 switch ( ptype ) {
109 case VIK_LAYER_PARAM_DOUBLE:
110 g_key_file_set_double ( keyfile, group, name, data.d );
111 break;
112 case VIK_LAYER_PARAM_UINT:
113 g_key_file_set_integer ( keyfile, group, name, data.u );
114 break;
115 case VIK_LAYER_PARAM_INT:
116 g_key_file_set_integer ( keyfile, group, name, data.i );
117 break;
118 case VIK_LAYER_PARAM_BOOLEAN:
119 g_key_file_set_boolean ( keyfile, group, name, data.b );
120 break;
121 case VIK_LAYER_PARAM_STRING:
122 g_key_file_set_string ( keyfile, group, name, data.s );
123 break;
124 case VIK_LAYER_PARAM_COLOR: {
125 gchar *str = g_strdup_printf ( "#%.2x%.2x%.2x", (int)(data.c.red/256),(int)(data.c.green/256),(int)(data.c.blue/256));
126 g_key_file_set_string ( keyfile, group, name, str );
127 g_free ( str );
128 break;
129 }
130 default: break;
131 }
132}
133
134static void defaults_run_setparam ( gpointer index_ptr, guint16 i, VikLayerParamData data, VikLayerParam *params )
135{
136 // Index is only an index into values from this layer
137 gint index = GPOINTER_TO_INT ( index_ptr );
138 VikLayerParam *vlp = (VikLayerParam *)g_ptr_array_index(paramsVD,index+i);
139
140 set_default_data ( data, vik_layer_get_interface(vlp->layer)->fixed_layer_name, vlp->name, vlp->type );
141}
142
143static VikLayerParamData defaults_run_getparam ( gpointer index_ptr, guint16 i, gboolean notused2 )
144{
145 // Index is only an index into values from this layer
146 gint index = GPOINTER_TO_INT ( index_ptr );
147 VikLayerParam *vlp = (VikLayerParam *)g_ptr_array_index(paramsVD,index+i);
148
149 return get_default_data ( vik_layer_get_interface(vlp->layer)->fixed_layer_name, vlp->name, vlp->type );
150}
151
20144311
RN
152static void use_internal_defaults_if_missing_default ( VikLayerTypeEnum type )
153{
154 VikLayerParam *params = vik_layer_get_interface(type)->params;
155 if ( ! params )
156 return;
157
158 guint16 params_count = vik_layer_get_interface(type)->params_count;
159 guint16 i;
160 // Process each parameter
161 for ( i = 0; i < params_count; i++ ) {
162 if ( params[i].group != VIK_LAYER_NOT_IN_PROPERTIES ) {
163 gpointer success = GINT_TO_POINTER (FALSE);
164 // Check current default is available
6cc5daf1 165 get_default_data_answer ( vik_layer_get_interface(type)->fixed_layer_name, params[i].name, params[i].type, &success );
20144311
RN
166 // If no longer have a viable default
167 if ( ! GPOINTER_TO_INT (success) ) {
168 // Reset value
169 if ( params[i].default_value ) {
170 VikLayerParamData paramd = params[i].default_value();
171 set_default_data ( paramd, vik_layer_get_interface(type)->fixed_layer_name, params[i].name, params[i].type );
172 }
173 }
174 }
175 }
176}
177
178static gboolean defaults_load_from_file()
179{
180 GKeyFileFlags flags = G_KEY_FILE_KEEP_COMMENTS;
181
182 GError *error = NULL;
183
184 gchar *fn = g_build_filename ( a_get_viking_dir(), VIKING_LAYER_DEFAULTS_INI_FILE, NULL );
185
186 if ( !g_key_file_load_from_file ( keyfile, fn, flags, &error ) ) {
187 g_warning ( "%s: %s", error->message, fn );
188 g_free ( fn );
189 g_error_free ( error );
190 return FALSE;
191 }
192
193 g_free ( fn );
194
195 // Ensure if have a key file, then any missing values are set from the internal defaults
196 VikLayerTypeEnum layer;
197 for ( layer = 0; layer < VIK_LAYER_NUM_TYPES; layer++ ) {
198 use_internal_defaults_if_missing_default ( layer );
199 }
200
201 return TRUE;
202}
203
a7023a1b
RN
204/* TRUE on success */
205static gboolean layer_defaults_save_to_file()
206{
207 gboolean answer = TRUE;
208 GError *error = NULL;
209 gchar *fn = g_build_filename ( a_get_viking_dir(), VIKING_LAYER_DEFAULTS_INI_FILE, NULL );
210 gsize size;
211
212 gchar *keyfilestr = g_key_file_to_data ( keyfile, &size, &error );
213
214 if ( error ) {
873fc9e4 215 g_warning ( "%s", error->message );
a7023a1b
RN
216 g_error_free ( error );
217 answer = FALSE;
218 goto tidy;
219 }
220
221 // optionally could do:
222 // g_file_set_contents ( fn, keyfilestr, size, &error );
223 // if ( error ) {
224 // g_warning ( "%s: %s", error->message, fn );
225 // g_error_free ( error );
226 // answer = FALSE;
227 // goto tidy;
228 // }
229
230 FILE *ff;
231 if ( !(ff = g_fopen ( fn, "w")) ) {
232 g_warning ( _("Could not open file: %s"), fn );
233 answer = FALSE;
234 goto tidy;
235 }
236 // Layer defaults not that secret, but just incase...
237 g_chmod ( fn, 0600 );
238
239 fputs ( keyfilestr, ff );
240 fclose ( ff );
241
242tidy:
243 g_free ( keyfilestr );
244 g_free ( fn );
245
246 return answer;
247}
248
249/**
250 * a_layer_defaults_show_window:
251 * @parent: The Window
252 * @layername: The layer
253 *
254 * This displays a Window showing the default parameter values for the selected layer
255 * It allows the parameters to be changed.
256 *
257 * Returns: %TRUE if the window is displayed (because there are parameters to view)
258 */
259gboolean a_layer_defaults_show_window ( GtkWindow *parent, const gchar *layername )
260{
261 if ( ! loaded ) {
262 // since we can't load the file in a_defaults_init (no params registered yet),
263 // do it once before we display the params.
264 defaults_load_from_file();
265 loaded = TRUE;
266 }
267
268 VikLayerTypeEnum layer = vik_layer_type_from_string ( layername );
269
270 // Need to know where the params start and they finish for this layer
271
272 // 1. inspect every registered param - see if it has the layer value required to determine overall size
273 // [they are contiguous from the start index]
274 // 2. copy the these params from the main list into a tmp struct
275 //
276 // Then pass this tmp struct to uibuilder for display
277
278 guint layer_params_count = 0;
279
280 gboolean found_first = FALSE;
281 gint index = 0;
282 int i;
283 for ( i = 0; i < paramsVD->len; i++ ) {
284 VikLayerParam *param = (VikLayerParam*)(g_ptr_array_index(paramsVD,i));
285 if ( param->layer == layer ) {
286 layer_params_count++;
287 if ( !found_first ) {
288 index = i;
289 found_first = TRUE;
290 }
291 }
292 }
293
294 // Have we any parameters to show!
295 if ( !layer_params_count )
296 return FALSE;
297
298 VikLayerParam *params = g_new(VikLayerParam,layer_params_count);
299 for ( i = 0; i < layer_params_count; i++ ) {
300 params[i] = *((VikLayerParam*)(g_ptr_array_index(paramsVD,i+index)));
301 }
302
303 gchar *title = g_strconcat ( layername, ": ", _("Layer Defaults"), NULL );
304
305 if ( a_uibuilder_properties_factory ( title,
306 parent,
307 params,
308 layer_params_count,
309 vik_layer_get_interface(layer)->params_groups,
310 vik_layer_get_interface(layer)->params_groups_count,
db43cfa4 311 (gboolean (*) (gpointer,guint16,VikLayerParamData,gpointer,gboolean)) defaults_run_setparam,
a7023a1b
RN
312 GINT_TO_POINTER ( index ),
313 params,
314 defaults_run_getparam,
db43cfa4
RN
315 GINT_TO_POINTER ( index ),
316 NULL ) ) {
a7023a1b
RN
317 // Save
318 layer_defaults_save_to_file();
319 }
320
321 g_free ( title );
322 g_free ( params );
323
324 return TRUE;
325}
326
327/**
328 * a_layer_defaults_register:
329 * @vlp: The parameter
330 * @defaultval: The default value
331 * @layername: The layer in which the parameter resides
332 *
333 * Call this function on to set the default value for the particular parameter
334 */
335void a_layer_defaults_register (VikLayerParam *vlp, VikLayerParamData defaultval, const gchar *layername )
336{
337 /* copy value */
338 VikLayerParam *newvlp = g_new(VikLayerParam,1);
339 *newvlp = *vlp;
340
341 g_ptr_array_add ( paramsVD, newvlp );
342
343 set_default_data ( defaultval, layername, vlp->name, vlp->type );
344}
345
346/**
347 * a_layer_defaults_init:
348 *
349 * Call this function at startup
350 */
351void a_layer_defaults_init()
352{
353 keyfile = g_key_file_new();
354
355 /* not copied */
356 paramsVD = g_ptr_array_new ();
357
358 loaded = FALSE;
359}
360
361/**
362 * a_layer_defaults_uninit:
363 *
364 * Call this function on program exit
365 */
366void a_layer_defaults_uninit()
367{
368 g_key_file_free ( keyfile );
919ed63e 369 g_ptr_array_foreach ( paramsVD, (GFunc)g_free, NULL );
a7023a1b
RN
370 g_ptr_array_free ( paramsVD, TRUE );
371}
372
373/**
374 * a_layer_defaults_get:
375 * @layername: String name of the layer
376 * @param_name: String name of the parameter
377 * @param_type: The parameter type
378 *
379 * Call this function to get the default value for the parameter requested
380 */
381VikLayerParamData a_layer_defaults_get ( const gchar *layername, const gchar *param_name, VikLayerParamType param_type )
382{
383 if ( ! loaded ) {
384 // since we can't load the file in a_defaults_init (no params registered yet),
385 // do it once before we get the first key.
386 defaults_load_from_file();
387 loaded = TRUE;
388 }
389
390 return get_default_data ( layername, param_name, param_type );
391}
c1b01373
RN
392
393/**
394 * a_layer_defaults_save:
395 *
396 * Call this function to save the current layer defaults
397 * Normally should only be performed if any layer defaults have been changed via direct manipulation of the layer
398 * rather than the user changing the preferences via the dialog window above
399 *
400 * This must only be performed once all layer parameters have been initialized
401 *
402 * Returns: %TRUE if saving was successful
403 */
404gboolean a_layer_defaults_save ()
405{
406 // Generate defaults
407 VikLayerTypeEnum layer;
408 for ( layer = 0; layer < VIK_LAYER_NUM_TYPES; layer++ ) {
409 use_internal_defaults_if_missing_default ( layer );
410 }
411
412 return layer_defaults_save_to_file();
413}