Diff of /trunk/src/relation_edit.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 76 by harbaum, Fri Feb 13 12:02:26 2009 UTC revision 191 by harbaum, Tue Jul 7 07:36:27 2009 UTC
# Line 22  Line 22 
22  /* --------------- relation dialog for an item (node or way) ----------- */  /* --------------- relation dialog for an item (node or way) ----------- */
23    
24  typedef struct {  typedef struct {
25    relation_item_t *item;    object_t *item;
26    appdata_t *appdata;    appdata_t *appdata;
27    GtkWidget *dialog, *view;    GtkWidget *dialog, *list;
28    GtkListStore *store;    GtkListStore *store;
   GtkWidget *but_add, *but_edit, *but_remove;  
29  } relitem_context_t;  } relitem_context_t;
30    
31  enum {  enum {
# Line 44  typedef struct role_chain_s { Line 43  typedef struct role_chain_s {
43  } role_chain_t;  } role_chain_t;
44    
45  static gboolean relation_add_item(GtkWidget *parent,  static gboolean relation_add_item(GtkWidget *parent,
46                                relation_t *relation, relation_item_t *item) {                                relation_t *relation, object_t *object) {
47    role_chain_t *chain = NULL, **chainP = &chain;    role_chain_t *chain = NULL, **chainP = &chain;
48    
49    printf("add item of type %d to relation #%ld\n",    printf("add object of type %d to relation #" ITEM_ID_FORMAT "\n",
50           item->type, relation->id);           object->type, relation->id);
51    
52    /* 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 */
53    
54    /* collect roles first */    /* collect roles first */
55    member_t *member = relation->member;    member_t *member = relation->member;
# Line 75  static gboolean relation_add_item(GtkWid Line 74  static gboolean relation_add_item(GtkWid
74    }    }
75    
76    /* ------------------ role dialog ---------------- */    /* ------------------ role dialog ---------------- */
77    GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Select role"),    GtkWidget *dialog =
78            GTK_WINDOW(parent), GTK_DIALOG_MODAL,      misc_dialog_new(MISC_DIALOG_NOSIZE,_("Select role"),
79            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,                      GTK_WINDOW(parent),
80            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,                      GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
81            NULL);                      GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
82                        NULL);
83    
84    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
85    
# Line 87  static gboolean relation_add_item(GtkWid Line 87  static gboolean relation_add_item(GtkWid
87    
88    char *info_str = NULL;    char *info_str = NULL;
89    if(type) info_str = g_strdup_printf(_("In relation of type: %s"), type);    if(type) info_str = g_strdup_printf(_("In relation of type: %s"), type);
90    else     info_str = g_strdup_printf(_("In relation #%ld"), relation->id);    else     info_str = g_strdup_printf(_("In relation #" ITEM_ID_FORMAT),
91                                          relation->id);
92    gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox),    gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox),
93                                gtk_label_new(info_str));                                gtk_label_new(info_str));
94    g_free(info_str);    g_free(info_str);
# Line 143  static gboolean relation_add_item(GtkWid Line 144  static gboolean relation_add_item(GtkWid
144    member_t **memberP = &relation->member;    member_t **memberP = &relation->member;
145    while(*memberP) memberP = &(*memberP)->next;    while(*memberP) memberP = &(*memberP)->next;
146    
147      g_assert((object->type == NODE)||(object->type == WAY)||
148               (object->type == RELATION));
149    
150    /* create new member */    /* create new member */
151    *memberP = g_new0(member_t, 1);    *memberP = g_new0(member_t, 1);
152    (*memberP)->type = item->type;    (*memberP)->object = *object;
153    (*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;  
   }  
