Parent Directory | Revision Log
Ignore created_by when copying tags
1 | harbaum | 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 | harbaum | 146 | |
47 | harbaum | 1 | 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 | harbaum | 146 | if(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 | harbaum | 1 | } |
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 | harbaum | 146 | GtkTreeSelection *selection = list_get_selection(context->list); |
92 | harbaum | 1 | 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 | harbaum | 146 | list_button_enable(context->list, LIST_BUTTON_REMOVE, FALSE); |
115 | list_button_enable(context->list, LIST_BUTTON_EDIT, FALSE); | ||
116 | harbaum | 1 | } |
117 | |||
118 | static gboolean tag_edit(tag_context_t *context) { | ||
119 | |||
120 | GtkTreeModel *model; | ||
121 | GtkTreeIter iter; | ||
122 | tag_t *tag; | ||
123 | |||
124 | harbaum | 146 | GtkTreeSelection *sel = list_get_selection(context->list); |
125 | harbaum | 1 | 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 | harbaum | 167 | 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 | harbaum | 1 | |
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 | harbaum | 42 | gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Key:")), |
151 | 0, 1, 0, 1, 0, 0, 0, 0); | ||
152 | harbaum | 1 | gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); |
153 | gtk_table_attach_defaults(GTK_TABLE(table), | ||
154 | harbaum | 42 | key = gtk_entry_new(), 1, 2, 0, 1); |
155 | harbaum | 1 | gtk_entry_set_activates_default(GTK_ENTRY(key), TRUE); |
156 | HILDON_ENTRY_NO_AUTOCAP(key); | ||
157 | |||
158 | harbaum | 42 | gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Value:")), |
159 | 0, 1, 1, 2, 0, 0, 0, 0); | ||
160 | harbaum | 1 | gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); |
161 | gtk_table_attach_defaults(GTK_TABLE(table), | ||
162 | value = gtk_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 | harbaum | 153 | type_name[context->object.type], type_name[context->object.type])) { |
209 | harbaum | 1 | |
210 | osm_tags_free(*context->tag); | ||
211 | |||
212 | harbaum | 153 | if(context->object.type == NODE) |
213 | harbaum | 234 | *context->tag = osm_tags_copy(context->appdata->map->last_node_tags); |
214 | harbaum | 1 | else |
215 | harbaum | 234 | *context->tag = osm_tags_copy(context->appdata->map->last_way_tags); |
216 | harbaum | 1 | |
217 | info_tags_replace(context); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | static void on_tag_add(GtkWidget *button, tag_context_t *context) { | ||
222 | /* search end of tag chain */ | ||
223 | tag_t **tag = context->tag; | ||
224 | while(*tag) | ||
225 | tag = &(*tag)->next; | ||
226 | |||
227 | /* create and append a new tag */ | ||
228 | *tag = g_new0(tag_t, 1); | ||
229 | if(!*tag) { | ||
230 | errorf(GTK_WIDGET(context->appdata->window), _("Out of memory")); | ||
231 | return; | ||
232 | } | ||
233 | |||
234 | /* fill with some empty strings */ | ||
235 | (*tag)->key = strdup(""); | ||
236 | (*tag)->value = strdup(""); | ||
237 | |||
238 | /* append a row for the new data */ | ||
239 | GtkTreeIter iter; | ||
240 | gtk_list_store_append(context->store, &iter); | ||
241 | gtk_list_store_set(context->store, &iter, | ||
242 | TAG_COL_KEY, (*tag)->key, | ||
243 | TAG_COL_VALUE, (*tag)->value, | ||
244 | TAG_COL_COLLISION, FALSE, | ||
245 | TAG_COL_DATA, *tag, | ||
246 | -1); | ||
247 | |||
248 | harbaum | 146 | gtk_tree_selection_select_iter( |
249 | list_get_selection(context->list), &iter); | ||
250 | harbaum | 1 | |
251 | if(!tag_edit(context)) { | ||
252 | printf("cancelled\n"); | ||
253 | on_tag_remove(NULL, context); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | void info_tags_replace(tag_context_t *context) { | ||
258 | gtk_list_store_clear(context->store); | ||
259 | |||
260 | GtkTreeIter iter; | ||
261 | tag_t *tag = *context->tag; | ||
262 | while(tag) { | ||
263 | gtk_list_store_append(context->store, &iter); | ||
264 | gtk_list_store_set(context->store, &iter, | ||
265 | TAG_COL_KEY, tag->key, | ||
266 | TAG_COL_VALUE, tag->value, | ||
267 | TAG_COL_COLLISION, info_tag_key_collision(*context->tag, tag), | ||
268 | TAG_COL_DATA, tag, | ||
269 | -1); | ||
270 | tag = tag->next; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | harbaum | 191 | static void on_relations(GtkWidget *button, tag_context_t *context) { |
275 | harbaum | 201 | relation_add_dialog(context->dialog, context->appdata, &context->object); |
276 | harbaum | 191 | } |
277 | |||
278 | harbaum | 1 | static GtkWidget *tag_widget(tag_context_t *context) { |
279 | harbaum | 148 | context->list = list_new(LIST_HILDON_WITH_HEADERS_ON_MAEMO5); |
280 | harbaum | 1 | |
281 | harbaum | 218 | list_set_static_buttons(context->list, FALSE, G_CALLBACK(on_tag_add), |
282 | harbaum | 146 | G_CALLBACK(on_tag_edit), G_CALLBACK(on_tag_remove), context); |
283 | harbaum | 1 | |
284 | harbaum | 146 | list_set_selection_function(context->list, view_selection_func, context); |
285 | harbaum | 1 | |
286 | harbaum | 146 | list_set_user_buttons(context->list, |
287 | harbaum | 191 | LIST_BUTTON_USER0, _("Last"), on_tag_last, |
288 | LIST_BUTTON_USER2, _("Relations"), on_relations, | ||
289 | harbaum | 146 | 0); |
290 | harbaum | 1 | |
291 | harbaum | 146 | /* setup both columns */ |
292 | list_set_columns(context->list, | ||
293 | _("Key"), TAG_COL_KEY, | ||
294 | harbaum | 148 | LIST_FLAG_ELLIPSIZE|LIST_FLAG_CAN_HIGHLIGHT, TAG_COL_COLLISION, |
295 | harbaum | 146 | _("Value"), TAG_COL_VALUE, |
296 | harbaum | 148 | LIST_FLAG_ELLIPSIZE, |
297 | harbaum | 146 | NULL); |
298 | |||
299 | GtkWidget *presets = josm_presets_select(context->appdata, context); | ||
300 | if(presets) | ||
301 | list_set_custom_user_button(context->list, LIST_BUTTON_USER1, presets); | ||
302 | |||
303 | /* disable if no appropriate "last" tags have been stored or if the */ | ||
304 | /* selected item isn't a node or way */ | ||
305 | harbaum | 153 | if(((context->object.type == NODE) && |
306 | harbaum | 146 | (!context->appdata->map->last_node_tags)) || |
307 | harbaum | 153 | ((context->object.type == WAY) && |
308 | harbaum | 146 | (!context->appdata->map->last_way_tags)) || |
309 | harbaum | 153 | ((context->object.type != NODE) && (context->object.type != WAY))) |
310 | harbaum | 146 | list_button_enable(context->list, LIST_BUTTON_USER0, FALSE); |
311 | |||
312 | /* --------- build and fill the store ------------ */ | ||
313 | harbaum | 1 | context->store = gtk_list_store_new(TAG_NUM_COLS, |
314 | G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER); | ||
315 | |||
316 | harbaum | 146 | list_set_store(context->list, context->store); |
317 | harbaum | 1 | |
318 | GtkTreeIter iter; | ||
319 | tag_t *tag = *context->tag; | ||
320 | while(tag) { | ||
321 | /* Append a row and fill in some data */ | ||
322 | gtk_list_store_append(context->store, &iter); | ||
323 | gtk_list_store_set(context->store, &iter, | ||
324 | TAG_COL_KEY, tag->key, | ||
325 | TAG_COL_VALUE, tag->value, | ||
326 | TAG_COL_COLLISION, info_tag_key_collision(*context->tag, tag), | ||
327 | TAG_COL_DATA, tag, | ||
328 | -1); | ||
329 | tag = tag->next; | ||
330 | } | ||
331 | |||
332 | g_object_unref(context->store); | ||
333 | |||
334 | harbaum | 146 | return context->list; |
335 | harbaum | 1 | } |
336 | |||
337 | harbaum | 155 | static void on_relation_members(GtkWidget *but, tag_context_t *context) { |
338 | g_assert(context->object.type == RELATION); | ||
339 | relation_show_members(context->dialog, context->object.relation); | ||
340 | } | ||
341 | |||
342 | harbaum | 1 | /* edit tags of currently selected node or way or of the relation */ |
343 | /* given */ | ||
344 | harbaum | 153 | gboolean info_dialog(GtkWidget *parent, appdata_t *appdata, object_t *object) { |
345 | harbaum | 1 | |
346 | tag_context_t *context = g_new0(tag_context_t, 1); | ||
347 | user_t *user = NULL; | ||
348 | char *str = NULL; | ||
349 | time_t stime = 0; | ||
350 | tag_t *work_copy = NULL; | ||
351 | |||
352 | context->appdata = appdata; | ||
353 | context->tag = &work_copy; | ||
354 | |||
355 | harbaum | 153 | /* use implicit selection if not explicitely given */ |
356 | if(!object) { | ||
357 | harbaum | 154 | g_assert((appdata->map->selected.object.type == NODE) || |
358 | (appdata->map->selected.object.type == WAY) || | ||
359 | (appdata->map->selected.object.type == RELATION)); | ||
360 | |||
361 | context->object = appdata->map->selected.object; | ||
362 | harbaum | 153 | } else |
363 | context->object = *object; | ||
364 | |||
365 | harbaum | 194 | // str = osm_object_string(&context->object); |
366 | // str[0] = g_ascii_toupper (str[0]); | ||
367 | |||
368 | harbaum | 153 | switch(context->object.type) { |
369 | case NODE: | ||
370 | harbaum | 161 | str = g_strdup_printf(_("Node #" ITEM_ID_FORMAT), context->object.node->id); |
371 | harbaum | 153 | user = context->object.node->user; |
372 | harbaum | 234 | work_copy = osm_tags_copy(context->object.node->tag); |
373 | harbaum | 153 | stime = context->object.node->time; |
374 | context->presets_type = PRESETS_TYPE_NODE; | ||
375 | break; | ||
376 | |||
377 | case WAY: | ||
378 | harbaum | 161 | str = g_strdup_printf(_("Way #" ITEM_ID_FORMAT), context->object.way->id); |
379 | harbaum | 153 | user = context->object.way->user; |
380 | harbaum | 234 | work_copy = osm_tags_copy(context->object.way->tag); |
381 | harbaum | 153 | stime = context->object.way->time; |
382 | context->presets_type = PRESETS_TYPE_WAY; | ||
383 | |||
384 | if(osm_way_get_last_node(context->object.way) == | ||
385 | osm_way_get_first_node(context->object.way)) | ||
386 | context->presets_type |= PRESETS_TYPE_CLOSEDWAY; | ||
387 | |||
388 | break; | ||
389 | |||
390 | harbaum | 154 | case RELATION: |
391 | harbaum | 161 | str = g_strdup_printf(_("Relation #" ITEM_ID_FORMAT), |
392 | context->object.relation->id); | ||
393 | harbaum | 153 | user = context->object.relation->user; |
394 | harbaum | 234 | work_copy = osm_tags_copy(context->object.relation->tag); |
395 | harbaum | 153 | stime = context->object.relation->time; |
396 | harbaum | 52 | context->presets_type = PRESETS_TYPE_RELATION; |
397 | harbaum | 153 | break; |
398 | |||
399 | default: | ||
400 | harbaum | 154 | g_assert((context->object.type == NODE) || |
401 | (context->object.type == WAY) || | ||
402 | (context->object.type == RELATION)); | ||
403 | harbaum | 153 | break; |
404 | harbaum | 1 | } |
405 | |||
406 | harbaum | 172 | context->dialog = misc_dialog_new(MISC_DIALOG_LARGE, str, |
407 | harbaum | 167 | GTK_WINDOW(parent), |
408 | harbaum | 1 | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
409 | GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, | ||
410 | NULL); | ||
411 | g_free(str); | ||
412 | |||
413 | gtk_dialog_set_default_response(GTK_DIALOG(context->dialog), | ||
414 | GTK_RESPONSE_ACCEPT); | ||
415 | |||
416 | GtkWidget *label; | ||
417 | GtkWidget *table = gtk_table_new(2, 2, FALSE); // x, y | ||
418 | |||
419 | /* ------------ user ----------------- */ | ||
420 | harbaum | 163 | if(user) { |
421 | label = gtk_label_new(user->name); | ||
422 | gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); | ||
423 | gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); | ||
424 | } | ||
425 | harbaum | 1 | |
426 | /* ------------ time ----------------- */ | ||
427 | |||
428 | struct tm *loctime = localtime(&stime); | ||
429 | char time_str[32]; | ||
430 | strftime(time_str, sizeof(time_str), "%x %X", loctime); | ||
431 | harbaum | 163 | label = gtk_label_new(time_str); |
432 | harbaum | 1 | gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 0, 1); |
433 | |||
434 | /* ------------ coordinate (only for nodes) ----------------- */ | ||
435 | harbaum | 153 | switch(context->object.type) { |
436 | case NODE: { | ||
437 | char pos_str[32]; | ||
438 | harbaum | 154 | pos_lat_str(pos_str, sizeof(pos_str), context->object.node->pos.lat); |
439 | harbaum | 153 | label = gtk_label_new(pos_str); |
440 | gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | ||
441 | harbaum | 154 | pos_lat_str(pos_str, sizeof(pos_str), context->object.node->pos.lon); |
442 | harbaum | 153 | label = gtk_label_new(pos_str); |
443 | gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2); | ||
444 | } break; | ||
445 | harbaum | 154 | |
446 | harbaum | 153 | case WAY: { |
447 | char *nodes_str = g_strdup_printf(_("Length: %u nodes"), | ||
448 | harbaum | 154 | osm_way_number_of_nodes(context->object.way)); |
449 | harbaum | 153 | label = gtk_label_new(nodes_str); |
450 | gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | ||
451 | g_free(nodes_str); | ||
452 | |||
453 | char *type_str = g_strdup_printf("%s (%s)", | ||
454 | harbaum | 154 | (osm_way_get_last_node(context->object.way) == |
455 | osm_way_get_first_node(context->object.way))? | ||
456 | harbaum | 153 | "closed way":"open way", |
457 | harbaum | 154 | (context->object.way->draw.flags & OSM_DRAW_FLAG_AREA)? |
458 | harbaum | 153 | "area":"line"); |
459 | |||
460 | label = gtk_label_new(type_str); | ||
461 | gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2); | ||
462 | g_free(type_str); | ||
463 | } break; | ||
464 | harbaum | 1 | |
465 | harbaum | 153 | case RELATION: { |
466 | harbaum | 1 | /* relations tell something about their members */ |
467 | gint nodes = 0, ways = 0, relations = 0; | ||
468 | harbaum | 153 | member_t *member = context->object.relation->member; |
469 | harbaum | 1 | while(member) { |
470 | harbaum | 155 | switch(member->object.type) { |
471 | harbaum | 1 | case NODE: |
472 | case NODE_ID: | ||
473 | nodes++; | ||
474 | break; | ||
475 | case WAY: | ||
476 | case WAY_ID: | ||
477 | ways++; | ||
478 | break; | ||
479 | case RELATION: | ||
480 | case RELATION_ID: | ||
481 | relations++; | ||
482 | break; | ||
483 | harbaum | 153 | |
484 | harbaum | 1 | default: |
485 | break; | ||
486 | } | ||
487 | |||
488 | member = member->next; | ||
489 | } | ||
490 | |||
491 | harbaum | 155 | char *str = |
492 | g_strdup_printf(_("Members: %d nodes, %d ways, %d relations"), | ||
493 | nodes, ways, relations); | ||
494 | harbaum | 1 | |
495 | harbaum | 155 | GtkWidget *member_btn = gtk_button_new_with_label(str); |
496 | gtk_signal_connect(GTK_OBJECT(member_btn), "clicked", | ||
497 | GTK_SIGNAL_FUNC(on_relation_members), context); | ||
498 | gtk_table_attach_defaults(GTK_TABLE(table), member_btn, 0, 2, 1, 2); | ||
499 | |||
500 | harbaum | 1 | g_free(str); |
501 | harbaum | 153 | break; |
502 | harbaum | 1 | |
503 | harbaum | 153 | default: |
504 | printf("ERROR: No node, way or relation\n"); | ||
505 | g_assert(0); | ||
506 | break; | ||
507 | } } | ||
508 | |||
509 | harbaum | 1 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), table, |
510 | FALSE, FALSE, 0); | ||
511 | |||
512 | |||
513 | /* ------------ tags ----------------- */ | ||
514 | |||
515 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), | ||
516 | tag_widget(context), TRUE, TRUE, 0); | ||
517 | |||
518 | /* ----------------------------------- */ | ||
519 | |||
520 | gtk_widget_show_all(context->dialog); | ||
521 | harbaum | 73 | gboolean ok = FALSE; |
522 | |||
523 | harbaum | 1 | if(gtk_dialog_run(GTK_DIALOG(context->dialog)) == GTK_RESPONSE_ACCEPT) { |
524 | harbaum | 73 | ok = TRUE; |
525 | |||
526 | harbaum | 1 | gtk_widget_destroy(context->dialog); |
527 | |||
528 | harbaum | 153 | /* replace original tags with work copy */ |
529 | switch(context->object.type) { | ||
530 | harbaum | 1 | |
531 | harbaum | 153 | case NODE: |
532 | osm_tags_free(context->object.node->tag); | ||
533 | harbaum | 234 | context->object.node->tag = osm_tags_copy(work_copy); |
534 | harbaum | 153 | break; |
535 | harbaum | 1 | |
536 | harbaum | 153 | case WAY: |
537 | osm_tags_free(context->object.way->tag); | ||
538 | harbaum | 234 | context->object.way->tag = osm_tags_copy(work_copy); |
539 | harbaum | 153 | break; |
540 | harbaum | 1 | |
541 | harbaum | 153 | case RELATION: |
542 | osm_tags_free(context->object.relation->tag); | ||
543 | harbaum | 234 | context->object.relation->tag = osm_tags_copy(work_copy); |
544 | harbaum | 153 | break; |
545 | |||
546 | default: | ||
547 | break; | ||
548 | } | ||
549 | |||
550 | /* since nodes being parts of ways but with no tags are invisible, */ | ||
551 | /* the result of editing them may have changed their visibility */ | ||
552 | if(!object && context->object.type != RELATION) | ||
553 | map_item_redraw(appdata, &appdata->map->selected); | ||
554 | harbaum | 1 | |
555 | harbaum | 153 | osm_object_set_flags(&context->object, OSM_FLAG_DIRTY, 0); |
556 | harbaum | 1 | } else { |
557 | gtk_widget_destroy(context->dialog); | ||
558 | osm_tags_free(work_copy); | ||
559 | } | ||
560 | harbaum | 153 | |
561 | harbaum | 1 | g_free(context); |
562 | harbaum | 73 | return ok; |
563 | harbaum | 1 | } |