38 |
RELITEM_NUM_COLS |
RELITEM_NUM_COLS |
39 |
}; |
}; |
40 |
|
|
|
static void relation_list_selected(relitem_context_t *context, |
|
|
gboolean selected) { |
|
|
|
|
|
if(context->but_remove) |
|
|
gtk_widget_set_sensitive(context->but_remove, FALSE); |
|
|
if(context->but_edit) |
|
|
gtk_widget_set_sensitive(context->but_edit, selected); |
|
|
} |
|
|
|
|
|
static gboolean |
|
|
relation_list_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, |
|
|
GtkTreePath *path, gboolean path_currently_selected, |
|
|
gpointer userdata) { |
|
|
relitem_context_t *context = (relitem_context_t*)userdata; |
|
|
GtkTreeIter iter; |
|
|
|
|
|
if(gtk_tree_model_get_iter(model, &iter, path)) { |
|
|
printf("selected an entry on the list\n"); |
|
|
|
|
|
g_assert(gtk_tree_path_get_depth(path) == 1); |
|
|
relation_list_selected(context, TRUE); |
|
|
} |
|
|
|
|
|
return TRUE; /* allow selection state to change */ |
|
|
} |
|
|
|
|
|
static void relation_remove_item(relation_t *relation, relation_item_t *item) { |
|
|
|
|
|
printf("remove item of type %d from relation #%ld\n", |
|
|
item->type, relation->id); |
|
|
|
|
|
member_t **member = &relation->member; |
|
|
while(*member) { |
|
|
if(((*member)->type == item->type) && |
|
|
(((item->type == NODE) && (item->node == (*member)->node)) || |
|
|
((item->type == WAY) && (item->way == (*member)->way)) || |
|
|
((item->type == RELATION) && (item->relation == (*member)->relation)))) { |
|
|
|
|
|
member_t *next = (*member)->next; |
|
|
osm_member_free(*member); |
|
|
*member = next; |
|
|
|
|
|
relation->flags |= OSM_FLAG_DIRTY; |
|
|
|
|
|
return; |
|
|
} else |
|
|
member = &(*member)->next; |
|
|
} |
|
|
g_assert(0); |
|
|
} |
|
|
|
|
41 |
typedef struct role_chain_s { |
typedef struct role_chain_s { |
42 |
char *role; |
char *role; |
43 |
struct role_chain_s *next; |
struct role_chain_s *next; |
44 |
} role_chain_t; |
} role_chain_t; |
45 |
|
|
46 |
static void relation_add_item(GtkWidget *parent, |
static gboolean relation_add_item(GtkWidget *parent, |
47 |
relation_t *relation, relation_item_t *item) { |
relation_t *relation, relation_item_t *item) { |
48 |
role_chain_t *chain = NULL, **chainP = &chain; |
role_chain_t *chain = NULL, **chainP = &chain; |
49 |
|
|
121 |
if(GTK_RESPONSE_ACCEPT != gtk_dialog_run(GTK_DIALOG(dialog))) { |
if(GTK_RESPONSE_ACCEPT != gtk_dialog_run(GTK_DIALOG(dialog))) { |
122 |
printf("user clicked cancel\n"); |
printf("user clicked cancel\n"); |
123 |
gtk_widget_destroy(dialog); |
gtk_widget_destroy(dialog); |
124 |
return; |
return FALSE; |
125 |
} |
} |
126 |
|
|
127 |
printf("user clicked ok\n"); |
printf("user clicked ok\n"); |
164 |
} |
} |
165 |
|
|
166 |
relation->flags |= OSM_FLAG_DIRTY; |
relation->flags |= OSM_FLAG_DIRTY; |
167 |
|
return TRUE; |
168 |
|
} |
169 |
|
|
170 |
|
static void relation_remove_item(relation_t *relation, relation_item_t *item) { |
171 |
|
|
172 |
|
printf("remove item of type %d from relation #%ld\n", |
173 |
|
item->type, relation->id); |
174 |
|
|
175 |
|
member_t **member = &relation->member; |
176 |
|
while(*member) { |
177 |
|
if(((*member)->type == item->type) && |
178 |
|
(((item->type == NODE) && (item->node == (*member)->node)) || |
179 |
|
((item->type == WAY) && (item->way == (*member)->way)) || |
180 |
|
((item->type == RELATION) && (item->relation == (*member)->relation)))) { |
181 |
|
|
182 |
|
member_t *next = (*member)->next; |
183 |
|
osm_member_free(*member); |
184 |
|
*member = next; |
185 |
|
|
186 |
|
relation->flags |= OSM_FLAG_DIRTY; |
187 |
|
|
188 |
|
return; |
189 |
|
} else |
190 |
|
member = &(*member)->next; |
191 |
|
} |
192 |
|
g_assert(0); |
193 |
|
} |
194 |
|
|
195 |
|
static void relation_list_selected(relitem_context_t *context, |
196 |
|
gboolean selected) { |
197 |
|
|
198 |
|
if(context->but_remove) |
199 |
|
gtk_widget_set_sensitive(context->but_remove, FALSE); |
200 |
|
if(context->but_edit) |
201 |
|
gtk_widget_set_sensitive(context->but_edit, selected); |
202 |
|
} |
203 |
|
|
204 |
|
static gboolean |
205 |
|
relation_list_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, |
206 |
|
GtkTreePath *path, gboolean path_currently_selected, |
207 |
|
gpointer userdata) { |
208 |
|
relitem_context_t *context = (relitem_context_t*)userdata; |
209 |
|
GtkTreeIter iter; |
210 |
|
|
211 |
|
if(gtk_tree_model_get_iter(model, &iter, path)) { |
212 |
|
g_assert(gtk_tree_path_get_depth(path) == 1); |
213 |
|
relation_list_selected(context, TRUE); |
214 |
|
} |
215 |
|
|
216 |
|
return TRUE; /* allow selection state to change */ |
217 |
} |
} |
218 |
|
|
219 |
static void on_relation_add(GtkWidget *but, relitem_context_t *context) { |
static void on_relation_add(GtkWidget *but, relitem_context_t *context) { |
220 |
/* open a dialog where the user can pick from a list of all */ |
/* create a new relation */ |
221 |
/* relations */ |
|
222 |
|
relation_t *relation = osm_relation_new(); |
223 |
|
if(!info_dialog(context->dialog, context->appdata, relation)) { |
224 |
|
printf("tag edit cancelled\n"); |
225 |
|
osm_relation_free(relation); |
226 |
|
} else { |
227 |
|
osm_relation_attach(context->appdata->osm, relation); |
228 |
|
|
229 |
|
/* add to list */ |
230 |
|
|
231 |
|
/* append a row for the new data */ |
232 |
|
/* try to find something descriptive */ |
233 |
|
char *name = osm_tag_get_by_key(relation->tag, "name"); |
234 |
|
if(!name) name = osm_tag_get_by_key(relation->tag, "ref"); |
235 |
|
|
236 |
|
GtkTreeIter iter; |
237 |
|
gtk_list_store_append(context->store, &iter); |
238 |
|
gtk_list_store_set(context->store, &iter, |
239 |
|
RELITEM_COL_SELECTED, FALSE, |
240 |
|
RELITEM_COL_TYPE, |
241 |
|
osm_tag_get_by_key(relation->tag, "type"), |
242 |
|
RELITEM_COL_NAME, name, |
243 |
|
RELITEM_COL_DATA, relation, |
244 |
|
-1); |
245 |
|
|
246 |
|
gtk_tree_selection_select_iter(gtk_tree_view_get_selection( |
247 |
|
GTK_TREE_VIEW(context->view)), &iter); |
248 |
|
|
249 |
|
/* scroll to end */ |
250 |
|
// GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment(); |
251 |
|
/* xyz */ |
252 |
|
} |
253 |
} |
} |
254 |
|
|
255 |
static relation_t *get_selection(relitem_context_t *context) { |
static relation_t *get_selection(relitem_context_t *context) { |
282 |
printf("remove relation #%ld\n", sel->id); |
printf("remove relation #%ld\n", sel->id); |
283 |
} |
} |
284 |
|
|
285 |
static void |
static char *relitem_get_role_in_relation(relation_item_t *item, relation_t *relation) { |
|
relitem_toggled(GtkCellRendererToggle *cell, const gchar *path_str, |
|
|
relitem_context_t *context) { |
|
|
GtkTreePath *path; |
|
|
GtkTreeIter iter; |
|
|
|
|
|
path = gtk_tree_path_new_from_string(path_str); |
|
|
gtk_tree_model_get_iter(GTK_TREE_MODEL(context->store), &iter, path); |
|
|
|
|
|
/* get current enabled flag */ |
|
|
gboolean enabled; |
|
|
gtk_tree_model_get(GTK_TREE_MODEL(context->store), &iter, |
|
|
RELITEM_COL_SELECTED, &enabled, -1); |
|
|
|
|
|
/* change it and store it */ |
|
|
enabled = !enabled; |
|
|
gtk_list_store_set(context->store, &iter, RELITEM_COL_SELECTED, enabled, -1); |
|
|
|
|
|
gtk_tree_path_free(path); |
|
|
} |
|
|
|
|
|
static gboolean relitem_is_in_relation(relation_item_t *item, relation_t *relation) { |
|
286 |
member_t *member = relation->member; |
member_t *member = relation->member; |
287 |
while(member) { |
while(member) { |
288 |
switch(member->type) { |
switch(member->type) { |
289 |
|
|
290 |
case NODE: |
case NODE: |
291 |
if((item->type == NODE) && (item->node == member->node)) |
if((item->type == NODE) && (item->node == member->node)) |
292 |
return TRUE; |
return member->role; |
293 |
break; |
break; |
294 |
|
|
295 |
case WAY: |
case WAY: |
296 |
if((item->type == WAY) && (item->way == member->way)) |
if((item->type == WAY) && (item->way == member->way)) |
297 |
return TRUE; |
return member->role; |
298 |
break; |
break; |
299 |
|
|
300 |
default: |
default: |
302 |
} |
} |
303 |
member = member->next; |
member = member->next; |
304 |
} |
} |
305 |
return FALSE; |
return NULL; |
306 |
} |
} |
307 |
|
|
308 |
static char *relitem_get_role_in_relation(relation_item_t *item, relation_t *relation) { |
static void |
309 |
|
relitem_toggled(GtkCellRendererToggle *cell, const gchar *path_str, |
310 |
|
relitem_context_t *context) { |
311 |
|
GtkTreePath *path; |
312 |
|
GtkTreeIter iter; |
313 |
|
|
314 |
|
path = gtk_tree_path_new_from_string(path_str); |
315 |
|
gtk_tree_model_get_iter(GTK_TREE_MODEL(context->store), &iter, path); |
316 |
|
gtk_tree_path_free(path); |
317 |
|
|
318 |
|
/* get current enabled flag */ |
319 |
|
gboolean enabled; |
320 |
|
relation_t *relation = NULL; |
321 |
|
gtk_tree_model_get(GTK_TREE_MODEL(context->store), &iter, |
322 |
|
RELITEM_COL_SELECTED, &enabled, |
323 |
|
RELITEM_COL_DATA, &relation, |
324 |
|
-1); |
325 |
|
|
326 |
|
if(!enabled) { |
327 |
|
printf("will now become be part of this relation\n"); |
328 |
|
if(relation_add_item(context->dialog, relation, context->item)) |
329 |
|
gtk_list_store_set(context->store, &iter, |
330 |
|
RELITEM_COL_SELECTED, TRUE, |
331 |
|
RELITEM_COL_ROLE, |
332 |
|
relitem_get_role_in_relation(context->item, relation), |
333 |
|
-1); |
334 |
|
} else { |
335 |
|
printf("item will not be part of this relation anymore\n"); |
336 |
|
relation_remove_item(relation, context->item); |
337 |
|
gtk_list_store_set(context->store, &iter, |
338 |
|
RELITEM_COL_SELECTED, FALSE, |
339 |
|
RELITEM_COL_ROLE, NULL, |
340 |
|
-1); |
341 |
|
} |
342 |
|
} |
343 |
|
|
344 |
|
static gboolean relitem_is_in_relation(relation_item_t *item, relation_t *relation) { |
345 |
member_t *member = relation->member; |
member_t *member = relation->member; |
346 |
while(member) { |
while(member) { |
347 |
switch(member->type) { |
switch(member->type) { |
348 |
|
|
349 |
case NODE: |
case NODE: |
350 |
if((item->type == NODE) && (item->node == member->node)) |
if((item->type == NODE) && (item->node == member->node)) |
351 |
return member->role; |
return TRUE; |
352 |
break; |
break; |
353 |
|
|
354 |
case WAY: |
case WAY: |
355 |
if((item->type == WAY) && (item->way == member->way)) |
if((item->type == WAY) && (item->way == member->way)) |
356 |
return member->role; |
return TRUE; |
357 |
break; |
break; |
358 |
|
|
359 |
default: |
default: |
361 |
} |
} |
362 |
member = member->next; |
member = member->next; |
363 |
} |
} |
364 |
return NULL; |
return FALSE; |
365 |
} |
} |
366 |
|
|
367 |
static GtkWidget *relation_list(relitem_context_t *context) { |
static GtkWidget *relation_list(relitem_context_t *context) { |
447 |
GtkWidget *hbox = gtk_hbox_new(TRUE,3); |
GtkWidget *hbox = gtk_hbox_new(TRUE,3); |
448 |
|
|
449 |
context->but_add = gtk_button_new_with_label(_("Add...")); |
context->but_add = gtk_button_new_with_label(_("Add...")); |
450 |
gtk_widget_set_sensitive(context->but_add, FALSE); |
// gtk_widget_set_sensitive(context->but_add, FALSE); |
451 |
gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_add); |
gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_add); |
452 |
gtk_signal_connect(GTK_OBJECT(context->but_add), "clicked", |
gtk_signal_connect(GTK_OBJECT(context->but_add), "clicked", |
453 |
GTK_SIGNAL_FUNC(on_relation_add), context); |
GTK_SIGNAL_FUNC(on_relation_add), context); |
491 |
|
|
492 |
context->dialog = gtk_dialog_new_with_buttons(str, |
context->dialog = gtk_dialog_new_with_buttons(str, |
493 |
GTK_WINDOW(appdata->window), GTK_DIALOG_MODAL, |
GTK_WINDOW(appdata->window), GTK_DIALOG_MODAL, |
494 |
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, |
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, |
|
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, |
|
495 |
NULL); |
NULL); |
496 |
g_free(str); |
g_free(str); |
497 |
|
|
510 |
/* ----------------------------------- */ |
/* ----------------------------------- */ |
511 |
|
|
512 |
gtk_widget_show_all(context->dialog); |
gtk_widget_show_all(context->dialog); |
513 |
if(gtk_dialog_run(GTK_DIALOG(context->dialog)) == GTK_RESPONSE_ACCEPT) { |
gtk_dialog_run(GTK_DIALOG(context->dialog)); |
|
printf("accepting new relation memberships\n"); |
|
|
|
|
|
/* walk the entire store to get all values */ |
|
|
GtkTreeIter iter; |
|
|
gboolean loop = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(context->store), &iter); |
|
|
while(loop) { |
|
|
gboolean enabled; |
|
|
relation_t *relation; |
|
|
|
|
|
gtk_tree_model_get(GTK_TREE_MODEL(context->store), &iter, |
|
|
RELITEM_COL_SELECTED, &enabled, |
|
|
RELITEM_COL_DATA, &relation, |
|
|
-1); |
|
|
|
|
|
|
|
|
if(relation && (enabled != relitem_is_in_relation(relitem, relation))) { |
|
|
printf("membership for relation #%ld has changed to %s\n", |
|
|
relation->id, enabled?"yes":"no"); |
|
|
|
|
|
if(!enabled) relation_remove_item(relation, relitem); |
|
|
else relation_add_item(context->dialog, relation, relitem); |
|
|
} |
|
|
|
|
|
loop = gtk_tree_model_iter_next(GTK_TREE_MODEL(context->store), &iter); |
|
|
} |
|
|
} |
|
|
|
|
514 |
gtk_widget_destroy(context->dialog); |
gtk_widget_destroy(context->dialog); |
515 |
|
|
516 |
g_free(context); |
g_free(context); |