154    
155    relation->flags |= OSM_FLAG_DIRTY;    relation->flags |= OSM_FLAG_DIRTY;
156    return TRUE;    return TRUE;
157  }  }
158    
159  static void relation_remove_item(relation_t *relation, relation_item_t *item) {  static void relation_remove_item(relation_t *relation, object_t *object) {
160    
161    printf("remove item of type %d from relation #%ld\n",    printf("remove object of type %d from relation #" ITEM_ID_FORMAT "\n",
162           item->type, relation->id);           object->type, relation->id);
163    
164    member_t **member = &relation->member;    member_t **member = &relation->member;
165    while(*member) {    while(*member) {
166      if(((*member)->type == item->type) &&      if(((*member)->object.type == object->type) &&
167         (((item->type == NODE) && (item->node == (*member)->node)) ||         (((object->type == NODE) &&
168          ((item->type == WAY) && (item->way == (*member)->way)) ||           (object->node == (*member)->object.node)) ||
169        ((item->type == RELATION) && (item->relation == (*member)->relation)))) {          ((object->type == WAY) &&
170             (object->way == (*member)->object.way)) ||
171            ((object->type == RELATION) &&
172             (object->relation == (*member)->object.relation)))) {
173    
174        member_t *next = (*member)->next;        member_t *next = (*member)->next;
175        osm_member_free(*member);        osm_member_free(*member);
# Line 195  static void relation_remove_item(relatio Line 187  static void relation_remove_item(relatio
187  static void relation_item_list_selected(relitem_context_t *context,  static void relation_item_list_selected(relitem_context_t *context,
188                                     gboolean selected) {                                     gboolean selected) {
189    
190    if(context->but_remove)    list_button_enable(context->list, LIST_BUTTON_REMOVE, selected);
191      gtk_widget_set_sensitive(context->but_remove, selected);    list_button_enable(context->list, LIST_BUTTON_EDIT, selected);
   if(context->but_edit)  
     gtk_widget_set_sensitive(context->but_edit, selected);  
192  }  }
193    
194  static gboolean  /* try to find something descriptive */
195  relation_item_list_selection_func(GtkTreeSelection *selection, GtkTreeModel *model,  static char *relation_get_descriptive_name(relation_t *relation) {
196                       GtkTreePath *path, gboolean path_currently_selected,    char *name = osm_tag_get_by_key(relation->tag, "ref");
197                       gpointer userdata) {    if (!name)
198    relitem_context_t *context = (relitem_context_t*)userdata;      name = osm_tag_get_by_key(relation->tag, "name");
199    GtkTreeIter iter;    if (!name)
200        name = osm_tag_get_by_key(relation->tag, "note");
201    if(gtk_tree_model_get_iter(model, &iter, path)) {    if (!name)
202      g_assert(gtk_tree_path_get_depth(path) == 1);      name = osm_tag_get_by_key(relation->tag, "fix" "me");
203      relation_item_list_selected(context, TRUE);    return name;
204    }  }
205    
206    return TRUE; /* allow selection state to change */  static gboolean relation_info_dialog(GtkWidget *parent, appdata_t *appdata,
207  }                                       relation_t *relation) {
208    
209      object_t object = { .type = RELATION };
210      object.relation = relation;
211      return info_dialog(parent, appdata, &object);
212    }
213    
214  static void on_relation_item_add(GtkWidget *but, relitem_context_t *context) {  static void on_relation_item_add(GtkWidget *but, relitem_context_t *context) {
215    /* create a new relation */    /* create a new relation */
216    
217    relation_t *relation = osm_relation_new();    relation_t *relation = osm_relation_new();
218    if(!info_dialog(context->dialog, context->appdata, relation)) {    if(!relation_info_dialog(context->dialog, context->appdata, relation)) {
219      printf("tag edit cancelled\n");      printf("tag edit cancelled\n");
220      osm_relation_free(relation);      osm_relation_free(relation);
221    } else {    } else {
# Line 229  static void on_relation_item_add(GtkWidg Line 224  static void on_relation_item_add(GtkWidg
224      /* add to list */      /* add to list */
225    
226      /* append a row for the new data */      /* append a row for the new data */
227      /* try to find something descriptive */      char *name = relation_get_descriptive_name(relation);
     char *name = osm_tag_get_by_key(relation->tag, "name");  
     if(!name) name = osm_tag_get_by_key(relation->tag, "ref");  
228    
229      GtkTreeIter iter;      GtkTreeIter iter;
230      gtk_list_store_append(context->store, &iter);      gtk_list_store_append(context->store, &iter);
# Line 243  static void on_relation_item_add(GtkWidg Line 236  static void on_relation_item_add(GtkWidg
236                         RELITEM_COL_DATA, relation,                         RELITEM_COL_DATA, relation,
237                         -1);                         -1);
238    
239      gtk_tree_selection_select_iter(gtk_tree_view_get_selection(      gtk_tree_selection_select_iter(list_get_selection(context->list), &iter);
                GTK_TREE_VIEW(context->view)), &iter);  
   
     /* scroll to end */  
     //    GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment();  
     /* xyz */  
240    }    }
241  }  }
242    
# Line 257  static relation_t *get_selection(relitem Line 245  static relation_t *get_selection(relitem
245    GtkTreeModel     *model;    GtkTreeModel     *model;
246    GtkTreeIter       iter;    GtkTreeIter       iter;
247    
248    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view));    selection = list_get_selection(context->list);
249    if(gtk_tree_selection_get_selected(selection, &model, &iter)) {    if(gtk_tree_selection_get_selected(selection, &model, &iter)) {
250      relation_t *relation;      relation_t *relation;
251      gtk_tree_model_get(model, &iter, RELITEM_COL_DATA, &relation, -1);      gtk_tree_model_get(model, &iter, RELITEM_COL_DATA, &relation, -1);
# Line 270  static void on_relation_item_edit(GtkWid Line 258  static void on_relation_item_edit(GtkWid
258    relation_t *sel = get_selection(context);    relation_t *sel = get_selection(context);
259    if(!sel) return;    if(!sel) return;
260    
261    printf("edit relation #%ld\n", sel->id);    printf("edit relation item #" ITEM_ID_FORMAT "\n", sel->id);
262    
263      if (!relation_info_dialog(context->dialog, context->appdata, sel))
264        return;
265    
266      // Locate the changed item
267      GtkTreeIter iter;
268      gboolean valid = gtk_tree_model_get_iter_first(
269        GTK_TREE_MODEL(context->store), &iter);
270      while (valid) {
271        relation_t *row_rel;
272        gtk_tree_model_get(GTK_TREE_MODEL(context->store), &iter,
273                           RELITEM_COL_DATA, &row_rel,
274                           -1);
275        if (row_rel == sel)
276          break;
277        valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(context->store), &iter);
278      }
279      if (!valid)
280        return;
281    
282    info_dialog(context->dialog, context->appdata, sel);    // Found it. Update all visible fields that belong to the relation iself.
283      gtk_list_store_set(context->store, &iter,
284        RELITEM_COL_TYPE,    osm_tag_get_by_key(sel->tag, "type"),
285        RELITEM_COL_NAME,    relation_get_descriptive_name(sel),
286        -1);
287    
288      // Order will probably have changed, so refocus
289      list_focus_on(context->list, &iter, TRUE);
290  }  }
291    
292  /* remove the selected relation */  /* remove the selected relation */
# Line 280  static void on_relation_item_remove(GtkW Line 294  static void on_relation_item_remove(GtkW
294    relation_t *sel = get_selection(context);    relation_t *sel = get_selection(context);
295    if(!sel) return;    if(!sel) return;
296    
297    printf("remove relation #%ld\n", sel->id);    printf("remove relation #" ITEM_ID_FORMAT "\n", sel->id);
298    
299    int members = 0;    gint members = osm_relation_members_num(sel);
   member_t *member = sel->member;  
   while(member) {  
     members++;  
     member = member->next;  
   }  
300    
301    if(members)    if(members)
302      if(!yes_no_f(context->dialog, NULL, 0, 0,      if(!yes_no_f(context->dialog, NULL, 0, 0,
# Line 298  static void on_relation_item_remove(GtkW Line 307  static void on_relation_item_remove(GtkW
307    
308    /* first remove selected row from list */    /* first remove selected row from list */
309    GtkTreeIter       iter;    GtkTreeIter       iter;
310    GtkTreeSelection *selection =    GtkTreeSelection *selection = list_get_selection(context->list);
     gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view));  
311    if(gtk_tree_selection_get_selected(selection, NULL, &iter))    if(gtk_tree_selection_get_selected(selection, NULL, &iter))
312      gtk_list_store_remove(context->store, &iter);      gtk_list_store_remove(context->store, &iter);
313    
# Line 309  static void on_relation_item_remove(GtkW Line 317  static void on_relation_item_remove(GtkW
317    relation_item_list_selected(context, FALSE);    relation_item_list_selected(context, FALSE);
318  }  }
319    
320  static char *relitem_get_role_in_relation(relation_item_t *item, relation_t *relation) {  static char *relitem_get_role_in_relation(object_t *item, relation_t *relation) {
321    member_t *member = relation->member;    member_t *member = relation->member;
322    while(member) {    while(member) {
323      switch(member->type) {      switch(member->object.type) {
324    
325      case NODE:      case NODE:
326        if((item->type == NODE) && (item->node == member->node))        if((item->type == NODE) && (item->node == member->object.node))
327          return member->role;          return member->role;
328        break;        break;
329    
330      case WAY:      case WAY:
331        if((item->type == WAY) && (item->way == member->way))        if((item->type == WAY) && (item->way == member->object.way))
332          return member->role;          return member->role;
333        break;        break;
334    
# Line 350  relitem_toggled(GtkCellRendererToggle *c Line 358  relitem_toggled(GtkCellRendererToggle *c
358                       RELITEM_COL_DATA, &relation,                       RELITEM_COL_DATA, &relation,
359                       -1);                       -1);
360    
361      list_pre_inplace_edit_tweak(GTK_TREE_MODEL(context->store));
362    
363    if(!enabled) {    if(!enabled) {
364      printf("will now become be part of this relation\n");      printf("will now become be part of this relation\n");
365      if(relation_add_item(context->dialog, relation, context->item))      if(relation_add_item(context->dialog, relation, context->item))
# Line 366  relitem_toggled(GtkCellRendererToggle *c Line 376  relitem_toggled(GtkCellRendererToggle *c
376                         RELITEM_COL_ROLE, NULL,                         RELITEM_COL_ROLE, NULL,
377                         -1);                         -1);
378    }    }
379    
380  }  }
381    
382  static gboolean relitem_is_in_relation(relation_item_t *item, relation_t *relation) {  static gboolean relitem_is_in_relation(object_t *item, relation_t *relation) {
383    member_t *member = relation->member;    member_t *member = relation->member;
384    while(member) {    while(member) {
385      switch(member->type) {      switch(member->object.type) {
386    
387      case NODE:      case NODE:
388        if((item->type == NODE) && (item->node == member->node))        if((item->type == NODE) && (item->node == member->object.node))
389          return TRUE;          return TRUE;
390        break;        break;
391    
392      case WAY:      case WAY:
393        if((item->type == WAY) && (item->way == member->way))        if((item->type == WAY) && (item->way == member->object.way))
394          return TRUE;          return TRUE;
395        break;        break;
396    
# Line 392  static gboolean relitem_is_in_relation(r Line 403  static gboolean relitem_is_in_relation(r
403  }  }
404    
405  static GtkWidget *relation_item_list_widget(relitem_context_t *context) {  static GtkWidget *relation_item_list_widget(relitem_context_t *context) {
406    GtkWidget *vbox = gtk_vbox_new(FALSE,3);    context->list = list_new(LIST_HILDON_WITH_HEADERS);
   context->view = gtk_tree_view_new();  
   
   gtk_tree_selection_set_select_function(  
          gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view)),  
          relation_item_list_selection_func,  
          context, NULL);  
   
   
   /* --- "selected" column --- */  
   GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();  
   g_signal_connect(renderer, "toggled", G_CALLBACK(relitem_toggled), context);  
   gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),  
         -1, _(""), renderer,  
         "active", RELITEM_COL_SELECTED,  
         NULL);  
   
   /* --- "Type" column --- */  
   renderer = gtk_cell_renderer_text_new();  
   gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),  
         -1, _("Type"), renderer, "text", RELITEM_COL_TYPE, NULL);  
   
   /* --- "Role" column --- */  
   renderer = gtk_cell_renderer_text_new();  
   gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),  
         -1, _("Role"), renderer, "text", RELITEM_COL_ROLE, NULL);  
   
   /* --- "Name" column --- */  
   renderer = gtk_cell_renderer_text_new();  
   g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);  
   GtkTreeViewColumn *column =  
     gtk_tree_view_column_new_with_attributes(_("Name"), renderer,  
                  "text", RELITEM_COL_NAME, NULL);  
   gtk_tree_view_column_set_expand(column, TRUE);  
   gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);  
