#include "viktrwlayer_pixmap.h"
#include "viktrwlayer_tpwin.h"
#include "viktrwlayer_propwin.h"
+#include "garminsymbols.h"
#include "thumbnails.h"
#include "background.h"
+#include "gpx.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
+#define GOOGLE_DIRECTIONS_STRING "(wget -O - \"http://maps.google.com/maps?q=%f,%f to %f,%f&output=js\" 2>/dev/null)"
#define VIK_TRW_LAYER_TRACK_GC 13
#define VIK_TRW_LAYER_TRACK_GC_RATES 10
#define VIK_TRW_LAYER_TRACK_GC_MIN 0
#define TRACKPOINT_SIZE_APPROX 5
#define WAYPOINT_SIZE_APPROX 5
+#define MIN_STOP_LENGTH 15
+#define MAX_STOP_LENGTH 86400
+#define DRAW_ELEVATION_FACTOR 30 /* height of elevation plotting, sort of relative to zoom level ("mpp" that isn't mpp necessarily) */
+ /* this is multiplied by user-inputted value from 1-100. */
enum {
VIK_TRW_LAYER_SUBLAYER_TRACKS,
VIK_TRW_LAYER_SUBLAYER_WAYPOINTS,
gboolean tracks_visible, waypoints_visible;
guint8 drawmode;
guint8 drawpoints;
+ guint8 drawelevation;
+ guint8 elevation_factor;
+ guint8 drawstops;
+ guint32 stop_length;
guint8 drawlines;
guint8 line_thickness;
guint8 bg_line_thickness;
guint8 wp_symbol;
guint8 wp_size;
+ gboolean wp_draw_symbols;
gdouble velocity_min, velocity_max;
GArray *track_gc;
/* track editing tool -- more specifically, moving tps */
gboolean moving_tp;
+ /* magic scissors tool */
+ gboolean magic_scissors_started;
+ VikCoord magic_scissors_coord;
+
gboolean drawlabels;
gboolean drawimages;
guint8 image_alpha;
GtkMenu *wp_right_click_menu;
+ /* menu */
+ VikStdLayerMenuItem menu_selection;
+
};
/* A caached waypoint image. */
gdouble ce1, ce2, cn1, cn2;
};
+static void vik_trw_layer_set_menu_selection(VikTrwLayer *vtl, guint16);
+static guint16 vik_trw_layer_get_menu_selection(VikTrwLayer *vtl);
+
+static void trw_layer_delete_item ( gpointer *pass_along );
+static void trw_layer_copy_item_cb( gpointer *pass_along);
+static void trw_layer_cut_item_cb( gpointer *pass_along);
+
static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] );
static void trw_layer_find_maxmin_tracks ( const gchar *name, GList **t, struct LatLon maxmin[2] );
static void trw_layer_realize_track ( gchar *name, VikTrack *track, gpointer pass_along[4] );
static void init_drawing_params ( struct DrawingParams *dp, VikViewport *vp );
-static gboolean tool_new_waypoint ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-static gboolean tool_new_track ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
static VikTrwLayer *trw_layer_copy ( VikTrwLayer *vtl, gpointer vp );
+static void trw_layer_marshall( VikTrwLayer *vtl, guint8 **data, gint *len );
+static VikTrwLayer *trw_layer_unmarshall( gpointer data, gint len, VikViewport *vvp );
+
static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerParamData data, VikViewport *vp );
static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id );
-static gpointer trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer );
-static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, gpointer item );
+static void trw_layer_del_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer );
+static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer, guint8 **item, guint *len );
+static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *item, guint len );
static void trw_layer_free_copied_item ( gint subtype, gpointer item );
+static void trw_layer_drag_drop_request ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, GtkTreeIter *src_item_iter, GtkTreePath *dest_path );
static void trw_layer_cancel_tps_of_track ( VikTrwLayer *vtl, const gchar *trk_name );
static void trw_layer_cancel_last_tp ( VikTrwLayer *vtl );
static void trw_layer_cancel_current_tp ( VikTrwLayer *vtl, gboolean destroy );
static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response );
static void trw_layer_tpwin_init ( VikTrwLayer *vtl );
-static gboolean tool_edit_trackpoint ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-static gboolean tool_show_picture ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-static gboolean tool_edit_waypoint ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
-static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gpointer tool_edit_trackpoint_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
+static gboolean tool_edit_trackpoint_move ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
+static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
+static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gpointer tool_edit_waypoint_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
+static gboolean tool_edit_waypoint_move ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
+static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
+static gpointer tool_new_track_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gpointer tool_magic_scissors_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_magic_scissors_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+
static gboolean uppercase_exists_in_hash ( GHashTable *hash, const gchar *str );
static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mode );
+static gchar *get_new_unique_sublayer_name (VikTrwLayer *vtl, gint sublayer_type, const gchar *name);
+static void waypoint_convert ( const gchar *name, VikWaypoint *wp, VikCoordMode *dest_mode );
+static void track_convert ( const gchar *name, VikTrack *tr, VikCoordMode *dest_mode );
+
static VikToolInterface trw_layer_tools[] = {
- { "Create Waypoint", (VikToolInterfaceFunc) tool_new_waypoint, NULL },
- { "Create Track", (VikToolInterfaceFunc) tool_new_track, NULL },
- { "Edit Waypoint", (VikToolInterfaceFunc) tool_edit_waypoint, (VikToolInterfaceFunc) tool_edit_waypoint_release },
- { "Edit Trackpoint", (VikToolInterfaceFunc) tool_edit_trackpoint, (VikToolInterfaceFunc) tool_edit_trackpoint_release },
- { "Show Picture", (VikToolInterfaceFunc) tool_show_picture, NULL },
-};
+ { "Create Waypoint", (VikToolConstructorFunc) tool_new_waypoint_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_new_waypoint_click, NULL, NULL },
+ { "Create Track", (VikToolConstructorFunc) tool_new_track_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_new_track_click, NULL, NULL },
+
+ { "Edit Waypoint", (VikToolConstructorFunc) tool_edit_waypoint_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_edit_waypoint_click,
+ (VikToolMouseFunc) tool_edit_waypoint_move,
+ (VikToolMouseFunc) tool_edit_waypoint_release },
+
+ { "Edit Trackpoint", (VikToolConstructorFunc) tool_edit_trackpoint_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_edit_trackpoint_click,
+ (VikToolMouseFunc) tool_edit_trackpoint_move,
+ (VikToolMouseFunc) tool_edit_trackpoint_release },
+
+ { "Show Picture", (VikToolConstructorFunc) tool_show_picture_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_show_picture_click, NULL, NULL },
+
+ { "Magic Scissors", (VikToolConstructorFunc) tool_magic_scissors_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_magic_scissors_click, NULL, NULL },
+};
/****** PARAMETERS ******/
static gchar *params_drawmodes[] = { "Draw by Track", "Draw by Velocity", "All Tracks Black", 0 };
static gchar *params_wpsymbols[] = { "Filled Square", "Square", "Circle", "X", 0 };
+
static VikLayerParamScale params_scales[] = {
/* min max step digits */
{ 1, 10, 1, 0 }, /* line_thickness */
{ 5, 500, 5, 0 }, /* image cache_size */
{ 0, 8, 1, 0 }, /* image cache_size */
{ 1, 64, 1, 0 }, /* wpsize */
+ { MIN_STOP_LENGTH, MAX_STOP_LENGTH, 1, 0 }, /* stop_length */
+ { 1, 100, 1, 0 }, /* stop_length */
};
VikLayerParam trw_layer_params[] = {
{ "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES },
{ "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES },
- { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Track Drawing Mode:", VIK_LAYER_WIDGET_RADIOGROUP, params_drawmodes },
+ { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Track Drawing Mode:", VIK_LAYER_WIDGET_RADIOGROUP, NULL },
{ "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, "Draw Track Lines", VIK_LAYER_WIDGET_CHECKBUTTON },
{ "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, "Draw Trackpoints", VIK_LAYER_WIDGET_CHECKBUTTON },
+ { "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, "Draw Elevation", VIK_LAYER_WIDGET_CHECKBUTTON },
+ { "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Draw Elevation Height %:", VIK_LAYER_WIDGET_HSCALE, params_scales + 9 },
+
+ { "drawstops", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, "Draw Stops", VIK_LAYER_WIDGET_CHECKBUTTON },
+ { "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Min Stop Length (seconds):", VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 8 },
+
{ "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Track Thickness:", VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 0 },
{ "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, "Track BG Thickness:", VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 6 },
{ "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, "Track Background Color", VIK_LAYER_WIDGET_COLOR, 0 },
{ "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, "Waypoint Text:", VIK_LAYER_WIDGET_COLOR, 0 },
{ "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, "Background:", VIK_LAYER_WIDGET_COLOR, 0 },
{ "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, "Fake BG Color Translucency:", VIK_LAYER_WIDGET_CHECKBUTTON, 0 },
- { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, "Waypoint symbol:", VIK_LAYER_WIDGET_RADIOGROUP, params_wpsymbols },
+ { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, "Waypoint marker:", VIK_LAYER_WIDGET_RADIOGROUP, NULL },
{ "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, "Waypoint size:", VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 7 },
+ { "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, "Draw Waypoint Symbols:", VIK_LAYER_WIDGET_CHECKBUTTON },
{ "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, "Draw Waypoint Images", VIK_LAYER_WIDGET_CHECKBUTTON },
{ "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, "Image Size (pixels):", VIK_LAYER_WIDGET_HSCALE, params_scales + 3 },
{ "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, "Image Memory Cache Size:", VIK_LAYER_WIDGET_HSCALE, params_scales + 5 },
};
-enum { PARAM_TV, PARAM_WV, PARAM_DM, PARAM_DL, PARAM_DP, PARAM_LT, PARAM_BLT, PARAM_TBGC, PARAM_VMIN, PARAM_VMAX, PARAM_DLA, PARAM_WPC, PARAM_WPTC, PARAM_WPBC, PARAM_WPBA, PARAM_WPSYM, PARAM_WPSIZE, PARAM_DI, PARAM_IS, PARAM_IA, PARAM_ICS, NUM_PARAMS };
+enum { PARAM_TV, PARAM_WV, PARAM_DM, PARAM_DL, PARAM_DP, PARAM_DE, PARAM_EF, PARAM_DS, PARAM_SL, PARAM_LT, PARAM_BLT, PARAM_TBGC, PARAM_VMIN, PARAM_VMAX, PARAM_DLA, PARAM_WPC, PARAM_WPTC, PARAM_WPBC, PARAM_WPBA, PARAM_WPSYM, PARAM_WPSIZE, PARAM_WPSYMS, PARAM_DI, PARAM_IS, PARAM_IA, PARAM_ICS, NUM_PARAMS };
/****** END PARAMETERS ******/
params_groups, /* params_groups */
sizeof(params_groups)/sizeof(params_groups[0]), /* number of groups */
+ VIK_MENU_ITEM_ALL,
+
(VikLayerFuncCreate) vik_trw_layer_create,
(VikLayerFuncRealize) vik_trw_layer_realize,
(VikLayerFuncPostRead) trw_layer_verify_thumbnails,
(VikLayerFuncDraw) vik_trw_layer_draw,
(VikLayerFuncChangeCoordMode) trw_layer_change_coord_mode,
+ (VikLayerFuncSetMenuItemsSelection) vik_trw_layer_set_menu_selection,
+ (VikLayerFuncGetMenuItemsSelection) vik_trw_layer_get_menu_selection,
+
(VikLayerFuncAddMenuItems) vik_trw_layer_add_menu_items,
(VikLayerFuncSublayerAddMenuItems) vik_trw_layer_sublayer_add_menu_items,
(VikLayerFuncSublayerToggleVisible) vik_trw_layer_sublayer_toggle_visible,
(VikLayerFuncCopy) trw_layer_copy,
+ (VikLayerFuncMarshall) trw_layer_marshall,
+ (VikLayerFuncUnmarshall) trw_layer_unmarshall,
(VikLayerFuncSetParam) trw_layer_set_param,
(VikLayerFuncGetParam) trw_layer_get_param,
(VikLayerFuncReadFileData) a_gpspoint_read_file,
(VikLayerFuncWriteFileData) a_gpspoint_write_file,
+ (VikLayerFuncDeleteItem) trw_layer_del_item,
(VikLayerFuncCopyItem) trw_layer_copy_item,
(VikLayerFuncPasteItem) trw_layer_paste_item,
(VikLayerFuncFreeCopiedItem) trw_layer_free_copied_item,
+
+ (VikLayerFuncDragDropRequest) trw_layer_drag_drop_request,
};
/* for copy & paste (I think?) */
typedef struct {
- gchar *name;
- VikWaypoint *wp;
-} NamedWaypoint;
-
-typedef struct {
- gchar *name;
- VikTrack *tr;
-} NamedTrack;
+ guint len;
+ guint8 data[0];
+ // gchar *name;
+ // VikWaypoint *wp;
+} FlatItem;
GType vik_trw_layer_get_type ()
{
return vtl_type;
}
+static void trw_layer_del_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer )
+{
+ static gpointer pass_along[5];
+ if (!sublayer) {
+ return;
+ }
+
+ pass_along[0] = vtl;
+ pass_along[1] = NULL;
+ pass_along[2] = (gpointer) subtype;
+ pass_along[3] = sublayer;
+ pass_along[4] = NULL;
+
+ trw_layer_delete_item ( pass_along );
+}
+
+static void trw_layer_copy_item_cb( gpointer pass_along[5])
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
+ gint subtype = (gint)pass_along[2];
+ gpointer * sublayer = pass_along[3];
+ guint8 *data = NULL;
+ guint len;
+
+ trw_layer_copy_item( vtl, subtype, sublayer, &data, &len);
+
+ if (data) {
+ a_clipboard_copy( VIK_CLIPBOARD_DATA_SUBLAYER, VIK_LAYER_TRW,
+ subtype, len, data);
+ }
+}
+
+static void trw_layer_cut_item_cb( gpointer pass_along[5])
+{
+ trw_layer_copy_item_cb(pass_along);
+ trw_layer_delete_item(pass_along);
+}
-static gpointer trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer )
+static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer, guint8 **item, guint *len )
{
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT && sublayer )
- {
- NamedWaypoint *nw = g_malloc ( sizeof ( NamedWaypoint ) );
- nw->name = g_strdup(sublayer);
- nw->wp = vik_waypoint_copy ( g_hash_table_lookup ( vtl->waypoints, sublayer ) );
- return nw;
+ FlatItem *fi;
+ guint8 *id;
+ guint il;
+
+ fprintf(stderr, "%s:%s() called\n", __FILE__, __PRETTY_FUNCTION__);
+ if (!sublayer) {
+ *item = NULL;
+ return;
}
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK && sublayer )
+
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
{
- NamedTrack *nt = g_malloc ( sizeof ( NamedTrack ) );
- nt->name = g_strdup(sublayer);
- nt->tr = g_hash_table_lookup ( vtl->tracks, sublayer );
- vik_track_ref(nt->tr);
- return nt;
+ vik_waypoint_marshall ( g_hash_table_lookup ( vtl->waypoints, sublayer ), &id, &il );
+ } else {
+ vik_track_marshall ( g_hash_table_lookup ( vtl->tracks, sublayer ), &id, &il );
}
- return NULL;
+
+ *len = sizeof(FlatItem) + strlen(sublayer) + 1 + il;
+ fi = g_malloc ( *len );
+ fi->len = strlen(sublayer) + 1;
+ memcpy(fi->data, sublayer, fi->len);
+ memcpy(fi->data + fi->len, id, il);
+ g_free(id);
+ *item = (guint8 *)fi;
}
-static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, gpointer item )
+static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *item, guint len )
{
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT && item )
+ FlatItem *fi = (FlatItem *) item;
+
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT && fi )
{
- NamedWaypoint *nw = (NamedWaypoint *) item;
- vik_trw_layer_add_waypoint ( vtl, g_strdup(nw->name), vik_waypoint_copy(nw->wp) );
+ VikWaypoint *w;
+ gchar *name;
+
+ name = get_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, (gchar *)fi->data);
+ w = vik_waypoint_unmarshall(fi->data + fi->len, len - sizeof(*fi) - fi->len);
+ vik_trw_layer_add_waypoint ( vtl, name, w );
+ waypoint_convert(name, w, &vtl->coord_mode);
return TRUE;
}
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK && item )
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK && fi )
{
- NamedTrack *nt = (NamedTrack *) item;
- vik_trw_layer_add_track ( vtl, g_strdup(nt->name), vik_track_copy(nt->tr) );
+ VikTrack *t;
+ gchar *name;
+ name = get_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, (gchar *)fi->data);
+ t = vik_track_unmarshall(fi->data + fi->len, len - sizeof(*fi) - fi->len);
+ vik_trw_layer_add_track ( vtl, name, t );
+ track_convert(name, t, &vtl->coord_mode);
return TRUE;
}
return FALSE;
static void trw_layer_free_copied_item ( gint subtype, gpointer item )
{
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT && item )
- {
- NamedWaypoint *nw = (NamedWaypoint *) item;
- g_free ( nw->name );
- vik_waypoint_free ( nw->wp );
- g_free ( nw );
- }
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK && item )
- {
- NamedTrack *nt = (NamedTrack *) item;
- g_free ( nt->name );
- vik_track_free ( nt->tr );
- g_free ( nt );
+ if (item) {
+ g_free(item);
}
}
case PARAM_WV: vtl->waypoints_visible = data.b; break;
case PARAM_DM: vtl->drawmode = data.u; break;
case PARAM_DP: vtl->drawpoints = data.b; break;
+ case PARAM_DE: vtl->drawelevation = data.b; break;
+ case PARAM_DS: vtl->drawstops = data.b; break;
case PARAM_DL: vtl->drawlines = data.b; break;
+ case PARAM_SL: if ( data.u >= MIN_STOP_LENGTH && data.u <= MAX_STOP_LENGTH )
+ vtl->stop_length = data.u;
+ break;
+ case PARAM_EF: if ( data.u >= 1 && data.u <= 100 )
+ vtl->elevation_factor = data.u;
+ break;
case PARAM_LT: if ( data.u > 0 && data.u < 15 && data.u != vtl->line_thickness )
{
vtl->line_thickness = data.u;
case PARAM_WPBA: gdk_gc_set_function(vtl->waypoint_bg_gc, data.b ? GDK_AND : GDK_COPY ); break;
case PARAM_WPSYM: if ( data.u < WP_NUM_SYMBOLS ) vtl->wp_symbol = data.u; break;
case PARAM_WPSIZE: if ( data.u > 0 && data.u <= 64 ) vtl->wp_size = data.u; break;
+ case PARAM_WPSYMS: vtl->wp_draw_symbols = data.b; break;
}
return TRUE;
}
case PARAM_WV: rv.b = vtl->waypoints_visible; break;
case PARAM_DM: rv.u = vtl->drawmode; break;
case PARAM_DP: rv.b = vtl->drawpoints; break;
+ case PARAM_DE: rv.b = vtl->drawelevation; break;
+ case PARAM_EF: rv.u = vtl->elevation_factor; break;
+ case PARAM_DS: rv.b = vtl->drawstops; break;
+ case PARAM_SL: rv.u = vtl->stop_length; break;
case PARAM_DL: rv.b = vtl->drawlines; break;
case PARAM_LT: rv.u = vtl->line_thickness; break;
case PARAM_BLT: rv.u = vtl->bg_line_thickness; break;
case PARAM_WPBA: rv.b = (vik_gc_get_function(vtl->waypoint_bg_gc)==GDK_AND); break;
case PARAM_WPSYM: rv.u = vtl->wp_symbol; break;
case PARAM_WPSIZE: rv.u = vtl->wp_size; break;
+ case PARAM_WPSYMS: rv.b = vtl->wp_draw_symbols; break;
}
return rv;
}
g_hash_table_insert ( dest, g_strdup ( name ), vik_track_copy(tr) );
}
+static void trw_layer_marshall( VikTrwLayer *vtl, guint8 **data, gint *len )
+{
+ guint8 *pd, *dd;
+ gint pl, dl;
+ gchar *tmpname;
+ FILE *f;
+
+ *data = NULL;
+
+ if ((f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) {
+ a_gpx_write_file(vtl, f);
+ vik_layer_marshall_params(VIK_LAYER(vtl), &pd, &pl);
+ fclose(f);
+ g_file_get_contents(tmpname, (void *)&dd, (void *)&dl, NULL);
+ *len = sizeof(pl) + pl + dl;
+ *data = g_malloc(*len);
+ memcpy(*data, &pl, sizeof(pl));
+ memcpy(*data + sizeof(pl), pd, pl);
+ memcpy(*data + sizeof(pl) + pl, dd, dl);
+
+ g_free(pd);
+ g_free(dd);
+ remove(tmpname);
+ g_free(tmpname);
+ }
+}
+
+static VikTrwLayer *trw_layer_unmarshall( gpointer data, gint len, VikViewport *vvp )
+{
+ VikTrwLayer *rv = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE ));
+ guint pl;
+ gchar *tmpname;
+ FILE *f;
+
+
+ memcpy(&pl, data, sizeof(pl));
+ data += sizeof(pl);
+ vik_layer_unmarshall_params ( VIK_LAYER(rv), data, pl, vvp );
+ data += pl;
+
+ if (!(f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) {
+ g_critical("couldn't open temp file\n");
+ exit(1);
+ }
+ fwrite(data, len - pl - sizeof(pl), 1, f);
+ rewind(f);
+ a_gpx_read_file(rv, f);
+ fclose(f);
+ remove(tmpname);
+ g_free(tmpname);
+ return rv;
+}
+
static VikTrwLayer *trw_layer_copy ( VikTrwLayer *vtl, gpointer vp )
{
VikTrwLayer *rv = vik_trw_layer_new ( vtl->drawmode );
rv->tracks_visible = vtl->tracks_visible;
rv->waypoints_visible = vtl->waypoints_visible;
rv->drawpoints = vtl->drawpoints;
+ rv->drawstops = vtl->drawstops;
+ rv->drawelevation = vtl->drawelevation;
+ rv->elevation_factor = vtl->elevation_factor;
rv->drawlines = vtl->drawlines;
+ rv->stop_length = vtl->stop_length;
rv->line_thickness = vtl->line_thickness;
rv->bg_line_thickness = vtl->bg_line_thickness;
rv->velocity_min = vtl->velocity_min;
rv->coord_mode = vtl->coord_mode;
rv->wp_symbol = vtl->wp_symbol;
rv->wp_size = vtl->wp_size;
+ rv->wp_draw_symbols = vtl->wp_draw_symbols;
trw_layer_new_track_gcs ( rv, VIK_VIEWPORT(vp) );
return rv;
}
+static GList * a_array_to_glist(gpointer data[])
+{
+ GList *gl = NULL;
+ gpointer * p;
+ for (p = data; *p; p++)
+ gl = g_list_prepend(gl, *p);
+ return(g_list_reverse(gl));
+}
+
VikTrwLayer *vik_trw_layer_new ( gint drawmode )
{
+ if (trw_layer_params[PARAM_DM].widget_data == NULL)
+ trw_layer_params[PARAM_DM].widget_data = a_array_to_glist(params_drawmodes);
+ if (trw_layer_params[PARAM_WPSYM].widget_data == NULL)
+ trw_layer_params[PARAM_WPSYM].widget_data = a_array_to_glist(params_wpsymbols);
+
VikTrwLayer *rv = VIK_TRW_LAYER ( g_object_new ( VIK_TRW_LAYER_TYPE, NULL ) );
vik_layer_init ( VIK_LAYER(rv), VIK_LAYER_TRW );
rv->waypoints_visible = rv->tracks_visible = TRUE;
rv->drawmode = drawmode;
rv->drawpoints = TRUE;
+ rv->drawstops = FALSE;
+ rv->drawelevation = FALSE;
+ rv->elevation_factor = 30;
+ rv->stop_length = 60;
rv->drawlines = TRUE;
rv->wplabellayout = NULL;
rv->wp_right_click_menu = NULL;
rv->velocity_max = 5.0;
rv->velocity_min = 0.0;
rv->line_thickness = 1;
- rv->line_thickness = 0;
+ rv->bg_line_thickness = 0;
rv->current_wp = NULL;
rv->current_wp_name = NULL;
rv->current_track = NULL;
rv->current_tp_track_name = NULL;
rv->moving_tp = FALSE;
rv->moving_wp = FALSE;
+
+ rv->magic_scissors_started = FALSE;
+
rv->waypoint_rightclick = FALSE;
rv->last_tpl = NULL;
rv->last_tp_track_name = NULL;
gboolean useoldvals = TRUE;
gboolean drawpoints;
+ gboolean drawstops;
+ gboolean drawelevation;
+ gdouble min_alt, max_alt, alt_diff = 0;
const guint8 tp_size_reg = 2;
const guint8 tp_size_cur = 4;
guint8 tp_size;
+ if ( dp->vtl->drawelevation )
+ {
+ /* assume if it has elevation at the beginning, it has it throughout. not ness a true good assumption */
+ if ( ( drawelevation = vik_track_get_minmax_alt ( track, &min_alt, &max_alt ) ) )
+ alt_diff = max_alt - min_alt;
+ }
+
if ( ! track->visible )
return;
trw_layer_draw_track ( name, track, dp, TRUE );
if ( drawing_white_background )
- drawpoints = FALSE;
- else
+ drawpoints = drawstops = FALSE;
+ else {
drawpoints = dp->vtl->drawpoints;
+ drawstops = dp->vtl->drawstops;
+ }
if (list) {
int x, y, oldx, oldy;
if ( list->next ) {
vik_viewport_draw_rectangle ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), TRUE, x-tp_size, y-tp_size, 2*tp_size, 2*tp_size );
-#if 0
- if ( VIK_TRACKPOINT(list->next->data)->altitude != VIK_DEFAULT_ALTITUDE )
- vik_viewport_draw_line ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), x, y, x, y-(VIK_TRACKPOINT(list->next->data)->altitude-540)/5);
-#endif
-
vik_viewport_draw_rectangle ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), TRUE, x-tp_size, y-tp_size, 2*tp_size, 2*tp_size );
/* stops */
- if (0 && VIK_TRACKPOINT(list->next->data)->timestamp - VIK_TRACKPOINT(list->data)->timestamp > 60 )
+ if ( drawstops && VIK_TRACKPOINT(list->next->data)->timestamp - VIK_TRACKPOINT(list->data)->timestamp > dp->vtl->stop_length )
vik_viewport_draw_arc ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, 11), TRUE, x-(3*tp_size), y-(3*tp_size), 6*tp_size, 6*tp_size, 0, 360*64 );
}
else
vik_viewport_draw_line ( dp->vp, dp->vtl->track_bg_gc, oldx, oldy, x, y);
}
else {
- GdkPoint tmp[4];
-#define FIXALTITUDE(what) (pow((VIK_TRACKPOINT((what))->altitude-330),2)/1500/dp->xmpp)
- if ( list && list->next && VIK_TRACKPOINT(list->next->data)->altitude != VIK_DEFAULT_ALTITUDE ) {
- tmp[0].x = oldx;
- tmp[0].y = oldy;
- tmp[1].x = oldx;
- tmp[1].y = oldy-FIXALTITUDE(list->data);
- tmp[2].x = x;
- tmp[2].y = y-FIXALTITUDE(list->next->data);
- tmp[3].x = x;
- tmp[3].y = y;
-
- GdkGC *tmp_gc;
- if ( ((oldx - x) > 0 && (oldy - y) > 0) || ((oldx - x) < 0 && (oldy - y) < 0))
- tmp_gc = GTK_WIDGET(dp->vp)->style->light_gc[3];
- else
- tmp_gc = GTK_WIDGET(dp->vp)->style->dark_gc[0];
- vik_viewport_draw_polygon ( dp->vp, tmp_gc, TRUE, tmp, 4);
- }
vik_viewport_draw_line ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), oldx, oldy, x, y);
- if ( list && list->next && VIK_TRACKPOINT(list->next->data)->altitude != VIK_DEFAULT_ALTITUDE ) {
+ if ( dp->vtl->drawelevation && list && list->next && VIK_TRACKPOINT(list->next->data)->altitude != VIK_DEFAULT_ALTITUDE ) {
+ GdkPoint tmp[4];
+ #define FIXALTITUDE(what) ((VIK_TRACKPOINT((what))->altitude-min_alt)/alt_diff*DRAW_ELEVATION_FACTOR*dp->vtl->elevation_factor/dp->xmpp)
+ if ( list && list->next && VIK_TRACKPOINT(list->next->data)->altitude != VIK_DEFAULT_ALTITUDE ) {
+ tmp[0].x = oldx;
+ tmp[0].y = oldy;
+ tmp[1].x = oldx;
+ tmp[1].y = oldy-FIXALTITUDE(list->data);
+ tmp[2].x = x;
+ tmp[2].y = y-FIXALTITUDE(list->next->data);
+ tmp[3].x = x;
+ tmp[3].y = y;
+
+ GdkGC *tmp_gc;
+ if ( ((oldx - x) > 0 && (oldy - y) > 0) || ((oldx - x) < 0 && (oldy - y) < 0))
+ tmp_gc = GTK_WIDGET(dp->vp)->style->light_gc[3];
+ else
+ tmp_gc = GTK_WIDGET(dp->vp)->style->dark_gc[0];
+ vik_viewport_draw_polygon ( dp->vp, tmp_gc, TRUE, tmp, 4);
+ }
vik_viewport_draw_line ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter), oldx, oldy-FIXALTITUDE(list->data), x, y-FIXALTITUDE(list->next->data));
}
}
wp->coord.north_south > dp->cn1 && wp->coord.north_south < dp->cn2 ) )
{
gint x, y;
+ GdkPixbuf *sym;
vik_viewport_coord_to_screen ( dp->vp, &(wp->coord), &x, &y );
/* if in shrunken_cache, get that. If not, get and add to shrunken_cache */
}
/* DRAW ACTUAL DOT */
- if ( wp == dp->vtl->current_wp ) {
+ if ( dp->vtl->wp_draw_symbols && wp->symbol && (sym = a_get_wp_sym(wp->symbol)) ) {
+ vik_viewport_draw_pixbuf ( dp->vp, sym, 0, 0, x - gdk_pixbuf_get_width(sym)/2, y - gdk_pixbuf_get_height(sym)/2, -1, -1 );
+ }
+ else if ( wp == dp->vtl->current_wp ) {
switch ( dp->vtl->wp_symbol ) {
case WP_SYMBOL_FILLED_SQUARE: vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_gc, TRUE, x - (dp->vtl->wp_size), y - (dp->vtl->wp_size), dp->vtl->wp_size*2, dp->vtl->wp_size*2 ); break;
case WP_SYMBOL_SQUARE: vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_gc, FALSE, x - (dp->vtl->wp_size), y - (dp->vtl->wp_size), dp->vtl->wp_size*2, dp->vtl->wp_size*2 ); break;
rv->has_verified_thumbnails = FALSE;
rv->wp_symbol = WP_SYMBOL_FILLED_SQUARE;
rv->wp_size = 4;
+ rv->wp_draw_symbols = TRUE;
rv->coord_mode = vik_viewport_get_coord_mode ( vp );
+ rv->menu_selection = vik_layer_get_interface(VIK_LAYER(rv)->type)->menu_items_selection;
+
return rv;
}
trw_layer_export ( layer_and_vlp, FILE_TYPE_GPSMAPPER );
}
+static void trw_layer_export_gpx ( gpointer layer_and_vlp[2] )
+{
+ trw_layer_export ( layer_and_vlp, FILE_TYPE_GPX );
+}
+
static void trw_layer_goto_wp ( gpointer layer_and_vlp[2] )
{
GHashTable *wps = vik_trw_layer_get_waypoints ( VIK_TRW_LAYER(layer_and_vlp[0]) );
gboolean vik_trw_layer_new_waypoint ( VikTrwLayer *vtl, GtkWindow *w, const VikCoord *def_coord )
{
gchar *name;
- static VikWaypoint st_wp;
- st_wp.coord = *def_coord;
- st_wp.altitude = VIK_DEFAULT_ALTITUDE;
+ VikWaypoint *wp = vik_waypoint_new();
+ wp->coord = *def_coord;
+ wp->altitude = VIK_DEFAULT_ALTITUDE;
- if ( a_dialog_new_waypoint ( w, &name, &st_wp, vik_trw_layer_get_waypoints ( vtl ), vtl->coord_mode ) )
+ if ( a_dialog_new_waypoint ( w, &name, wp, vik_trw_layer_get_waypoints ( vtl ), vtl->coord_mode ) )
{
- VikWaypoint *wp = vik_waypoint_new();
- *wp = st_wp;
+ wp->visible = TRUE;
vik_trw_layer_add_waypoint ( vtl, name, wp );
return TRUE;
}
+ vik_waypoint_free(wp);
return FALSE;
}
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show ( item );
+ item = gtk_menu_item_new_with_label ( "Export Layer as GPX" );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_export_gpx), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+
item = gtk_menu_item_new_with_label ( "New Waypoint" );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wp), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
#endif
vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, iter );
g_hash_table_insert ( vtl->tracks_iters, name, iter );
- t->visible = TRUE;
+ /* t->visible = TRUE; */
}
}
else
- t->visible = TRUE;
+ ; /* t->visible = TRUE; // this is now used by file input functions */
g_hash_table_insert ( vtl->tracks, name, t );
else if (vtl->last_tp_track_name && g_strcasecmp(trk_name, vtl->last_tp_track_name) == 0)
trw_layer_cancel_last_tp ( vtl );
}
+
+static gchar *get_new_unique_sublayer_name (VikTrwLayer *vtl, gint sublayer_type, const gchar *name)
+{
+ gint i = 2;
+ gchar *newname = g_strdup(name);
+ while ((sublayer_type == VIK_TRW_LAYER_SUBLAYER_TRACK) ?
+ (void *)vik_trw_layer_get_track(vtl, newname) : (void *)vik_trw_layer_get_waypoint(vtl, newname)) {
+ gchar *new_newname = g_strdup_printf("%s#%d", name, i);
+ g_free(newname);
+ newname = new_newname;
+ i++;
+ }
+ return newname;
+}
+
+void vik_trw_layer_filein_add_waypoint ( VikTrwLayer *vtl, gchar *name, VikWaypoint *wp )
+{
+ vik_trw_layer_add_waypoint ( vtl,
+ get_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, name),
+ wp );
+}
+void vik_trw_layer_filein_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *tr )
+{
+ vik_trw_layer_add_track ( vtl,
+ get_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, name),
+ tr );
+}
+
+static void trw_layer_enum_item ( const gchar *name, GList **tr, GList **l )
+{
+ *l = g_list_append(*l, (gpointer)name);
+}
+
+static void trw_layer_move_item ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, gchar *name, gint type )
+{
+ gchar *newname = get_new_unique_sublayer_name(vtl_dest, type, name);
+ if (type == VIK_TRW_LAYER_SUBLAYER_TRACK) {
+ VikTrack *t;
+ t = vik_track_copy(vik_trw_layer_get_track(vtl_src, name));
+ vik_trw_layer_delete_track(vtl_src, name);
+ vik_trw_layer_add_track(vtl_dest, newname, t);
+ }
+ if (type==VIK_TRW_LAYER_SUBLAYER_WAYPOINT) {
+ VikWaypoint *w;
+ w = vik_waypoint_copy(vik_trw_layer_get_waypoint(vtl_src, name));
+ vik_trw_layer_delete_waypoint(vtl_src, name);
+ vik_trw_layer_add_waypoint(vtl_dest, newname, w);
+ }
+}
+
+static void trw_layer_drag_drop_request ( VikTrwLayer *vtl_src, VikTrwLayer *vtl_dest, GtkTreeIter *src_item_iter, GtkTreePath *dest_path )
+{
+ VikTreeview *vt = VIK_LAYER(vtl_src)->vt;
+ gint type = vik_treeview_item_get_data(vt, src_item_iter);
+
+ if (!vik_treeview_item_get_pointer(vt, src_item_iter)) {
+ GList *items = NULL;
+ GList *iter;
+
+ if (type==VIK_TRW_LAYER_SUBLAYER_TRACKS) {
+ g_hash_table_foreach ( vtl_src->tracks, (GHFunc)trw_layer_enum_item, &items);
+ }
+ if (type==VIK_TRW_LAYER_SUBLAYER_WAYPOINTS) {
+ g_hash_table_foreach ( vtl_src->waypoints, (GHFunc)trw_layer_enum_item, &items);
+ }
+
+ iter = items;
+ while (iter) {
+ if (type==VIK_TRW_LAYER_SUBLAYER_TRACKS) {
+ trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_TRACK);
+ } else {
+ trw_layer_move_item ( vtl_src, vtl_dest, iter->data, VIK_TRW_LAYER_SUBLAYER_WAYPOINT);
+ }
+ iter = iter->next;
+ }
+ if (items)
+ g_list_free(items);
+ } else {
+ gchar *name = vik_treeview_item_get_pointer(vt, src_item_iter);
+ trw_layer_move_item(vtl_src, vtl_dest, name, type);
+ }
+}
+
-static gboolean trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name )
+gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, const gchar *trk_name )
{
VikTrack *t = g_hash_table_lookup ( vtl->tracks, trk_name );
gboolean was_visible = FALSE;
return was_visible;
}
+gboolean vik_trw_layer_delete_waypoint ( VikTrwLayer *vtl, const gchar *wp_name )
+{
+ gboolean was_visible = FALSE;
+ VikWaypoint *wp;
+
+ wp = g_hash_table_lookup ( vtl->waypoints, wp_name );
+ if ( wp ) {
+ GtkTreeIter *it;
+
+ if ( wp == vtl->current_wp ) {
+ vtl->current_wp = NULL;
+ vtl->current_wp_name = NULL;
+ vtl->moving_wp = FALSE;
+ }
+
+ was_visible = wp->visible;
+ g_assert ( ( it = g_hash_table_lookup ( vtl->waypoints_iters, (gchar *) wp_name ) ) );
+ vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, it );
+ g_hash_table_remove ( vtl->waypoints_iters, (gchar *) wp_name );
+ g_hash_table_remove ( vtl->waypoints, wp_name ); /* last because this frees name */
+ }
+
+ return was_visible;
+}
+
+static void remove_item_from_treeview(const gchar *name, GtkTreeIter *it, VikTreeview * vt)
+{
+ vik_treeview_item_delete (vt, it );
+}
+
+void vik_trw_layer_delete_all_tracks ( VikTrwLayer *vtl )
+{
+
+ vtl->current_track = NULL;
+ if (vtl->current_tp_track_name)
+ trw_layer_cancel_current_tp(vtl, FALSE);
+ if (vtl->last_tp_track_name)
+ trw_layer_cancel_last_tp ( vtl );
+
+ g_hash_table_foreach(vtl->tracks_iters, (GHFunc) remove_item_from_treeview, VIK_LAYER(vtl)->vt);
+ g_hash_table_remove_all(vtl->tracks_iters);
+ g_hash_table_remove_all(vtl->tracks);
+
+ /* TODO: only update if the layer is visible (ticked) */
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
+void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl )
+{
+ vtl->current_wp = NULL;
+ vtl->current_wp_name = NULL;
+ vtl->moving_wp = FALSE;
+
+ g_hash_table_foreach(vtl->waypoints_iters, (GHFunc) remove_item_from_treeview, VIK_LAYER(vtl)->vt);
+ g_hash_table_remove_all(vtl->waypoints_iters);
+ g_hash_table_remove_all(vtl->waypoints);
+
+ /* TODO: only update if the layer is visible (ticked) */
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+}
+
static void trw_layer_delete_item ( gpointer pass_along[5] )
{
VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
gboolean was_visible = FALSE;
if ( (gint) pass_along[2] == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
{
- VikWaypoint *wp;
- wp = g_hash_table_lookup ( vtl->waypoints, pass_along[3] );
- if ( wp )
- {
- GtkTreeIter *it;
-
- if ( wp == vtl->current_wp ) {
- vtl->current_wp = NULL;
- vtl->current_wp_name = NULL;
- vtl->moving_wp = FALSE;
- }
-
- was_visible = wp->visible;
- g_assert ( ( it = g_hash_table_lookup ( vtl->waypoints_iters, (gchar *) pass_along[3] ) ) );
- vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, it );
- g_hash_table_remove ( vtl->waypoints_iters, (gchar *) pass_along[3] );
- g_hash_table_remove ( vtl->waypoints, pass_along[3] ); /* last because this frees name */
- }
+ was_visible = vik_trw_layer_delete_waypoint ( vtl, (gchar *) pass_along[3] );
}
else
{
- was_visible = trw_layer_delete_track ( vtl, (gchar *) pass_along[3] );
+ was_visible = vik_trw_layer_delete_track ( vtl, (gchar *) pass_along[3] );
}
-
if ( was_visible )
vik_layer_emit_update ( VIK_LAYER(vtl) );
}
}
if ( new_tr_name )
vik_trw_layer_add_track ( vtl, new_tr_name, tracks[i] );
-
}
if ( tracks )
{
g_free ( tracks );
- trw_layer_delete_track ( vtl, (gchar *) pass_along[3] );
+ vik_trw_layer_delete_track ( vtl, (gchar *) pass_along[3] );
vik_layer_emit_update ( VIK_LAYER(vtl) ); /* chase thru the hoops */
}
}
p2 = VIK_TRACKPOINT(g_list_last(VIK_TRACK(value)->trackpoints)->data);
if (!p1->has_timestamp || !p2->has_timestamp) {
- printf("no timestamp\n");
+ g_print("no timestamp\n");
return;
}
- /* printf("Got track named %s, times %d, %d\n", (gchar *)key, p1->timestamp, p2->timestamp); */
+ /* g_print("Got track named %s, times %d, %d\n", (gchar *)key, p1->timestamp, p2->timestamp); */
if (abs(t1 - p2->timestamp) < thr*60 ||
/* p1 p2 t1 t2 */
abs(p1->timestamp - t2) < thr*60
t1 = ((VikTrackpoint *)trps->data)->timestamp;
t2 = ((VikTrackpoint *)g_list_last(trps)->data)->timestamp;
- /* printf("Original track times: %d and %d\n", t1, t2); */
+ /* g_print("Original track times: %d and %d\n", t1, t2); */
params[0] = &nearby_tracks;
params[1] = trps;
params[2] = (gpointer)thr;
time_t t1, t2;
t1 = get_first_trackpoint(l)->timestamp;
t2 = get_last_trackpoint(l)->timestamp;
- printf(" %20s: track %d - %d\n", (char *)l->data, (int)t1, (int)t2);
+ g_print(" %20s: track %d - %d\n", (char *)l->data, (int)t1, (int)t2);
*/
/* remove trackpoints from merged track, delete track */
tr->trackpoints = g_list_concat(tr->trackpoints, get_track(l)->trackpoints);
get_track(l)->trackpoints = NULL;
- trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), l->data);
+ vik_trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), l->data);
track_count ++;
l = g_list_next(l);
while (iter) {
ts = VIK_TRACKPOINT(iter->data)->timestamp;
if (ts < prev_ts) {
- printf("panic: ts < prev_ts: this should never happen!\n");
+ g_print("panic: ts < prev_ts: this should never happen!\n");
return;
}
if (ts - prev_ts > thr*60) {
new_tr_name = g_strdup_printf("%s #%d", (gchar *) pass_along[3], i++);
vik_trw_layer_add_track(VIK_TRW_LAYER(pass_along[0]), new_tr_name, tr);
- /* fprintf(stderr, "adding track %s, times %d - %d\n", new_tr_name, VIK_TRACKPOINT(tr->trackpoints->data)->timestamp,
+ /* g_print("adding track %s, times %d - %d\n", new_tr_name, VIK_TRACKPOINT(tr->trackpoints->data)->timestamp,
VIK_TRACKPOINT(g_list_last(tr->trackpoints)->data)->timestamp);*/
iter = g_list_next(iter);
}
g_list_free(newlists);
- trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), (gchar *)pass_along[3]);
+ vik_trw_layer_delete_track(VIK_TRW_LAYER(pass_along[0]), (gchar *)pass_along[3]);
vik_layer_emit_update(VIK_LAYER(pass_along[0]));
}
return NULL;
}
- wp = vik_waypoint_copy ( VIK_WAYPOINT(g_hash_table_lookup ( l->waypoints, sublayer )) );
- g_hash_table_remove ( l->waypoints, sublayer );
-
iter = g_hash_table_lookup ( l->waypoints_iters, sublayer );
g_hash_table_steal ( l->waypoints_iters, sublayer );
+ wp = vik_waypoint_copy ( VIK_WAYPOINT(g_hash_table_lookup ( l->waypoints, sublayer )) );
+ g_hash_table_remove ( l->waypoints, sublayer );
+
rv = g_strdup(newname);
for ( i = strlen(rv) - 1; i >= 0; i-- )
rv[i] = toupper(rv[i]);
return NULL;
}
- g_hash_table_lookup_extended ( l->tracks, sublayer, (gpointer *)&orig_key, (gpointer *)&tr );
+ g_hash_table_lookup_extended ( l->tracks, sublayer, (void *)&orig_key, (void *)&tr );
g_hash_table_steal ( l->tracks, sublayer );
iter = g_hash_table_lookup ( l->tracks_iters, sublayer );
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
+ item = gtk_image_menu_item_new_from_stock ( GTK_STOCK_CUT, NULL );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_cut_item_cb), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_from_stock ( GTK_STOCK_COPY, NULL );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_copy_item_cb), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+
item = gtk_image_menu_item_new_from_stock ( GTK_STOCK_DELETE, NULL );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_item), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
return rv;
}
-/* Params are: vvp, event, last match found or NULL */
-static void tool_show_picture_wp ( char *name, VikWaypoint *wp, gpointer params[2] )
-{
- if ( wp->image && wp->visible )
- {
- gint x, y, slackx, slacky;
- GdkEventButton *event = (GdkEventButton *) params[1];
- vik_viewport_coord_to_screen ( VIK_VIEWPORT(params[0]), &(wp->coord), &x, &y );
- slackx = wp->image_width / 2;
- slacky = wp->image_height / 2;
- if ( x <= event->x + slackx && x >= event->x - slackx
- && y <= event->y + slacky && y >= event->y - slacky )
- {
- params[2] = wp->image; /* we've found a match. however continue searching
- * since we want to find the last match -- that
- * is, the match that was drawn last. */
- }
- }
+/* to be called when last_tpl no long exists. */
+static void trw_layer_cancel_last_tp ( VikTrwLayer *vtl )
+{
+ if ( vtl->tpwin ) /* can't join with a non-existant TP. */
+ vik_trw_layer_tpwin_disable_join ( vtl->tpwin );
+ vtl->last_tpl = NULL;
+ vtl->last_tp_track_name = NULL;
}
-static gboolean tool_show_picture ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+static void trw_layer_cancel_current_tp ( VikTrwLayer *vtl, gboolean destroy )
{
- gpointer params[3] = { vvp, event, NULL };
- g_hash_table_foreach ( vtl->waypoints, (GHFunc) tool_show_picture_wp, params );
- if ( params[2] )
+ if ( vtl->tpwin )
{
- /* thanks to the Gaim people for showing me ShellExecute and g_spawn_command_line_async */
-#ifdef WINDOWS
- ShellExecute(NULL, NULL, (char *) params[2], NULL, ".\\", 0);
-#else /* WINDOWS */
- GError *err = NULL;
- gchar *quoted_file = g_shell_quote ( (gchar *) params[2] );
- gchar *cmd = g_strdup_printf ( "eog %s", quoted_file );
- g_free ( quoted_file );
- if ( ! g_spawn_command_line_async ( cmd, &err ) )
+ if ( destroy)
{
- a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), "Could not launch eog to open file." );
- g_error_free ( err );
+ gtk_widget_destroy ( GTK_WIDGET(vtl->tpwin) );
+ vtl->tpwin = NULL;
}
- g_free ( cmd );
-#endif /* WINDOWS */
- return TRUE; /* found a match */
+ else
+ vik_trw_layer_tpwin_set_empty ( vtl->tpwin );
+ }
+ if ( vtl->current_tpl )
+ {
+ vtl->current_tpl = NULL;
+ vtl->current_tp_track_name = NULL;
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
- else
- return FALSE; /* go through other layers, searching for a match */
}
-static gboolean tool_new_waypoint ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response )
{
- VikCoord coord;
- vik_viewport_screen_to_coord ( vvp, event->x, event->y, &coord );
- if (vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), &coord ) && VIK_LAYER(vtl)->visible)
- vik_layer_emit_update ( VIK_LAYER(vtl) );
- return TRUE;
-}
-
-typedef struct {
- gint x, y;
- gint closest_x, closest_y;
- gchar *closest_track_name;
- VikTrackpoint *closest_tp;
- VikViewport *vvp;
- GList *closest_tpl;
-} TPSearchParams;
-
-static void track_search_closest_tp ( gchar *name, VikTrack *t, TPSearchParams *params )
-{
- GList *tpl = t->trackpoints;
- VikTrackpoint *tp;
-
- if ( !t->visible )
- return;
-
- while (tpl)
- {
- gint x, y;
- tp = VIK_TRACKPOINT(tpl->data);
-
- vik_viewport_coord_to_screen ( params->vvp, &(tp->coord), &x, &y );
-
- if ( abs (x - params->x) <= TRACKPOINT_SIZE_APPROX && abs (y - params->y) <= TRACKPOINT_SIZE_APPROX &&
- ((!params->closest_tp) || /* was the old trackpoint we already found closer than this one? */
- abs(x - params->x)+abs(y - params->y) < abs(x - params->closest_x)+abs(y - params->closest_y)))
- {
- params->closest_track_name = name;
- params->closest_tp = tp;
- params->closest_tpl = tpl;
- params->closest_x = x;
- params->closest_y = y;
- }
- tpl = tpl->next;
- }
-}
-
-/* to be called when last_tpl no long exists. */
-static void trw_layer_cancel_last_tp ( VikTrwLayer *vtl )
-{
- if ( vtl->tpwin ) /* can't join with a non-existant TP. */
- vik_trw_layer_tpwin_disable_join ( vtl->tpwin );
- vtl->last_tpl = NULL;
- vtl->last_tp_track_name = NULL;
-}
-
-static void trw_layer_cancel_current_tp ( VikTrwLayer *vtl, gboolean destroy )
-{
- if ( vtl->tpwin )
- {
- if ( destroy)
- {
- gtk_widget_destroy ( GTK_WIDGET(vtl->tpwin) );
- vtl->tpwin = NULL;
- }
- else
- vik_trw_layer_tpwin_set_empty ( vtl->tpwin );
- }
- if ( vtl->current_tpl )
- {
- vtl->current_tpl = NULL;
- vtl->current_tp_track_name = NULL;
- vik_layer_emit_update(VIK_LAYER(vtl));
- }
-}
-
-static void trw_layer_tpwin_response ( VikTrwLayer *vtl, gint response )
-{
- g_assert ( vtl->tpwin != NULL );
- if ( response == VIK_TRW_LAYER_TPWIN_CLOSE )
- trw_layer_cancel_current_tp ( vtl, TRUE );
- else if ( response == VIK_TRW_LAYER_TPWIN_SPLIT && vtl->current_tpl->next && vtl->current_tpl->prev )
- {
- gchar *name;
- if ( ( name = a_dialog_new_track ( GTK_WINDOW(vtl->tpwin), vtl->tracks ) ) )
- {
- VikTrack *tr = vik_track_new ();
- GList *newglist = g_list_alloc ();
- newglist->prev = NULL;
- newglist->next = vtl->current_tpl->next;
- newglist->data = vik_trackpoint_copy(VIK_TRACKPOINT(vtl->current_tpl->data));
- tr->trackpoints = newglist;
+ g_assert ( vtl->tpwin != NULL );
+ if ( response == VIK_TRW_LAYER_TPWIN_CLOSE )
+ trw_layer_cancel_current_tp ( vtl, TRUE );
+ else if ( response == VIK_TRW_LAYER_TPWIN_SPLIT && vtl->current_tpl->next && vtl->current_tpl->prev )
+ {
+ gchar *name;
+ if ( ( name = a_dialog_new_track ( GTK_WINDOW(vtl->tpwin), vtl->tracks ) ) )
+ {
+ VikTrack *tr = vik_track_new ();
+ GList *newglist = g_list_alloc ();
+ newglist->prev = NULL;
+ newglist->next = vtl->current_tpl->next;
+ newglist->data = vik_trackpoint_copy(VIK_TRACKPOINT(vtl->current_tpl->data));
+ tr->trackpoints = newglist;
vtl->current_tpl->next->prev = newglist; /* end old track here */
vtl->current_tpl->next = NULL;
/* if we did this before, trw_layer_delete_track would have canceled the current tp because
* it was the current track. canceling the current tp would have set vtl->current_tpl to NULL */
- trw_layer_delete_track ( vtl, tmp );
+ vik_trw_layer_delete_track ( vtl, tmp );
trw_layer_cancel_last_tp ( vtl ); /* same TP, can't join. */
vik_layer_emit_update(VIK_LAYER(vtl));
/* set layer name and TP data */
}
+/***************************************************************************
+ ** Tool code
+ ***************************************************************************/
+
+/*** Utility data structures and functions ****/
+
+typedef struct {
+ gint x, y;
+ gint closest_x, closest_y;
+ gchar *closest_wp_name;
+ VikWaypoint *closest_wp;
+ VikViewport *vvp;
+} WPSearchParams;
+
+typedef struct {
+ gint x, y;
+ gint closest_x, closest_y;
+ gchar *closest_track_name;
+ VikTrackpoint *closest_tp;
+ VikViewport *vvp;
+ GList *closest_tpl;
+} TPSearchParams;
+
+static void waypoint_search_closest_tp ( gchar *name, VikWaypoint *wp, WPSearchParams *params )
+{
+ gint x, y;
+ if ( !wp->visible )
+ return;
+
+ vik_viewport_coord_to_screen ( params->vvp, &(wp->coord), &x, &y );
+
+ if ( abs (x - params->x) <= WAYPOINT_SIZE_APPROX && abs (y - params->y) <= WAYPOINT_SIZE_APPROX &&
+ ((!params->closest_wp) || /* was the old waypoint we already found closer than this one? */
+ abs(x - params->x)+abs(y - params->y) < abs(x - params->closest_x)+abs(y - params->closest_y)))
+ {
+ params->closest_wp_name = name;
+ params->closest_wp = wp;
+ params->closest_x = x;
+ params->closest_y = y;
+ }
+}
+
+static void track_search_closest_tp ( gchar *name, VikTrack *t, TPSearchParams *params )
+{
+ GList *tpl = t->trackpoints;
+ VikTrackpoint *tp;
+
+ if ( !t->visible )
+ return;
+
+ while (tpl)
+ {
+ gint x, y;
+ tp = VIK_TRACKPOINT(tpl->data);
+
+ vik_viewport_coord_to_screen ( params->vvp, &(tp->coord), &x, &y );
+
+ if ( abs (x - params->x) <= TRACKPOINT_SIZE_APPROX && abs (y - params->y) <= TRACKPOINT_SIZE_APPROX &&
+ ((!params->closest_tp) || /* was the old trackpoint we already found closer than this one? */
+ abs(x - params->x)+abs(y - params->y) < abs(x - params->closest_x)+abs(y - params->closest_y)))
+ {
+ params->closest_track_name = name;
+ params->closest_tp = tp;
+ params->closest_tpl = tpl;
+ params->closest_x = x;
+ params->closest_y = y;
+ }
+ tpl = tpl->next;
+ }
+}
+
static VikTrackpoint *closest_tp_in_five_pixel_interval ( VikTrwLayer *vtl, VikViewport *vvp, gint x, gint y )
{
TPSearchParams params;
return params.closest_tp;
}
-static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+static VikWaypoint *closest_wp_in_five_pixel_interval ( VikTrwLayer *vtl, VikViewport *vvp, gint x, gint y )
+{
+ WPSearchParams params;
+ params.x = x;
+ params.y = y;
+ params.vvp = vvp;
+ params.closest_wp = NULL;
+ params.closest_wp_name = NULL;
+ g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, ¶ms);
+ return params.closest_wp;
+}
+
+/* background drawing hook, to be passed the viewport */
+static gboolean tool_sync_done = TRUE;
+
+static gboolean tool_sync(gpointer data)
+{
+ VikViewport *vvp = data;
+ gdk_threads_enter();
+ vik_viewport_sync(vvp);
+ tool_sync_done = TRUE;
+ gdk_threads_leave();
+ return FALSE;
+}
+
+typedef struct {
+ VikViewport *vvp;
+ gboolean holding;
+ GdkGC *gc;
+ int oldx, oldy;
+} tool_ed_t;
+
+static void marker_begin_move ( tool_ed_t *t, gint x, gint y )
+{
+ t->holding = TRUE;
+ t->gc = vik_viewport_new_gc (t->vvp, "black", 2);
+ gdk_gc_set_function ( t->gc, GDK_INVERT );
+ vik_viewport_draw_rectangle ( t->vvp, t->gc, FALSE, x-3, y-3, 6, 6 );
+ vik_viewport_sync(t->vvp);
+ t->oldx = x;
+ t->oldy = y;
+}
+
+static void marker_moveto ( tool_ed_t *t, gint x, gint y )
+{
+ VikViewport *vvp = t->vvp;
+ vik_viewport_draw_rectangle ( vvp, t->gc, FALSE, t->oldx-3, t->oldy-3, 6, 6 );
+ vik_viewport_draw_rectangle ( vvp, t->gc, FALSE, x-3, y-3, 6, 6 );
+ t->oldx = x;
+ t->oldy = y;
+ if (tool_sync_done) {
+ g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, tool_sync, vvp, NULL);
+ tool_sync_done = FALSE;
+ }
+}
+
+static void marker_end_move ( tool_ed_t *t )
+{
+ vik_viewport_draw_rectangle ( t->vvp, t->gc, FALSE, t->oldx-3, t->oldy-3, 6, 6 );
+ g_object_unref ( t->gc );
+ t->holding = FALSE;
+}
+
+/*** Edit waypoint ****/
+
+static gpointer tool_edit_waypoint_create ( VikWindow *vw, VikViewport *vvp)
+{
+ tool_ed_t *t = g_new(tool_ed_t, 1);
+ t->vvp = vvp;
+ t->holding = FALSE;
+ return t;
+}
+
+static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
+{
+ WPSearchParams params;
+ tool_ed_t *t = data;
+ VikViewport *vvp = t->vvp;
+
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
+
+ if ( t->holding ) {
+ return TRUE;
+ }
+
+ if ( vtl->current_wp && vtl->current_wp->visible )
+ {
+ /* first check if current WP is within area (other may be 'closer', but we want to move the current) */
+ gint x, y;
+ vik_viewport_coord_to_screen ( vvp, &(vtl->current_wp->coord), &x, &y );
+
+ if ( abs(x - event->x) <= WAYPOINT_SIZE_APPROX &&
+ abs(y - event->y) <= WAYPOINT_SIZE_APPROX )
+ {
+ if ( event->button == 3 )
+ vtl->waypoint_rightclick = TRUE; /* remember that we're clicking; other layers will ignore release signal */
+ else {
+ marker_begin_move(t, event->x, event->y);
+ }
+ return TRUE;
+ }
+ }
+
+ params.vvp = vvp;
+ params.x = event->x;
+ params.y = event->y;
+ params.closest_wp_name = NULL;
+ /* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
+ params.closest_wp = NULL;
+ g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, ¶ms);
+ if ( vtl->current_wp == params.closest_wp && vtl->current_wp != NULL )
+ {
+ /* how do we get here? I'm putting in the abort until we can figure it out. -alex */
+ marker_begin_move(t, event->x, event->y);
+ printf("Abort: shouldn't be here\n");
+ exit(1);
+ }
+ else if ( params.closest_wp )
+ {
+ if ( event->button == 3 )
+ vtl->waypoint_rightclick = TRUE; /* remember that we're clicking; other layers will ignore release signal */
+ else
+ vtl->waypoint_rightclick = FALSE;
+
+ vtl->current_wp = params.closest_wp;
+ vtl->current_wp_name = params.closest_wp_name;
+
+ if ( params.closest_wp )
+ vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup ( vtl->waypoints_iters, vtl->current_wp_name ) );
+
+ /* could make it so don't update if old WP is off screen and new is null but oh well */
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ return TRUE;
+ }
+
+ vtl->current_wp = NULL;
+ vtl->current_wp_name = NULL;
+ vtl->waypoint_rightclick = FALSE;
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ return FALSE;
+}
+
+static gboolean tool_edit_waypoint_move ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
+{
+ tool_ed_t *t = data;
+ VikViewport *vvp = t->vvp;
+
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
+
+ if ( t->holding ) {
+ VikCoord new_coord;
+ vik_viewport_screen_to_coord ( vvp, event->x, event->y, &new_coord );
+
+ /* snap to TP */
+ if ( event->state & GDK_CONTROL_MASK )
+ {
+ VikTrackpoint *tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+ if ( tp )
+ new_coord = tp->coord;
+ }
+
+ /* snap to WP */
+ if ( event->state & GDK_SHIFT_MASK )
+ {
+ VikWaypoint *wp = closest_wp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+ if ( wp && wp != vtl->current_wp )
+ new_coord = wp->coord;
+ }
+
+ {
+ gint x, y;
+ vik_viewport_coord_to_screen ( vvp, &new_coord, &x, &y );
+ marker_moveto ( t, x, y );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
+{
+ tool_ed_t *t = data;
+ VikViewport *vvp = t->vvp;
+
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
+
+ if ( t->holding && event->button == 1 )
+ {
+ VikCoord new_coord;
+ vik_viewport_screen_to_coord ( vvp, event->x, event->y, &new_coord );
+
+ /* snap to TP */
+ if ( event->state & GDK_CONTROL_MASK )
+ {
+ VikTrackpoint *tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+ if ( tp )
+ new_coord = tp->coord;
+ }
+
+ /* snap to WP */
+ if ( event->state & GDK_SHIFT_MASK )
+ {
+ VikWaypoint *wp = closest_wp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+ if ( wp && wp != vtl->current_wp )
+ new_coord = wp->coord;
+ }
+
+ marker_end_move ( t );
+
+ vtl->current_wp->coord = new_coord;
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ return TRUE;
+ }
+ /* PUT IN RIGHT PLACE!!! */
+ if ( event->button == 3 && vtl->waypoint_rightclick )
+ {
+ if ( vtl->wp_right_click_menu )
+ gtk_object_sink ( GTK_OBJECT(vtl->wp_right_click_menu) );
+ vtl->wp_right_click_menu = GTK_MENU ( gtk_menu_new () );
+ vik_trw_layer_sublayer_add_menu_items ( vtl, vtl->wp_right_click_menu, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, vtl->current_wp_name, g_hash_table_lookup ( vtl->waypoints_iters, vtl->current_wp_name ) );
+ gtk_menu_popup ( vtl->wp_right_click_menu, NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time() );
+ vtl->waypoint_rightclick = FALSE;
+ }
+ return FALSE;
+}
+
+/*** New track ****/
+
+static gpointer tool_new_track_create ( VikWindow *vw, VikViewport *vvp)
+{
+ return vvp;
+}
+
+static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+{
+ VikTrackpoint *tp;
+
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
+
+ if ( event->button == 3 && vtl->current_track )
+ {
+ /* undo */
+ if ( vtl->current_track->trackpoints )
+ {
+ GList *last = g_list_last(vtl->current_track->trackpoints);
+ g_free ( last->data );
+ vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
+ }
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ return TRUE;
+ }
+
+ if ( event->type == GDK_2BUTTON_PRESS )
+ {
+ /* subtract last (duplicate from double click) tp then end */
+ if ( vtl->current_track && vtl->current_track->trackpoints && vtl->ct_x1 == vtl->ct_x2 && vtl->ct_y1 == vtl->ct_y2 )
+ {
+ GList *last = g_list_last(vtl->current_track->trackpoints);
+ g_free ( last->data );
+ vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
+ /* undo last, then end */
+ vtl->current_track = NULL;
+ }
+ return TRUE;
+ }
+
+ if ( ! vtl->current_track )
+ {
+ gchar *name;
+ if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->tracks ) ) )
+ {
+ vtl->current_track = vik_track_new();
+ vtl->current_track->visible = TRUE;
+ vik_trw_layer_add_track ( vtl, name, vtl->current_track );
+ }
+ else
+ return TRUE;
+ }
+ tp = vik_trackpoint_new();
+ vik_viewport_screen_to_coord ( vvp, event->x, event->y, &(tp->coord) );
+
+ /* snap to other TP */
+ if ( event->state & GDK_CONTROL_MASK )
+ {
+ VikTrackpoint *other_tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+ if ( other_tp )
+ tp->coord = other_tp->coord;
+ }
+
+ tp->newsegment = FALSE;
+ tp->has_timestamp = FALSE;
+ tp->timestamp = 0;
+ tp->altitude = VIK_DEFAULT_ALTITUDE;
+ vtl->current_track->trackpoints = g_list_append ( vtl->current_track->trackpoints, tp );
+
+ vtl->ct_x1 = vtl->ct_x2;
+ vtl->ct_y1 = vtl->ct_y2;
+ vtl->ct_x2 = event->x;
+ vtl->ct_y2 = event->y;
+
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ return TRUE;
+}
+
+
+/*** New waypoint ****/
+
+static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp)
{
- if ( vtl->moving_tp )
- {
- /* vtl->moving_tp_x, vtl->moving_tp_y, etc. */
- VikCoord new_coord;
- vtl->moving_tp = FALSE;
- vik_viewport_screen_to_coord ( vvp, event->x, event->y, &new_coord );
+ return vvp;
+}
- /* snap to TP */
- if ( event->state & GDK_CONTROL_MASK )
- {
- VikTrackpoint *tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
- if ( tp && tp != vtl->current_tpl->data )
- new_coord = tp->coord;
- }
+static gboolean tool_new_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+{
+ VikCoord coord;
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
+ vik_viewport_screen_to_coord ( vvp, event->x, event->y, &coord );
+ if (vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), &coord ) && VIK_LAYER(vtl)->visible)
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
+ return TRUE;
+}
- VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
- /* diff dist is diff from orig */
- vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track_name );
- /* can't join with itself! */
- trw_layer_cancel_last_tp ( vtl );
+/*** Edit trackpoint ****/
- vik_layer_emit_update ( VIK_LAYER(vtl) );
- return TRUE;
- }
- return FALSE;
+static gpointer tool_edit_trackpoint_create ( VikWindow *vw, VikViewport *vvp)
+{
+ tool_ed_t *t = g_new(tool_ed_t, 1);
+ t->vvp = vvp;
+ t->holding = FALSE;
+ return t;
}
-static gboolean tool_edit_trackpoint ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+static gboolean tool_edit_trackpoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
{
+ tool_ed_t *t = data;
+ VikViewport *vvp = t->vvp;
TPSearchParams params;
/* OUTDATED DOCUMENTATION:
find 5 pixel range on each side. then put these UTM, and a pointer
/* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
params.closest_tp = NULL;
+ if ( event->button != 1 )
+ return FALSE;
+
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
+
if ( vtl->current_tpl )
{
/* first check if it is within range of prev. tp. and if current_tp track is shown. (if it is, we are moving that trackpoint.) */
if ( current_tr->visible &&
abs(x - event->x) < TRACKPOINT_SIZE_APPROX &&
- abs(y - event->y) < TRACKPOINT_SIZE_APPROX )
- {
- vtl->moving_tp = TRUE;
+ abs(y - event->y) < TRACKPOINT_SIZE_APPROX ) {
+ marker_begin_move ( t, event->x, event->y );
return TRUE;
}
return TRUE;
}
-
/* these aren't the droids you're looking for */
return FALSE;
}
-typedef struct {
- gint x, y;
- gint closest_x, closest_y;
- gchar *closest_wp_name;
- VikWaypoint *closest_wp;
- VikViewport *vvp;
-} WPSearchParams;
-
-static void waypoint_search_closest_tp ( gchar *name, VikWaypoint *wp, WPSearchParams *params )
+static gboolean tool_edit_trackpoint_move ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
{
- gint x, y;
- if ( !wp->visible )
- return;
+ tool_ed_t *t = data;
+ VikViewport *vvp = t->vvp;
- vik_viewport_coord_to_screen ( params->vvp, &(wp->coord), &x, &y );
-
- if ( abs (x - params->x) <= WAYPOINT_SIZE_APPROX && abs (y - params->y) <= WAYPOINT_SIZE_APPROX &&
- ((!params->closest_wp) || /* was the old waypoint we already found closer than this one? */
- abs(x - params->x)+abs(y - params->y) < abs(x - params->closest_x)+abs(y - params->closest_y)))
- {
- params->closest_wp_name = name;
- params->closest_wp = wp;
- params->closest_x = x;
- params->closest_y = y;
- }
-}
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
-static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
-{
- if ( vtl->moving_wp )
+ if ( t->holding )
{
VikCoord new_coord;
- vtl->moving_wp = FALSE;
+ GdkGC *gc;
vik_viewport_screen_to_coord ( vvp, event->x, event->y, &new_coord );
/* snap to TP */
if ( event->state & GDK_CONTROL_MASK )
{
VikTrackpoint *tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
- if ( tp )
+ if ( tp && tp != vtl->current_tpl->data )
new_coord = tp->coord;
}
+ // VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
+ {
+ gint x, y;
+ vik_viewport_coord_to_screen ( vvp, &new_coord, &x, &y );
+ marker_moveto ( t, x, y );
+ }
- /* snap to WP */
- if ( event->state & GDK_SHIFT_MASK )
- {
- VikWaypoint *wp = closest_wp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
- if ( wp && wp != vtl->current_wp )
- new_coord = wp->coord;
- }
-
- vtl->current_wp->coord = new_coord;
- vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
- /* PUT IN RIGHT PLACE!!! */
- if ( vtl->waypoint_rightclick )
- {
- if ( vtl->wp_right_click_menu )
- gtk_object_sink ( GTK_OBJECT(vtl->wp_right_click_menu) );
- vtl->wp_right_click_menu = GTK_MENU ( gtk_menu_new () );
- vik_trw_layer_sublayer_add_menu_items ( vtl, vtl->wp_right_click_menu, NULL, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, vtl->current_wp_name, g_hash_table_lookup ( vtl->waypoints_iters, vtl->current_wp_name ) );
- gtk_menu_popup ( vtl->wp_right_click_menu, NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time() );
- vtl->waypoint_rightclick = FALSE;
- }
return FALSE;
}
-static VikWaypoint *closest_wp_in_five_pixel_interval ( VikTrwLayer *vtl, VikViewport *vvp, gint x, gint y )
+static gboolean tool_edit_trackpoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data )
{
- WPSearchParams params;
- params.x = x;
- params.y = y;
- params.vvp = vvp;
- params.closest_wp = NULL;
- params.closest_wp_name = NULL;
- g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, ¶ms);
- return params.closest_wp;
-}
+ tool_ed_t *t = data;
+ VikViewport *vvp = t->vvp;
-static gboolean tool_edit_waypoint ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
-{
- WPSearchParams params;
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
+ if ( event->button != 1)
+ return FALSE;
- if ( vtl->current_wp && vtl->current_wp->visible )
- {
- /* first check if current WP is within area (other may be 'closer', but we want to move the current) */
- gint x, y;
- vik_viewport_coord_to_screen ( vvp, &(vtl->current_wp->coord), &x, &y );
+ if ( t->holding ) {
+ VikCoord new_coord;
+ vik_viewport_screen_to_coord ( vvp, event->x, event->y, &new_coord );
- if ( abs(x - event->x) < WAYPOINT_SIZE_APPROX &&
- abs(y - event->y) < WAYPOINT_SIZE_APPROX )
+ /* snap to TP */
+ if ( event->state & GDK_CONTROL_MASK )
{
- if ( event->button == 3 )
- vtl->waypoint_rightclick = TRUE; /* remember that we're clicking; other layers will ignore release signal */
- else
- vtl->moving_wp = TRUE;
- return TRUE;
+ VikTrackpoint *tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
+ if ( tp && tp != vtl->current_tpl->data )
+ new_coord = tp->coord;
}
- }
- params.vvp = vvp;
- params.x = event->x;
- params.y = event->y;
- params.closest_wp_name = NULL;
- /* TODO: should get track listitem so we can break it up, make a new track, mess it up, all that. */
- params.closest_wp = NULL;
- g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_search_closest_tp, ¶ms);
- if ( vtl->current_wp == params.closest_wp && vtl->current_wp != NULL )
- {
- vtl->moving_wp = TRUE;
- }
- else if ( params.closest_wp )
- {
- if ( event->button == 3 )
- vtl->waypoint_rightclick = TRUE; /* remember that we're clicking; other layers will ignore release signal */
- else
- vtl->waypoint_rightclick = FALSE;
+ VIK_TRACKPOINT(vtl->current_tpl->data)->coord = new_coord;
- vtl->current_wp = params.closest_wp;
- vtl->current_wp_name = params.closest_wp_name;
- vtl->moving_wp = FALSE;
+ marker_end_move ( t );
- if ( params.closest_wp )
- vik_treeview_select_iter ( VIK_LAYER(vtl)->vt, g_hash_table_lookup ( vtl->waypoints_iters, vtl->current_wp_name ) );
+ /* diff dist is diff from orig */
+ vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track_name );
+ /* can't join with itself! */
+ trw_layer_cancel_last_tp ( vtl );
- /* could make it so don't update if old WP is off screen and new is null but oh well */
vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
-
- vtl->current_wp = NULL;
- vtl->current_wp_name = NULL;
- vtl->moving_wp = FALSE;
- vtl->waypoint_rightclick = FALSE;
return FALSE;
}
-static gboolean tool_new_track ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+
+/*** Magic Scissors ***/
+static gpointer tool_magic_scissors_create ( VikWindow *vw, VikViewport *vvp)
{
- VikTrackpoint *tp;
+ return vvp;
+}
- if ( event->button == 3 && vtl->current_track )
- {
- /* undo */
- if ( vtl->current_track->trackpoints )
- {
- GList *last = g_list_last(vtl->current_track->trackpoints);
- g_free ( last->data );
- vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
- }
+static gboolean tool_magic_scissors_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+{
+ VikCoord tmp;
+ vik_viewport_screen_to_coord ( vvp, event->x, event->y, &tmp );
+ if ( vtl->magic_scissors_started ) {
+ struct LatLon start, end;
+ gchar *cmd;
+ vik_coord_to_latlon ( &(vtl->magic_scissors_coord), &start );
+ vik_coord_to_latlon ( &(tmp), &end );
+ cmd = g_strdup_printf(GOOGLE_DIRECTIONS_STRING, start.lat, start.lon, end.lat, end.lon );
+ a_babel_convert_from_shellcommand ( vtl, cmd, "google", NULL, NULL );
+ g_free ( cmd );
vik_layer_emit_update ( VIK_LAYER(vtl) );
- return TRUE;
+ } else {
+ vtl->magic_scissors_coord = tmp;
}
+ vtl->magic_scissors_started = !vtl->magic_scissors_started;
+ return TRUE;
+}
- if ( event->type == GDK_2BUTTON_PRESS )
+/*** Show picture ****/
+
+static gpointer tool_show_picture_create ( VikWindow *vw, VikViewport *vvp)
+{
+ return vvp;
+}
+
+/* Params are: vvp, event, last match found or NULL */
+static void tool_show_picture_wp ( char *name, VikWaypoint *wp, gpointer params[2] )
+{
+ if ( wp->image && wp->visible )
{
- /* subtract last (duplicate from double click) tp then end */
- if ( vtl->current_track && vtl->current_track->trackpoints && vtl->ct_x1 == vtl->ct_x2 && vtl->ct_y1 == vtl->ct_y2 )
+ gint x, y, slackx, slacky;
+ GdkEventButton *event = (GdkEventButton *) params[1];
+
+ vik_viewport_coord_to_screen ( VIK_VIEWPORT(params[0]), &(wp->coord), &x, &y );
+ slackx = wp->image_width / 2;
+ slacky = wp->image_height / 2;
+ if ( x <= event->x + slackx && x >= event->x - slackx
+ && y <= event->y + slacky && y >= event->y - slacky )
{
- GList *last = g_list_last(vtl->current_track->trackpoints);
- g_free ( last->data );
- vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
- /* undo last, then end */
- vtl->current_track = NULL;
+ params[2] = wp->image; /* we've found a match. however continue searching
+ * since we want to find the last match -- that
+ * is, the match that was drawn last. */
}
- return TRUE;
}
+}
- if ( ! vtl->current_track )
+static gboolean tool_show_picture_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+{
+ gpointer params[3] = { vvp, event, NULL };
+ if (!vtl || vtl->vl.type != VIK_LAYER_TRW)
+ return FALSE;
+ g_hash_table_foreach ( vtl->waypoints, (GHFunc) tool_show_picture_wp, params );
+ if ( params[2] )
{
- gchar *name;
- if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->tracks ) ) )
+ /* thanks to the Gaim people for showing me ShellExecute and g_spawn_command_line_async */
+#ifdef WINDOWS
+ ShellExecute(NULL, NULL, (char *) params[2], NULL, ".\\", 0);
+#else /* WINDOWS */
+ GError *err = NULL;
+ gchar *quoted_file = g_shell_quote ( (gchar *) params[2] );
+ gchar *cmd = g_strdup_printf ( "eog %s", quoted_file );
+ g_free ( quoted_file );
+ if ( ! g_spawn_command_line_async ( cmd, &err ) )
{
- vtl->current_track = vik_track_new();
- vtl->current_track->visible = TRUE;
- vik_trw_layer_add_track ( vtl, name, vtl->current_track );
+ a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_LAYER(vtl), "Could not launch eog to open file." );
+ g_error_free ( err );
}
- else
- return TRUE;
+ g_free ( cmd );
+#endif /* WINDOWS */
+ return TRUE; /* found a match */
}
- tp = vik_trackpoint_new();
- vik_viewport_screen_to_coord ( vvp, event->x, event->y, &(tp->coord) );
+ else
+ return FALSE; /* go through other layers, searching for a match */
+}
+
+/***************************************************************************
+ ** End tool code
+ ***************************************************************************/
- /* snap to other TP */
- if ( event->state & GDK_CONTROL_MASK )
- {
- VikTrackpoint *other_tp = closest_tp_in_five_pixel_interval ( vtl, vvp, event->x, event->y );
- if ( other_tp )
- tp->coord = other_tp->coord;
- }
- tp->newsegment = FALSE;
- tp->has_timestamp = FALSE;
- tp->timestamp = 0;
- tp->altitude = VIK_DEFAULT_ALTITUDE;
- vtl->current_track->trackpoints = g_list_append ( vtl->current_track->trackpoints, tp );
- vtl->ct_x1 = vtl->ct_x2;
- vtl->ct_y1 = vtl->ct_y2;
- vtl->ct_x2 = event->x;
- vtl->ct_y2 = event->y;
- vik_layer_emit_update ( VIK_LAYER(vtl) );
- return TRUE;
-}
static void image_wp_make_list ( char *name, VikWaypoint *wp, GSList **pics )
{
g_hash_table_foreach ( vtl->tracks, (GHFunc) track_convert, &dest_mode );
}
}
+
+VikWaypoint *vik_trw_layer_get_waypoint ( VikTrwLayer *vtl, gchar *name )
+{
+ return g_hash_table_lookup ( vtl->waypoints, name );
+}
+
+VikTrack *vik_trw_layer_get_track ( VikTrwLayer *vtl, gchar *name )
+{
+ return g_hash_table_lookup ( vtl->tracks, name );
+}
+
+static void vik_trw_layer_set_menu_selection(VikTrwLayer *vtl, guint16 selection)
+{
+ vtl->menu_selection = selection;
+}
+
+static guint16 vik_trw_layer_get_menu_selection(VikTrwLayer *vtl)
+{
+ return(vtl->menu_selection);
+}
+