Parent Directory | Revision Log
Various fremantleization
1 | /* |
2 | * Copyright (C) 2008 Till Harbaum <till@harbaum.org>. |
3 | * |
4 | * This file is part of OSM2Go. |
5 | * |
6 | * OSM2Go 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 | * OSM2Go 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 OSM2Go. If not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | #include "appdata.h" |
21 | |
22 | enum { |
23 | TAG_COL_KEY = 0, |
24 | TAG_COL_VALUE, |
25 | TAG_COL_COLLISION, |
26 | TAG_COL_DATA, |
27 | TAG_NUM_COLS |
28 | }; |
29 | |
30 | gboolean info_tag_key_collision(tag_t *tags, tag_t *tag) { |
31 | while(tags) { |
32 | if((tags != tag) && (strcasecmp(tags->key, tag->key) == 0)) |
33 | return TRUE; |
34 | |
35 | tags = tags->next; |
36 | } |
37 | return FALSE; |
38 | } |
39 | |
40 | static gboolean |
41 | view_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, |
42 | GtkTreePath *path, gboolean path_currently_selected, |
43 | gpointer userdata) { |
44 | tag_context_t *context = (tag_context_t*)userdata; |
45 | GtkTreeIter iter; |
46 | |
47 | if(gtk_tree_model_get_iter(model, &iter, path)) { |
48 | g_assert(gtk_tree_path_get_depth(path) == 1); |
49 | |
50 | tag_t *tag; |
51 | gtk_tree_model_get(model, &iter, TAG_COL_DATA, &tag, -1); |
52 | |
53 | /* you just cannot delete or edit the "created_by" tag */ |
54 | if(!tag || strcasecmp(tag->key, "created_by") == 0) { |
55 | list_button_enable(context->list, LIST_BUTTON_REMOVE, FALSE); |
56 | list_button_enable(context->list, LIST_BUTTON_EDIT, FALSE); |
57 | } else { |
58 | list_button_enable(context->list, LIST_BUTTON_REMOVE, TRUE); |
59 | list_button_enable(context->list, LIST_BUTTON_EDIT, TRUE); |
60 | } |
61 | } |
62 | |
63 | return TRUE; /* allow selection state to change */ |
64 | } |
65 | |
66 | static void update_collisions(GtkListStore *store, tag_t *tags) { |
67 | GtkTreeIter iter; |
68 | tag_t *tag = NULL; |
69 | |
70 | /* walk the entire store to get all values */ |
71 | if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { |
72 | gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, TAG_COL_DATA, &tag, -1); |
73 | g_assert(tag); |
74 | gtk_list_store_set(store, &iter, |
75 | TAG_COL_COLLISION, info_tag_key_collision(tags, tag), -1); |
76 | |
77 | while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)) { |
78 | gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, |
79 | TAG_COL_DATA, &tag, -1); |
80 | g_assert(tag); |
81 | gtk_list_store_set(store, &iter, |
82 | TAG_COL_COLLISION, info_tag_key_collision(tags, tag), -1); |
83 | } |
84 | } |
85 | } |
86 | |
87 | static void on_tag_remove(GtkWidget *but, tag_context_t *context) { |
88 | GtkTreeModel *model; |
89 | GtkTreeIter iter; |
90 | |
91 | GtkTreeSelection *selection = list_get_selection(context->list); |
92 | if(gtk_tree_selection_get_selected(selection, &model, &iter)) { |
93 | tag_t *tag; |
94 | gtk_tree_model_get(model, &iter, TAG_COL_DATA, &tag, -1); |
95 | |
96 | g_assert(tag); |
97 | |
98 | /* de-chain */ |
99 | printf("de-chaining tag %s/%s\n", tag->key, tag->value); |
100 | tag_t **prev = context->tag; |
101 | while(*prev != tag) prev = &((*prev)->next); |
102 | *prev = tag->next; |
103 | |
104 | /* free tag itself */ |
105 | osm_tag_free(tag); |
106 | |
107 | /* and remove from store */ |
108 | gtk_list_store_remove(GTK_LIST_STORE(model), &iter); |
109 | |
110 | update_collisions(context->store, *context->tag); |
111 | } |
112 | |
113 | /* disable remove and edit buttons */ |
114 | list_button_enable(context->list, LIST_BUTTON_REMOVE, FALSE); |
115 | list_button_enable(context->list, LIST_BUTTON_EDIT, FALSE); |
116 | } |
117 | |
118 | static gboolean tag_edit(tag_context_t *context) { |
119 | |
120 | GtkTreeModel *model; |
121 | GtkTreeIter iter; |
122 | tag_t *tag; |
123 | |
124 | GtkTreeSelection *sel = list_get_selection(context->list); |
125 | if(!sel) { |
126 | printf("got no selection object\n"); |
127 | return FALSE; |
128 | } |
129 | |
130 | if(!gtk_tree_selection_get_selected(sel, &model, &iter)) { |
131 | printf("nothing selected\n"); |
132 | return FALSE; |
133 | } |
134 | |
135 | gtk_tree_model_get(model, &iter, TAG_COL_DATA, &tag, -1); |
136 | printf("got %s/%s\n", tag->key, tag->value); |
137 | |
138 | GtkWidget *dialog = misc_dialog_new(MISC_DIALOG_SMALL, _("Edit Tag"), |
139 | GTK_WINDOW(context->dialog), |
140 | GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, |
141 | GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, |
142 | NULL); |
143 | |
144 | gtk_dialog_set_default_response(GTK_DIALOG(dialog), |
145 | GTK_RESPONSE_ACCEPT); |
146 | |
147 | GtkWidget *label, *key, *value; |
148 | GtkWidget *table = gtk_table_new(2, 2, FALSE); |
149 | |
150 | gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Key:")), |
151 | 0, 1, 0, 1, 0, 0, 0, 0); |
152 | gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); |
153 | gtk_table_attach_defaults(GTK_TABLE(table), |
154 | key = entry_new(), 1, 2, 0, 1); |
155 | gtk_entry_set_activates_default(GTK_ENTRY(key), TRUE); |
156 | HILDON_ENTRY_NO_AUTOCAP(key); |
157 | |
158 | gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Value:")), |
159 | 0, 1, 1, 2, 0, 0, 0, 0); |
160 | gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); |
161 | gtk_table_attach_defaults(GTK_TABLE(table), |
162 | value = entry_new(), 1, 2, 1, 2); |
163 | gtk_entry_set_activates_default(GTK_ENTRY(value), TRUE); |
164 | HILDON_ENTRY_NO_AUTOCAP(value); |
165 | |
166 | gtk_entry_set_text(GTK_ENTRY(key), tag->key); |
167 | gtk_entry_set_text(GTK_ENTRY(value), tag->value); |
168 | |
169 | gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), table); |
170 | |
171 | gtk_widget_show_all(dialog); |
172 | |
173 | if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) { |
174 | free(tag->key); free(tag->value); |
175 | tag->key = strdup((char*)gtk_entry_get_text(GTK_ENTRY(key))); |
176 | tag->value = strdup((char*)gtk_entry_get_text(GTK_ENTRY(value))); |
177 | printf("setting %s/%s\n", tag->key, tag->value); |
178 | |
179 | gtk_list_store_set(context->store, &iter, |
180 | TAG_COL_KEY, tag->key, |
181 | TAG_COL_VALUE, tag->value, |
182 | -1); |
183 | |
184 | gtk_widget_destroy(dialog); |
185 | |
186 | /* update collisions for all entries */ |
187 | update_collisions(context->store, *context->tag); |
188 | return TRUE; |
189 | } |
190 | |
191 | gtk_widget_destroy(dialog); |
192 | return FALSE; |
193 | } |
194 | |
195 | static void on_tag_edit(GtkWidget *button, tag_context_t *context) { |
196 | tag_edit(context); |
197 | } |
198 | |
199 | static void on_tag_last(GtkWidget *button, tag_context_t *context) { |
200 | static const char *type_name[] = { "illegal", "node", "way", "relation" }; |
201 | |
202 | if(yes_no_f(context->dialog, |
203 | context->appdata, MISC_AGAIN_ID_OVERWRITE_TAGS, 0, |
204 | _("Overwrite tags?"), |
205 | _("This will overwrite all tags of this %s with the " |
206 | "ones from the %s selected last.\n\n" |
207 | "Do you really want this?"), |
208 | type_name[context->object.type], type_name[context->object.type])) { |
209 | |
210 | osm_tags_free(*context->tag); |
211 | |
212 | if(context->object.type == NODE) |
213 | *context->tag = osm_tags_copy(context->appdata->map->last_node_tags); |
214 | else |
215 | *context->tag = osm_tags_copy(context->appdata->map->last_way_tags); |
216 | |
217 | info_tags_replace(context); |
218 | } |
219 | } |
220 | |
221 | static void on_tag_add(GtkWidget *button, tag_context_t *context) { |
222 | |
223 | /* search end of tag chain */ |
224 | tag_t **tag = context->tag; |
225 | while(*tag) |
226 | tag = &(*tag)->next; |
227 | |
228 | /* create and append a new tag */ |
229 | *tag = g_new0(tag_t, 1); |
230 | if(!*tag) { |
231 | errorf(GTK_WIDGET(context->appdata->window), _("Out of memory")); |
232 | return; |
233 | } |
234 | |
235 | /* fill with some empty strings */ |
236 | (*tag)->key = strdup(""); |
237 | (*tag)->value = strdup(""); |
238 | |
239 | /* append a row for the new data */ |
240 | GtkTreeIter iter; |
241 | gtk_list_store_append(context->store, &iter); |
242 | gtk_list_store_set(context->store, &iter, |
243 | TAG_COL_KEY, (*tag)->key, |
244 | TAG_COL_VALUE, (*tag)->value, |
245 | TAG_COL_COLLISION, FALSE, |
246 | TAG_COL_DATA, *tag, |
247 | -1); |
248 | |
249 | gtk_tree_selection_select_iter( |
250 | list_get_selection(context->list), &iter); |
251 | |
252 | if(!tag_edit(context)) { |
253 | printf("cancelled\n"); |
254 | on_tag_remove(NULL, context); |
255 | } |
256 | } |
257 | |
258 | void info_tags_replace(tag_context_t *context) { |
259 | gtk_list_store_clear(context->store); |
260 | |
261 | GtkTreeIter iter; |
262 | tag_t *tag = *context->tag; |
263 | while(tag) { |
264 | gtk_list_store_append(context->store, &iter); |
265 | gtk_list_store_set(context->store, &iter, |
266 | TAG_COL_KEY, tag->key, |
267 | TAG_COL_VALUE, tag->value, |
268 | TAG_COL_COLLISION, info_tag_key_collision(*context->tag, tag), |
269 | TAG_COL_DATA, tag, |
270 | -1); |
271 | tag = tag->next; |
272 | } |
273 | } |
274 | |
275 | static void on_relations(GtkWidget *button, tag_context_t *context) { |
276 | relation_add_dialog(context->dialog, context->appdata, &context->object); |
277 | } |
278 | |
279 | static GtkWidget *tag_widget(tag_context_t *context) { |
280 | context->list = list_new(LIST_HILDON_WITHOUT_HEADERS); |
281 | |
282 | list_set_static_buttons(context->list, 0, G_CALLBACK(on_tag_add), |
283 | G_CALLBACK(on_tag_edit), G_CALLBACK(on_tag_remove), context); |
284 | |
285 | list_set_selection_function(context->list, view_selection_func, context); |
286 | |
287 | list_set_user_buttons(context->list, |
288 | LIST_BUTTON_USER0, _("Last"), on_tag_last, |
289 | LIST_BUTTON_USER2, _("Relations"), on_relations, |
290 | 0); |
291 | |
292 | /* setup both columns */ |
293 | list_set_columns(context->list, |
294 | _("Key"), TAG_COL_KEY, |
295 | LIST_FLAG_ELLIPSIZE|LIST_FLAG_CAN_HIGHLIGHT, TAG_COL_COLLISION, |
296 | _("Value"), TAG_COL_VALUE, |
297 | LIST_FLAG_ELLIPSIZE, |
298 | NULL); |
299 | |
300 | GtkWidget *presets = josm_build_presets_button(context->appdata, context); |
301 | if(presets) |
302 | list_set_custom_user_button(context->list, LIST_BUTTON_USER1, presets); |
303 | |
304 | /* disable if no appropriate "last" tags have been stored or if the */ |
305 | /* selected item isn't a node or way */ |
306 | if(((context->object.type == NODE) && |
307 | (!context->appdata->map->last_node_tags)) || |
308 | ((context->object.type == WAY) && |
309 | (!context->appdata->map->last_way_tags)) || |
310 | ((context->object.type != NODE) && (context->object.type != WAY))) |
311 | list_button_enable(context->list, LIST_BUTTON_USER0, FALSE); |
312 | |
313 | /* --------- build and fill the store ------------ */ |
314 | context->store = gtk_list_store_new(TAG_NUM_COLS, |
315 | G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER); |
316 | |
317 | list_set_store(context->list, context->store); |
318 | |
319 | GtkTreeIter iter; |
320 | |
321 | tag_t *tag = *context->tag; |
322 | while(tag) { |
323 | /* Append a row and fill in some data */ |
324 | gtk_list_store_append(context->store, &iter); |
325 | gtk_list_store_set(context->store, &iter, |
326 | TAG_COL_KEY, tag->key, |
327 | TAG_COL_VALUE, tag->value, |
328 | TAG_COL_COLLISION, info_tag_key_collision(*context->tag, tag), |
329 | TAG_COL_DATA, tag, |
330 | -1); |
331 | tag = tag->next; |
332 | } |
333 | |
334 | g_object_unref(context->store); |
335 | |
336 | return context->list; |
337 | } |
338 | |
339 | static void on_relation_members(GtkWidget *but, tag_context_t *context) { |
340 | g_assert(context->object.type == RELATION); |
341 | relation_show_members(context->dialog, context->object.relation); |
342 | } |
343 | |
344 | static void table_attach(GtkWidget *table, GtkWidget *child, int x, int y) { |
345 | gtk_table_attach_defaults(GTK_TABLE(table), child, x, x+1, y, y+1); |
346 | } |
347 | |
348 | static GtkWidget *details_widget(tag_context_t *context, gboolean big) { |
349 | GtkWidget *table = gtk_table_new(big?4:2, 2, FALSE); // y, x |
350 | |
351 | user_t *user = OBJECT_USER(context->object); |
352 | time_t stime = OBJECT_TIME(context->object); |
353 | GtkWidget *label; |
354 | |
355 | /* ------------ user ----------------- */ |
356 | if(user) { |
357 | if(big) table_attach(table, gtk_label_new(_("User:")), 0, 0); |
358 | |
359 | label = gtk_label_new(user->name); |
360 | gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); |
361 | table_attach(table, label, big?1:0, 0); |
362 | } |
363 | |
364 | /* ------------ time ----------------- */ |
365 | |
366 | if(big) table_attach(table, gtk_label_new(_("Date/Time:")), 0, 1); |
367 | struct tm *loctime = localtime(&stime); |
368 | char time_str[32]; |
369 | strftime(time_str, sizeof(time_str), "%x %X", loctime); |
370 | label = gtk_label_new(time_str); |
371 | table_attach(table, label, 1, big?1:0); |
372 | |
373 | /* ------------ coordinate (only for nodes) ----------------- */ |
374 | switch(context->object.type) { |
375 | case NODE: { |
376 | char pos_str[32]; |
377 | pos_lat_str(pos_str, sizeof(pos_str), context->object.node->pos.lat); |
378 | label = gtk_label_new(pos_str); |
379 | if(big) table_attach(table, gtk_label_new(_("Latitude:")), 0, 2); |
380 | table_attach(table, label, big?1:0, big?2:1); |
381 | pos_lat_str(pos_str, sizeof(pos_str), context->object.node->pos.lon); |
382 | label = gtk_label_new(pos_str); |
383 | if(big) table_attach(table, gtk_label_new(_("Longitude:")), 0, 3); |
384 | table_attach(table, label, 1, big?3:1); |
385 | } break; |
386 | |
387 | case WAY: { |
388 | char *nodes_str = g_strdup_printf(_("%s%u nodes"), |
389 | big?"":_("Length: "), |
390 | osm_way_number_of_nodes(context->object.way)); |
391 | label = gtk_label_new(nodes_str); |
392 | if(big) table_attach(table, gtk_label_new(_("Length:")), 0, 2); |
393 | table_attach(table, label, big?1:0, big?2:1); |
394 | g_free(nodes_str); |
395 | |
396 | char *type_str = g_strdup_printf("%s (%s)", |
397 | (osm_way_get_last_node(context->object.way) == |
398 | osm_way_get_first_node(context->object.way))? |
399 | "closed way":"open way", |
400 | (context->object.way->draw.flags & OSM_DRAW_FLAG_AREA)? |
401 | "area":"line"); |
402 | |
403 | label = gtk_label_new(type_str); |
404 | if(big) table_attach(table, gtk_label_new(_("Type:")), 0, 3); |
405 | table_attach(table, label, 1, big?3:1); |
406 | g_free(type_str); |
407 | } break; |
408 | |
409 | case RELATION: { |
410 | /* relations tell something about their members */ |
411 | gint nodes = 0, ways = 0, relations = 0; |
412 | member_t *member = context->object.relation->member; |
413 | while(member) { |
414 | switch(member->object.type) { |
415 | case NODE: |
416 | case NODE_ID: |
417 | nodes++; |
418 | break; |
419 | case WAY: |
420 | case WAY_ID: |
421 | ways++; |
422 | break; |
423 | case RELATION: |
424 | case RELATION_ID: |
425 | relations++; |
426 | break; |
427 | |
428 | default: |
429 | break; |
430 | } |
431 | |
432 | member = member->next; |
433 | } |
434 | |
435 | char *str = |
436 | g_strdup_printf(_("Members: %d nodes, %d ways, %d relations"), |
437 | nodes, ways, relations); |
438 | |
439 | GtkWidget *member_btn = button_new_with_label(str); |
440 | gtk_signal_connect(GTK_OBJECT(member_btn), "clicked", |
441 | GTK_SIGNAL_FUNC(on_relation_members), context); |
442 | |
443 | gtk_table_attach_defaults(GTK_TABLE(table), member_btn, 0, 2, |
444 | big?2:1, big?4:2); |
445 | |
446 | g_free(str); |
447 | break; |
448 | |
449 | default: |
450 | printf("ERROR: No node, way or relation\n"); |
451 | g_assert(0); |
452 | break; |
453 | } } |
454 | |
455 | return table; |
456 | } |
457 | |
458 | #ifdef FREMANTLE |
459 | /* put additional infos into a seperate dialog for fremantle as */ |
460 | /* screen space is sparse there */ |
461 | static void info_more(tag_context_t *context) { |
462 | GtkWidget *dialog = |
463 | misc_dialog_new(MISC_DIALOG_SMALL, _("Object details"), |
464 | GTK_WINDOW(context->dialog), |
465 | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
466 | NULL); |
467 | |
468 | gtk_dialog_set_default_response(GTK_DIALOG(dialog), |
469 | GTK_RESPONSE_CANCEL); |
470 | |
471 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), |
472 | details_widget(context, TRUE), |
473 | FALSE, FALSE, 0); |
474 | gtk_widget_show_all(dialog); |
475 | gtk_dialog_run(GTK_DIALOG(dialog)); |
476 | gtk_widget_destroy(dialog); |
477 | } |
478 | #endif |
479 | |
480 | /* edit tags of currently selected node or way or of the relation */ |
481 | /* given */ |
482 | gboolean info_dialog(GtkWidget *parent, appdata_t *appdata, object_t *object) { |
483 | |
484 | tag_context_t *context = g_new0(tag_context_t, 1); |
485 | char *str = NULL; |
486 | tag_t *work_copy = NULL; |
487 | |
488 | context->appdata = appdata; |
489 | context->tag = &work_copy; |
490 | |
491 | /* use implicit selection if not explicitely given */ |
492 | if(!object) { |
493 | g_assert((appdata->map->selected.object.type == NODE) || |
494 | (appdata->map->selected.object.type == WAY) || |
495 | (appdata->map->selected.object.type == RELATION)); |
496 | |
497 | context->object = appdata->map->selected.object; |
498 | } else |
499 | context->object = *object; |
500 | |
501 | // str = osm_object_string(&context->object); |
502 | // str[0] = g_ascii_toupper (str[0]); |
503 | |
504 | g_assert(osm_object_is_real(&context->object)); |
505 | |
506 | work_copy = osm_tags_copy(OBJECT_TAG(context->object)); |
507 | |
508 | switch(context->object.type) { |
509 | case NODE: |
510 | str = g_strdup_printf(_("Node #" ITEM_ID_FORMAT), |
511 | OBJECT_ID(context->object)); |
512 | context->presets_type = PRESETS_TYPE_NODE; |
513 | break; |
514 | |
515 | case WAY: |
516 | str = g_strdup_printf(_("Way #" ITEM_ID_FORMAT), |
517 | OBJECT_ID(context->object)); |
518 | context->presets_type = PRESETS_TYPE_WAY; |
519 | |
520 | if(osm_way_get_last_node(context->object.way) == |
521 | osm_way_get_first_node(context->object.way)) |
522 | context->presets_type |= PRESETS_TYPE_CLOSEDWAY; |
523 | |
524 | break; |
525 | |
526 | case RELATION: |
527 | str = g_strdup_printf(_("Relation #" ITEM_ID_FORMAT), |
528 | OBJECT_ID(context->object)); |
529 | context->presets_type = PRESETS_TYPE_RELATION; |
530 | break; |
531 | |
532 | default: |
533 | g_assert((context->object.type == NODE) || |
534 | (context->object.type == WAY) || |
535 | (context->object.type == RELATION)); |
536 | break; |
537 | } |
538 | |
539 | context->dialog = misc_dialog_new(MISC_DIALOG_LARGE, str, |
540 | GTK_WINDOW(parent), |
541 | #ifdef FREMANTLE |
542 | _("More"), GTK_RESPONSE_HELP, |
543 | #endif |
544 | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
545 | GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, |
546 | NULL); |
547 | g_free(str); |
548 | |
549 | gtk_dialog_set_default_response(GTK_DIALOG(context->dialog), |
550 | GTK_RESPONSE_ACCEPT); |
551 | |
552 | #ifndef FREMANTLE |
553 | /* -------- details box --------- */ |
554 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), |
555 | details_widget(context, FALSE), |
556 | FALSE, FALSE, 0); |
557 | #endif |
558 | |
559 | /* ------------ tags ----------------- */ |
560 | |
561 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), |
562 | tag_widget(context), TRUE, TRUE, 0); |
563 | |
564 | /* ----------------------------------- */ |
565 | |
566 | gtk_widget_show_all(context->dialog); |
567 | gboolean ok = FALSE, quit = FALSE; |
568 | |
569 | do { |
570 | switch(gtk_dialog_run(GTK_DIALOG(context->dialog))) { |
571 | case GTK_RESPONSE_ACCEPT: |
572 | quit = TRUE; |
573 | ok = TRUE; |
574 | break; |
575 | #ifdef FREMANTLE |
576 | case GTK_RESPONSE_HELP: |
577 | info_more(context); |
578 | break; |
579 | #endif |
580 | |
581 | default: |
582 | quit = TRUE; |
583 | break; |
584 | } |
585 | |
586 | } while(!quit); |
587 | |
588 | gtk_widget_destroy(context->dialog); |
589 | |
590 | if(ok) { |
591 | if(osm_object_is_real(&context->object)) { |
592 | osm_tags_free(OBJECT_TAG(context->object)); |
593 | OBJECT_TAG(context->object) = osm_tags_copy(work_copy); |
594 | } |
595 | |
596 | /* since nodes being parts of ways but with no tags are invisible, */ |
597 | /* the result of editing them may have changed their visibility */ |
598 | if(!object && context->object.type != RELATION) |
599 | map_item_redraw(appdata, &appdata->map->selected); |
600 | |
601 | osm_object_set_flags(&context->object, OSM_FLAG_DIRTY, 0); |
602 | } else |
603 | osm_tags_free(work_copy); |
604 | |
605 | g_free(context); |
606 | return ok; |
607 | } |