#include "icons/icons.h"
#include "vikexttools.h"
#include "garminsymbols.h"
+#include "vikmapslayer.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
static void draw_mouse_motion ( VikWindow *vw, GdkEventMotion *event );
static void draw_zoom_cb ( GtkAction *a, VikWindow *vw );
static void draw_goto_cb ( GtkAction *a, VikWindow *vw );
+static void draw_refresh_cb ( GtkAction *a, VikWindow *vw );
static void draw_status ( VikWindow *vw );
VikStatusbar *viking_vs;
GtkToolbar *toolbar;
+ GtkComboBox *tb_zoom_combo;
GtkItemFactory *item_factory;
if (vw != NULL && check_file_magic_vik ( file_name ) ) {
VikWindow *newvw = vik_window_new_window ();
if (newvw)
- vik_window_open_file ( newvw, file_name, change_fn );
+ vik_window_open_file ( newvw, file_name, TRUE );
}
else {
vik_window_open_file ( vw, file_name, change_fn );
}
+static void set_toolbar_zoom ( VikWindow *vw, gdouble mpp )
+{
+ gint active = 2 + ( log (mpp) / log (2) );
+ // Can we not hard code size here?
+ if ( active > 17 )
+ active = 17;
+ gtk_combo_box_set_active ( vw->tb_zoom_combo, active );
+}
+
+static void zoom_changed ( GtkComboBox *combo, VikWindow *vw )
+{
+ gint active = gtk_combo_box_get_active ( combo );
+
+ // But has it really changed?
+ // Unfortunately this function gets invoked even on manual setting of the combo value
+ gdouble zoom_request = pow (2, active-2 );
+ gdouble current_zoom = vik_viewport_get_zoom ( vw->viking_vvp );
+ if ( current_zoom != 0.0 && zoom_request != current_zoom ) {
+ vik_viewport_set_zoom ( vw->viking_vvp, zoom_request );
+ // Force drawing update
+ draw_update ( vw );
+ }
+}
+
+static GtkWidget *create_zoom_combo_all_levels ()
+{
+ GtkWidget *zoom_combo = gtk_combo_box_new_text();
+ GtkComboBox *combo = GTK_COMBO_BOX ( zoom_combo );
+ gtk_combo_box_append_text ( combo, "0.25");
+ gtk_combo_box_append_text ( combo, "0.5");
+ gtk_combo_box_append_text ( combo, "1");
+ gtk_combo_box_append_text ( combo, "2");
+ gtk_combo_box_append_text ( combo, "4");
+ gtk_combo_box_append_text ( combo, "8");
+ gtk_combo_box_append_text ( combo, "16");
+ gtk_combo_box_append_text ( combo, "32");
+ gtk_combo_box_append_text ( combo, "64");
+ gtk_combo_box_append_text ( combo, "128");
+ gtk_combo_box_append_text ( combo, "256");
+ gtk_combo_box_append_text ( combo, "512");
+ gtk_combo_box_append_text ( combo, "1024");
+ gtk_combo_box_append_text ( combo, "2048");
+ gtk_combo_box_append_text ( combo, "4096");
+ gtk_combo_box_append_text ( combo, "8192");
+ gtk_combo_box_append_text ( combo, "16384");
+ gtk_combo_box_append_text ( combo, "32768");
+ /* Create tooltip */
+ GtkTooltips *tooltips = gtk_tooltips_new ();
+ gtk_tooltips_set_tip ( tooltips, GTK_WIDGET (combo), _("Select zoom level"), NULL);
+ return zoom_combo;
+}
+
static void window_init ( VikWindow *vw )
{
GtkWidget *main_vbox;
vik_ext_tools_add_menu_items ( vw, vw->uim );
+ vw->tb_zoom_combo = GTK_COMBO_BOX(create_zoom_combo_all_levels());
+
+ g_signal_connect ( G_OBJECT(vw->tb_zoom_combo), "changed", G_CALLBACK(zoom_changed), vw );
+
+ // Add the zoom combo to the toolbar at the end
+ GtkToolItem *tooli = gtk_tool_item_new ();
+ gtk_container_add ( GTK_CONTAINER(tooli), GTK_WIDGET (vw->tb_zoom_combo) );
+ gtk_toolbar_insert ( vw->toolbar, tooli, gtk_toolbar_get_n_items (vw->toolbar) );
+
g_signal_connect (G_OBJECT (vw), "delete_event", G_CALLBACK (delete_event), NULL);
g_signal_connect_swapped (G_OBJECT(vw->viking_vvp), "expose_event", G_CALLBACK(draw_sync), vw);
g_signal_connect_swapped (G_OBJECT(vw->viking_vvp), "motion_notify_event", G_CALLBACK(draw_mouse_motion), vw);
g_signal_connect_swapped (G_OBJECT(vw->viking_vlp), "update", G_CALLBACK(draw_update), vw);
- g_signal_connect_swapped (G_OBJECT (vw->viking_vvp), "key_press_event", G_CALLBACK (key_press_event), vw);
+ // Allow key presses to be processed anywhere
+ g_signal_connect_swapped (G_OBJECT (vw), "key_press_event", G_CALLBACK (key_press_event), vw);
gtk_window_set_default_size ( GTK_WINDOW(vw), VIKING_WINDOW_WIDTH, VIKING_WINDOW_HEIGHT);
return VIK_WINDOW ( g_object_new ( VIK_WINDOW_TYPE, NULL ) );
}
+/**
+ * Update the displayed map
+ * Only update the top most visible map layer
+ * ATM this assumes (as per defaults) the top most map has full alpha setting
+ * such that other other maps even though they may be active will not be seen
+ * It's more complicated to work out which maps are actually visible due to alpha settings
+ * and overkill for this simple refresh method.
+ */
+static void simple_map_update ( VikWindow *vw, gboolean only_new )
+{
+ // Find the most relevent single map layer to operate on
+ VikLayer *vl = vik_aggregate_layer_get_top_visible_layer_of_type (vik_layers_panel_get_top_layer(vw->viking_vlp), VIK_LAYER_MAPS);
+ if ( vl )
+ vik_maps_layer_download ( VIK_MAPS_LAYER(vl), vw->viking_vvp, only_new );
+}
+
+/**
+ * This is the global key press handler
+ * Global shortcuts are available at any time and hence are not restricted to when a certain tool is enabled
+ */
static gboolean key_press_event( VikWindow *vw, GdkEventKey *event, gpointer data )
{
+ // The keys handled here are not in the menuing system for a couple of reasons:
+ // . Keeps the menu size compact (alebit at expense of discoverably)
+ // . Allows differing key bindings to perform the same actions
+
+ // First decide if key events are related to the maps layer
+ gboolean map_download = FALSE;
+ gboolean map_download_only_new = TRUE; // Only new or reload
+
+ GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask();
+
+ // Standard 'Refresh' keys: F5 or Ctrl+r
+ // Note 'F5' is actually handled via draw_refresh_cb() later on
+ // (not 'R' it's 'r' notice the case difference!!)
+ if ( event->keyval == GDK_r && (event->state & modifiers) == GDK_CONTROL_MASK ) {
+ map_download = TRUE;
+ map_download_only_new = TRUE;
+ }
+ // Full cache reload with Ctrl+F5 or Ctrl+Shift+r [This is not in the menu system]
+ // Note the use of uppercase R here since shift key has been pressed
+ else if ( (event->keyval == GDK_F5 && (event->state & modifiers) == GDK_CONTROL_MASK ) ||
+ ( event->keyval == GDK_R && (event->state & modifiers) == (GDK_CONTROL_MASK + GDK_SHIFT_MASK) ) ) {
+ map_download = TRUE;
+ map_download_only_new = FALSE;
+ }
+
+ if ( map_download ) {
+ simple_map_update ( vw, map_download_only_new );
+ }
+
VikLayer *vl = vik_layers_panel_get_selected ( vw->viking_vlp );
if (vl && vw->vt->active_tool != -1 && vw->vt->tools[vw->vt->active_tool].ti.key_press ) {
gint ltype = vw->vt->tools[vw->vt->active_tool].layer_type;
{
vik_viewport_sync(vw->viking_vvp);
draw_status ( vw );
- /* other things may be necc here later. */
+}
+
+/*
+ * Split the status update, as sometimes only need to update the tool part
+ * also on initialization the zoom related stuff is not ready to be used
+ */
+static void draw_status_tool ( VikWindow *vw )
+{
+ if ( vw->current_tool == TOOL_LAYER )
+ // Use tooltip rather than the internal name as the tooltip is i8n
+ vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, vik_layer_get_interface(vw->tool_layer_id)->tools[vw->tool_tool_id].radioActionEntry.tooltip );
+ else
+ vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, _(tool_names[vw->current_tool]) );
}
static void draw_status ( VikWindow *vw )
else
/* xmpp should be a whole number so don't show useless .000 bit */
g_snprintf ( zoom_level, 22, "%d %s", (int)xmpp, unit );
- if ( vw->current_tool == TOOL_LAYER )
- // Use tooltip rather than the internal name as the tooltip is i8n
- vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, vik_layer_get_interface(vw->tool_layer_id)->tools[vw->tool_tool_id].radioActionEntry.tooltip );
- else
- vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_TOOL, _(tool_names[vw->current_tool]) );
vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_ZOOM, zoom_level );
+ // OK maybe not quite in the statusbar - but we have the zoom level so use it
+ set_toolbar_zoom ( vw, xmpp ); // But it's a status of some kind!
+
+ draw_status_tool ( vw );
}
void vik_window_set_redraw_trigger(VikLayer *vl)
vik_viewport_screen_to_coord ( vw->viking_vvp, event->x, event->y, &coord );
vik_coord_to_utm ( &coord, &utm );
- a_coords_utm_to_latlon ( &utm, &ll );
- a_coords_latlon_to_string ( &ll, &lat, &lon );
+
+ if ( vik_viewport_get_drawmode ( vw->viking_vvp ) == VIK_VIEWPORT_DRAWMODE_UTM ) {
+ // Reuse lat for the first part (Zone + N or S, and lon for the second part (easting and northing) of a UTM format:
+ // ZONE[N|S] EASTING NORTHING
+ lat = g_malloc(4*sizeof(gchar));
+ // NB zone is stored in a char but is an actual number
+ g_snprintf (lat, 4, "%d%c", utm.zone, utm.letter);
+ lon = g_malloc(16*sizeof(gchar));
+ g_snprintf (lon, 16, "%d %d", (gint)utm.easting, (gint)utm.northing);
+ }
+ else {
+ a_coords_utm_to_latlon ( &utm, &ll );
+ a_coords_latlon_to_string ( &ll, &lat, &lon );
+ }
+
/* Change interpolate method according to scale */
zoom = vik_viewport_get_zoom(vw->viking_vvp);
if (zoom > 2.0)
********************************************************************************/
static void draw_ruler(VikViewport *vvp, GdkDrawable *d, GdkGC *gc, gint x1, gint y1, gint x2, gint y2, gdouble distance)
{
- PangoFontDescription *pfd;
PangoLayout *pl;
gchar str[128];
GdkGC *labgc = vik_viewport_new_gc ( vvp, "#cccccc", 1);
gint wb, hb, xb, yb;
pl = gtk_widget_create_pango_layout (GTK_WIDGET(vvp), NULL);
-
- pfd = pango_font_description_from_string ("Sans 8"); // FIXME: settable option? global variable?
- pango_layout_set_font_description (pl, pfd);
- pango_font_description_free (pfd);
-
+ pango_layout_set_font_description (pl, GTK_WIDGET(vvp)->style->font_desc);
pango_layout_set_text(pl, "N", -1);
gdk_draw_layout(d, gc, x1-5, y1-CR-3*CW-8, pl);
ruler_deactivate ( vl, s );
return TRUE;
}
+ // Regardless of whether we used it, return false so other GTK things may use it
return FALSE;
}
-static VikToolInterface ruler_tool =
- { { "Ruler", "vik-icon-ruler", N_("_Ruler"), "<control><shift>R", N_("Ruler Tool"), 2 },
+static VikToolInterface ruler_tool =
+ // NB Ctrl+Shift+R is used for Refresh (deemed more important), so use 'U' instead
+ { { "Ruler", "vik-icon-ruler", N_("_Ruler"), "<control><shift>U", N_("Ruler Tool"), 2 },
(VikToolConstructorFunc) ruler_create,
(VikToolDestructorFunc) ruler_destroy,
(VikToolActivationFunc) NULL,
draw_update ( vw );
}
-void draw_goto_cb ( GtkAction *a, VikWindow *vw )
+static void draw_goto_cb ( GtkAction *a, VikWindow *vw )
{
VikCoord new_center;
draw_update ( vw );
}
+/**
+ * Refresh maps displayed
+ */
+static void draw_refresh_cb ( GtkAction *a, VikWindow *vw )
+{
+ // Only get 'new' maps
+ simple_map_update ( vw, TRUE );
+}
+
static void menu_addlayer_cb ( GtkAction *a, VikWindow *vw )
{
gint type;
#if GTK_CHECK_VERSION (2, 14, 0)
gchar *uri;
uri = g_strdup_printf("ghelp:%s", PACKAGE);
- gtk_show_uri(NULL, uri, GDK_CURRENT_TIME, NULL);
+ GError *error = NULL;
+ gboolean show = gtk_show_uri (NULL, uri, GDK_CURRENT_TIME, &error);
+ if ( !show && !error )
+ // No error to show, so unlikely this will get called
+ a_dialog_error_msg ( GTK_WINDOW(vw), _("The help system is not available.") );
+ else if ( error ) {
+ // Main error path
+ a_dialog_error_msg_extra ( GTK_WINDOW(vw), _("Help is not available because: %s.\nEnsure a Mime Type ghelp handler program is installed (e.g. yelp)."), error->message );
+ g_error_free ( error );
+ }
g_free(uri);
+#else
+ a_dialog_error_msg ( GTK_WINDOW(vw), "Help is not available in this build." ); // Unlikely to happen so not going to bother with I8N
#endif
#endif /* WINDOWS */
}
vt->n_tools = 0;
vt->active_tool = -1;
vt->vw = vw;
- if (!vw->viking_vvp) {
- g_critical("no viewport found.");
- exit(1);
- }
return vt;
}
if (tool == vt->n_tools) {
g_critical("trying to activate a non-existent tool...");
- exit(1);
+ return;
}
/* is the tool already active? */
if (vt->active_tool == tool) {
}
}
}
- draw_status ( vw );
+ draw_status_tool ( vw );
}
static void window_set_filename ( VikWindow *vw, const gchar *filename )
case LOAD_TYPE_UNSUPPORTED_FAILURE:
a_dialog_error_msg_extra ( GTK_WINDOW(vw), _("Unsupported file type for %s"), filename );
break;
+ case LOAD_TYPE_VIK_FAILURE_NON_FATAL:
+ {
+ // Since we can process .vik files with issues just show a warning in the status bar
+ // Not that a user can do much about it... or tells them what this issue is yet...
+ gchar *msg = g_strdup_printf (_("WARNING: issues encountered loading %s"), a_file_basename (filename) );
+ vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, msg );
+ g_free ( msg );
+ }
+ // No break, carry on to show any data
case LOAD_TYPE_VIK_SUCCESS:
{
GtkWidget *mode_button;
else {
files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER(vw->open_dia) );
gboolean change_fn = newwindow && (g_slist_length(files)==1); /* only change fn if one file */
-
+ gboolean first_vik_file = TRUE;
cur_file = files;
while ( cur_file ) {
+
gchar *file_name = cur_file->data;
- vik_window_open_file ( vw, file_name, change_fn );
+ if ( newwindow && check_file_magic_vik ( file_name ) ) {
+ // Load first of many .vik files in current window
+ if ( first_vik_file ) {
+ vik_window_open_file ( vw, file_name, TRUE );
+ first_vik_file = FALSE;
+ }
+ else {
+ // Load each subsequent .vik file in a separate window
+ VikWindow *newvw = vik_window_new_window ();
+ if (newvw)
+ vik_window_open_file ( newvw, file_name, TRUE );
+ }
+ }
+ else
+ // Other file types
+ vik_window_open_file ( vw, file_name, change_fn );
+
g_free (file_name);
cur_file = g_slist_next (cur_file);
}
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
+ GtkFileFilter *filter;
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name( filter, _("All") );
+ gtk_file_filter_add_pattern ( filter, "*" );
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->save_dia), filter);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name( filter, _("Viking") );
+ gtk_file_filter_add_pattern ( filter, "*.vik" );
+ gtk_file_filter_add_pattern ( filter, "*.viking" );
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->save_dia), filter);
+ // Default to a Viking file
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(vw->save_dia), filter);
+
gtk_window_set_transient_for ( GTK_WINDOW(vw->save_dia), GTK_WINDOW(vw) );
gtk_window_set_destroy_with_parent ( GTK_WINDOW(vw->save_dia), TRUE );
}
gdouble old_xmpp, old_ympp;
GError *error = NULL;
+ GtkWidget *msgbox = gtk_message_dialog_new ( GTK_WINDOW(vw),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_NONE,
+ _("Generating image file...") );
+
+ g_signal_connect_swapped (msgbox, "response", G_CALLBACK (gtk_widget_destroy), msgbox);
+ // Ensure dialog shown
+ gtk_widget_show_all ( msgbox );
+ // Try harder...
+ vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, _("Generating image file...") );
+ while ( gtk_events_pending() )
+ gtk_main_iteration ();
+ // Despite many efforts & variations, GTK on my Linux system doesn't show the actual msgbox contents :(
+ // At least the empty box can give a clue something's going on + the statusbar msg...
+ // Windows version under Wine OK!
+
/* backup old zoom & set new */
old_xmpp = vik_viewport_get_xmpp ( vw->viking_vvp );
old_ympp = vik_viewport_get_ympp ( vw->viking_vvp );
/* save buffer as file. */
pixbuf_to_save = gdk_pixbuf_get_from_drawable ( NULL, GDK_DRAWABLE(vik_viewport_get_pixmap ( vw->viking_vvp )), NULL, 0, 0, 0, 0, w, h);
+ if ( !pixbuf_to_save ) {
+ g_warning("Failed to generate internal pixmap size: %d x %d", w, h);
+ gtk_message_dialog_set_markup ( GTK_MESSAGE_DIALOG(msgbox), _("Failed to generate internal image.\n\nTry creating a smaller image.") );
+ goto cleanup;
+ }
+
gdk_pixbuf_save ( pixbuf_to_save, fn, save_as_png ? "png" : "jpeg", &error, NULL );
if (error)
{
g_warning("Unable to write to file %s: %s", fn, error->message );
+ gtk_message_dialog_set_markup ( GTK_MESSAGE_DIALOG(msgbox), _("Failed to generate image file.") );
g_error_free (error);
}
+ else {
+ // Success
+ gtk_message_dialog_set_markup ( GTK_MESSAGE_DIALOG(msgbox), _("Image file generated.") );
+ }
g_object_unref ( G_OBJECT(pixbuf_to_save) );
+ cleanup:
+ vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, "" );
+ gtk_dialog_add_button ( GTK_DIALOG(msgbox), GTK_STOCK_OK, GTK_RESPONSE_OK );
+ gtk_dialog_run ( GTK_DIALOG(msgbox) ); // Don't care about the result
+
/* pretend like nothing happened ;) */
vik_viewport_set_xmpp ( vw->viking_vvp, old_xmpp );
vik_viewport_set_ympp ( vw->viking_vvp, old_ympp );
{
VikWindow *vw = VIK_WINDOW(pass_along[0]);
GtkSpinButton *width_spin = GTK_SPIN_BUTTON(pass_along[1]), *height_spin = GTK_SPIN_BUTTON(pass_along[2]);
- GtkSpinButton *zoom_spin = GTK_SPIN_BUTTON(pass_along[3]);
+
+ gint active = gtk_combo_box_get_active ( GTK_COMBO_BOX(pass_along[3]) );
+ gdouble zoom = pow (2, active-2 );
+
gdouble width_min, width_max, height_min, height_max;
gint width, height;
gtk_spin_button_get_range ( height_spin, &height_min, &height_max );
/* TODO: support for xzoom and yzoom values */
- width = vik_viewport_get_width ( vw->viking_vvp ) * vik_viewport_get_xmpp ( vw->viking_vvp ) / gtk_spin_button_get_value ( zoom_spin );
- height = vik_viewport_get_height ( vw->viking_vvp ) * vik_viewport_get_xmpp ( vw->viking_vvp ) / gtk_spin_button_get_value ( zoom_spin );
+ width = vik_viewport_get_width ( vw->viking_vvp ) * vik_viewport_get_xmpp ( vw->viking_vvp ) / zoom;
+ height = vik_viewport_get_height ( vw->viking_vvp ) * vik_viewport_get_xmpp ( vw->viking_vvp ) / zoom;
if ( width > width_max || width < width_min || height > height_max || height < height_min )
a_dialog_info_msg ( GTK_WINDOW(vw), _("Viewable region outside allowable pixel size bounds for image. Clipping width/height values.") );
static void draw_to_image_file_total_area_cb (GtkSpinButton *spinbutton, gpointer *pass_along)
{
GtkSpinButton *width_spin = GTK_SPIN_BUTTON(pass_along[1]), *height_spin = GTK_SPIN_BUTTON(pass_along[2]);
- GtkSpinButton *zoom_spin = GTK_SPIN_BUTTON(pass_along[3]);
+
+ gint active = gtk_combo_box_get_active ( GTK_COMBO_BOX(pass_along[3]) );
+ gdouble zoom = pow (2, active-2 );
+
gchar *label_text;
gdouble w, h;
- w = gtk_spin_button_get_value(width_spin) * gtk_spin_button_get_value(zoom_spin);
- h = gtk_spin_button_get_value(height_spin) * gtk_spin_button_get_value(zoom_spin);
+ w = gtk_spin_button_get_value(width_spin) * zoom;
+ h = gtk_spin_button_get_value(height_spin) * zoom;
if (pass_along[4]) /* save many images; find TOTAL area covered */
{
w *= gtk_spin_button_get_value(GTK_SPIN_BUTTON(pass_along[4]));
g_free ( label_text );
}
-static void draw_to_image_file ( VikWindow *vw, const gchar *fn, gboolean one_image_only )
+/*
+ * Get an allocated filename (or directory as specified)
+ */
+static gchar* draw_image_filename ( VikWindow *vw, gboolean one_image_only )
+{
+ gchar *fn = NULL;
+ if ( one_image_only )
+ {
+ // Single file
+ if (!vw->save_img_dia) {
+ vw->save_img_dia = gtk_file_chooser_dialog_new (_("Save Image"),
+ GTK_WINDOW(vw),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ GtkFileChooser *chooser = GTK_FILE_CHOOSER ( vw->save_img_dia );
+ /* Add filters */
+ GtkFileFilter *filter;
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name ( filter, _("All") );
+ gtk_file_filter_add_pattern ( filter, "*" );
+ gtk_file_chooser_add_filter ( chooser, filter );
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name ( filter, _("JPG") );
+ gtk_file_filter_add_mime_type ( filter, "image/jpeg");
+ gtk_file_chooser_add_filter ( chooser, filter );
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name ( filter, _("PNG") );
+ gtk_file_filter_add_mime_type ( filter, "image/png");
+ gtk_file_chooser_add_filter ( chooser, filter );
+
+ // Default to pngs
+ gtk_file_chooser_set_filter ( chooser, filter );
+
+ gtk_window_set_transient_for ( GTK_WINDOW(vw->save_img_dia), GTK_WINDOW(vw) );
+ gtk_window_set_destroy_with_parent ( GTK_WINDOW(vw->save_img_dia), TRUE );
+ }
+
+ if ( gtk_dialog_run ( GTK_DIALOG(vw->save_img_dia) ) == GTK_RESPONSE_ACCEPT ) {
+ fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(vw->save_img_dia) );
+ if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) )
+ if ( ! a_dialog_yes_or_no ( GTK_WINDOW(vw->save_img_dia), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) )
+ fn = NULL;
+ }
+ gtk_widget_hide ( vw->save_img_dia );
+ }
+ else {
+ // A directory
+ // For some reason this method is only written to work in UTM...
+ if ( vik_viewport_get_coord_mode(vw->viking_vvp) != VIK_COORD_UTM ) {
+ a_dialog_error_msg ( GTK_WINDOW(vw), _("You must be in UTM mode to use this feature") );
+ return fn;
+ }
+
+ if (!vw->save_img_dir_dia) {
+ vw->save_img_dir_dia = gtk_file_chooser_dialog_new (_("Choose a directory to hold images"),
+ GTK_WINDOW(vw),
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_transient_for ( GTK_WINDOW(vw->save_img_dir_dia), GTK_WINDOW(vw) );
+ gtk_window_set_destroy_with_parent ( GTK_WINDOW(vw->save_img_dir_dia), TRUE );
+ }
+
+ if ( gtk_dialog_run ( GTK_DIALOG(vw->save_img_dir_dia) ) == GTK_RESPONSE_ACCEPT ) {
+ fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(vw->save_img_dir_dia) );
+ }
+ gtk_widget_hide ( vw->save_img_dir_dia );
+ }
+ return fn;
+}
+
+static void draw_to_image_file ( VikWindow *vw, gboolean one_image_only )
{
/* todo: default for answers inside VikWindow or static (thruout instance) */
GtkWidget *dialog = gtk_dialog_new_with_buttons ( _("Save to Image File"), GTK_WINDOW(vw),
GtkWidget *png_radio, *jpeg_radio;
GtkWidget *current_window_button;
gpointer current_window_pass_along[7];
- GtkWidget *zoom_label, *zoom_spin;
+ GtkWidget *zoom_label, *zoom_combo;
GtkWidget *total_size_label;
/* only used if (!one_image_only) */
GtkWidget *tiles_width_spin = NULL, *tiles_height_spin = NULL;
-
width_label = gtk_label_new ( _("Width (pixels):") );
- width_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vw->draw_image_width, 10, 5000, 10, 100, 0 )), 10, 0 );
+ width_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vw->draw_image_width, 10, 50000, 10, 100, 0 )), 10, 0 );
height_label = gtk_label_new ( _("Height (pixels):") );
- height_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vw->draw_image_height, 10, 5000, 10, 100, 0 )), 10, 0 );
-
+ height_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vw->draw_image_height, 10, 50000, 10, 100, 0 )), 10, 0 );
+#ifdef WINDOWS
+ GtkWidget *win_warning_label = gtk_label_new ( _("WARNING: USING LARGE IMAGES OVER 10000x10000\nMAY CRASH THE PROGRAM!") );
+#endif
zoom_label = gtk_label_new ( _("Zoom (meters per pixel):") );
/* TODO: separate xzoom and yzoom factors */
- zoom_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( vik_viewport_get_xmpp(vw->viking_vvp), VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM/2.0, 1, 100, 0 )), 16, 0);
+ zoom_combo = create_zoom_combo_all_levels();
+
+ gdouble mpp = vik_viewport_get_xmpp(vw->viking_vvp);
+ gint active = 2 + ( log (mpp) / log (2) );
+
+ // Can we not hard code size here?
+ if ( active > 17 )
+ active = 17;
+ gtk_combo_box_set_active ( GTK_COMBO_BOX(zoom_combo), active );
total_size_label = gtk_label_new ( NULL );
current_window_pass_along [0] = vw;
current_window_pass_along [1] = width_spin;
current_window_pass_along [2] = height_spin;
- current_window_pass_along [3] = zoom_spin;
+ current_window_pass_along [3] = zoom_combo;
current_window_pass_along [4] = NULL; /* used for one_image_only != 1 */
current_window_pass_along [5] = NULL;
current_window_pass_along [6] = total_size_label;
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), width_spin, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), height_label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), height_spin, FALSE, FALSE, 0);
+#ifdef WINDOWS
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), win_warning_label, FALSE, FALSE, 0);
+#endif
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), current_window_button, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), png_radio, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), jpeg_radio, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), zoom_label, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), zoom_spin, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), zoom_combo, FALSE, FALSE, 0);
if ( ! one_image_only )
{
GtkWidget *tiles_width_label, *tiles_height_label;
-
tiles_width_label = gtk_label_new ( _("East-west image tiles:") );
tiles_width_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new ( 5, 1, 10, 1, 100, 0 )), 1, 0 );
tiles_height_label = gtk_label_new ( _("North-south image tiles:") );
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), total_size_label, FALSE, FALSE, 0);
g_signal_connect ( G_OBJECT(width_spin), "value-changed", G_CALLBACK(draw_to_image_file_total_area_cb), current_window_pass_along );
g_signal_connect ( G_OBJECT(height_spin), "value-changed", G_CALLBACK(draw_to_image_file_total_area_cb), current_window_pass_along );
- g_signal_connect ( G_OBJECT(zoom_spin), "value-changed", G_CALLBACK(draw_to_image_file_total_area_cb), current_window_pass_along );
+ g_signal_connect ( G_OBJECT(zoom_combo), "changed", G_CALLBACK(draw_to_image_file_total_area_cb), current_window_pass_along );
draw_to_image_file_total_area_cb ( NULL, current_window_pass_along ); /* set correct size info now */
if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
{
gtk_widget_hide ( GTK_WIDGET(dialog) );
+
+ gchar *fn = draw_image_filename ( vw, one_image_only );
+ if ( !fn )
+ return;
+
+ gint active = gtk_combo_box_get_active ( GTK_COMBO_BOX(zoom_combo) );
+ gdouble zoom = pow (2, active-2 );
+
if ( one_image_only )
save_image_file ( vw, fn,
vw->draw_image_width = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(width_spin) ),
vw->draw_image_height = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(height_spin) ),
- gtk_spin_button_get_value ( GTK_SPIN_BUTTON(zoom_spin) ), /* do not save this value, default is current zoom */
+ zoom,
vw->draw_image_save_as_png = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON(png_radio) ) );
else {
// NB is in UTM mode ATM
save_image_dir ( vw, fn,
vw->draw_image_width = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(width_spin) ),
vw->draw_image_height = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(height_spin) ),
- gtk_spin_button_get_value ( GTK_SPIN_BUTTON(zoom_spin) ), /* do not save this value, default is current zoom */
+ zoom,
vw->draw_image_save_as_png = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON(png_radio) ),
gtk_spin_button_get_value ( GTK_SPIN_BUTTON(tiles_width_spin) ),
gtk_spin_button_get_value ( GTK_SPIN_BUTTON(tiles_height_spin) ) );
}
+
+ g_free ( fn );
}
gtk_widget_destroy ( GTK_WIDGET(dialog) );
}
static void draw_to_image_file_cb ( GtkAction *a, VikWindow *vw )
{
- gchar *fn;
- if (!vw->save_img_dia) {
- vw->save_img_dia = gtk_file_chooser_dialog_new (_("Save Image"),
- GTK_WINDOW(vw),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_window_set_transient_for ( GTK_WINDOW(vw->save_img_dia), GTK_WINDOW(vw) );
- gtk_window_set_destroy_with_parent ( GTK_WINDOW(vw->save_img_dia), TRUE );
- }
-
- while ( gtk_dialog_run ( GTK_DIALOG(vw->save_img_dia) ) == GTK_RESPONSE_ACCEPT )
- {
- fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(vw->save_img_dia) );
- if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE || a_dialog_yes_or_no ( GTK_WINDOW(vw->save_img_dia), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) )
- {
- draw_to_image_file ( vw, fn, TRUE );
- break;
- }
- g_free(fn);
- fn = NULL;
- }
- gtk_widget_hide ( vw->save_img_dia );
+ draw_to_image_file ( vw, TRUE );
}
static void draw_to_image_dir_cb ( GtkAction *a, VikWindow *vw )
{
- gchar *fn = NULL;
-
- if ( vik_viewport_get_coord_mode(vw->viking_vvp) != VIK_COORD_UTM ) {
- a_dialog_error_msg ( GTK_WINDOW(vw), _("You must be in UTM mode to use this feature") );
- return;
- }
-
- if (!vw->save_img_dir_dia) {
- vw->save_img_dir_dia = gtk_file_chooser_dialog_new (_("Choose a directory to hold images"),
- GTK_WINDOW(vw),
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_window_set_transient_for ( GTK_WINDOW(vw->save_img_dir_dia), GTK_WINDOW(vw) );
- gtk_window_set_destroy_with_parent ( GTK_WINDOW(vw->save_img_dir_dia), TRUE );
- }
-
- while ( gtk_dialog_run ( GTK_DIALOG(vw->save_img_dir_dia) ) == GTK_RESPONSE_ACCEPT )
- {
- fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(vw->save_img_dir_dia) );
- if ( fn )
- {
- draw_to_image_file ( vw, fn, FALSE );
- g_free(fn);
- fn = NULL;
- break;
- }
- }
- gtk_widget_hide ( vw->save_img_dir_dia );
+ draw_to_image_file ( vw, FALSE );
}
#if GTK_CHECK_VERSION(2,10,0)
{ "GotoSearch", GTK_STOCK_JUMP_TO, N_("Go to _Location..."), NULL, N_("Go to address/place using text search"), (GCallback)goto_address },
{ "GotoLL", GTK_STOCK_JUMP_TO, N_("_Go to Lat/Lon..."), NULL, N_("Go to arbitrary lat/lon coordinate"), (GCallback)draw_goto_cb },
{ "GotoUTM", GTK_STOCK_JUMP_TO, N_("Go to UTM..."), NULL, N_("Go to arbitrary UTM coordinate"), (GCallback)draw_goto_cb },
+ { "Refresh", GTK_STOCK_REFRESH, N_("_Refresh"), "F5", N_("Refresh any maps displayed"), (GCallback)draw_refresh_cb },
{ "SetHLColor",GTK_STOCK_SELECT_COLOR, N_("Set _Highlight Color..."), NULL, NULL, (GCallback)set_highlight_color },
{ "SetBGColor",GTK_STOCK_SELECT_COLOR, N_("Set Bac_kground Color..."), NULL, NULL, (GCallback)set_bg_color },
{ "ZoomIn", GTK_STOCK_ZOOM_IN, N_("Zoom _In"), "<control>plus", NULL, (GCallback)draw_zoom_cb },
};
static GtkToggleActionEntry toggle_entries[] = {
- { "ShowScale", NULL, N_("Show _Scale"), "F5", N_("Show Scale"), (GCallback)set_draw_scale, TRUE },
+ { "ShowScale", NULL, N_("Show _Scale"), "<shift>F5", N_("Show Scale"), (GCallback)set_draw_scale, TRUE },
{ "ShowCenterMark", NULL, N_("Show _Center Mark"), "F6", N_("Show Center Mark"), (GCallback)set_draw_centermark, TRUE },
{ "ShowHighlight", GTK_STOCK_UNDERLINE, N_("Show _Highlight"), "F7", N_("Show Highlight"), (GCallback)set_draw_highlight, TRUE },
{ "FullScreen", GTK_STOCK_FULLSCREEN, N_("_Full Screen"), "F11", N_("Activate full screen mode"), (GCallback)full_screen_cb, FALSE },
return vw->selected_track;
}
-void vik_window_set_selected_track ( VikWindow *vw, gpointer *vt, gpointer vtl, gpointer name )
+void vik_window_set_selected_track ( VikWindow *vw, gpointer *vt, gpointer vtl )
{
vw->selected_track = vt;
vw->containing_vtl = vtl;
return vw->selected_waypoint;
}
-void vik_window_set_selected_waypoint ( VikWindow *vw, gpointer *vwp, gpointer vtl, gpointer name )
+void vik_window_set_selected_waypoint ( VikWindow *vw, gpointer *vwp, gpointer vtl )
{
vw->selected_waypoint = vwp;
vw->containing_vtl = vtl;