2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 * Copyright (C) 2003-2007, Evan Battaglia <gtoevan@gmx.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <glib/gi18n.h>
27 #include "uibuilder.h"
28 #include "vikradiogroup.h"
29 #include "vikfileentry.h"
30 #include "vikfilelist.h"
32 GtkWidget
*a_uibuilder_new_widget ( VikLayerParam
*param
, VikLayerParamData data
)
35 switch ( param
->widget_type
)
37 case VIK_LAYER_WIDGET_COLOR
:
38 if ( param
->type
== VIK_LAYER_PARAM_COLOR
)
39 rv
= gtk_color_button_new_with_color ( &(data
.c
) );
41 case VIK_LAYER_WIDGET_CHECKBUTTON
:
42 if ( param
->type
== VIK_LAYER_PARAM_BOOLEAN
)
44 //rv = gtk_check_button_new_with_label ( //param->title );
45 rv
= gtk_check_button_new ();
47 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(rv
), TRUE
);
50 case VIK_LAYER_WIDGET_COMBOBOX
:
52 if ( param
->type
== VIK_LAYER_PARAM_UINT
&& param
->widget_data
)
54 gchar
**pstr
= param
->widget_data
;
55 rv
= gtk_combo_box_new_text ();
57 gtk_combo_box_append_text ( GTK_COMBO_BOX ( rv
), *(pstr
++) );
58 if ( param
->extra_widget_data
) /* map of alternate uint values for options */
61 for ( i
= 0; ((const char **)param
->widget_data
)[i
]; i
++ )
62 if ( ((guint
*)param
->extra_widget_data
)[i
] == data
.u
)
64 gtk_combo_box_set_active ( GTK_COMBO_BOX(rv
), i
);
68 gtk_combo_box_set_active ( GTK_COMBO_BOX ( rv
), data
.u
);
72 case VIK_LAYER_WIDGET_RADIOGROUP
:
73 /* widget_data and extra_widget_data are GList */
74 if ( param
->type
== VIK_LAYER_PARAM_UINT
&& param
->widget_data
)
76 rv
= vik_radio_group_new ( param
->widget_data
);
77 if ( param
->extra_widget_data
) /* map of alternate uint values for options */
80 int nb_elem
= g_list_length(param
->widget_data
);
81 for ( i
= 0; i
< nb_elem
; i
++ )
82 if ( GPOINTER_TO_UINT ( g_list_nth_data(param
->extra_widget_data
, i
) ) == data
.u
)
84 vik_radio_group_set_selected ( VIK_RADIO_GROUP(rv
), i
);
88 else if ( data
.u
) /* zero is already default */
89 vik_radio_group_set_selected ( VIK_RADIO_GROUP(rv
), data
.u
);
92 case VIK_LAYER_WIDGET_RADIOGROUP_STATIC
:
93 if ( param
->type
== VIK_LAYER_PARAM_UINT
&& param
->widget_data
)
95 rv
= vik_radio_group_new_static ( (const gchar
**) param
->widget_data
);
96 if ( param
->extra_widget_data
) /* map of alternate uint values for options */
99 for ( i
= 0; ((const char **)param
->widget_data
)[i
]; i
++ )
100 if ( ((guint
*)param
->extra_widget_data
)[i
] == data
.u
)
102 vik_radio_group_set_selected ( VIK_RADIO_GROUP(rv
), i
);
106 else if ( data
.u
) /* zero is already default */
107 vik_radio_group_set_selected ( VIK_RADIO_GROUP(rv
), data
.u
);
110 case VIK_LAYER_WIDGET_SPINBUTTON
:
111 if ( (param
->type
== VIK_LAYER_PARAM_DOUBLE
|| param
->type
== VIK_LAYER_PARAM_UINT
112 || param
->type
== VIK_LAYER_PARAM_INT
) && param
->widget_data
)
114 gdouble init_val
= (param
->type
== VIK_LAYER_PARAM_DOUBLE
) ? data
.d
: (param
->type
== VIK_LAYER_PARAM_UINT
? data
.u
: data
.i
);
115 VikLayerParamScale
*scale
= (VikLayerParamScale
*) param
->widget_data
;
116 rv
= gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new( init_val
, scale
->min
, scale
->max
, scale
->step
, scale
->step
, scale
->step
)), scale
->step
, scale
->digits
);
119 case VIK_LAYER_WIDGET_ENTRY
:
120 if ( param
->type
== VIK_LAYER_PARAM_STRING
)
122 rv
= gtk_entry_new ();
123 gtk_entry_set_text ( GTK_ENTRY(rv
), data
.s
);
126 case VIK_LAYER_WIDGET_PASSWORD
:
127 if ( param
->type
== VIK_LAYER_PARAM_STRING
)
129 rv
= gtk_entry_new ();
130 gtk_entry_set_visibility ( GTK_ENTRY(rv
), FALSE
);
131 gtk_entry_set_text ( GTK_ENTRY(rv
), data
.s
);
132 #if GTK_CHECK_VERSION(2,12,0)
133 gtk_widget_set_tooltip_text ( GTK_WIDGET(rv
),
134 _("Take care that this password will be stored clearly in a plain file.") );
138 case VIK_LAYER_WIDGET_FILEENTRY
:
139 if ( param
->type
== VIK_LAYER_PARAM_STRING
)
141 rv
= vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN
);
142 vik_file_entry_set_filename ( VIK_FILE_ENTRY(rv
), data
.s
);
145 case VIK_LAYER_WIDGET_FOLDERENTRY
:
146 if ( param
->type
== VIK_LAYER_PARAM_STRING
)
148 rv
= vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
);
149 vik_file_entry_set_filename ( VIK_FILE_ENTRY(rv
), data
.s
);
153 case VIK_LAYER_WIDGET_FILELIST
:
154 if ( param
->type
== VIK_LAYER_PARAM_STRING_LIST
)
156 rv
= vik_file_list_new ( param
->title
);
157 vik_file_list_set_files ( VIK_FILE_LIST(rv
), data
.sl
);
160 case VIK_LAYER_WIDGET_HSCALE
:
161 if ( (param
->type
== VIK_LAYER_PARAM_DOUBLE
|| param
->type
== VIK_LAYER_PARAM_UINT
162 || param
->type
== VIK_LAYER_PARAM_INT
) && param
->widget_data
)
164 gdouble init_val
= (param
->type
== VIK_LAYER_PARAM_DOUBLE
) ? data
.d
: (param
->type
== VIK_LAYER_PARAM_UINT
? data
.u
: data
.i
);
165 VikLayerParamScale
*scale
= (VikLayerParamScale
*) param
->widget_data
;
166 rv
= gtk_hscale_new_with_range ( scale
->min
, scale
->max
, scale
->step
);
167 gtk_scale_set_digits ( GTK_SCALE(rv
), scale
->digits
);
168 gtk_range_set_value ( GTK_RANGE(rv
), init_val
);
174 VikLayerParamData
a_uibuilder_widget_get_value ( GtkWidget
*widget
, VikLayerParam
*param
)
176 VikLayerParamData rv
;
177 switch ( param
->widget_type
)
179 case VIK_LAYER_WIDGET_COLOR
:
180 gtk_color_button_get_color ( GTK_COLOR_BUTTON(widget
), &(rv
.c
) );
182 case VIK_LAYER_WIDGET_CHECKBUTTON
:
183 rv
.b
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
185 case VIK_LAYER_WIDGET_COMBOBOX
:
187 rv
.i
= gtk_combo_box_get_active ( GTK_COMBO_BOX(widget
) );
188 if ( rv
.i
== -1 ) rv
.i
= 0;
190 if ( param
->extra_widget_data
)
191 rv
.u
= ((guint
*)param
->extra_widget_data
)[rv
.u
];
194 case VIK_LAYER_WIDGET_RADIOGROUP
:
195 case VIK_LAYER_WIDGET_RADIOGROUP_STATIC
:
196 rv
.u
= vik_radio_group_get_selected(VIK_RADIO_GROUP(widget
));
197 if ( param
->extra_widget_data
)
198 rv
.u
= GPOINTER_TO_UINT ( g_list_nth_data(param
->extra_widget_data
, rv
.u
) );
200 case VIK_LAYER_WIDGET_SPINBUTTON
:
201 if ( param
->type
== VIK_LAYER_PARAM_UINT
)
202 rv
.u
= gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(widget
) );
203 else if ( param
->type
== VIK_LAYER_PARAM_INT
)
204 rv
.i
= gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(widget
) );
206 rv
.d
= gtk_spin_button_get_value ( GTK_SPIN_BUTTON(widget
) );
208 case VIK_LAYER_WIDGET_ENTRY
:
209 case VIK_LAYER_WIDGET_PASSWORD
:
210 rv
.s
= gtk_entry_get_text ( GTK_ENTRY(widget
) );
212 case VIK_LAYER_WIDGET_FILEENTRY
:
213 case VIK_LAYER_WIDGET_FOLDERENTRY
:
214 rv
.s
= vik_file_entry_get_filename ( VIK_FILE_ENTRY(widget
) );
216 case VIK_LAYER_WIDGET_FILELIST
:
217 rv
.sl
= vik_file_list_get_files ( VIK_FILE_LIST(widget
) );
219 case VIK_LAYER_WIDGET_HSCALE
:
220 if ( param
->type
== VIK_LAYER_PARAM_UINT
)
221 rv
.u
= (guint32
) gtk_range_get_value ( GTK_RANGE(widget
) );
222 else if ( param
->type
== VIK_LAYER_PARAM_INT
)
223 rv
.i
= (gint32
) gtk_range_get_value ( GTK_RANGE(widget
) );
225 rv
.d
= gtk_range_get_value ( GTK_RANGE(widget
) );
232 gint
a_uibuilder_properties_factory ( GtkWindow
*parent
, VikLayerParam
*params
,
233 guint16 params_count
, gchar
**groups
, guint8 groups_count
,
234 gboolean (*setparam
) (gpointer
,guint16
,VikLayerParamData
,gpointer
),
235 gpointer pass_along1
, gpointer pass_along2
,
236 VikLayerParamData (*getparam
) (gpointer
,guint16
),
237 gpointer pass_along_getparam
)
238 /* pass_along1 and pass_along2 are for set_param first and last params */
240 guint16 i
, j
, widget_count
= 0;
241 gboolean must_redraw
= FALSE
;
244 return 1; /* no params == no options, so all is good */
246 for ( i
= 0; i
< params_count
; i
++ )
247 if ( params
[i
].group
!= VIK_LAYER_NOT_IN_PROPERTIES
)
250 if ( widget_count
== 0)
251 return 0; /* TODO -- should be one? */
254 /* create widgets and titles; place in table */
255 GtkWidget
*dialog
= gtk_dialog_new_with_buttons ( "Layer Properties",
257 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
258 GTK_STOCK_CANCEL
, GTK_RESPONSE_REJECT
,
259 GTK_STOCK_OK
, GTK_RESPONSE_ACCEPT
, NULL
);
263 GtkWidget
*table
= NULL
;
264 GtkWidget
**tables
= NULL
; /* for more than one group */
266 GtkWidget
*notebook
= NULL
;
267 GtkWidget
**widgets
= g_malloc ( sizeof(GtkWidget
*) * widget_count
);
269 if ( groups
&& groups_count
> 1 )
271 guint8 current_group
;
272 guint16 tab_widget_count
;
273 notebook
= gtk_notebook_new ();
274 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog
)->vbox
), notebook
, FALSE
, FALSE
, 0);
275 tables
= g_malloc ( sizeof(GtkWidget
*) * groups_count
);
276 for ( current_group
= 0; current_group
< groups_count
; current_group
++ )
278 tab_widget_count
= 0;
279 for ( j
= 0; j
< params_count
; j
++ )
280 if ( params
[j
].group
== current_group
)
283 if ( tab_widget_count
)
285 tables
[current_group
] = gtk_table_new ( tab_widget_count
, 1, FALSE
);
286 gtk_notebook_append_page ( GTK_NOTEBOOK(notebook
), tables
[current_group
], gtk_label_new(groups
[current_group
]) );
292 table
= gtk_table_new( widget_count
, 1, FALSE
);
293 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog
)->vbox
), table
, FALSE
, FALSE
, 0);
296 for ( i
= 0, j
= 0; i
< params_count
; i
++ )
298 if ( params
[i
].group
!= VIK_LAYER_NOT_IN_PROPERTIES
)
301 table
= tables
[MAX(0, params
[i
].group
)]; /* round up NOT_IN_GROUP, that's not reasonable here */
303 widgets
[j
] = a_uibuilder_new_widget ( &(params
[i
]), getparam ( pass_along_getparam
, i
) );
305 g_assert ( widgets
[j
] != NULL
);
307 gtk_table_attach ( GTK_TABLE(table
), gtk_label_new(params
[i
].title
), 0, 1, j
, j
+1, 0, 0, 0, 0 );
308 gtk_table_attach ( GTK_TABLE(table
), widgets
[j
], 1, 2, j
, j
+1, GTK_EXPAND
| GTK_FILL
, 0, 2, 2 );
313 gtk_widget_show_all ( dialog
);
315 resp
= gtk_dialog_run (GTK_DIALOG (dialog
));
316 if ( resp
== GTK_RESPONSE_ACCEPT
)
318 for ( i
= 0, j
= 0; i
< params_count
; i
++ )
320 if ( params
[i
].group
!= VIK_LAYER_NOT_IN_PROPERTIES
)
322 if ( setparam ( pass_along1
, i
,
323 a_uibuilder_widget_get_value ( widgets
[j
], &(params
[i
]) ), pass_along2
) )
329 gtk_widget_destroy ( dialog
); /* hide before redrawing. */
332 return must_redraw
? 2 : 3; /* user clicked OK */
337 gtk_widget_destroy ( dialog
);
344 static void uibuilder_run_setparam ( VikLayerParamData
*paramdatas
, guint16 i
, VikLayerParamData data
, VikLayerParam
*params
)
346 /* could have to copy it if it's a string! */
347 switch ( params
[i
].type
) {
348 case VIK_LAYER_PARAM_STRING
:
349 paramdatas
[i
].s
= g_strdup ( data
.s
);
352 paramdatas
[i
] = data
; /* string list will have to be freed by layer. anything else not freed */
356 static VikLayerParamData
uibuilder_run_getparam ( VikLayerParamData
*params_defaults
, guint16 i
)
358 return params_defaults
[i
];
362 VikLayerParamData
*a_uibuilder_run_dialog ( GtkWindow
*parent
, VikLayerParam
*params
,
363 guint16 params_count
, gchar
**groups
, guint8 groups_count
,
364 VikLayerParamData
*params_defaults
)
366 VikLayerParamData
*paramdatas
= g_new(VikLayerParamData
, params_count
);
367 if ( a_uibuilder_properties_factory ( parent
,
372 (gpointer
) uibuilder_run_setparam
,
375 (gpointer
) uibuilder_run_getparam
,
376 params_defaults
) > 0 ) {
380 g_free ( paramdatas
);
384 /* frees data from last (if ness) */
385 void a_uibuilder_free_paramdatas ( VikLayerParamData
*paramdatas
, VikLayerParam
*params
, guint16 params_count
)
388 /* may have to free strings, etc. */
389 for ( i
= 0; i
< params_count
; i
++ ) {
390 switch ( params
[i
].type
) {
391 case VIK_LAYER_PARAM_STRING
:
392 g_free ( (gchar
*) paramdatas
[i
].s
);
394 case VIK_LAYER_PARAM_STRING_LIST
: {
395 /* should make a util function out of this */
396 GList
*iter
= paramdatas
[i
].sl
;
398 g_free ( iter
->data
);
401 g_list_free ( paramdatas
[i
].sl
);
406 g_free ( paramdatas
);