Diff of /trunk/src/relation_edit.c

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

revision 75 by harbaum, Thu Feb 12 19:58:20 2009 UTC revision 76 by harbaum, Fri Feb 13 12:02:26 2009 UTC
# Line 192  static void relation_remove_item(relatio Line 192  static void relation_remove_item(relatio
192    g_assert(0);    g_assert(0);
193  }  }
194    
195  static void relation_list_selected(relitem_context_t *context,  static void relation_item_list_selected(relitem_context_t *context,
196                                     gboolean selected) {                                     gboolean selected) {
197    
198    if(context->but_remove)    if(context->but_remove)
# Line 202  static void relation_list_selected(relit Line 202  static void relation_list_selected(relit
202  }  }
203    
204  static gboolean  static gboolean
205  relation_list_selection_func(GtkTreeSelection *selection, GtkTreeModel *model,  relation_item_list_selection_func(GtkTreeSelection *selection, GtkTreeModel *model,
206                       GtkTreePath *path, gboolean path_currently_selected,                       GtkTreePath *path, gboolean path_currently_selected,
207                       gpointer userdata) {                       gpointer userdata) {
208    relitem_context_t *context = (relitem_context_t*)userdata;    relitem_context_t *context = (relitem_context_t*)userdata;
# Line 210  relation_list_selection_func(GtkTreeSele Line 210  relation_list_selection_func(GtkTreeSele
210    
211    if(gtk_tree_model_get_iter(model, &iter, path)) {    if(gtk_tree_model_get_iter(model, &iter, path)) {
212      g_assert(gtk_tree_path_get_depth(path) == 1);      g_assert(gtk_tree_path_get_depth(path) == 1);
213      relation_list_selected(context, TRUE);      relation_item_list_selected(context, TRUE);
214    }    }
215    
216    return TRUE; /* allow selection state to change */    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_item_add(GtkWidget *but, relitem_context_t *context) {
220    /* create a new relation */    /* create a new relation */
221    
222    relation_t *relation = osm_relation_new();    relation_t *relation = osm_relation_new();
# Line 266  static relation_t *get_selection(relitem Line 266  static relation_t *get_selection(relitem
266    return NULL;    return NULL;
267  }  }
268    
269  static void on_relation_edit(GtkWidget *but, relitem_context_t *context) {  static void on_relation_item_edit(GtkWidget *but, relitem_context_t *context) {
270    relation_t *sel = get_selection(context);    relation_t *sel = get_selection(context);
271    if(!sel) return;    if(!sel) return;
272    
# Line 276  static void on_relation_edit(GtkWidget * Line 276  static void on_relation_edit(GtkWidget *
276  }  }
277    
278  /* remove the selected relation */  /* remove the selected relation */
279  static void on_relation_remove(GtkWidget *but, relitem_context_t *context) {  static void on_relation_item_remove(GtkWidget *but, relitem_context_t *context) {
280    relation_t *sel = get_selection(context);    relation_t *sel = get_selection(context);
281    if(!sel) return;    if(!sel) return;
282    
# Line 306  static void on_relation_remove(GtkWidget Line 306  static void on_relation_remove(GtkWidget
306    /* then really delete it */    /* then really delete it */
307    osm_relation_delete(context->appdata->osm, sel, FALSE);    osm_relation_delete(context->appdata->osm, sel, FALSE);
308    
309    relation_list_selected(context, FALSE);    relation_item_list_selected(context, FALSE);
310  }  }
311    
312  static char *relitem_get_role_in_relation(relation_item_t *item, relation_t *relation) {  static char *relitem_get_role_in_relation(relation_item_t *item, relation_t *relation) {
# Line 391  static gboolean relitem_is_in_relation(r Line 391  static gboolean relitem_is_in_relation(r
391    return FALSE;    return FALSE;
392  }  }
393    
394  static GtkWidget *relation_list(relitem_context_t *context) {  static GtkWidget *relation_item_list_widget(relitem_context_t *context) {
395    GtkWidget *vbox = gtk_vbox_new(FALSE,3);    GtkWidget *vbox = gtk_vbox_new(FALSE,3);
396    context->view = gtk_tree_view_new();    context->view = gtk_tree_view_new();
397    
398    gtk_tree_selection_set_select_function(    gtk_tree_selection_set_select_function(
399           gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view)),           gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view)),
400           relation_list_selection_func,           relation_item_list_selection_func,
401           context, NULL);           context, NULL);
402    
403    
# Line 477  static GtkWidget *relation_list(relitem_ Line 477  static GtkWidget *relation_list(relitem_
477    //  gtk_widget_set_sensitive(context->but_add, FALSE);    //  gtk_widget_set_sensitive(context->but_add, FALSE);
478    gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_add);    gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_add);
479    gtk_signal_connect(GTK_OBJECT(context->but_add), "clicked",    gtk_signal_connect(GTK_OBJECT(context->but_add), "clicked",
480                       GTK_SIGNAL_FUNC(on_relation_add), context);                       GTK_SIGNAL_FUNC(on_relation_item_add), context);
481    
482    context->but_edit = gtk_button_new_with_label(_("Edit..."));    context->but_edit = gtk_button_new_with_label(_("Edit..."));
483    gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_edit);    gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_edit);
484    gtk_signal_connect(GTK_OBJECT(context->but_edit), "clicked",    gtk_signal_connect(GTK_OBJECT(context->but_edit), "clicked",
485                       GTK_SIGNAL_FUNC(on_relation_edit), context);                       GTK_SIGNAL_FUNC(on_relation_item_edit), context);
486    
487    context->but_remove = gtk_button_new_with_label(_("Remove"));    context->but_remove = gtk_button_new_with_label(_("Remove"));
488    gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_remove);    gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_remove);
489    gtk_signal_connect(GTK_OBJECT(context->but_remove), "clicked",    gtk_signal_connect(GTK_OBJECT(context->but_remove), "clicked",
490                       GTK_SIGNAL_FUNC(on_relation_remove), context);                       GTK_SIGNAL_FUNC(on_relation_item_remove), context);
491    
492    relation_list_selected(context, FALSE);    relation_item_list_selected(context, FALSE);
493    
494    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
495    return vbox;    return vbox;
# Line 523  void relation_add_dialog(appdata_t *appd Line 523  void relation_add_dialog(appdata_t *appd
523    g_free(str);    g_free(str);
524    
525    gtk_dialog_set_default_response(GTK_DIALOG(context->dialog),    gtk_dialog_set_default_response(GTK_DIALOG(context->dialog),
526                                    GTK_RESPONSE_ACCEPT);                                    GTK_RESPONSE_CLOSE);
527    
528      /* making the dialog a little wider makes it less "crowded" */
529    #ifdef USE_HILDON
530      gtk_window_set_default_size(GTK_WINDOW(context->dialog), 500, 300);
531    #else
532      gtk_window_set_default_size(GTK_WINDOW(context->dialog), 400, 200);
533    #endif
534      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox),
535                         relation_item_list_widget(context), TRUE, TRUE, 0);
536    
537      /* ----------------------------------- */
538    
539      gtk_widget_show_all(context->dialog);
540      gtk_dialog_run(GTK_DIALOG(context->dialog));
541      gtk_widget_destroy(context->dialog);
542    
543      g_free(context);
544    }
545    
546    /* -------------------- global relation list ----------------- */
547    
548    typedef struct {
549      appdata_t *appdata;
550      GtkWidget *dialog, *view;
551      GtkWidget *but_members, *but_add, *but_edit, *but_remove;
552      GtkListStore *store;
553    } relation_context_t;
554    
555    enum {
556      RELATION_COL_ID = 0,
557      RELATION_COL_TYPE,
558      RELATION_COL_NAME,
559      RELATION_COL_MEMBERS,
560      RELATION_COL_DATA,
561      RELATION_NUM_COLS
562    };
563    
564    static void relation_list_selected(relation_context_t *context,
565                                       gboolean selected) {
566    
567      if(context->but_members)
568        gtk_widget_set_sensitive(context->but_members, selected);
569    }
570    
571    static gboolean
572    relation_list_selection_func(GtkTreeSelection *selection, GtkTreeModel *model,
573                         GtkTreePath *path, gboolean path_currently_selected,
574                         gpointer userdata) {
575      relation_context_t *context = (relation_context_t*)userdata;
576      GtkTreeIter iter;
577    
578      if(gtk_tree_model_get_iter(model, &iter, path)) {
579        g_assert(gtk_tree_path_get_depth(path) == 1);
580        relation_list_selected(context, TRUE);
581      }
582    
583      return TRUE; /* allow selection state to change */
584    }
585    
586    static relation_t *get_selected_relation(relation_context_t *context) {
587      GtkTreeSelection *selection;
588      GtkTreeModel     *model;
589      GtkTreeIter       iter;
590    
591      selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view));
592      if(gtk_tree_selection_get_selected(selection, &model, &iter)) {
593        relation_t *relation;
594        gtk_tree_model_get(model, &iter, RELATION_COL_DATA, &relation, -1);
595        return(relation);
596      }
597      return NULL;
598    }
599    
600    typedef struct {
601      relation_t *relation;
602      GtkWidget *dialog, *view;
603      GtkListStore *store;
604    } member_context_t;
605    
606    enum {
607      MEMBER_COL_TYPE = 0,
608      MEMBER_COL_ID,
609      MEMBER_COL_NAME,
610      MEMBER_COL_ROLE,
611      MEMBER_COL_REF_ONLY,
612      MEMBER_COL_DATA,
613      MEMBER_NUM_COLS
614    };
615    
616    static gboolean
617    member_list_selection_func(GtkTreeSelection *selection, GtkTreeModel *model,
618                         GtkTreePath *path, gboolean path_currently_selected,
619                         gpointer userdata) {
620      GtkTreeIter iter;
621    
622      if(gtk_tree_model_get_iter(model, &iter, path)) {
623        g_assert(gtk_tree_path_get_depth(path) == 1);
624    
625        member_t *member = NULL;
626        gtk_tree_model_get(model, &iter, MEMBER_COL_DATA, &member, -1);
627        if(member && member->type < NODE_ID)
628          return TRUE;
629      }
630    
631      return FALSE;
632    }
633    
634    
635    static GtkWidget *member_list_widget(member_context_t *context) {
636      GtkWidget *vbox = gtk_vbox_new(FALSE,3);
637      context->view = gtk_tree_view_new();
638    
639      gtk_tree_selection_set_select_function(
640             gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view)),
641             member_list_selection_func,
642             context, NULL);
643    
644      /* --- "type" column --- */
645      GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
646      g_object_set(renderer, "foreground", "grey", NULL);
647      gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),
648            -1, _("Type"), renderer, "text", MEMBER_COL_TYPE,
649            "foreground-set", MEMBER_COL_REF_ONLY,  NULL);
650    
651    
652      /* --- "id" column --- */
653      renderer = gtk_cell_renderer_text_new();
654      g_object_set(renderer, "foreground", "grey", NULL);
655      gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),
656            -1, _("Id"), renderer, "text", MEMBER_COL_ID,
657            "foreground-set", MEMBER_COL_REF_ONLY, NULL);
658    
659      /* --- "Name" column --- */
660      renderer = gtk_cell_renderer_text_new();
661      g_object_set(renderer, "foreground", "grey", NULL);
662      g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
663      GtkTreeViewColumn *column =
664        gtk_tree_view_column_new_with_attributes(_("Name"), renderer,
665                         "text", MEMBER_COL_NAME,
666                         "foreground-set", MEMBER_COL_REF_ONLY,  NULL);
667      gtk_tree_view_column_set_expand(column, TRUE);
668      gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);
669    
670      /* --- "role" column --- */
671      renderer = gtk_cell_renderer_text_new();
672      g_object_set(renderer, "foreground", "grey", NULL);
673      gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),
674            -1, _("Role"), renderer, "text", MEMBER_COL_ROLE,
675            "foreground-set", MEMBER_COL_REF_ONLY, NULL);
676    
677      /* build and fill the store */
678      context->store = gtk_list_store_new(MEMBER_NUM_COLS,
679                  G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
680                  G_TYPE_BOOLEAN, G_TYPE_POINTER);
681    
682      gtk_tree_view_set_model(GTK_TREE_VIEW(context->view),
683                              GTK_TREE_MODEL(context->store));
684    
685      GtkTreeIter iter;
686      member_t *member = context->relation->member;
687      while(member) {
688        tag_t *tags = osm_object_get_tags(member->type, member->ptr);
689        char *id = osm_id_string(member->type, member->ptr);
690    
691        /* try to find something descriptive */
692        char *name = NULL;
693        if(tags)
694          name = osm_tag_get_by_key(tags, "name");
695    
696        /* Append a row and fill in some data */
697        gtk_list_store_append(context->store, &iter);
698        gtk_list_store_set(context->store, &iter,
699           MEMBER_COL_TYPE, osm_type_string(member->type),
700           MEMBER_COL_ID,   id,
701           MEMBER_COL_NAME, name,
702           MEMBER_COL_ROLE, member->role,
703           MEMBER_COL_REF_ONLY, member->type >= NODE_ID,
704           MEMBER_COL_DATA, member,
705           -1);
706    
707        g_free(id);
708        member = member->next;
709      }
710    
711      g_object_unref(context->store);
712    
713      /* put it into a scrolled window */
714      GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
715      gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
716                                     GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
717      gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),
718                                          GTK_SHADOW_ETCHED_IN);
719      gtk_container_add(GTK_CONTAINER(scrolled_window), context->view);
720    
721      gtk_box_pack_start_defaults(GTK_BOX(vbox), scrolled_window);
722    
723      return vbox;
724    }
725    
726    /* user clicked "members..." button in relation list */
727    static void on_relation_members(GtkWidget *but, relation_context_t *context) {
728      member_context_t *mcontext = g_new0(member_context_t, 1);
729    
730      /* display members list */
731      mcontext->relation = get_selected_relation(context);
732      if(!mcontext->relation) return;
733    
734      char *str = osm_tag_get_by_key(mcontext->relation->tag, "name");
735      if(!str) str = osm_tag_get_by_key(mcontext->relation->tag, "ref");
736      if(!str)
737        str = g_strdup_printf(_("Members of relation #%ld"),
738                              mcontext->relation->id);
739      else
740        str = g_strdup_printf(_("Members of relation \"%s\""), str);
741    
742      mcontext->dialog =
743        gtk_dialog_new_with_buttons(str,
744            GTK_WINDOW(context->dialog), GTK_DIALOG_MODAL,
745            GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
746            NULL);
747      g_free(str);
748    
749      gtk_dialog_set_default_response(GTK_DIALOG(mcontext->dialog),
750                                      GTK_RESPONSE_CLOSE);
751    
752      /* making the dialog a little wider makes it less "crowded" */
753    #ifdef USE_HILDON
754      gtk_window_set_default_size(GTK_WINDOW(mcontext->dialog), 500, 300);
755    #else
756      gtk_window_set_default_size(GTK_WINDOW(mcontext->dialog), 400, 200);
757    #endif
758    
759      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(mcontext->dialog)->vbox),
760                         member_list_widget(mcontext), TRUE, TRUE, 0);
761    
762      /* ----------------------------------- */
763    
764      gtk_widget_show_all(mcontext->dialog);
765      gtk_dialog_run(GTK_DIALOG(mcontext->dialog));
766      gtk_widget_destroy(mcontext->dialog);
767    
768      g_free(mcontext);
769    }
770    
771    static GtkWidget *relation_list_widget(relation_context_t *context) {
772      GtkWidget *vbox = gtk_vbox_new(FALSE,3);
773      context->view = gtk_tree_view_new();
774    
775      gtk_tree_selection_set_select_function(
776             gtk_tree_view_get_selection(GTK_TREE_VIEW(context->view)),
777             relation_list_selection_func,
778             context, NULL);
779    
780      /* --- "id" column --- */
781      GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
782      gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),
783            -1, _("Id"), renderer, "text", RELATION_COL_ID, NULL);
784    
785      /* --- "Type" column --- */
786      renderer = gtk_cell_renderer_text_new();
787      gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),
788            -1, _("Type"), renderer, "text", RELATION_COL_TYPE, NULL);
789    
790      /* --- "Name" column --- */
791      renderer = gtk_cell_renderer_text_new();
792      g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
793      GtkTreeViewColumn *column =
794        gtk_tree_view_column_new_with_attributes(_("Name"), renderer,
795                     "text", RELATION_COL_NAME, NULL);
796      gtk_tree_view_column_set_expand(column, TRUE);
797      gtk_tree_view_insert_column(GTK_TREE_VIEW(context->view), column, -1);
798    
799      /* --- "members" column --- */
800      renderer = gtk_cell_renderer_text_new();
801      gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(context->view),
802            -1, _("Members"), renderer, "text", RELATION_COL_MEMBERS, NULL);
803    
804      /* build and fill the store */
805      context->store = gtk_list_store_new(RELATION_NUM_COLS,
806                    G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
807                    G_TYPE_POINTER);
808    
809      gtk_tree_view_set_model(GTK_TREE_VIEW(context->view),
810                              GTK_TREE_MODEL(context->store));
811    
812      GtkTreeIter iter;
813      relation_t *relation = context->appdata->osm->relation;
814      while(relation) {
815        char *id = g_strdup_printf("#%ld", relation->id);
816    
817        /* try to find something descriptive */
818        char *name = osm_tag_get_by_key(relation->tag, "name");
819        if(!name) name = osm_tag_get_by_key(relation->tag, "ref");
820    
821        char *num = g_strdup_printf("%d", osm_relation_members_num(relation));
822    
823        /* Append a row and fill in some data */
824        gtk_list_store_append(context->store, &iter);
825        gtk_list_store_set(context->store, &iter,
826                           RELATION_COL_ID, id,
827                           RELATION_COL_TYPE,
828                           osm_tag_get_by_key(relation->tag, "type"),
829                           RELATION_COL_NAME, name,
830                           RELATION_COL_MEMBERS, num,
831                           RELATION_COL_DATA, relation,
832                           -1);
833    
834        g_free(id);
835        g_free(num);
836        relation = relation->next;
837      }
838    
839      g_object_unref(context->store);
840    
841      /* put it into a scrolled window */
842      GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
843      gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
844                                     GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
845      gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),
846                                          GTK_SHADOW_ETCHED_IN);
847      gtk_container_add(GTK_CONTAINER(scrolled_window), context->view);
848    
849      gtk_box_pack_start_defaults(GTK_BOX(vbox), scrolled_window);
850    
851      /* ------- button box ------------ */
852    
853      GtkWidget *hbox = gtk_hbox_new(TRUE,3);
854    
855      context->but_add = gtk_button_new_with_label(_("Add..."));
856      gtk_widget_set_sensitive(context->but_add, FALSE);
857      gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_add);
858      //  gtk_signal_connect(GTK_OBJECT(context->but_add), "clicked",
859      //                         GTK_SIGNAL_FUNC(on_relation_add), context);
860    
861      context->but_edit = gtk_button_new_with_label(_("Edit..."));
862      gtk_widget_set_sensitive(context->but_edit, FALSE);
863      gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_edit);
864      //  gtk_signal_connect(GTK_OBJECT(context->but_edit), "clicked",
865      //                         GTK_SIGNAL_FUNC(on_relation_edit), context);
866    
867      context->but_members = gtk_button_new_with_label(_("Members..."));
868      gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_members);
869      gtk_signal_connect(GTK_OBJECT(context->but_members), "clicked",
870                         GTK_SIGNAL_FUNC(on_relation_members), context);
871    
872      context->but_remove = gtk_button_new_with_label(_("Remove"));
873      gtk_widget_set_sensitive(context->but_remove, FALSE);
874      gtk_box_pack_start_defaults(GTK_BOX(hbox), context->but_remove);
875      //  gtk_signal_connect(GTK_OBJECT(context->but_remove), "clicked",
876      //                 GTK_SIGNAL_FUNC(on_relation_remove), context);
877    
878      gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
879    
880      relation_list_selected(context, FALSE);
881    
882      return vbox;
883    }
884    
885    /* a global view on all relations */
886    void relation_list(appdata_t *appdata) {
887      relation_context_t *context = g_new0(relation_context_t, 1);
888      context->appdata = appdata;
889    
890      printf("relation list\n");
891    
892      context->dialog =
893        gtk_dialog_new_with_buttons(_("All relations"),
894            GTK_WINDOW(appdata->window), GTK_DIALOG_MODAL,
895            GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
896            NULL);
897    
898      gtk_dialog_set_default_response(GTK_DIALOG(context->dialog),
899                                      GTK_RESPONSE_CLOSE);
900    
901    /* making the dialog a little wider makes it less "crowded" */    /* making the dialog a little wider makes it less "crowded" */
902  #ifdef USE_HILDON  #ifdef USE_HILDON
# Line 532  void relation_add_dialog(appdata_t *appd Line 905  void relation_add_dialog(appdata_t *appd
905    gtk_window_set_default_size(GTK_WINDOW(context->dialog), 400, 200);    gtk_window_set_default_size(GTK_WINDOW(context->dialog), 400, 200);
906  #endif  #endif
907    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox),    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context->dialog)->vbox),
908                       relation_list(context), TRUE, TRUE, 0);                       relation_list_widget(context), TRUE, TRUE, 0);
909    
910    /* ----------------------------------- */    /* ----------------------------------- */
911    

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