Contents of /trunk/src/settings.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 204 - (show annotations)
Mon Nov 23 18:32:06 2009 UTC (14 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 29210 byte(s)
Map jump function
1 /*
2 * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3 *
4 * This file is part of GPXView.
5 *
6 * GPXView 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 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GPXView 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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GPXView. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "gpxview.h"
21 #include <math.h>
22
23 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
24 #include <hildon/hildon-check-button.h>
25 #endif
26
27 typedef struct {
28 GtkWidget *cbox_gps;
29 GtkWidget *loc;
30 } settings_dialog_state_t;
31
32 /* ------------------------ special gui elements for fremantle ------------------ */
33
34 static GtkWidget *toggle_button_new_with_label(char *label) {
35 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
36 return gtk_check_button_new_with_label(label);
37 #else
38 GtkWidget *cbut = gtk_toggle_button_new_with_label(label);
39 hildon_gtk_widget_set_theme_size(cbut,
40 (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
41 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(cbut), FALSE);
42 return cbut;
43 #endif
44 }
45
46 static void toggle_button_set_active(GtkWidget *button, gboolean active) {
47 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), active);
48 }
49
50 static gboolean toggle_button_get_active(GtkWidget *button) {
51 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
52 }
53
54 static GtkWidget *check_button_new_with_label(char *label) {
55 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
56 return gtk_check_button_new_with_label(label);
57 #else
58 GtkWidget *cbut =
59 hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
60 gtk_button_set_label(GTK_BUTTON(cbut), label);
61 return cbut;
62 #endif
63 }
64
65 static void check_button_set_active(GtkWidget *button, gboolean active) {
66 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
67 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), active);
68 #else
69 hildon_check_button_set_active(HILDON_CHECK_BUTTON(button), active);
70 #endif
71 }
72
73 static gboolean check_button_get_active(GtkWidget *button) {
74 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
75 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
76 #else
77 return hildon_check_button_get_active(HILDON_CHECK_BUTTON(button));
78 #endif
79 }
80
81 /* Our usual callback function */
82 static void settings_update(GtkWidget *widget, gpointer data) {
83 settings_dialog_state_t *hstate = (settings_dialog_state_t *)data;
84
85 if(check_button_get_active(hstate->cbox_gps))
86 gtk_widget_set_sensitive(hstate->loc, FALSE);
87 else
88 gtk_widget_set_sensitive(hstate->loc, TRUE);
89 }
90
91 typedef struct {
92 appdata_t *appdata;
93 GtkWidget *settings_dialog;
94 GtkWidget *view;
95 GtkListStore *store;
96 GtkWidget *but_add, *but_edit, *but_remove;
97 gboolean changed;
98 } location_context_t;
99
100 enum {
101 LOCATION_COL_NAME = 0,
102 LOCATION_COL_LAT,
103 LOCATION_COL_LON,
104 LOCATION_COL_DATA,
105 LOCATION_NUM_COLS
106 };
107
108 static void location_select(location_context_t *context) {
109 GtkTreeSelection *selection =
110 gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view));
111
112 GtkTreePath *path = gtk_tree_path_new_from_indices(
113 context->appdata->active_location, -1);
114
115 /* Modify a particular row */
116 GtkTreeIter iter;
117 gtk_tree_model_get_iter(GTK_TREE_MODEL(context->store), &iter, path);
118 gtk_tree_selection_select_iter(selection, &iter);
119 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(context->view),
120 path, NULL, TRUE, 0, 0);
121 gtk_tree_path_free(path);
122
123 if(!context->appdata->active_location && context->but_remove)
124 gtk_widget_set_sensitive(context->but_remove, FALSE);
125 }
126
127 #ifdef ENABLE_MAEMO_MAPPER
128 #include "dbus.h"
129
130 typedef struct {
131 appdata_t *appdata;
132 pos_t pos;
133 GtkWidget *import_button;
134 GtkWidget *export_button;
135 GtkWidget *lat, *lon;
136 } mm_context_t;
137
138 static void on_mm_import_clicked(GtkButton *button, gpointer data) {
139 char str[32];
140 mm_context_t *context = (mm_context_t*)data;
141
142 pos_lat_str(str, sizeof(str), context->appdata->mmpos.lat);
143 gtk_entry_set_text(GTK_ENTRY(context->lat), str);
144 pos_lon_str(str, sizeof(str), context->appdata->mmpos.lon);
145 gtk_entry_set_text(GTK_ENTRY(context->lon), str);
146 }
147
148 static void on_mm_export_clicked(GtkButton *button, gpointer data) {
149 mm_context_t *context = (mm_context_t*)data;
150
151 /* update position from entries */
152 pos_t pos;
153 pos.lat = lat_get(context->lat);
154 pos.lon = lon_get(context->lon);
155
156 g_assert(!isnan(pos.lat) && !isnan(pos.lon));
157
158 dbus_mm_set_position(context->appdata, &pos);
159 }
160
161 static void callback_modified_pos(GtkWidget *widget, gpointer data ) {
162 mm_context_t *context = (mm_context_t*)data;
163
164 gboolean valid =
165 (!isnan(lat_get(context->lat))) && (!isnan(lon_get(context->lon)));
166
167 gtk_widget_set_sensitive(context->export_button, valid);
168 }
169 #endif
170
171 static void on_location_edit(GtkWidget *button, location_context_t *context) {
172 GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Edit Location"),
173 GTK_WINDOW(context->settings_dialog), GTK_DIALOG_MODAL,
174 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
175 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
176
177 #if defined(USE_MAEMO) && defined(HILDON_HELP)
178 hildon_help_dialog_help_enable(GTK_DIALOG(dialog),
179 HELP_ID_LOCEDIT, context->appdata->osso_context);
180 #endif
181
182 printf("edit, active = %d\n", context->appdata->active_location);
183
184 location_t *loc = NULL;
185 if(context->appdata->active_location) {
186 loc = context->appdata->location;
187 int i = context->appdata->active_location-1;
188 while(i--) {
189 g_assert(loc->next);
190 loc = loc->next;
191 }
192 printf("location edit for %s\n", loc->name);
193 } else
194 printf("location edit for Home\n");
195
196 #ifdef ENABLE_MAEMO_MAPPER
197 mm_context_t mm_context;
198 #else
199 GtkWidget *lat, *lon;
200 #endif
201
202 GtkWidget *label, *name;
203 GtkWidget *table = gtk_table_new(2, 3, FALSE);
204
205 gtk_table_attach_defaults(GTK_TABLE(table),
206 label = gtk_label_new(_("Name:")), 0, 1, 0, 1);
207 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
208 gtk_table_attach_defaults(GTK_TABLE(table),
209 name = gtk_entry_new(), 1, 2, 0, 1);
210
211 pos_t pos;
212 if(loc) pos = loc->pos;
213 else pos = context->appdata->home;
214
215 /* avoid to use "nan" as the user will then not be displayed a nice */
216 /* preset value to alter */
217 if(isnan(pos.lat)) pos.lat = 0;
218 if(isnan(pos.lon)) pos.lon = 0;
219
220 gtk_table_attach_defaults(GTK_TABLE(table),
221 label = gtk_label_new(_("Latitude:")), 0, 1, 1, 2);
222 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
223 #ifdef ENABLE_MAEMO_MAPPER
224 gtk_table_attach_defaults(GTK_TABLE(table),
225 mm_context.lat = lat_entry_new(pos.lat), 1, 2, 1, 2);
226 g_signal_connect(G_OBJECT(mm_context.lat), "changed",
227 G_CALLBACK(callback_modified_pos), &mm_context);
228 #else
229 gtk_table_attach_defaults(GTK_TABLE(table),
230 lat = lat_entry_new(pos.lat), 1, 2, 1, 2);
231 #endif
232
233
234 gtk_table_attach_defaults(GTK_TABLE(table),
235 label = gtk_label_new(_("Longitude:")), 0, 1, 2, 3);
236 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
237 #ifdef ENABLE_MAEMO_MAPPER
238 gtk_table_attach_defaults(GTK_TABLE(table),
239 mm_context.lon = lon_entry_new(pos.lon), 1, 2, 2, 3);
240 g_signal_connect(G_OBJECT(mm_context.lon), "changed",
241 G_CALLBACK(callback_modified_pos), &mm_context);
242 #else
243 gtk_table_attach_defaults(GTK_TABLE(table),
244 lon = lon_entry_new(pos.lon), 1, 2, 2, 3);
245 #endif
246
247 if(loc)
248 gtk_entry_set_text(GTK_ENTRY(name), loc->name);
249 else {
250 gtk_entry_set_text(GTK_ENTRY(name), _("Home"));
251 gtk_widget_set_sensitive(GTK_WIDGET(name), FALSE);
252 }
253
254 #ifdef ENABLE_MAEMO_MAPPER
255 mm_context.appdata = context->appdata;
256 if(loc) mm_context.pos = loc->pos;
257 else mm_context.pos = context->appdata->home;
258
259 mm_context.import_button = gtk_button_new();
260 gtk_button_set_image(GTK_BUTTON(mm_context.import_button),
261 icon_get_widget(ICON_MISC, 3));
262 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
263 mm_context.import_button);
264 gtk_signal_connect(GTK_OBJECT(mm_context.import_button), "clicked",
265 (GtkSignalFunc)on_mm_import_clicked, &mm_context);
266
267 if(!context->appdata->mmpos_valid)
268 gtk_widget_set_sensitive(mm_context.import_button, FALSE);
269
270 mm_context.export_button = gtk_button_new();
271 gtk_button_set_image(GTK_BUTTON(mm_context.export_button),
272 icon_get_widget(ICON_MISC, 0));
273 gtk_signal_connect(GTK_OBJECT(mm_context.export_button), "clicked",
274 (GtkSignalFunc)on_mm_export_clicked, &mm_context);
275 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
276 mm_context.export_button);
277 #endif
278
279 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), table);
280
281 gtk_widget_show_all(dialog);
282
283 if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
284 pos_t pos;
285
286 #ifdef ENABLE_MAEMO_MAPPER
287 pos.lat = lat_get(mm_context.lat);
288 pos.lon = lon_get(mm_context.lon);
289 #else
290 pos.lat = lat_get(lat);
291 pos.lon = lon_get(lon);
292 #endif
293
294 if(isnan(pos.lat) || isnan(pos.lon))
295 errorf(_("Ignoring invalid position"));
296 else {
297 char *p = (char*)gtk_entry_get_text(GTK_ENTRY(name));
298 printf("%s is at %f/%f\n", p, pos.lat, pos.lon);
299
300 /* now the list has to be re-done */
301 GtkTreePath *path = gtk_tree_path_new_from_indices(
302 context->appdata->active_location, -1);
303
304 /* Modify a particular row or create a new one if that doesn't exist */
305 GtkTreeIter iter;
306 if(!gtk_tree_model_get_iter(GTK_TREE_MODEL(context->store),&iter,path))
307 gtk_list_store_append(context->store, &iter);
308
309 char lat_str[32], lon_str[32];
310 pos_lat_str(lat_str, sizeof(lat_str), pos.lat);
311 pos_lon_str(lon_str, sizeof(lon_str), pos.lon);
312
313 if(loc) {
314 free(loc->name);
315 loc->name = strdup(p);
316 loc->pos.lat = pos.lat;
317 loc->pos.lon = pos.lon;
318
319 gtk_list_store_set(context->store, &iter,
320 LOCATION_COL_NAME, loc->name,
321 LOCATION_COL_LAT, lat_str,
322 LOCATION_COL_LON, lon_str,
323 LOCATION_COL_DATA, loc,
324 -1);
325
326 } else {
327 context->appdata->home.lat = pos.lat;
328 context->appdata->home.lon = pos.lon;
329
330 gtk_list_store_set(context->store, &iter,
331 LOCATION_COL_LAT, lat_str,
332 LOCATION_COL_LON, lon_str,
333 -1);
334 }
335 context->changed = TRUE;
336 }
337 }
338 gtk_widget_destroy(dialog);
339 }
340
341 static void on_location_add(GtkWidget *button, location_context_t *context) {
342 location_t **loc = &context->appdata->location;
343 int prev_active = context->appdata->active_location;
344
345 int i = 1;
346 while(*loc) {
347 loc = &(*loc)->next;
348 i++;
349 }
350
351 *loc = g_new0(location_t, 1);
352 if(!*loc) {
353 errorf(_("Out of memory"));
354 return;
355 }
356
357 (*loc)->name = strdup(_("<new>"));
358 #if 0
359 (*loc)->pos.lat = DEFAULT_LAT;
360 (*loc)->pos.lon = DEFAULT_LON;
361 #endif
362
363 context->changed = FALSE;
364 context->appdata->active_location = i;
365 on_location_edit(button, context);
366
367 if(context->changed)
368 location_select(context);
369 else {
370 /* remove newly attached entry and select previous one */
371 location_t *tmp = *loc;
372 *loc = NULL;
373 free(tmp->name);
374 free(tmp);
375
376 context->appdata->active_location = prev_active;
377 }
378 }
379
380 static void on_location_remove(GtkWidget *but, location_context_t *context) {
381 GtkTreeSelection *selection;
382 GtkTreeModel *model;
383 GtkTreeIter iter;
384
385 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view));
386 if(gtk_tree_selection_get_selected(selection, &model, &iter)) {
387 location_t *loc;
388 gtk_tree_model_get(model, &iter, LOCATION_COL_DATA, &loc, -1);
389
390 g_assert(loc);
391
392 /* de-chain */
393 location_t **prev = &context->appdata->location;
394 while(*prev != loc) prev = &((*prev)->next);
395 *prev = loc->next;
396
397 /* free location itself */
398 if(loc->name) free(loc->name);
399 free(loc);
400
401 /* and remove from store */
402 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
403 }
404
405 /* disable remove button */
406 gtk_widget_set_sensitive(context->but_remove, FALSE);
407 /* select the first entry */
408
409 context->appdata->active_location = 0;
410 location_select(context);
411 }
412
413 static gboolean
414 view_selection_func(GtkTreeSelection *selection, GtkTreeModel *model,
415 GtkTreePath *path, gboolean path_currently_selected,
416 gpointer userdata) {
417 location_context_t *context = (location_context_t*)userdata;
418 GtkTreeIter iter;
419
420 if(gtk_tree_model_get_iter(model, &iter, path)) {
421 g_assert(gtk_tree_path_get_depth(path) == 1);
422
423 /* if the first entry has been selected */
424 if(!path_currently_selected && context->but_remove) {
425 context->appdata->active_location = gtk_tree_path_get_indices(path)[0];
426 gtk_widget_set_sensitive(context->but_remove,
427 context->appdata->active_location);
428 }
429 }
430
431 return TRUE; /* allow selection state to change */
432 }
433
434 static GtkWidget *location_widget(location_context_t *context) {
435
436 GtkWidget *vbox = gtk_vbox_new(FALSE,3);
437
438 #ifndef USE_PANNABLE_AREA
439 context->view = gtk_tree_view_new();
440 #else
441 context->view = hildon_gtk_tree_view_new(HILDON_UI_MODE_EDIT);
442 #endif
443
444 gtk_tree_selection_set_select_function(
445 gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view)),
446 view_selection_func,
447 context, NULL);
448
449 #ifndef USE_MAEMO
450 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(context->view), FALSE);
451 #endif
452
453 /* --- "Name" column --- */
454 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
455 g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL );
456 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(
457 _("Name"), renderer, "text", LOCATION_COL_NAME, NULL);
458 gtk_tree_view_column_set_expand(column, TRUE);
459 gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);
460
461 /* --- "Latitude" column --- */
462 renderer = gtk_cell_renderer_text_new();
463 // g_object_set(renderer, "xalign", 1.0, NULL );
464 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),
465 -1, _("Latitude"), renderer, "text", LOCATION_COL_LAT, NULL);
466
467 /* --- "Longitude" column --- */
468 renderer = gtk_cell_renderer_text_new();
469 // g_object_set(renderer, "xalign", 1.0, NULL );
470 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),
471 -1, _("Longitude"), renderer, "text", LOCATION_COL_LON, NULL);
472
473 /* build and fill the store */
474 context->store = gtk_list_store_new(LOCATION_NUM_COLS,
475 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
476
477 gtk_tree_view_set_model(GTK_TREE_VIEW(context->view),
478 GTK_TREE_MODEL(context->store));
479
480 char lat[32], lon[32];
481 GtkTreeIter iter;
482
483 /* add home position */
484 pos_lat_str(lat, sizeof(lat), context->appdata->home.lat);
485 pos_lon_str(lon, sizeof(lon), context->appdata->home.lon);
486 gtk_list_store_append(context->store, &iter);
487 gtk_list_store_set(context->store, &iter,
488 LOCATION_COL_NAME, _("Home"),
489 LOCATION_COL_LAT, lat,
490 LOCATION_COL_LON, lon,
491 LOCATION_COL_DATA, NULL,
492 -1);
493
494 location_t *loc = context->appdata->location;
495 while(loc) {
496 pos_lat_str(lat, sizeof(lat), loc->pos.lat);
497 pos_lon_str(lon, sizeof(lon), loc->pos.lon);
498
499 /* Append a row and fill in some data */
500 gtk_list_store_append(context->store, &iter);
501 gtk_list_store_set(context->store, &iter,
502 LOCATION_COL_NAME, loc->name,
503 LOCATION_COL_LAT, lat,
504 LOCATION_COL_LON, lon,
505 LOCATION_COL_DATA, loc,
506 -1);
507 loc = loc->next;
508 }
509
510 g_object_unref(context->store);
511
512 /* select the "active" row */
513 location_select(context);
514
515 /* put it into a scrolled window */
516 #ifndef USE_PANNABLE_AREA
517 GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
518 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
519 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
520 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),
521 GTK_SHADOW_ETCHED_IN);
522 gtk_container_add(GTK_CONTAINER(scrolled_window), context->view);
523 gtk_box_pack_start_defaults(GTK_BOX(vbox), scrolled_window);
524 #else
525 /* fremantle doesn't use a pannable area here. instead the entire */
526 /* settings are inside one big pannable area */
527 gtk_box_pack_start_defaults(GTK_BOX(vbox), context->view);
528 #endif
529
530 /* ------- button box ------------ */
531
532 GtkWidget *hbox = gtk_hbox_new(TRUE,3);
533 context->but_add = gtk_button_new_with_label(_("Add"));
534 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
535 hildon_gtk_widget_set_theme_size(context->but_add,
536 (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
537 #endif
538 gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_add);
539 gtk_signal_connect(GTK_OBJECT(context->but_add), "clicked",
540 GTK_SIGNAL_FUNC(on_location_add), context);
541
542 context->but_edit = gtk_button_new_with_label(_("Edit"));
543 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
544 hildon_gtk_widget_set_theme_size(context->but_edit,
545 (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
546 #endif
547 gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_edit);
548 gtk_signal_connect(GTK_OBJECT(context->but_edit), "clicked",
549 GTK_SIGNAL_FUNC(on_location_edit), context);
550
551 context->but_remove = gtk_button_new_with_label(_("Remove"));
552 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
553 hildon_gtk_widget_set_theme_size(context->but_remove,
554 (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
555 #endif
556 gtk_widget_set_sensitive(context->but_remove,
557 context->appdata->active_location);
558 gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_remove);
559 gtk_signal_connect(GTK_OBJECT(context->but_remove), "clicked",
560 GTK_SIGNAL_FUNC(on_location_remove), context);
561
562 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
563 return vbox;
564 }
565
566 #ifdef FREMANTLE
567 static GtkWidget *title_new(char *title) {
568 GtkWidget *vbox = gtk_vbox_new(FALSE, 10);
569 gtk_box_pack_start_defaults(GTK_BOX(vbox), gtk_label_new(""));
570 GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
571 gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_hseparator_new());
572 gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_label_new(title));
573 gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_hseparator_new());
574 gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox);
575 return vbox;
576 }
577 #endif
578
579 void cb_menu_settings(GtkWidget *window, gpointer data) {
580 appdata_t *appdata = (appdata_t *)data;
581 GtkWidget *vbox, *label, *hbox, *ihbox;
582 GtkWidget *cbox_imperial;
583 settings_dialog_state_t hstate;
584
585 GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Settings"),
586 GTK_WINDOW(appdata->window), GTK_DIALOG_MODAL,
587 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
588 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
589 NULL);
590
591 #if defined(USE_MAEMO) && defined(HILDON_HELP)
592 hildon_help_dialog_help_enable(GTK_DIALOG(dialog),
593 HELP_ID_SETTINGS, appdata->osso_context);
594 #endif
595
596 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
597 gtk_window_set_default_size(GTK_WINDOW(dialog), 550, 500);
598 #endif
599
600 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
601 /* in fremantle all settings reside in one pannable long list */
602 GtkWidget *pannable_area = hildon_pannable_area_new();
603
604 /* all elements are inside one long vbox */
605 vbox = gtk_vbox_new(FALSE, 0);
606 #else
607 GtkWidget *notebook = gtk_notebook_new();
608 #endif
609
610 /* ------------------ the "home" widget ---------------------- */
611 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
612 // gtk_box_pack_start_defaults(GTK_BOX(vbox), title_new(_("GPS")));
613 #else
614 vbox = gtk_vbox_new(FALSE, 0);
615 #endif
616
617 hstate.cbox_gps = check_button_new_with_label(_("Enable GPS"));
618 check_button_set_active(hstate.cbox_gps, appdata->use_gps);
619 gtk_box_pack_start(GTK_BOX(vbox), hstate.cbox_gps, FALSE, FALSE, 0);
620
621 location_context_t location_context;
622 memset(&location_context, 0, sizeof(location_context_t));
623 location_context.appdata = appdata;
624 location_context.settings_dialog = dialog;
625
626 /* location widget */
627 gtk_box_pack_start(GTK_BOX(vbox), hstate.loc = location_widget(&location_context),
628 TRUE, TRUE, 0);
629
630 settings_update(NULL, &hstate);
631
632 /* Connect the "toggled" signal of the button to our callback */
633 gtk_signal_connect (GTK_OBJECT (hstate.cbox_gps), "toggled",
634 GTK_SIGNAL_FUNC(settings_update), (gpointer)&hstate);
635
636 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
637 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
638 gtk_label_new(_("GPS")));
639 #endif
640
641 /* ---------------- misc old main menu entries ----------------- */
642
643 #ifndef FREMANTLE
644 vbox = gtk_vbox_new(FALSE, 0);
645 #endif
646
647 cbox_imperial = check_button_new_with_label(_("Imperial units"));
648 check_button_set_active(cbox_imperial, appdata->imperial);
649 gtk_box_pack_start(GTK_BOX(vbox), cbox_imperial, FALSE, FALSE, 0);
650
651 hbox = gtk_hbox_new(FALSE,2);
652 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Username:")),
653 FALSE, FALSE, 0);
654 #ifndef FREMANTLE
655 GtkWidget *username = gtk_entry_new();
656 #else
657 GtkWidget *username = hildon_entry_new(HILDON_SIZE_AUTO);
658 #endif
659
660 if(appdata->username)
661 gtk_entry_set_text(GTK_ENTRY(username), appdata->username);
662
663 gtk_box_pack_start(GTK_BOX(hbox), username, FALSE, FALSE, 0);
664
665 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
666
667 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
668 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
669 gtk_label_new(_("Misc")));
670 #endif
671
672 /* ----------------- gpxlist settings ------------------- */
673
674 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
675 gtk_box_pack_start_defaults(GTK_BOX(vbox), title_new(_("GPX list")));
676 #else
677 vbox = gtk_vbox_new(FALSE, 0);
678 #endif
679
680 hbox = gtk_hbox_new(FALSE,2);
681 ihbox = gtk_hbox_new(FALSE, 0);
682 gtk_box_pack_start_defaults(GTK_BOX(hbox), label = gtk_label_new(_("Visible items:")));
683 gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
684
685 GtkWidget *cbox_fname = toggle_button_new_with_label(_("Filename"));
686 toggle_button_set_active(cbox_fname, appdata->gpxlist_items & GPXLIST_ITEM_FILENAME);
687 gtk_box_pack_start_defaults(GTK_BOX(ihbox), cbox_fname);
688 GtkWidget *cbox_date = toggle_button_new_with_label(_("Date"));
689 toggle_button_set_active(cbox_date, appdata->gpxlist_items & GPXLIST_ITEM_DATE);
690 gtk_box_pack_start_defaults(GTK_BOX(ihbox), cbox_date);
691 GtkWidget *cbox_num = toggle_button_new_with_label(_("# Caches"));
692 toggle_button_set_active(cbox_num, appdata->gpxlist_items & GPXLIST_ITEM_CNUM);
693 gtk_box_pack_start_defaults(GTK_BOX(ihbox), cbox_num);
694 gtk_box_pack_start_defaults(GTK_BOX(hbox), ihbox);
695
696 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
697
698 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
699 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
700 gtk_label_new(_("GPX list")));
701 #endif
702
703 /* ----------------- cachelist settings ------------------- */
704
705 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
706 gtk_box_pack_start_defaults(GTK_BOX(vbox), title_new(_("Cache list")));
707 #else
708 vbox = gtk_vbox_new(FALSE, 0);
709 #endif
710
711 hbox = gtk_hbox_new(FALSE,2);
712 ihbox = gtk_hbox_new(FALSE, 0);
713 gtk_box_pack_start_defaults(GTK_BOX(hbox), label = gtk_label_new(_("Visible items:")));
714 gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
715
716 GtkWidget *cbox_wpt = toggle_button_new_with_label(_("Wpt"));
717 toggle_button_set_active(cbox_wpt, appdata->cachelist_items & CACHELIST_ITEM_ID);
718 gtk_box_pack_start_defaults(GTK_BOX(ihbox), cbox_wpt);
719 GtkWidget *cbox_size = toggle_button_new_with_label(_("Size"));
720 toggle_button_set_active(cbox_size, appdata->cachelist_items & CACHELIST_ITEM_SIZE);
721 gtk_box_pack_start_defaults(GTK_BOX(ihbox), cbox_size);
722 GtkWidget *cbox_rate = toggle_button_new_with_label(_("Rating"));
723 toggle_button_set_active(cbox_rate, appdata->cachelist_items & CACHELIST_ITEM_RATING);
724 gtk_box_pack_start_defaults(GTK_BOX(ihbox), cbox_rate);
725 gtk_box_pack_start_defaults(GTK_BOX(hbox), ihbox);
726
727 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
728
729 GtkWidget *cbox_cachelist_hidef =
730 check_button_new_with_label(_("Hide caches marked \"found\""));
731 check_button_set_active(cbox_cachelist_hidef, appdata->cachelist_hide_found);
732
733 gtk_box_pack_start(GTK_BOX(vbox), cbox_cachelist_hidef, FALSE, FALSE, 0);
734
735 #ifdef USE_MAEMO
736 GtkWidget *cbox_cachelist_dss =
737 check_button_new_with_label(_("Disable screen saver"));
738 check_button_set_active(cbox_cachelist_dss, appdata->cachelist_disable_screensaver);
739
740 gtk_box_pack_start(GTK_BOX(vbox), cbox_cachelist_dss, FALSE, FALSE, 0);
741 #endif
742
743 GtkWidget *cbox_update =
744 check_button_new_with_label(_("Update every 30 sec"));
745 check_button_set_active(cbox_update, appdata->cachelist_update);
746 gtk_box_pack_start(GTK_BOX(vbox), cbox_update, FALSE, FALSE, 0);
747
748 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
749 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
750 gtk_label_new(_("Cache list")));
751 #endif
752
753 /* ----------------- cache settings ------------------- */
754
755 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
756 gtk_box_pack_start_defaults(GTK_BOX(vbox), title_new(_("Cache")));
757 #else
758 vbox = gtk_vbox_new(FALSE, 0);
759 #endif
760
761 hbox = gtk_hbox_new(FALSE,2);
762 gtk_box_pack_start_defaults(GTK_BOX(hbox),
763 label = gtk_label_new(_("Compass damping:")));
764 gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
765
766 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Min")), FALSE, FALSE,0);
767 GtkWidget *scale = gtk_hscale_new_with_range(1, MAX_AVERAGE, 1);
768 gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_LEFT);
769 gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
770 gtk_range_set_value(GTK_RANGE(scale), appdata->compass_damping);
771 gtk_box_pack_start_defaults(GTK_BOX(hbox), scale);
772 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Max")), FALSE, FALSE,0);
773
774 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
775
776 GtkWidget *cbox_gcvote = check_button_new_with_label(_("Use GCVote service"));
777 check_button_set_active(cbox_gcvote, !appdata->disable_gcvote);
778 gtk_box_pack_start(GTK_BOX(vbox), cbox_gcvote, FALSE, FALSE, 0);
779
780 #ifdef USE_MAEMO
781 GtkWidget *cbox_goto_dss = check_button_new_with_label(
782 _("Disable screen saver in \"goto\" view"));
783 check_button_set_active(cbox_goto_dss, appdata->goto_disable_screensaver);
784 gtk_box_pack_start(GTK_BOX(vbox), cbox_goto_dss, FALSE, FALSE, 0);
785 #endif
786
787 #if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
788 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
789 gtk_label_new(_("Cache")));
790 #endif
791
792 /* -------------------------------------------------------- */
793
794 #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
795 hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(pannable_area), vbox);
796 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), pannable_area);
797 #else
798 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), notebook);
799 #endif
800
801 gtk_widget_show_all(dialog);
802
803 if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
804 gboolean prev_cachelist_hide_found = appdata->cachelist_hide_found;
805
806 appdata->use_gps =
807 check_button_get_active(hstate.cbox_gps);
808 appdata->imperial =
809 check_button_get_active(cbox_imperial);
810
811 if(appdata->username) {
812 g_free(appdata->username);
813 appdata->username = NULL;
814 }
815
816 const char *uname = gtk_entry_get_text(GTK_ENTRY(username));
817 if(uname && strlen(uname)>0)
818 appdata->username = g_strdup(uname);
819
820 appdata->compass_damping = 0.5 + gtk_range_get_value(GTK_RANGE(scale));
821
822 appdata->gpxlist_items = GPXLIST_ITEM_VALID;
823 if(toggle_button_get_active(cbox_fname))
824 appdata->gpxlist_items |= GPXLIST_ITEM_FILENAME;
825 if(toggle_button_get_active(cbox_date))
826 appdata->gpxlist_items |= GPXLIST_ITEM_DATE;
827 if(toggle_button_get_active(cbox_num))
828 appdata->gpxlist_items |= GPXLIST_ITEM_CNUM;
829
830 appdata->cachelist_items = CACHELIST_ITEM_VALID;
831 if(toggle_button_get_active(cbox_wpt))
832 appdata->cachelist_items |= CACHELIST_ITEM_ID;
833 if(toggle_button_get_active(cbox_size))
834 appdata->cachelist_items |= CACHELIST_ITEM_SIZE;
835 if(toggle_button_get_active(cbox_rate))
836 appdata->cachelist_items |= CACHELIST_ITEM_RATING;
837
838 appdata->cachelist_hide_found =
839 check_button_get_active(cbox_cachelist_hidef);
840
841 #ifdef USE_MAEMO
842 appdata->goto_disable_screensaver =
843 check_button_get_active(cbox_goto_dss);
844 appdata->cachelist_disable_screensaver =
845 check_button_get_active(cbox_cachelist_dss);
846 #endif
847 appdata->cachelist_update = check_button_get_active(cbox_update);
848
849 appdata->disable_gcvote = !check_button_get_active(cbox_gcvote);
850
851 /* build some additional flags that are used to decide whether a */
852 /* redraw is necessary */
853 int flags = CHANGE_FLAG_POS;
854
855 if(prev_cachelist_hide_found != appdata->cachelist_hide_found)
856 flags |= CHANGE_FLAG_MASK; // visibility mask has changed
857
858 main_after_settings_redraw(appdata, flags);
859 }
860 gtk_widget_destroy(dialog);
861 }
862