407    
408      list_set_columns(context->list,
409                       _(""), RELITEM_COL_SELECTED, LIST_FLAG_TOGGLE,
410                                G_CALLBACK(relitem_toggled), context,
411                       _("Type"), RELITEM_COL_TYPE, 0,
412                       _("Role"), RELITEM_COL_ROLE, 0,
413                       _("Name"), RELITEM_COL_NAME, LIST_FLAG_ELLIPSIZE,
414                       NULL);
415    
416    /* build and fill the store */    /* build and fill the store */
417    context->store = gtk_list_store_new(RELITEM_NUM_COLS,    context->store = gtk_list_store_new(RELITEM_NUM_COLS,
418                  G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING,                  G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING,
419                  G_TYPE_STRING, G_TYPE_POINTER);                  G_TYPE_STRING, G_TYPE_POINTER);
420    
421    gtk_tree_view_set_model(GTK_TREE_VIEW(context->view),    list_set_store(context->list, context->store);
422                            GTK_TREE_MODEL(context->store));  
423      // Debatable whether to sort by the "selected" or the "Name" column by
424      // default. Both are be useful, in different ways.
425      gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(context->store),
426                                           RELITEM_COL_NAME, GTK_SORT_ASCENDING);
427    
428    GtkTreeIter iter;    GtkTreeIter iter;
429    relation_t *relation = context->appdata->osm->relation;    relation_t *relation = context->appdata->osm->relation;
430    while(relation) {    while(relation) {
431      /* try to find something descriptive */      /* try to find something descriptive */
432      char *name = osm_tag_get_by_key(relation->tag, "name");      char *name = relation_get_descriptive_name(relation);
     if(!name) name = osm_tag_get_by_key(relation->tag, "ref");  
433    
434      /* Append a row and fill in some data */      /* Append a row and fill in some data */
435      gtk_list_store_append(context->store, &iter);      gtk_list_store_append(context->store, &iter);
# Line 459  static GtkWidget *relation_item_list_wid Line 446  static GtkWidget *relation_item_list_wid
446    
447    g_object_unref(context->store);    g_object_unref(context->store);
448    
449    /* put it into a scrolled window */    list_set_static_buttons(context->list, G_CALLBACK(on_relation_item_add),
450    GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);          G_CALLBACK(on_relation_item_edit),G_CALLBACK(on_relation_item_remove),
451    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),          context);
                                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);  
   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),  
                                       GTK_SHADOW_ETCHED_IN);  
   gtk_container_add(GTK_CONTAINER(scrolled_window), context->view);  
   
   gtk_box_pack_start_defaults(GTK_BOX(vbox), scrolled_window);  
   
   /* ------- button box ------------ */  
   
   GtkWidget *hbox = gtk_hbox_new(TRUE,3);  
   
   context->but_add = gtk_button_new_with_label(_("Add..."));  
   //  gtk_widget_set_sensitive(context->but_add, FALSE);  
   gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_add);  
   gtk_signal_connect(GTK_OBJECT(context->but_add), "clicked",  
                      GTK_SIGNAL_FUNC(on_relation_item_add), context);  
   
   context->but_edit = gtk_button_new_with_label(_("Edit..."));  
   gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_edit);  
   gtk_signal_connect(GTK_OBJECT(context->but_edit), "clicked",  
                      GTK_SIGNAL_FUNC(on_relation_item_edit), context);  
   
   context->but_remove = gtk_button_new_with_label(_("Remove"));  
   gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_remove);  
   gtk_signal_connect(GTK_OBJECT(context->but_remove), "clicked",  
                      GTK_SIGNAL_FUNC(on_relation_item_remove), context);  
