61 |
} role_chain_t; |
} role_chain_t; |
62 |
|
|
63 |
static gboolean relation_add_item(GtkWidget *parent, |
static gboolean relation_add_item(GtkWidget *parent, |
64 |
relation_t *relation, object_t *item) { |
relation_t *relation, object_t *object) { |
65 |
role_chain_t *chain = NULL, **chainP = &chain; |
role_chain_t *chain = NULL, **chainP = &chain; |
66 |
|
|
67 |
printf("add item of type %d to relation #%ld\n", |
printf("add object of type %d to relation #%ld\n", |
68 |
item->type, relation->id); |
object->type, relation->id); |
69 |
|
|
70 |
/* ask the user for the role of the new item in this relation */ |
/* ask the user for the role of the new object in this relation */ |
71 |
|
|
72 |
/* collect roles first */ |
/* collect roles first */ |
73 |
member_t *member = relation->member; |
member_t *member = relation->member; |
160 |
member_t **memberP = &relation->member; |
member_t **memberP = &relation->member; |
161 |
while(*memberP) memberP = &(*memberP)->next; |
while(*memberP) memberP = &(*memberP)->next; |
162 |
|
|
163 |
|
g_assert((object->type == NODE)||(object->type == WAY)|| |
164 |
|
(object->type == RELATION)); |
165 |
|
|
166 |
/* create new member */ |
/* create new member */ |
167 |
*memberP = g_new0(member_t, 1); |
*memberP = g_new0(member_t, 1); |
168 |
(*memberP)->type = item->type; |
(*memberP)->object = *object; |
169 |
(*memberP)->role = role; |
(*memberP)->role = role; |
|
switch(item->type) { |
|
|
case NODE: |
|
|
(*memberP)->node = item->node; |
|
|
break; |
|
|
case WAY: |
|
|
(*memberP)->way = item->way; |
|
|
break; |
|
|
case RELATION: |
|
|
(*memberP)->relation = item->relation; |
|
|
break; |
|
|
default: |
|
|
g_assert((item->type == NODE)||(item->type == WAY)|| |
|
|
(item->type == RELATION)); |
|
|
break; |
|
|
} |
|
170 |
|
|
171 |
relation->flags |= OSM_FLAG_DIRTY; |
relation->flags |= OSM_FLAG_DIRTY; |
172 |
return TRUE; |
return TRUE; |
173 |
} |
} |
174 |
|
|
175 |
static void relation_remove_item(relation_t *relation, object_t *item) { |
static void relation_remove_item(relation_t *relation, object_t *object) { |
176 |
|
|
177 |
printf("remove item of type %d from relation #%ld\n", |
printf("remove object of type %d from relation #%ld\n", |
178 |
item->type, relation->id); |
object->type, relation->id); |
179 |
|
|
180 |
member_t **member = &relation->member; |
member_t **member = &relation->member; |
181 |
while(*member) { |
while(*member) { |
182 |
if(((*member)->type == item->type) && |
if(((*member)->object.type == object->type) && |
183 |
(((item->type == NODE) && (item->node == (*member)->node)) || |
(((object->type == NODE) && |
184 |
((item->type == WAY) && (item->way == (*member)->way)) || |
(object->node == (*member)->object.node)) || |
185 |
((item->type == RELATION) && (item->relation == (*member)->relation)))) { |
((object->type == WAY) && |
186 |
|
(object->way == (*member)->object.way)) || |
187 |
|
((object->type == RELATION) && |
188 |
|
(object->relation == (*member)->object.relation)))) { |
189 |
|
|
190 |
member_t *next = (*member)->next; |
member_t *next = (*member)->next; |
191 |
osm_member_free(*member); |
osm_member_free(*member); |
336 |
static char *relitem_get_role_in_relation(object_t *item, relation_t *relation) { |
static char *relitem_get_role_in_relation(object_t *item, relation_t *relation) { |
337 |
member_t *member = relation->member; |
member_t *member = relation->member; |
338 |
while(member) { |
while(member) { |
339 |
switch(member->type) { |
switch(member->object.type) { |
340 |
|
|
341 |
case NODE: |
case NODE: |
342 |
if((item->type == NODE) && (item->node == member->node)) |
if((item->type == NODE) && (item->node == member->object.node)) |
343 |
return member->role; |
return member->role; |
344 |
break; |
break; |
345 |
|
|
346 |
case WAY: |
case WAY: |
347 |
if((item->type == WAY) && (item->way == member->way)) |
if((item->type == WAY) && (item->way == member->object.way)) |
348 |
return member->role; |
return member->role; |
349 |
break; |
break; |
350 |
|
|
398 |
static gboolean relitem_is_in_relation(object_t *item, relation_t *relation) { |
static gboolean relitem_is_in_relation(object_t *item, relation_t *relation) { |
399 |
member_t *member = relation->member; |
member_t *member = relation->member; |
400 |
while(member) { |
while(member) { |
401 |
switch(member->type) { |
switch(member->object.type) { |
402 |
|
|
403 |
case NODE: |
case NODE: |
404 |
if((item->type == NODE) && (item->node == member->node)) |
if((item->type == NODE) && (item->node == member->object.node)) |
405 |
return TRUE; |
return TRUE; |
406 |
break; |
break; |
407 |
|
|
408 |
case WAY: |
case WAY: |
409 |
if((item->type == WAY) && (item->way == member->way)) |
if((item->type == WAY) && (item->way == member->object.way)) |
410 |
return TRUE; |
return TRUE; |
411 |
break; |
break; |
412 |
|
|
604 |
|
|
605 |
member_t *member = NULL; |
member_t *member = NULL; |
606 |
gtk_tree_model_get(model, &iter, MEMBER_COL_DATA, &member, -1); |
gtk_tree_model_get(model, &iter, MEMBER_COL_DATA, &member, -1); |
607 |
if(member && member->type < NODE_ID) |
if(member && member->object.type < NODE_ID) |
608 |
return TRUE; |
return TRUE; |
609 |
} |
} |
610 |
|
|
624 |
/* --- "type" column --- */ |
/* --- "type" column --- */ |
625 |
GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); |
GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); |
626 |
g_object_set(renderer, "foreground", "grey", NULL); |
g_object_set(renderer, "foreground", "grey", NULL); |
627 |
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view), |
GtkTreeViewColumn *column = |
628 |
-1, _("Type"), renderer, "text", MEMBER_COL_TYPE, |
gtk_tree_view_column_new_with_attributes(_("Type"), renderer, |
629 |
"foreground-set", MEMBER_COL_REF_ONLY, NULL); |
"text", MEMBER_COL_TYPE, |
630 |
|
"foreground-set", MEMBER_COL_REF_ONLY, NULL); |
631 |
|
gtk_tree_view_column_set_sort_column_id(column, MEMBER_COL_TYPE); |
632 |
|
gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1); |
633 |
|
|
634 |
/* --- "id" column --- */ |
/* --- "id" column --- */ |
635 |
renderer = gtk_cell_renderer_text_new(); |
renderer = gtk_cell_renderer_text_new(); |
636 |
g_object_set(renderer, "foreground", "grey", NULL); |
g_object_set(renderer, "foreground", "grey", NULL); |
637 |
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view), |
column = gtk_tree_view_column_new_with_attributes(_("Id"), renderer, |
638 |
-1, _("Id"), renderer, "text", MEMBER_COL_ID, |
"text", MEMBER_COL_ID, |
639 |
"foreground-set", MEMBER_COL_REF_ONLY, NULL); |
"foreground-set", MEMBER_COL_REF_ONLY, NULL); |
640 |
|
gtk_tree_view_column_set_sort_column_id(column, MEMBER_COL_ID); |
641 |
|
gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1); |
642 |
|
|
643 |
|
|
644 |
/* --- "Name" column --- */ |
/* --- "Name" column --- */ |
645 |
renderer = gtk_cell_renderer_text_new(); |
renderer = gtk_cell_renderer_text_new(); |
646 |
g_object_set(renderer, "foreground", "grey", NULL); |
g_object_set(renderer, "foreground", "grey", NULL); |
647 |
g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
648 |
GtkTreeViewColumn *column = |
column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, |
|
gtk_tree_view_column_new_with_attributes(_("Name"), renderer, |
|
649 |
"text", MEMBER_COL_NAME, |
"text", MEMBER_COL_NAME, |
650 |
"foreground-set", MEMBER_COL_REF_ONLY, NULL); |
"foreground-set", MEMBER_COL_REF_ONLY, NULL); |
651 |
gtk_tree_view_column_set_expand(column, TRUE); |
gtk_tree_view_column_set_expand(column, TRUE); |
652 |
|
gtk_tree_view_column_set_sort_column_id(column, MEMBER_COL_NAME); |
653 |
gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1); |
gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1); |
654 |
|
|
655 |
/* --- "role" column --- */ |
/* --- "role" column --- */ |
656 |
renderer = gtk_cell_renderer_text_new(); |
renderer = gtk_cell_renderer_text_new(); |
657 |
g_object_set(renderer, "foreground", "grey", NULL); |
g_object_set(renderer, "foreground", "grey", NULL); |
658 |
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view), |
column = gtk_tree_view_column_new_with_attributes(_("Role"), renderer, |
659 |
-1, _("Role"), renderer, "text", MEMBER_COL_ROLE, |
"text", MEMBER_COL_ROLE, |
660 |
"foreground-set", MEMBER_COL_REF_ONLY, NULL); |
"foreground-set", MEMBER_COL_REF_ONLY, NULL); |
661 |
|
gtk_tree_view_column_set_sort_column_id(column, MEMBER_COL_ROLE); |
662 |
|
gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1); |
663 |
|
|
664 |
|
|
665 |
/* build and fill the store */ |
/* build and fill the store */ |
666 |
context->store = gtk_list_store_new(MEMBER_NUM_COLS, |
context->store = gtk_list_store_new(MEMBER_NUM_COLS, |
673 |
GtkTreeIter iter; |
GtkTreeIter iter; |
674 |
member_t *member = context->relation->member; |
member_t *member = context->relation->member; |
675 |
while(member) { |
while(member) { |
676 |
tag_t *tags = osm_object_get_tags(member->type, member->ptr); |
tag_t *tags = osm_object_get_tags(&member->object); |
677 |
char *id = osm_id_string(member->type, member->ptr); |
char *id = osm_object_id_string(&member->object); |
678 |
|
|
679 |
/* try to find something descriptive */ |
/* try to find something descriptive */ |
680 |
char *name = NULL; |
char *name = NULL; |
684 |
/* Append a row and fill in some data */ |
/* Append a row and fill in some data */ |
685 |
gtk_list_store_append(context->store, &iter); |
gtk_list_store_append(context->store, &iter); |
686 |
gtk_list_store_set(context->store, &iter, |
gtk_list_store_set(context->store, &iter, |
687 |
MEMBER_COL_TYPE, osm_type_string(member->type), |
MEMBER_COL_TYPE, osm_object_type_string(&member->object), |
688 |
MEMBER_COL_ID, id, |
MEMBER_COL_ID, id, |
689 |
MEMBER_COL_NAME, name, |
MEMBER_COL_NAME, name, |
690 |
MEMBER_COL_ROLE, member->role, |
MEMBER_COL_ROLE, member->role, |
691 |
MEMBER_COL_REF_ONLY, member->type >= NODE_ID, |
MEMBER_COL_REF_ONLY, member->object.type >= NODE_ID, |
692 |
MEMBER_COL_DATA, member, |
MEMBER_COL_DATA, member, |
693 |
-1); |
-1); |
694 |
|
|
711 |
return vbox; |
return vbox; |
712 |
} |
} |
713 |
|
|
714 |
/* user clicked "members..." button in relation list */ |
void relation_show_members(GtkWidget *parent, relation_t *relation) { |
|
static void on_relation_members(GtkWidget *but, relation_context_t *context) { |
|
715 |
member_context_t *mcontext = g_new0(member_context_t, 1); |
member_context_t *mcontext = g_new0(member_context_t, 1); |
716 |
|
mcontext->relation = relation; |
|
/* display members list */ |
|
|
mcontext->relation = get_selected_relation(context); |
|
|
if(!mcontext->relation) return; |
|
717 |
|
|
718 |
char *str = osm_tag_get_by_key(mcontext->relation->tag, "name"); |
char *str = osm_tag_get_by_key(mcontext->relation->tag, "name"); |
719 |
if(!str) str = osm_tag_get_by_key(mcontext->relation->tag, "ref"); |
if(!str) str = osm_tag_get_by_key(mcontext->relation->tag, "ref"); |
725 |
|
|
726 |
mcontext->dialog = |
mcontext->dialog = |
727 |
gtk_dialog_new_with_buttons(str, |
gtk_dialog_new_with_buttons(str, |
728 |
GTK_WINDOW(context->dialog), GTK_DIALOG_MODAL, |
GTK_WINDOW(parent), GTK_DIALOG_MODAL, |
729 |
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, |
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, |
730 |
NULL); |
NULL); |
731 |
g_free(str); |
g_free(str); |
749 |
g_free(mcontext); |
g_free(mcontext); |
750 |
} |
} |
751 |
|
|
752 |
|
/* user clicked "members..." button in relation list */ |
753 |
|
static void on_relation_members(GtkWidget *but, relation_context_t *context) { |
754 |
|
relation_t *sel = get_selected_relation(context); |
755 |
|
|
756 |
|
if(sel) |
757 |
|
relation_show_members(context->dialog, sel); |
758 |
|
} |
759 |
|
|
760 |
|
|
761 |
static void on_relation_add(GtkWidget *but, relation_context_t *context) { |
static void on_relation_add(GtkWidget *but, relation_context_t *context) { |
762 |
/* create a new relation */ |
/* create a new relation */ |
763 |
|
|