Diff of /trunk/src/misc.c

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

revision 212 by harbaum, Wed Nov 25 13:52:17 2009 UTC revision 217 by harbaum, Thu Nov 26 21:21:03 2009 UTC
# Line 28  Line 28 
28    
29  #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)  #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
30  #include <hildon/hildon-entry.h>  #include <hildon/hildon-entry.h>
31    #include <hildon/hildon-touch-selector.h>
32    #include <hildon/hildon-picker-button.h>
33    #include <hildon/hildon-picker-dialog.h>
34    #endif
35    
36    #ifdef FREMANTLE
37    #define PICKER_DIALOG
38  #endif  #endif
39    
40  char strlastchr(char *str) {  char strlastchr(char *str) {
# Line 532  GtkWidget *left_label_new(char *str) { Line 539  GtkWidget *left_label_new(char *str) {
539    return widget;    return widget;
540  }  }
541    
542  static void pos_set(GtkMenuItem *item, float lat, float lon) {  static void pos_set(GtkWidget *item, float lat, float lon) {
543    char str[32];    char str[32];
544    
545    pos_lat_str(str, sizeof(str)-1, lat);    pos_lat_str(str, sizeof(str)-1, lat);
# Line 544  static void pos_set(GtkMenuItem *item, f Line 551  static void pos_set(GtkMenuItem *item, f
551    gtk_entry_set_text(GTK_ENTRY(lon_entry), str);    gtk_entry_set_text(GTK_ENTRY(lon_entry), str);
552  }  }
553    
554  static void cb_gps(GtkMenuItem *item, gpointer data) {  static void cb_gps(GtkWidget *item, gpointer data) {
555    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
556    
557    pos_t *refpos = get_pos(appdata);    pos_t *refpos = get_pos(appdata);
# Line 552  static void cb_gps(GtkMenuItem *item, gp Line 559  static void cb_gps(GtkMenuItem *item, gp
559    else        pos_set(item, refpos->lat, refpos->lon);    else        pos_set(item, refpos->lat, refpos->lon);
560  }  }
561    
562  static void cb_geomath(GtkMenuItem *item, gpointer data) {  static void cb_geomath(GtkWidget *item, gpointer data) {
563    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
564    
565    pos_set(item, appdata->geomath.lat, appdata->geomath.lon);    pos_set(item, appdata->geomath.lat, appdata->geomath.lon);
566  }  }
567    
568  #ifdef ENABLE_OSM_GPS_MAP  #ifdef ENABLE_OSM_GPS_MAP
569  static void cb_map(GtkMenuItem *item, gpointer data) {  static void cb_map(GtkWidget *item, gpointer data) {
570    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
571    
572    pos_set(item, appdata->map.pos.lat, appdata->map.pos.lon);    pos_set(item, appdata->map.pos.lat, appdata->map.pos.lon);
573  }  }
574  #endif  #endif
575    
576  static const gchar *menu_item_get_label(GtkMenuItem *menu_item) {  static void cb_cache(GtkWidget *item, gpointer data) {
   GList *children, *l;  
   GtkWidget *child;  
   children = gtk_container_get_children (GTK_CONTAINER (menu_item));  
   for (l = g_list_first (children); l != NULL;  
        l = g_list_next (l)) {  
     child = (GtkWidget *)l->data;  
     if (GTK_IS_LABEL (child)) {  
       return gtk_label_get_label (GTK_LABEL (child));  
     }  
   }  
   return NULL;  
 }  
   
 static void cb_cache(GtkMenuItem *item, gpointer data) {  
   const char *label = menu_item_get_label(item);  
577    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
578    
579    cache_t *cache = appdata->cur_cache;    cache_t *cache = appdata->cur_cache;
580    g_assert(cache);    g_assert(cache);
581    
582    if(!strcmp(label, cache->id))    gint id = (gint)g_object_get_data(G_OBJECT(item), "id");
583    
584      if(!id)
585      pos_set(item, cache->pos.lat, cache->pos.lon);      pos_set(item, cache->pos.lat, cache->pos.lon);
586    else {    else {
587      wpt_t *wpt = cache->wpt;      wpt_t *wpt = cache->wpt;
588      while(wpt) {      while(wpt && id > 1) {
       if(!strcmp(label, wpt->id)) {  
         pos_set(item, wpt->pos.lat, wpt->pos.lon);  
         return;  
       }  
   
589        wpt = wpt->next;        wpt = wpt->next;
590          id--;
591      }      }
592    
593        if(id == 1)
594          pos_set(item, wpt->pos.lat, wpt->pos.lon);
595    }    }
596  }  }
597    
598    #ifndef PICKER_DIALOG
599  static GtkWidget *menu_add(GtkWidget *menu, appdata_t *appdata,  static GtkWidget *menu_add(GtkWidget *menu, appdata_t *appdata,
600                             GtkWidget *icon, char *menu_str,                             GtkWidget *icon, char *menu_str,
601                             void(*func)(GtkMenuItem*, gpointer),                             void(*func)(GtkWidget*, gpointer), gint id,
602                             GtkWidget *lon_entry, GtkWidget *lat_entry) {                             GtkWidget *lon_entry, GtkWidget *lat_entry) {
603    
604    GtkWidget *item = gtk_image_menu_item_new_with_label(menu_str);    GtkWidget *item = gtk_image_menu_item_new_with_label(menu_str);
# Line 614  static GtkWidget *menu_add(GtkWidget *me Line 608  static GtkWidget *menu_add(GtkWidget *me
608    
609    g_object_set_data(G_OBJECT(item), "lat_entry", (gpointer)lat_entry);    g_object_set_data(G_OBJECT(item), "lat_entry", (gpointer)lat_entry);
610    g_object_set_data(G_OBJECT(item), "lon_entry", (gpointer)lon_entry);    g_object_set_data(G_OBJECT(item), "lon_entry", (gpointer)lon_entry);
611      g_object_set_data(G_OBJECT(item), "id", (gpointer)id);
612    
613    if(func)    if(func)
614      gtk_signal_connect(GTK_OBJECT(item), "activate",      gtk_signal_connect(GTK_OBJECT(item), "activate",
# Line 628  static GtkWidget *popup_menu_create(appd Line 623  static GtkWidget *popup_menu_create(appd
623                      GtkWidget *lat_entry, GtkWidget *lon_entry) {                      GtkWidget *lat_entry, GtkWidget *lon_entry) {
624    GtkWidget *menu = gtk_menu_new();    GtkWidget *menu = gtk_menu_new();
625    
626    menu_add(menu, appdata, NULL, _("Current position (GPS)"),    menu_add(menu, appdata, icon_get_widget(ICON_POS, 18),
627             cb_gps, lon_entry, lat_entry);             _("Current position (GPS)"), cb_gps, 0, lon_entry, lat_entry);
628    menu_add(menu, appdata, NULL, _("Geomath projection"),    menu_add(menu, appdata, icon_get_widget(ICON_POS, 19),
629             cb_geomath, lon_entry, lat_entry);             _("Geomath projection"), cb_geomath, 0, lon_entry, lat_entry);
630  #ifdef ENABLE_OSM_GPS_MAP  #ifdef ENABLE_OSM_GPS_MAP
631    menu_add(menu, appdata, NULL, _("Map position"),    menu_add(menu, appdata, icon_get_widget(ICON_POS, 20),
632             cb_map, lon_entry, lat_entry);             _("Map position"), cb_map, 0, lon_entry, lat_entry);
633  #endif  #endif
634    
635    if(appdata->cur_cache) {    if(appdata->cur_cache) {
636      cache_t *cache = appdata->cur_cache;      cache_t *cache = appdata->cur_cache;
637    
638        char *name = cache->name;
639        if(!name) name = cache->id;
640    
641      if(!isnan(cache->pos.lat) && !isnan(cache->pos.lon)) {      if(!isnan(cache->pos.lat) && !isnan(cache->pos.lon)) {
642        menu_add(menu, appdata, icon_get_widget(ICON_CACHE_TYPE, cache->type),        menu_add(menu, appdata, icon_get_widget(ICON_POS, cache->type + 6),
643                 cache->id, cb_cache, lon_entry, lat_entry);                 name, cb_cache, 0, lon_entry, lat_entry);
644      }      }
645    
     printf("appending cache waypoints\n");  
646      wpt_t *wpt = cache->wpt;      wpt_t *wpt = cache->wpt;
647        gint id = 1;
648      while(wpt) {      while(wpt) {
649        GtkWidget *icon = NULL;        GtkWidget *icon = NULL;
650        if(wpt->sym != WPT_SYM_UNKNOWN)        if(wpt->sym != WPT_SYM_UNKNOWN)
651          icon = icon_get_widget(ICON_WPT, wpt->sym);          icon = icon_get_widget(ICON_POS, wpt->sym);
652    
653          char *name = wpt->desc;
654          if(!name) name = wpt->cmt;
655          if(!name) name = wpt->id;
656    
657        menu_add(menu, appdata, icon, wpt->id, cb_cache,        menu_add(menu, appdata, icon, name, cb_cache, id++,
658                 lon_entry, lat_entry);                 lon_entry, lat_entry);
659    
660        wpt = wpt->next;        wpt = wpt->next;
# Line 682  static void on_popup_destroy(GtkWidget * Line 684  static void on_popup_destroy(GtkWidget *
684    GtkWidget *menu = g_object_get_data(G_OBJECT(widget), "menu");    GtkWidget *menu = g_object_get_data(G_OBJECT(widget), "menu");
685    gtk_widget_destroy(menu);    gtk_widget_destroy(menu);
686  }  }
687    #endif
688    
689    #ifdef PICKER_DIALOG
690    
691    enum {
692      PICKER_COL_ICON = 0,
693      PICKER_COL_NAME,
694      PICKER_COL_ID,
695      PICKER_COL_CB,
696      PICKER_NUM_COLS
697    };
698    
699    static void picker_add(GtkListStore *store,  appdata_t *appdata,
700                           GdkPixbuf *icon, char *menu_str,
701                           void(*func)(GtkWidget*, gpointer), gint id) {
702      GtkTreeIter     iter;
703    
704      /* Append a row and fill in some data */
705      gtk_list_store_append (store, &iter);
706    
707      gtk_list_store_set(store, &iter,
708                         PICKER_COL_ICON, icon,
709                         PICKER_COL_NAME, menu_str,
710                         PICKER_COL_ID, id,
711                         PICKER_COL_CB, func,
712                         -1);
713    }
714    
715    static void on_picker_activated(GtkTreeView        *treeview,
716                                    GtkTreePath        *path,
717                                    GtkTreeViewColumn  *col,
718                                    gpointer            userdata) {
719      GtkTreeIter   iter;
720      GtkTreeModel *model = gtk_tree_view_get_model(treeview);
721    
722      if(gtk_tree_model_get_iter(model, &iter, path)) {
723        gint id;
724        void(*func)(GtkWidget*, gpointer);
725        gtk_tree_model_get(model, &iter,
726                           PICKER_COL_ID, &id,
727                           PICKER_COL_CB, &func,
728                           -1);
729    
730        /* set id on widget as callbacks expect it this way */
731        g_object_set_data(G_OBJECT(treeview), "id", (gpointer)id);
732        func(GTK_WIDGET(treeview), userdata);
733      }
734    }
735    
736    static GtkWidget *picker_create(appdata_t *appdata,
737                                    GtkWidget *lat_entry, GtkWidget *lon_entry) {
738      GtkCellRenderer *renderer;
739      GtkListStore    *store;
740    
741      GtkWidget *view = gtk_tree_view_new();
742    
743      g_object_set_data(G_OBJECT(view), "lat_entry", (gpointer)lat_entry);
744      g_object_set_data(G_OBJECT(view), "lon_entry", (gpointer)lon_entry);
745    
746      /* --- "Icon" column --- */
747      renderer = gtk_cell_renderer_pixbuf_new();
748      gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
749          -1, "Icon", renderer, "pixbuf", PICKER_COL_ICON, NULL);
750    
751      /* --- "Name" column --- */
752      renderer = gtk_cell_renderer_text_new();
753      g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL );
754      GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(
755                     "Name", renderer, "text", PICKER_COL_NAME, NULL);
756      gtk_tree_view_column_set_expand(column, TRUE);
757      gtk_tree_view_insert_column(GTK_TREE_VIEW(view), column, -1);
758    
759      store = gtk_list_store_new(PICKER_NUM_COLS,
760                                 GDK_TYPE_PIXBUF,
761                                 G_TYPE_STRING,
762                                 G_TYPE_INT,
763                                 G_TYPE_POINTER);
764    
765      picker_add(store, appdata, icon_get(ICON_POS, 18),
766                 _("Current position (GPS)"), cb_gps, 0);
767      picker_add(store, appdata, icon_get(ICON_POS, 19),
768                 _("Geomath projection"), cb_geomath, 0);
769    #ifdef ENABLE_OSM_GPS_MAP
770      picker_add(store, appdata, icon_get(ICON_POS, 20),
771                 _("Map position"), cb_map, 0);
772    #endif
773    
774      if(appdata->cur_cache) {
775        cache_t *cache = appdata->cur_cache;
776    
777        char *name = cache->name;
778        if(!name) name = cache->id;
779    
780        if(!isnan(cache->pos.lat) && !isnan(cache->pos.lon)) {
781          picker_add(store, appdata, icon_get(ICON_POS, cache->type + 6),
782                     name, cb_cache, 0);
783        }
784    
785        wpt_t *wpt = cache->wpt;
786        gint id = 1;
787        while(wpt) {
788          GdkPixbuf *icon = NULL;
789          if(wpt->sym != WPT_SYM_UNKNOWN)
790            icon = icon_get(ICON_POS, wpt->sym);
791    
792          char *name = wpt->desc;
793          if(!name) name = wpt->cmt;
794          if(!name) name = wpt->id;
795    
796          picker_add(store, appdata, icon, name, cb_cache, id++);
797          wpt = wpt->next;
798        }
799      }
800    
801    
802      gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
803      g_object_unref(store);
804    
805      /* make list react on clicks */
806      g_signal_connect(view, "row-activated",
807                       (GCallback)on_picker_activated, appdata);
808    
809    #if 0
810      g_signal_connect(view, "destroy",
811                       (GCallback)cachelist_destroy, ce);
812    #endif
813    
814      /* put this inside a scrolled view */
815    #ifndef USE_PANNABLE_AREA
816      GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
817      gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
818                                     GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
819      gtk_container_add(GTK_CONTAINER(scrolled_window), view);
820      return scrolled_window;
821    #else
822      GtkWidget *pannable_area = hildon_pannable_area_new();
823      gtk_container_add(GTK_CONTAINER(pannable_area), view);
824      return pannable_area;
825    #endif
826    }
827    
828    static gint on_picker_button_press(GtkWidget *button,
829                       GdkEventButton *event, gpointer data) {
830      appdata_t *appdata = (appdata_t*)data;
831    
832      gpointer lat_entry = g_object_get_data(G_OBJECT(button), "lat_entry");
833      gpointer lon_entry = g_object_get_data(G_OBJECT(button), "lon_entry");
834    
835      if(event->type == GDK_BUTTON_PRESS) {
836        GtkWidget *dialog =
837          gtk_dialog_new_with_buttons(_("Preset coordinates"),
838              GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
839                                      GTK_DIALOG_MODAL,
840              GTK_STOCK_OK,     GTK_RESPONSE_ACCEPT,
841              GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
842              NULL);
843    
844        gtk_window_set_default_size(GTK_WINDOW(dialog), 400, 200);
845    
846        gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox),
847                                    picker_create(appdata, lat_entry, lon_entry));
848    
849        gtk_widget_show_all(dialog);
850        gtk_dialog_run(GTK_DIALOG(dialog));
851        gtk_widget_destroy(dialog);
852    
853        return TRUE;
854      }
855      return FALSE;
856    }
857    #endif
858    
859  GtkWidget *coo_popup(appdata_t *appdata,  GtkWidget *coo_popup(appdata_t *appdata,
860                       GtkWidget *lat_entry, GtkWidget *lon_entry) {                       GtkWidget *lat_entry, GtkWidget *lon_entry) {
861    
862    GtkWidget *button = gtk_button_new();    GtkWidget *button = gtk_button_new();
 #ifdef FREMANTLE  
   hildon_gtk_widget_set_theme_size(button,  
           (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));  
 #endif  
863    
864    gtk_button_set_image(GTK_BUTTON(button),    gtk_button_set_image(GTK_BUTTON(button), icon_get_widget(ICON_POS, 17));
        gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON));  
865    
866    gtk_widget_set_tooltip_text(button, _("Preset coordinates"));    gtk_widget_set_tooltip_text(button, _("Preset coordinates"));
867    
868    #ifndef PICKER_DIALOG
869    gtk_signal_connect(GTK_OBJECT(button), "button-press-event",    gtk_signal_connect(GTK_OBJECT(button), "button-press-event",
870                       (GtkSignalFunc)on_popup_button_press, appdata);                       (GtkSignalFunc)on_popup_button_press, appdata);
871    
# Line 705  GtkWidget *coo_popup(appdata_t *appdata, Line 874  GtkWidget *coo_popup(appdata_t *appdata,
874    
875    g_object_set_data(G_OBJECT(button), "menu",    g_object_set_data(G_OBJECT(button), "menu",
876                      popup_menu_create(appdata, lat_entry, lon_entry));                      popup_menu_create(appdata, lat_entry, lon_entry));
877    #else
878    #ifdef FREMANTLE
879      hildon_gtk_widget_set_theme_size(button,
880            (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
881    #endif
882    
883      g_object_set_data(G_OBJECT(button), "lat_entry", (gpointer)lat_entry);
884      g_object_set_data(G_OBJECT(button), "lon_entry", (gpointer)lon_entry);
885    
886      gtk_signal_connect(GTK_OBJECT(button), "button-press-event",
887                         (GtkSignalFunc)on_picker_button_press, appdata);
888    #endif
889    
890    return button;    return button;
891  }  }
# Line 716  GtkWidget *entry_new(void) { Line 897  GtkWidget *entry_new(void) {
897    return hildon_entry_new(HILDON_SIZE_AUTO);    return hildon_entry_new(HILDON_SIZE_AUTO);
898  #endif  #endif
899  }  }
900    
901    gboolean pos_differ(pos_t *pos1, pos_t *pos2) {
902      int lat1 = (60000 * pos1->lat)+0.5, lon1 = (60000 * pos1->lon)+0.5;
903      int lat2 = (60000 * pos2->lat)+0.5, lon2 = (60000 * pos2->lon)+0.5;
904    
905      return((lat1 != lat2) || (lon1 != lon2));
906    }
907    

Legend:
Removed from v.212  
changed lines
  Added in v.217