452    
453    relation_item_list_selected(context, FALSE);    relation_item_list_selected(context, FALSE);
454    
455    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);    return context->list;
   return vbox;  
456  }  }
457    
458  void relation_add_dialog(appdata_t *appdata, relation_item_t *relitem) {  void relation_add_dialog(appdata_t *appdata, object_t *object) {
459    relitem_context_t *context = g_new0(relitem_context_t, 1);    relitem_context_t *context = g_new0(relitem_context_t, 1);
460    map_t *map = appdata->map;    map_t *map = appdata->map;
461    g_assert(map);    g_assert(map);
462    
463    context->appdata = appdata;    context->appdata = appdata;
464    context->item = relitem;    context->item = object;
465    
466    char *str = NULL;    char *str = NULL;
467    switch(relitem->type) {    switch(object->type) {
468    case NODE:    case NODE:
469      str = g_strdup_printf(_("Relations for node #%ld"), relitem->node->id);      str = g_strdup_printf(_("Relations for node #" ITEM_ID_FORMAT),
470                              object->node->id);
471      break;      break;
472    case WAY:    case WAY:
473      str = g_strdup_printf(_("Relations for way #%ld"), relitem->way->id);      str = g_strdup_printf(_("Relations for way #" ITEM_ID_FORMAT),
474                              object->way->id);
475      break;      break;
476    default:    default:
477      g_assert((relitem->type == NODE) || (relitem->type == WAY));      g_assert((object->type == NODE) || (object->type == WAY));
478      break;      break;
479    }    }
480    
481    context->dialog = gtk_dialog_new_with_buttons(str,    context->dialog =
482          GTK_WINDOW(appdata->window), GTK_DIALOG_MODAL,      misc_dialog_new(MISC_DIALOG_LARGE, str,
483          GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,                      GTK_WINDOW(appdata->window),
484          NULL);                      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
485                        NULL);
486    g_free(str);    g_free(str);
487    
488    gtk_dialog_set_default_response(GTK_DIALOG(context->dialog),    gtk_dialog_set_default_response(GTK_DIALOG(context->dialog),
489                                    GTK_RESPONSE_CLOSE);                                    GTK_RESPONSE_CLOSE);
490    
   /* making the dialog a little wider makes it less "crowded" */  
 #ifdef USE_HILDON  
   gtk_window_set_default_size(GTK_WINDOW(context->dialog), 500, 300);  
 #else  
   gtk_window_set_default_size(GTK_WINDOW(context->dialog), 400, 200);  
 #endif  
491    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox),    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox),
492                       relation_item_list_widget(context), TRUE, TRUE, 0);                       relation_item_list_widget(context), TRUE, TRUE, 0);
493    
# Line 547  void relation_add_dialog(appdata_t *appd Line 504  void relation_add_dialog(appdata_t *appd
504    
505  typedef struct {  typedef struct {
506    appdata_t *appdata;    appdata_t *appdata;
507    GtkWidget *dialog, *view;    GtkWidget *dialog, *list, *show_btn;
   GtkWidget *but_members, *but_add, *but_edit, *but_remove;  
508    GtkListStore *store;    GtkListStore *store;
509      object_t *object;     /* object this list relates to, NULL if global */
510  } relation_context_t;  } relation_context_t;
511    
512  enum {  enum {
# Line 561  enum { Line 518  enum {
518    RELATION_NUM_COLS    RELATION_NUM_COLS
519  };  };
520    
521    static relation_t *get_selected_relation(relation_context_t *context) {
522      GtkTreeSelection *selection;
523      GtkTreeModel     *model;
524      GtkTreeIter       iter;
525    
526      selection = list_get_selection(context->list);
527      if(gtk_tree_selection_get_selected(selection, &model, &iter)) {
528        relation_t *relation;
529        gtk_tree_model_get(model, &iter, RELATION_COL_DATA, &relation, -1);
530        return(relation);
531      }
532      return NULL;
533    }
534    
535  static void relation_list_selected(relation_context_t *context,  static void relation_list_selected(relation_context_t *context,
536                                     gboolean selected) {                                     relation_t *selected) {
537    
538      list_button_enable(context->list, LIST_BUTTON_USER0,
539                         (selected != NULL) && (selected->member != NULL));
540      gtk_widget_set_sensitive(context->show_btn,
541                         (selected != NULL) && (selected->member != NULL));
542    
543    if(context->but_members)    list_button_enable(context->list, LIST_BUTTON_REMOVE, selected != NULL);
544      gtk_widget_set_sensitive(context->but_members, selected);    list_button_enable(context->list, LIST_BUTTON_EDIT, selected != NULL);
545  }  }
546    
547  static gboolean  static gboolean
# Line 577  relation_list_selection_func(GtkTreeSele Line 553  relation_list_selection_func(GtkTreeSele
553    
554    if(gtk_tree_model_get_iter(model, &iter, path)) {    if(gtk_tree_model_get_iter(model, &iter, path)) {
555      g_assert(gtk_tree_path_get_depth(path) == 1);      g_assert(gtk_tree_path_get_depth(path) == 1);
556      relation_list_selected(context, TRUE);  
557        relation_t *relation = NULL;
558        gtk_tree_model_get(model, &iter, RELATION_COL_DATA, &relation, -1);
559        relation_list_selected(context, relation);
560    }    }
561    
562    return TRUE; /* allow selection state to change */    return TRUE; /* allow selection state to change */
563  }  }
564    
 static relation_t *get_selected_relation(relation_context_t *context) {  
   GtkTreeSelection *selection;  
   GtkTreeModel     *model;  
   GtkTreeIter       iter;  
   
   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view));  
   if(gtk_tree_selection_get_selected(selection, &model, &iter)) {  
     relation_t *relation;  
     gtk_tree_model_get(model, &iter, RELATION_COL_DATA, &relation, -1);  
     return(relation);  
   }  
   return NULL;  
 }  
   
