/*
* viking -- GPS Data and Topo Analyzer, Explorer, and Manager
*
- * Copyright (C) 2013, Rob Norris <rw_norris@hotmail.com>
+ * Copyright (C) 2013-2015, Rob Norris <rw_norris@hotmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "viking.h"
#include "viktrwlayer_waypointlist.h"
+#include "viktrwlayer_wpwin.h"
// Long formatted date+basic time - listing this way ensures the string comparison sort works - so no local type format %x or %c here!
#define WAYPOINT_LIST_DATE_FORMAT "%Y-%m-%d %H:%M"
VikWaypoint *wpt = VIK_WAYPOINT(values[MA_WPT]);
VikViewport *vvp = VIK_VIEWPORT(values[MA_VVP]);
- vik_viewport_set_center_coord ( vvp, &(wpt->coord) );
+ vik_viewport_set_center_coord ( vvp, &(wpt->coord), TRUE );
trw_layer_waypoint_select (values);
static void trw_layer_show_picture ( menu_array_values values )
{
- VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
VikWaypoint *wpt = VIK_WAYPOINT(values[MA_WPT]);
-
#ifdef WINDOWS
ShellExecute(NULL, "open", wpt->image, NULL, NULL, SW_SHOWNORMAL);
#else
+ VikTrwLayer *vtl = VIK_TRW_LAYER(values[MA_VTL]);
GError *err = NULL;
gchar *quoted_file = g_shell_quote ( wpt->image );
gchar *cmd = g_strdup_printf ( "%s %s", a_vik_get_image_viewer(), quoted_file );
}
+typedef struct {
+ gboolean has_layer_names;
+ gboolean include_positions;
+ GString *str;
+} copy_data_t;
+
+/**
+ * At the moment allow copying the data displayed** with or without the positions
+ * (since the position data is not shown in the list but is useful in copying to external apps)
+ *
+ * ** ATM The visibility flag is not copied and neither is a text representation of the waypoint symbol
+ */
+static void copy_selection (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ copy_data_t *cd = (copy_data_t*) data;
+
+ gchar* layername; gtk_tree_model_get ( model, iter, 0, &layername, -1 );
+ gchar* name; gtk_tree_model_get ( model, iter, 1, &name, -1 );
+ gchar* date; gtk_tree_model_get ( model, iter, 2, &date, -1 );
+ gchar* comment; gtk_tree_model_get ( model, iter, 4, &comment, -1 );
+ if ( comment == NULL )
+ comment = g_strdup ( "" );
+ gint hh; gtk_tree_model_get ( model, iter, 5, &hh, -1 );
+
+ VikWaypoint *wpt; gtk_tree_model_get ( model, iter, WPT_COL_NUM, &wpt, -1 );
+ struct LatLon ll;
+ if ( wpt ) {
+ vik_coord_to_latlon ( &wpt->coord, &ll );
+ }
+ gchar sep = '\t'; // Could make this configurable - but simply always make it a tab character for now
+ // NB Even if the columns have been reordered - this copies it out only in the original default order
+ // if col 0 is displayed then also copy the layername
+ // Note that the lat/lon data copy is using the users locale
+ if ( cd->has_layer_names ) {
+ if ( cd->include_positions )
+ g_string_append_printf ( cd->str, "%s%c%s%c%s%c%s%c%d%c%.6f%c%.6f\n", layername, sep, name, sep, date, sep, comment, sep, hh, sep, ll.lat, sep, ll.lon );
+ else
+ g_string_append_printf ( cd->str, "%s%c%s%c%s%c%s%c%d\n", layername, sep, name, sep, date, sep, comment, sep, hh );
+ }
+ else {
+ if ( cd->include_positions )
+ g_string_append_printf ( cd->str, "%s%c%s%c%s%c%d%c%.6f%c%.6f\n", name, sep, date, sep, comment, sep, hh, sep, ll.lat, sep, ll.lon );
+ else
+ g_string_append_printf ( cd->str, "%s%c%s%c%s%c%d\n", name, sep, date, sep, comment, sep, hh );
+ }
+ g_free ( layername );
+ g_free ( name );
+ g_free ( date );
+ g_free ( comment );
+}
+
+static void trw_layer_copy_selected ( GtkWidget *tree_view, gboolean include_positions )
+{
+ GtkTreeSelection *selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(tree_view) );
+ // NB GTK3 has gtk_tree_view_get_n_columns() but we're GTK2 ATM
+ GList *gl = gtk_tree_view_get_columns ( GTK_TREE_VIEW(tree_view) );
+ guint count = g_list_length ( gl );
+ g_list_free ( gl );
+ copy_data_t cd;
+ cd.has_layer_names = (count > WPT_LIST_COLS-3);
+ cd.str = g_string_new ( NULL );
+ cd.include_positions = include_positions;
+ gtk_tree_selection_selected_foreach ( selection, copy_selection, &cd );
+
+ a_clipboard_copy ( VIK_CLIPBOARD_DATA_TEXT, 0, 0, 0, cd.str->str, NULL );
+
+ g_string_free ( cd.str, TRUE );
+}
+
+static void trw_layer_copy_selected_only_visible_columns ( GtkWidget *tree_view )
+{
+ trw_layer_copy_selected ( tree_view, FALSE );
+}
+
+static void trw_layer_copy_selected_with_position ( GtkWidget *tree_view )
+{
+ trw_layer_copy_selected ( tree_view, TRUE );
+}
+
+static void add_copy_menu_items ( GtkMenu *menu, GtkWidget *tree_view )
+{
+ GtkWidget *item = gtk_image_menu_item_new_with_mnemonic ( _("_Copy Data") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_copy_selected_only_visible_columns), tree_view );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Copy Data (with _positions)") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_copy_selected_with_position), tree_view );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+}
+
static gboolean add_menu_items ( GtkMenu *menu, VikTrwLayer *vtl, VikWaypoint *wpt, gpointer wpt_uuid, VikViewport *vvp, GtkWidget *tree_view, gpointer data )
{
static menu_array_values values;
gtk_widget_show ( item );
gtk_widget_set_sensitive ( item, GPOINTER_TO_INT(wpt->image) );
+ add_copy_menu_items ( menu, tree_view );
+
+ return TRUE;
+}
+
+static gboolean trw_layer_waypoint_menu_popup_multi ( GtkWidget *tree_view,
+ GdkEventButton *event,
+ gpointer data )
+{
+ GtkWidget *menu = gtk_menu_new();
+
+ add_copy_menu_items ( GTK_MENU(menu), tree_view );
+
+ gtk_menu_popup ( GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time() );
+
return TRUE;
}
// This relies on an row being selected as part of the right click
GtkTreeSelection *selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(tree_view) );
if ( gtk_tree_selection_count_selected_rows (selection) != 1 )
- return FALSE;
+ return trw_layer_waypoint_menu_popup_multi ( tree_view, event, data );
GtkTreePath *path;
GtkTreeModel *model = gtk_tree_view_get_model ( GTK_TREE_VIEW(tree_view) );
udataU.wp = wpt;
udataU.uuid = NULL;
- gpointer *wptf;
+ gpointer wptf;
wptf = g_hash_table_find ( vik_trw_layer_get_waypoints(vtl), (GHRFunc) trw_layer_waypoint_find_uuid, &udataU );
if ( wptf && udataU.uuid ) {
*/
static void trw_layer_waypoint_list_add ( vik_trw_waypoint_list_t *vtdl,
GtkTreeStore *store,
- vik_units_distance_t dist_units,
- vik_units_height_t height_units )
+ vik_units_height_t height_units,
+ const gchar* date_format )
{
GtkTreeIter t_iter;
VikWaypoint *wpt = vtdl->wpt;
#if GLIB_CHECK_VERSION(2,26,0)
GDateTime* gdt = g_date_time_new_from_unix_utc ( wpt->timestamp );
- gchar *time = g_date_time_format ( gdt, WAYPOINT_LIST_DATE_FORMAT );
- strncpy ( time_buf, time, sizeof(time_buf) );
+ gchar *time = g_date_time_format ( gdt, date_format );
+ g_strlcpy ( time_buf, time, sizeof(time_buf) );
g_free ( time );
g_date_time_unref ( gdt);
#else
GDate* gdate_start = g_date_new ();
g_date_set_time_t ( gdate_start, wpt->timestamp );
- g_date_strftime ( time_buf, sizeof(time_buf), WAYPOINT_LIST_DATE_FORMAT, gdate_start );
+ g_date_strftime ( time_buf, sizeof(time_buf), date_format, gdate_start );
g_date_free ( gdate_start );
#endif
}
//gtk_tree_selection_set_select_function ( gtk_tree_view_get_selection (GTK_TREE_VIEW(vt)), vik_treeview_selection_filter, vt, NULL );
- vik_units_distance_t dist_units = a_vik_get_units_distance ();
vik_units_height_t height_units = a_vik_get_units_height ();
//GList *gl = get_waypoints_and_layers_cb ( vl, user_data );
//g_list_foreach ( waypoints_and_layers, (GFunc) trw_layer_waypoint_list_add, store );
+ gchar *date_format = NULL;
+ if ( !a_settings_get_string ( VIK_SETTINGS_LIST_DATE_FORMAT, &date_format ) )
+ date_format = g_strdup ( WAYPOINT_LIST_DATE_FORMAT );
+
GList *gl = waypoints_and_layers;
while ( gl ) {
- trw_layer_waypoint_list_add ( (vik_trw_waypoint_list_t*)gl->data, store, dist_units, height_units );
+ trw_layer_waypoint_list_add ( (vik_trw_waypoint_list_t*)gl->data, store, height_units, date_format );
gl = g_list_next ( gl );
}
+ g_free ( date_format );
GtkWidget *view = gtk_tree_view_new();
GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_set_expand ( column, TRUE );
if ( height_units == VIK_UNITS_HEIGHT_FEET )
- column = my_new_column_text ( _("Max Height\n(Feet)"), renderer, view, column_runner++ );
+ (void)my_new_column_text ( _("Max Height\n(Feet)"), renderer, view, column_runner++ );
else
- column = my_new_column_text ( _("Max Height\n(Metres)"), renderer, view, column_runner++ );
+ (void)my_new_column_text ( _("Max Height\n(Metres)"), renderer, view, column_runner++ );
GtkCellRenderer *renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
g_object_set (G_OBJECT (renderer_pixbuf), "xalign", 0.5, NULL);
gtk_tree_view_append_column ( GTK_TREE_VIEW(view), column );
gtk_tree_view_set_model ( GTK_TREE_VIEW(view), GTK_TREE_MODEL(store) );
- gtk_tree_selection_set_mode ( gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), GTK_SELECTION_BROWSE ); // GTK_SELECTION_MULTIPLE
+ gtk_tree_selection_set_mode ( gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), GTK_SELECTION_MULTIPLE );
gtk_tree_view_set_rules_hint ( GTK_TREE_VIEW(view), TRUE );
g_object_unref(store);