565  typedef struct {  typedef struct {
566    relation_t *relation;    relation_t *relation;
567    GtkWidget *dialog, *view;    GtkWidget *dialog, *view;
# Line 624  member_list_selection_func(GtkTreeSelect Line 589  member_list_selection_func(GtkTreeSelect
589    
590      member_t *member = NULL;      member_t *member = NULL;
591      gtk_tree_model_get(model, &iter, MEMBER_COL_DATA, &member, -1);      gtk_tree_model_get(model, &iter, MEMBER_COL_DATA, &member, -1);
592      if(member && member->type < NODE_ID)      if(member && member->object.type < NODE_ID)
593        return TRUE;        return TRUE;
594    }    }
595    
# Line 644  static GtkWidget *member_list_widget(mem Line 609  static GtkWidget *member_list_widget(mem
609    /* --- "type" column --- */    /* --- "type" column --- */
610    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
611    g_object_set(renderer, "foreground", "grey", NULL);    g_object_set(renderer, "foreground", "grey", NULL);
612    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),    GtkTreeViewColumn *column =
613          -1, _("Type"), renderer, "text", MEMBER_COL_TYPE,      gtk_tree_view_column_new_with_attributes(_("Type"), renderer,
614          "foreground-set", MEMBER_COL_REF_ONLY,  NULL);                       "text", MEMBER_COL_TYPE,
615                         "foreground-set", MEMBER_COL_REF_ONLY,  NULL);
616      gtk_tree_view_column_set_sort_column_id(column, MEMBER_COL_TYPE);
617      gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);
618    
619    /* --- "id" column --- */    /* --- "id" column --- */
620    renderer = gtk_cell_renderer_text_new();    renderer = gtk_cell_renderer_text_new();
621    g_object_set(renderer, "foreground", "grey", NULL);    g_object_set(renderer, "foreground", "grey", NULL);
622    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),    column = gtk_tree_view_column_new_with_attributes(_("Id"), renderer,
623          -1, _("Id"), renderer, "text", MEMBER_COL_ID,                       "text", MEMBER_COL_ID,
624          "foreground-set", MEMBER_COL_REF_ONLY, NULL);                       "foreground-set", MEMBER_COL_REF_ONLY,  NULL);
625      gtk_tree_view_column_set_sort_column_id(column, MEMBER_COL_ID);
626      gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);
627    
628    
629    /* --- "Name" column --- */    /* --- "Name" column --- */
630    renderer = gtk_cell_renderer_text_new();    renderer = gtk_cell_renderer_text_new();
631    g_object_set(renderer, "foreground", "grey", NULL);    g_object_set(renderer, "foreground", "grey", NULL);
632    g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);    g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
633    GtkTreeViewColumn *column =    column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer,
     gtk_tree_view_column_new_with_attributes(_("Name"), renderer,  
634                       "text", MEMBER_COL_NAME,                       "text", MEMBER_COL_NAME,
635                       "foreground-set", MEMBER_COL_REF_ONLY,  NULL);                       "foreground-set", MEMBER_COL_REF_ONLY,  NULL);
636    gtk_tree_view_column_set_expand(column, TRUE);    gtk_tree_view_column_set_expand(column, TRUE);
637      gtk_tree_view_column_set_sort_column_id(column, MEMBER_COL_NAME);
638    gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);    gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);
639    
640    /* --- "role" column --- */    /* --- "role" column --- */
641    renderer = gtk_cell_renderer_text_new();    renderer = gtk_cell_renderer_text_new();
642    g_object_set(renderer, "foreground", "grey", NULL);    g_object_set(renderer, "foreground", "grey", NULL);
643    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),    column = gtk_tree_view_column_new_with_attributes(_("Role"), renderer,
644          -1, _("Role"), renderer, "text", MEMBER_COL_ROLE,                       "text", MEMBER_COL_ROLE,
645          "foreground-set", MEMBER_COL_REF_ONLY, NULL);                       "foreground-set", MEMBER_COL_REF_ONLY,  NULL);
646      gtk_tree_view_column_set_sort_column_id(column, MEMBER_COL_ROLE);
647      gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);
648    
649    
650    /* build and fill the store */    /* build and fill the store */
651    context->store = gtk_list_store_new(MEMBER_NUM_COLS,    context->store = gtk_list_store_new(MEMBER_NUM_COLS,
# Line 685  static GtkWidget *member_list_widget(mem Line 658  static GtkWidget *member_list_widget(mem
658    GtkTreeIter iter;    GtkTreeIter iter;
659    member_t *member = context->relation->member;    member_t *member = context->relation->member;
660    while(member) {    while(member) {
661      tag_t *tags = osm_object_get_tags(member->type, member->ptr);      tag_t *tags = osm_object_get_tags(&member->object);
662      char *id = osm_id_string(member->type, member->ptr);      char *id = osm_object_id_string(&member->object);
663    
664      /* try to find something descriptive */      /* try to find something descriptive */
665      char *name = NULL;      char *name = NULL;
# Line 696  static GtkWidget *member_list_widget(mem Line 669  static GtkWidget *member_list_widget(mem
669      /* Append a row and fill in some data */      /* Append a row and fill in some data */
670      gtk_list_store_append(context->store, &iter);      gtk_list_store_append(context->store, &iter);
671      gtk_list_store_set(context->store, &iter,      gtk_list_store_set(context->store, &iter,
672         MEMBER_COL_TYPE, osm_type_string(member->type),         MEMBER_COL_TYPE, osm_object_type_string(&member->object),
673         MEMBER_COL_ID,   id,         MEMBER_COL_ID,   id,
674         MEMBER_COL_NAME, name,         MEMBER_COL_NAME, name,
675         MEMBER_COL_ROLE, member->role,         MEMBER_COL_ROLE, member->role,
676         MEMBER_COL_REF_ONLY, member->type >= NODE_ID,         MEMBER_COL_REF_ONLY, member->object.type >= NODE_ID,
677         MEMBER_COL_DATA, member,         MEMBER_COL_DATA, member,
678         -1);         -1);
679    
# Line 723  static GtkWidget *member_list_widget(mem Line 696  static GtkWidget *member_list_widget(mem
696    return vbox;    return vbox;
697  }  }
698    
699  /* 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) {  
700    member_context_t *mcontext = g_new0(member_context_t, 1);    member_context_t *mcontext = g_new0(member_context_t, 1);
701      mcontext->relation = relation;
   /* display members list */  
   mcontext->relation = get_selected_relation(context);  
   if(!mcontext->relation) return;  
702    
703    char *str = osm_tag_get_by_key(mcontext->relation->tag, "name");    char *str = osm_tag_get_by_key(mcontext->relation->tag, "name");
704    if(!str) str = osm_tag_get_by_key(mcontext->relation->tag, "ref");    if(!str) str = osm_tag_get_by_key(mcontext->relation->tag, "ref");
705    if(!str)    if(!str)
706      str = g_strdup_printf(_("Members of relation #%ld"),      str = g_strdup_printf(_("Members of relation #" ITEM_ID_FORMAT),
707                            mcontext->relation->id);                            mcontext->relation->id);
708    else    else
709      str = g_strdup_printf(_("Members of relation \"%s\""), str);      str = g_strdup_printf(_("Members of relation \"%s\""), str);
710    
711    mcontext->dialog =    mcontext->dialog =
712      gtk_dialog_new_with_buttons(str,      misc_dialog_new(MISC_DIALOG_MEDIUM, str,
713          GTK_WINDOW(context->dialog), GTK_DIALOG_MODAL,                      GTK_WINDOW(parent),
714          GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,                      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
715          NULL);                      NULL);
716    g_free(str);    g_free(str);
717    
718    gtk_dialog_set_default_response(GTK_DIALOG(mcontext->dialog),    gtk_dialog_set_default_response(GTK_DIALOG(mcontext->dialog),
719                                    GTK_RESPONSE_CLOSE);                                    GTK_RESPONSE_CLOSE);
720    
   /* making the dialog a little wider makes it less "crowded" */  
 #ifdef USE_HILDON  
   gtk_window_set_default_size(GTK_WINDOW(mcontext->dialog), 500, 300);  
 #else  
   gtk_window_set_default_size(GTK_WINDOW(mcontext->dialog), 400, 200);  
 #endif  
   
721    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(mcontext->dialog)->vbox),    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(mcontext->dialog)->vbox),
722                       member_list_widget(mcontext), TRUE, TRUE, 0);                       member_list_widget(mcontext), TRUE, TRUE, 0);
723    
# Line 768  static void on_relation_members(GtkWidge Line 730  static void on_relation_members(GtkWidge
730    g_free(mcontext);    g_free(mcontext);
731  }  }
732    
733  static GtkWidget *relation_list_widget(relation_context_t *context) {  /* user clicked "members..." button in relation list */
734    GtkWidget *vbox = gtk_vbox_new(FALSE,3);  static void on_relation_members(GtkWidget *but, relation_context_t *context) {
735    context->view = gtk_tree_view_new();    relation_t *sel = get_selected_relation(context);
736    
737      if(sel)
738        relation_show_members(context->dialog, sel);
739    }
740    
   gtk_tree_selection_set_select_function(  
          gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view)),  
          relation_list_selection_func,  
          context, NULL);  
741    
742    /* --- "id" column --- */  static void on_relation_add(GtkWidget *but, relation_context_t *context) {
743    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();    /* create a new relation */
   gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),  
         -1, _("Id"), renderer, "text", RELATION_COL_ID, NULL);  
744    
745    /* --- "Type" column --- */    relation_t *relation = osm_relation_new();
746    renderer = gtk_cell_renderer_text_new();    if(!relation_info_dialog(context->dialog, context->appdata, relation)) {
747    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),      printf("tag edit cancelled\n");
748          -1, _("Type"), renderer, "text", RELATION_COL_TYPE, NULL);      osm_relation_free(relation);
749      } else {
750        osm_relation_attach(context->appdata->osm, relation);
751    
752    /* --- "Name" column --- */      /* append a row for the new data */
   renderer = gtk_cell_renderer_text_new();  
   g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);  
   GtkTreeViewColumn *column =  
     gtk_tree_view_column_new_with_attributes(_("Name"), renderer,  
                  "text", RELATION_COL_NAME, NULL);  
   gtk_tree_view_column_set_expand(column, TRUE);  
   gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);  
753    
754    /* --- "members" column --- */      char *name = relation_get_descriptive_name(relation);
755    renderer = gtk_cell_renderer_text_new();  
756    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),      guint num = osm_relation_members_num(relation);
757          -1, _("Members"), renderer, "text", RELATION_COL_MEMBERS, NULL);  
758        /* Append a row and fill in some data */
759        GtkTreeIter iter;
760        gtk_list_store_append(context->store, &iter);
761        gtk_list_store_set(context->store, &iter,
762                           RELATION_COL_ID, relation->id,
763                           RELATION_COL_TYPE,
764                           osm_tag_get_by_key(relation->tag, "type"),
765                           RELATION_COL_NAME, name,
766                           RELATION_COL_MEMBERS, num,
767                           RELATION_COL_DATA, relation,
768                           -1);
769    
770        gtk_tree_selection_select_iter(list_get_selection(context->list), &iter);
771    
772        /* scroll to end */
773        //    GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment();
774        /* xyz */
775      }
776    }
777    
778    /* user clicked "edit..." button in relation list */
779    static void on_relation_edit(GtkWidget *but, relation_context_t *context) {
780      relation_t *sel = get_selected_relation(context);
781      if(!sel) return;
782    
783      printf("edit relation #" ITEM_ID_FORMAT "\n", sel->id);
784    
785      if (!relation_info_dialog(context->dialog, context->appdata, sel))
786        return;
787    
788      // Locate the changed item
789      GtkTreeIter iter;
790      gboolean valid = gtk_tree_model_get_iter_first(
791        GTK_TREE_MODEL(context->store), &iter);
792      while (valid) {
793        relation_t *row_rel;
794        gtk_tree_model_get(GTK_TREE_MODEL(context->store), &iter,
795                           RELATION_COL_DATA, &row_rel,
796                           -1);
797        if (row_rel == sel)
798          break;
799        valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(context->store), &iter);
800      }
801      if (!valid)
802        return;
803    
804      // Found it. Update all visible fields.
805      gtk_list_store_set(context->store, &iter,
806        RELATION_COL_ID,      sel->id,
807        RELATION_COL_TYPE,    osm_tag_get_by_key(sel->tag, "type"),
808        RELATION_COL_NAME,    relation_get_descriptive_name(sel),
809        RELATION_COL_MEMBERS, osm_relation_members_num(sel),
810        -1);
811    
812      // Order will probably have changed, so refocus
813      list_focus_on(context->list, &iter, TRUE);
814    }
815    
816    
817    /* remove the selected relation */
818    static void on_relation_remove(GtkWidget *but, relation_context_t *context) {
819      relation_t *sel = get_selected_relation(context);
820      if(!sel) return;
821    
822      printf("remove relation #" ITEM_ID_FORMAT "\n", sel->id);
823    
824      gint members = osm_relation_members_num(sel);
825    
826      if(members)
827        if(!yes_no_f(context->dialog, NULL, 0, 0,
828                     _("Delete non-empty relation?"),
829                     _("This relation still has %d members. "
830                       "Delete it anyway?"), members))
831          return;
832    
833      /* first remove selected row from list */
834      GtkTreeIter       iter;
835      GtkTreeSelection *selection = list_get_selection(context->list);
836      if(gtk_tree_selection_get_selected(selection, NULL, &iter))
837        gtk_list_store_remove(context->store, &iter);
838    
839      /* then really delete it */
840      osm_relation_delete(context->appdata->osm, sel, FALSE);
841    
842      relation_list_selected(context, NULL);
843    }
844    
845    static GtkWidget *relation_list_widget(relation_context_t *context) {
846      context->list = list_new(LIST_HILDON_WITH_HEADERS);
847    
848      list_set_selection_function(context->list, relation_list_selection_func,
849                                  context);
850    
851      list_set_columns(context->list,
852                       _("Id"),      RELATION_COL_ID, 0,
853                       _("Type"),    RELATION_COL_TYPE, 0,
854                       _("Name"),    RELATION_COL_NAME, LIST_FLAG_ELLIPSIZE,
855                       _("Members"), RELATION_COL_MEMBERS, 0,
856                       NULL);
857    
858    /* build and fill the store */    /* build and fill the store */
859    context->store = gtk_list_store_new(RELATION_NUM_COLS,    context->store = gtk_list_store_new(RELATION_NUM_COLS,
860                  G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,                  G_TYPE_ITEM_ID_T, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT,
861                  G_TYPE_POINTER);                  G_TYPE_POINTER);
862    
863    gtk_tree_view_set_model(GTK_TREE_VIEW(context->view),    list_set_store(context->list, context->store);
                           GTK_TREE_MODEL(context->store));  
864    
865      // Sorting by ref/name by default is useful for places with lots of numbered
866      // bus routes. Especially for small screens.
867      gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(context->store),
868                                           RELATION_COL_NAME, GTK_SORT_ASCENDING);
869    
870    GtkTreeIter iter;    GtkTreeIter iter;
871    relation_t *relation = context->appdata->osm->relation;    relation_t *relation = NULL;
872    while(relation) {    relation_chain_t *rchain = NULL;
     char *id = g_strdup_printf("#%ld", relation->id);  
873    
874      /* try to find something descriptive */    if(context->object)
875      char *name = osm_tag_get_by_key(relation->tag, "name");      rchain = osm_object_to_relation(context->appdata->osm, context->object);
876      if(!name) name = osm_tag_get_by_key(relation->tag, "ref");    else
877        relation = context->appdata->osm->relation;
878    
879      char *num = g_strdup_printf("%d", osm_relation_members_num(relation));    while(relation || rchain) {
880        relation_t *rel = relation?relation:rchain->relation;
881    
882        char *name = relation_get_descriptive_name(rel);
883        guint num = osm_relation_members_num(rel);
884    
885      /* Append a row and fill in some data */      /* Append a row and fill in some data */
886      gtk_list_store_append(context->store, &iter);      gtk_list_store_append(context->store, &iter);
887      gtk_list_store_set(context->store, &iter,      gtk_list_store_set(context->store, &iter,
888                         RELATION_COL_ID, id,                         RELATION_COL_ID, rel->id,
889                         RELATION_COL_TYPE,                         RELATION_COL_TYPE,
890                         osm_tag_get_by_key(relation->tag, "type"),                         osm_tag_get_by_key(rel->tag, "type"),
891                         RELATION_COL_NAME, name,                         RELATION_COL_NAME, name,
892                         RELATION_COL_MEMBERS, num,                         RELATION_COL_MEMBERS, num,
893                         RELATION_COL_DATA, relation,                         RELATION_COL_DATA, rel,
894                         -1);                         -1);
895    
896      g_free(id);      if(relation) relation = relation->next;
897      g_free(num);      if(rchain)   rchain = rchain->next;
     relation = relation->next;  
898    }    }
899    
900      if(rchain)
901        osm_relation_chain_free(rchain);
902    
903    g_object_unref(context->store);    g_object_unref(context->store);
904    
905    /* put it into a scrolled window */    list_set_static_buttons(context->list, G_CALLBACK(on_relation_add),
906    GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);       G_CALLBACK(on_relation_edit), G_CALLBACK(on_relation_remove), context);
   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),  
                                  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);  
   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),  
                                       GTK_SHADOW_ETCHED_IN);  
   gtk_container_add(GTK_CONTAINER(scrolled_window), context->view);  
   
   gtk_box_pack_start_defaults(GTK_BOX(vbox), scrolled_window);  
   
   /* ------- button box ------------ */  
   
   GtkWidget *hbox = gtk_hbox_new(TRUE,3);  
   
   context->but_add = gtk_button_new_with_label(_("Add..."));  
   gtk_widget_set_sensitive(context->but_add, FALSE);  
   gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_add);  
   //  gtk_signal_connect(GTK_OBJECT(context->but_add), "clicked",  
   //                         GTK_SIGNAL_FUNC(on_relation_add), context);  
   
   context->but_edit = gtk_button_new_with_label(_("Edit..."));  
   gtk_widget_set_sensitive(context->but_edit, FALSE);  
   gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_edit);  
   //  gtk_signal_connect(GTK_OBJECT(context->but_edit), "clicked",  
   //                         GTK_SIGNAL_FUNC(on_relation_edit), context);  
   
   context->but_members = gtk_button_new_with_label(_("Members..."));  
   gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_members);  
   gtk_signal_connect(GTK_OBJECT(context->but_members), "clicked",  
                      GTK_SIGNAL_FUNC(on_relation_members), context);  
   
   context->but_remove = gtk_button_new_with_label(_("Remove"));  
   gtk_widget_set_sensitive(context->but_remove, FALSE);  
   gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_remove);  
   //  gtk_signal_connect(GTK_OBJECT(context->but_remove), "clicked",  
   //                 GTK_SIGNAL_FUNC(on_relation_remove), context);  
907    
908    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);    list_set_user_buttons(context->list,
909            LIST_BUTTON_USER0, _("Members"), G_CALLBACK(on_relation_members),
910            0);
911    
912    relation_list_selected(context, FALSE);    relation_list_selected(context, NULL);
913    
914    return vbox;    return context->list;
915  }  }
916    
917  /* a global view on all relations */  /* a global view on all relations */
918  void relation_list(appdata_t *appdata) {  void relation_list(GtkWidget *parent, appdata_t *appdata, object_t *object) {
919    relation_context_t *context = g_new0(relation_context_t, 1);    relation_context_t *context = g_new0(relation_context_t, 1);
920    context->appdata = appdata;    context->appdata = appdata;
921    
922    printf("relation list\n");    char *str = NULL;
923      if(!object)
924        str = g_strdup(_("All relations"));
925      else {
926        str = g_strdup_printf(_("Relations of %s"), osm_object_string(object));
927        context->object = object;
928      }
929    
930    context->dialog =    context->dialog =
931      gtk_dialog_new_with_buttons(_("All relations"),      misc_dialog_new(MISC_DIALOG_LARGE, str,
932          GTK_WINDOW(appdata->window), GTK_DIALOG_MODAL,                      GTK_WINDOW(parent),
933          GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,                      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
934          NULL);                      NULL);
935    
936      g_free(str);
937    
938    gtk_dialog_set_default_response(GTK_DIALOG(context->dialog),    gtk_dialog_set_default_response(GTK_DIALOG(context->dialog),
939                                    GTK_RESPONSE_CLOSE);                                    GTK_RESPONSE_CLOSE);
940    
941    /* making the dialog a little wider makes it less "crowded" */    context->show_btn = gtk_dialog_add_button(GTK_DIALOG(context->dialog),
942  #ifdef USE_HILDON                                              _("Select"), GTK_RESPONSE_HELP);
943    gtk_window_set_default_size(GTK_WINDOW(context->dialog), 500, 300);  
 #else  
   gtk_window_set_default_size(GTK_WINDOW(context->dialog), 400, 200);  
 #endif  
944    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox),    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox),
945                       relation_list_widget(context), TRUE, TRUE, 0);                       relation_list_widget(context), TRUE, TRUE, 0);
946    
947    /* ----------------------------------- */    /* ----------------------------------- */
948    
949    
950    gtk_widget_show_all(context->dialog);    gtk_widget_show_all(context->dialog);
951    gtk_dialog_run(GTK_DIALOG(context->dialog));    if(gtk_dialog_run(GTK_DIALOG(context->dialog)) == GTK_RESPONSE_HELP) {
952    gtk_widget_destroy(context->dialog);      map_item_deselect(appdata);
953    
954        relation_t *sel = get_selected_relation(context);
955        if(sel) map_relation_select(appdata, sel);
956      }
957    
958      gtk_widget_destroy(context->dialog);
959    g_free(context);    g_free(context);
960  }  }
961    
962    // vim:et:ts=8:sw=2:sts=2:ai

Legend:
Removed from v.76  
changed lines
  Added in v.191