X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/c29a31985e639878d65faacbdac2a87431875edd..acb810758218b7b3a22276ffdd72e19819095a69:/src/vikwindow.c diff --git a/src/vikwindow.c b/src/vikwindow.c index 8ae5efae..6d4ccf44 100644 --- a/src/vikwindow.c +++ b/src/vikwindow.c @@ -76,6 +76,10 @@ static GSList *window_list = NULL; #define DRAW_IMAGE_DEFAULT_HEIGHT 1024 #define DRAW_IMAGE_DEFAULT_SAVE_AS_PNG TRUE +// The last used directories +static gchar *last_folder_files_uri = NULL; +static gchar *last_folder_images_uri = NULL; + static void window_finalize ( GObject *gob ); static GObjectClass *parent_class; @@ -204,9 +208,6 @@ struct _VikWindow { gboolean modified; VikLoadType_t loaded_type; - GtkWidget *open_dia, *save_dia; - GtkWidget *save_img_dia, *save_img_dir_dia; - gboolean only_updating_coord_mode_ui; /* hack for a bug in GTK */ GtkUIManager *uim; @@ -305,12 +306,17 @@ static gboolean statusbar_idle_update ( statusbar_idle_data *sid ) */ void vik_window_statusbar_update ( VikWindow *vw, const gchar* message, vik_statusbar_type_t vs_type ) { + GThread *thread = vik_window_get_thread ( vw ); + if ( !thread ) + // Do nothing + return; + statusbar_idle_data *sid = g_malloc ( sizeof (statusbar_idle_data) ); sid->vs = vw->viking_vs; sid->vs_type = vs_type; sid->message = g_strdup ( message ); - if ( g_thread_self() == vik_window_get_thread ( vw ) ) { + if ( g_thread_self() == thread ) { g_idle_add ( (GSourceFunc) statusbar_idle_update, sid ); } else { @@ -323,8 +329,11 @@ void vik_window_statusbar_update ( VikWindow *vw, const gchar* message, vik_stat static void destroy_window ( GtkWidget *widget, gpointer data ) { - if ( ! --window_count ) + if ( ! --window_count ) { + g_free ( last_folder_files_uri ); + g_free ( last_folder_images_uri ); gtk_main_quit (); + } } #define VIK_SETTINGS_WIN_SIDEPANEL "window_sidepanel" @@ -474,7 +483,8 @@ void vik_window_new_window_finish ( VikWindow *vw ) vik_statusbar_set_message ( vw->viking_vs, VIK_STATUSBAR_INFO, _("Trying to determine location...") ); - a_background_thread ( GTK_WINDOW(vw), + a_background_thread ( BACKGROUND_POOL_REMOTE, + GTK_WINDOW(vw), _("Determining location"), (vik_thr_func) determine_location_thread, vw, @@ -575,7 +585,7 @@ static void zoom_changed (GtkMenuShell *menushell, GtkWidget *aw = gtk_menu_get_active ( GTK_MENU (menushell) ); gint active = GPOINTER_TO_INT(g_object_get_data ( G_OBJECT (aw), "position" )); - gdouble zoom_request = pow (2, active-2 ); + gdouble zoom_request = pow (2, active-5 ); // But has it really changed? gdouble current_zoom = vik_viewport_get_zoom ( vw->viking_vvp ); @@ -592,7 +602,7 @@ static void zoom_changed (GtkMenuShell *menushell, static GtkWidget *create_zoom_menu_all_levels ( gdouble mpp ) { GtkWidget *menu = gtk_menu_new (); - char *itemLabels[] = { "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768" }; + char *itemLabels[] = { "0.031", "0.063", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768" }; int i; for (i = 0 ; i < G_N_ELEMENTS(itemLabels) ; i++) @@ -603,7 +613,7 @@ static GtkWidget *create_zoom_menu_all_levels ( gdouble mpp ) g_object_set_data (G_OBJECT (item), "position", GINT_TO_POINTER(i)); } - gint active = 2 + round ( log (mpp) / log (2) ); + gint active = 5 + round ( log (mpp) / log (2) ); // Ensure value derived from mpp is in bounds of the menu if ( active >= G_N_ELEMENTS(itemLabels) ) active = G_N_ELEMENTS(itemLabels) - 1; @@ -830,7 +840,7 @@ static void vik_window_init ( VikWindow *vw ) center_changed_cb ( vw ); vw->hpaned = gtk_hpaned_new (); - gtk_paned_pack1 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vlp), FALSE, FALSE ); + gtk_paned_pack1 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vlp), FALSE, TRUE ); gtk_paned_pack2 ( GTK_PANED(vw->hpaned), GTK_WIDGET (vw->viking_vvp), TRUE, TRUE ); /* This packs the button into the window (a gtk container). */ @@ -889,11 +899,6 @@ static void vik_window_init ( VikWindow *vw ) gtk_window_set_default_size ( GTK_WINDOW(vw), width, height ); - vw->open_dia = NULL; - vw->save_dia = NULL; - vw->save_img_dia = NULL; - vw->save_img_dir_dia = NULL; - vw->show_side_panel = TRUE; vw->show_statusbar = TRUE; vw->show_toolbar = TRUE; @@ -2147,42 +2152,56 @@ static void click_layer_selected (VikLayer *vl, clicker *ck) ck->cont = !vik_layer_get_interface(vl->type)->select_click ( vl, ck->event, ck->vvp, ck->tool_edit ); } +#ifdef WINDOWS +// Hopefully Alt keys by default +#define VIK_MOVE_MODIFIER GDK_MOD1_MASK +#else +// Alt+mouse on Linux desktops tend to be used by the desktop manager +// Thus use an alternate modifier - you may need to set something into this group +#define VIK_MOVE_MODIFIER GDK_MOD5_MASK +#endif + static VikLayerToolFuncStatus selecttool_click (VikLayer *vl, GdkEventButton *event, tool_ed_t *t) { t->vw->select_move = FALSE; /* Only allow selection on primary button */ if ( event->button == 1 ) { - /* Enable click to apply callback to potentially all track/waypoint layers */ - /* Useful as we can find things that aren't necessarily in the currently selected layer */ - GList* gl = vik_layers_panel_get_all_layers_of_type ( t->vw->viking_vlp, VIK_LAYER_TRW, FALSE ); // Don't get invisible layers - clicker ck; - ck.cont = TRUE; - ck.vvp = t->vw->viking_vvp; - ck.event = event; - ck.tool_edit = t; - g_list_foreach ( gl, (GFunc) click_layer_selected, &ck ); - g_list_free ( gl ); - - // If nothing found then deselect & redraw screen if necessary to remove the highlight - if ( ck.cont ) { - GtkTreeIter iter; - VikTreeview *vtv = vik_layers_panel_get_treeview ( t->vw->viking_vlp ); - - if ( vik_treeview_get_selected_iter ( vtv, &iter ) ) { - // Only clear if selected thing is a TrackWaypoint layer or a sublayer - gint type = vik_treeview_item_get_type ( vtv, &iter ); - if ( type == VIK_TREEVIEW_TYPE_SUBLAYER || - VIK_LAYER(vik_treeview_item_get_pointer ( vtv, &iter ))->type == VIK_LAYER_TRW ) { + + if ( event->state & VIK_MOVE_MODIFIER ) + vik_window_pan_click ( t->vw, event ); + else { + /* Enable click to apply callback to potentially all track/waypoint layers */ + /* Useful as we can find things that aren't necessarily in the currently selected layer */ + GList* gl = vik_layers_panel_get_all_layers_of_type ( t->vw->viking_vlp, VIK_LAYER_TRW, FALSE ); // Don't get invisible layers + clicker ck; + ck.cont = TRUE; + ck.vvp = t->vw->viking_vvp; + ck.event = event; + ck.tool_edit = t; + g_list_foreach ( gl, (GFunc) click_layer_selected, &ck ); + g_list_free ( gl ); + + // If nothing found then deselect & redraw screen if necessary to remove the highlight + if ( ck.cont ) { + GtkTreeIter iter; + VikTreeview *vtv = vik_layers_panel_get_treeview ( t->vw->viking_vlp ); + + if ( vik_treeview_get_selected_iter ( vtv, &iter ) ) { + // Only clear if selected thing is a TrackWaypoint layer or a sublayer + gint type = vik_treeview_item_get_type ( vtv, &iter ); + if ( type == VIK_TREEVIEW_TYPE_SUBLAYER || + VIK_LAYER(vik_treeview_item_get_pointer ( vtv, &iter ))->type == VIK_LAYER_TRW ) { - vik_treeview_item_unselect ( vtv, &iter ); - if ( vik_window_clear_highlight ( t->vw ) ) - draw_update ( t->vw ); - } + vik_treeview_item_unselect ( vtv, &iter ); + if ( vik_window_clear_highlight ( t->vw ) ) + draw_update ( t->vw ); + } + } + } + else { + // Something found - so enable movement + t->vw->select_move = TRUE; } - } - else { - // Something found - so enable movement - t->vw->select_move = TRUE; } } else if ( ( event->button == 3 ) && ( vl && ( vl->type == VIK_LAYER_TRW ) ) ) { @@ -2204,19 +2223,30 @@ static VikLayerToolFuncStatus selecttool_move (VikLayer *vl, GdkEventMotion *eve if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_move ) vik_layer_get_interface(VIK_LAYER_TRW)->select_move ( vl, event, t->vvp, t ); } + else + // Optional Panning + if ( event->state & VIK_MOVE_MODIFIER ) + vik_window_pan_move ( t->vw, event ); + return VIK_LAYER_TOOL_ACK; } static VikLayerToolFuncStatus selecttool_release (VikLayer *vl, GdkEventButton *event, tool_ed_t *t) { - /* Only allow deselection on primary button */ - if ( event->button == 1 ) { + if ( t->vw->select_move ) { // Don't care about vl here if ( t->vtl ) if ( vik_layer_get_interface(VIK_LAYER_TRW)->select_release ) vik_layer_get_interface(VIK_LAYER_TRW)->select_release ( (VikLayer*)t->vtl, event, t->vvp, t ); } + if ( event->button == 1 && (event->state & VIK_MOVE_MODIFIER) ) + vik_window_pan_release ( t->vw, event ); + + // Force pan off incase it was on + t->vw->pan_move = FALSE; + t->vw->pan_x = t->vw->pan_y = -1; + // End of this select movement t->vw->select_move = FALSE; @@ -3153,77 +3183,75 @@ static void load_file ( GtkAction *a, VikWindow *vw ) g_critical("Houston, we've had a problem."); return; } - - if ( ! vw->open_dia ) - { - vw->open_dia = gtk_file_chooser_dialog_new (_("Please select a GPS data file to open. "), - GTK_WINDOW(vw), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); - gchar *cwd = g_get_current_dir(); - if ( cwd ) { - gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER(vw->open_dia), cwd ); - g_free ( cwd ); - } - GtkFileFilter *filter; - // NB file filters are listed this way for alphabetical ordering + GtkWidget *dialog = gtk_file_chooser_dialog_new (_("Please select a GPS data file to open. "), + GTK_WINDOW(vw), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + if ( last_folder_files_uri ) + gtk_file_chooser_set_current_folder_uri ( GTK_FILE_CHOOSER(dialog), last_folder_files_uri ); + + GtkFileFilter *filter; + // NB file filters are listed this way for alphabetical ordering #ifdef VIK_CONFIG_GEOCACHES - filter = gtk_file_filter_new (); - gtk_file_filter_set_name( filter, _("Geocaching") ); - gtk_file_filter_add_pattern ( filter, "*.loc" ); // No MIME type available - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); + filter = gtk_file_filter_new (); + gtk_file_filter_set_name( filter, _("Geocaching") ); + gtk_file_filter_add_pattern ( filter, "*.loc" ); // No MIME type available + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter); #endif - filter = gtk_file_filter_new (); - gtk_file_filter_set_name( filter, _("Google Earth") ); - gtk_file_filter_add_mime_type ( filter, "application/vnd.google-earth.kml+xml"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); - - filter = gtk_file_filter_new (); - gtk_file_filter_set_name( filter, _("GPX") ); - gtk_file_filter_add_pattern ( filter, "*.gpx" ); // No MIME type available - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(vw->open_dia), 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 (GTK_FILE_CHOOSER(vw->open_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->open_dia), filter); - - // NB could have filters for gpspoint (*.gps,*.gpsoint?) + gpsmapper (*.gsm,*.gpsmapper?) - // However assume this are barely used and thus not worthy of inclusion - // as they'll just make the options too many and have no clear file pattern - // one can always use the all option - 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->open_dia), filter); - // Default to any file - same as before open filters were added - gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(vw->open_dia), filter); + filter = gtk_file_filter_new (); + gtk_file_filter_set_name( filter, _("Google Earth") ); + gtk_file_filter_add_mime_type ( filter, "application/vnd.google-earth.kml+xml"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter); + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name( filter, _("GPX") ); + gtk_file_filter_add_pattern ( filter, "*.gpx" ); // No MIME type available + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), 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 (GTK_FILE_CHOOSER(dialog), 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(dialog), filter); + + // NB could have filters for gpspoint (*.gps,*.gpsoint?) + gpsmapper (*.gsm,*.gpsmapper?) + // However assume this are barely used and thus not worthy of inclusion + // as they'll just make the options too many and have no clear file pattern + // one can always use the all option + 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(dialog), filter); + // Default to any file - same as before open filters were added + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(dialog), filter); + + gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER(dialog), TRUE ); + gtk_window_set_transient_for ( GTK_WINDOW(dialog), GTK_WINDOW(vw) ); + gtk_window_set_destroy_with_parent ( GTK_WINDOW(dialog), TRUE ); - gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER(vw->open_dia), TRUE ); - gtk_window_set_transient_for ( GTK_WINDOW(vw->open_dia), GTK_WINDOW(vw) ); - gtk_window_set_destroy_with_parent ( GTK_WINDOW(vw->open_dia), TRUE ); - } - if ( gtk_dialog_run ( GTK_DIALOG(vw->open_dia) ) == GTK_RESPONSE_ACCEPT ) + if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) { - gtk_widget_hide ( vw->open_dia ); + g_free ( last_folder_files_uri ); + last_folder_files_uri = gtk_file_chooser_get_current_folder_uri ( GTK_FILE_CHOOSER(dialog) ); + #ifdef VIKING_PROMPT_IF_MODIFIED if ( (vw->modified || vw->filename) && newwindow ) #else if ( vw->filename && newwindow ) #endif - g_signal_emit ( G_OBJECT(vw), window_signals[VW_OPENWINDOW_SIGNAL], 0, gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER(vw->open_dia) ) ); + g_signal_emit ( G_OBJECT(vw), window_signals[VW_OPENWINDOW_SIGNAL], 0, gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER(dialog) ) ); else { - files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER(vw->open_dia) ); + + files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER(dialog) ); gboolean change_fn = newwindow && (g_slist_length(files)==1); /* only change fn if one file */ gboolean first_vik_file = TRUE; cur_file = files; @@ -3253,65 +3281,64 @@ static void load_file ( GtkAction *a, VikWindow *vw ) g_slist_free (files); } } - else - gtk_widget_hide ( vw->open_dia ); + gtk_widget_destroy ( dialog ); } static gboolean save_file_as ( GtkAction *a, VikWindow *vw ) { gboolean rv = FALSE; const gchar *fn; - if ( ! vw->save_dia ) - { - vw->save_dia = gtk_file_chooser_dialog_new (_("Save as Viking File."), - GTK_WINDOW(vw), - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); - gchar *cwd = g_get_current_dir(); - if ( cwd ) { - gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER(vw->save_dia), cwd ); - g_free ( cwd ); - } - 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); + GtkWidget *dialog = gtk_file_chooser_dialog_new (_("Save as Viking File."), + GTK_WINDOW(vw), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + if ( last_folder_files_uri ) + gtk_file_chooser_set_current_folder_uri ( GTK_FILE_CHOOSER(dialog), last_folder_files_uri ); + + 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(dialog), 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(dialog), filter); + // Default to a Viking file + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(dialog), 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(dialog), GTK_WINDOW(vw) ); + gtk_window_set_destroy_with_parent ( GTK_WINDOW(dialog), TRUE ); - 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 ); - } // Auto append / replace extension with '.vik' to the suggested file name as it's going to be a Viking File gchar* auto_save_name = g_strdup ( window_get_filename ( vw ) ); if ( ! a_file_check_ext ( auto_save_name, ".vik" ) ) auto_save_name = g_strconcat ( auto_save_name, ".vik", NULL ); - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(vw->save_dia), auto_save_name); + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(dialog), auto_save_name); - while ( gtk_dialog_run ( GTK_DIALOG(vw->save_dia) ) == GTK_RESPONSE_ACCEPT ) + while ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) { - fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(vw->save_dia) ); - if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE || a_dialog_yes_or_no ( GTK_WINDOW(vw->save_dia), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) ) + fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(dialog) ); + if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == FALSE || a_dialog_yes_or_no ( GTK_WINDOW(dialog), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) ) { window_set_filename ( vw, fn ); rv = window_save ( vw ); - vw->modified = FALSE; + if ( rv ) { + vw->modified = FALSE; + g_free ( last_folder_files_uri ); + last_folder_files_uri = gtk_file_chooser_get_current_folder_uri ( GTK_FILE_CHOOSER(dialog) ); + } break; } } g_free ( auto_save_name ); - gtk_widget_hide ( vw->save_dia ); + gtk_widget_destroy ( dialog ); return rv; } @@ -3964,55 +3991,52 @@ static gchar* draw_image_filename ( VikWindow *vw, gboolean one_image_only ) 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); - - gchar *cwd = g_get_current_dir(); - if ( cwd ) { - gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER(vw->save_img_dia), cwd ); - g_free ( cwd ); - } + GtkWidget *dialog = 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); + if ( last_folder_images_uri ) + gtk_file_chooser_set_current_folder_uri ( GTK_FILE_CHOOSER(dialog), last_folder_images_uri ); + + GtkFileChooser *chooser = GTK_FILE_CHOOSER ( dialog ); + /* 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 ); - 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, _("JPG") ); - gtk_file_filter_add_mime_type ( filter, "image/jpeg"); - gtk_file_chooser_add_filter ( chooser, filter ); + if ( !vw->draw_image_save_as_png ) + gtk_file_chooser_set_filter ( chooser, filter ); - if ( !vw->draw_image_save_as_png ) - gtk_file_chooser_set_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 ); - 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 ); + if ( vw->draw_image_save_as_png ) + gtk_file_chooser_set_filter ( chooser, filter ); - if ( vw->draw_image_save_as_png ) - gtk_file_chooser_set_filter ( chooser, filter ); + gtk_window_set_transient_for ( GTK_WINDOW(dialog), GTK_WINDOW(vw) ); + gtk_window_set_destroy_with_parent ( GTK_WINDOW(dialog), TRUE ); - 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(dialog) ) == GTK_RESPONSE_ACCEPT ) { + g_free ( last_folder_images_uri ); + last_folder_images_uri = gtk_file_chooser_get_current_folder_uri ( GTK_FILE_CHOOSER(dialog) ); - 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) ); + fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(dialog) ); 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; + if ( ! a_dialog_yes_or_no ( GTK_WINDOW(dialog), _("The file \"%s\" exists, do you wish to overwrite it?"), a_file_basename ( fn ) ) ) + fn = NULL; } - gtk_widget_hide ( vw->save_img_dia ); + gtk_widget_destroy ( dialog ); } else { // A directory @@ -4022,21 +4046,19 @@ static gchar* draw_image_filename ( VikWindow *vw, gboolean one_image_only ) 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) ); + GtkWidget *dialog = 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(dialog), GTK_WINDOW(vw) ); + gtk_window_set_destroy_with_parent ( GTK_WINDOW(dialog), TRUE ); + + if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) { + fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(dialog) ); } - gtk_widget_hide ( vw->save_img_dir_dia ); + gtk_widget_destroy ( dialog ); } return fn; } @@ -4344,7 +4366,7 @@ static GtkActionEntry entries[] = { { "Save", GTK_STOCK_SAVE, N_("_Save"), "S", N_("Save the file"), (GCallback)save_file }, { "SaveAs", GTK_STOCK_SAVE_AS, N_("Save _As..."), NULL, N_("Save the file under different name"), (GCallback)save_file_as }, { "FileProperties", NULL, N_("Properties..."), NULL, N_("File Properties"), (GCallback)file_properties_cb }, - { "GenImg", GTK_STOCK_CLEAR, N_("_Generate Image File..."), NULL, N_("Save a snapshot of the workspace into a file"), (GCallback)draw_to_image_file_cb }, + { "GenImg", GTK_STOCK_FILE, N_("_Generate Image File..."), NULL, N_("Save a snapshot of the workspace into a file"), (GCallback)draw_to_image_file_cb }, { "GenImgDir", GTK_STOCK_DND_MULTIPLE, N_("Generate _Directory of Images..."), NULL, N_("Generate _Directory of Images"), (GCallback)draw_to_image_dir_cb }, { "Print", GTK_STOCK_PRINT, N_("_Print..."), NULL, N_("Print maps"), (GCallback)print_cb }, { "Exit", GTK_STOCK_QUIT, N_("E_xit"), "W", N_("Exit the program"), (GCallback)window_close }, @@ -4770,7 +4792,12 @@ gboolean vik_window_clear_highlight ( VikWindow *vw ) return need_redraw; } +/** + * May return NULL if the window no longer exists + */ GThread *vik_window_get_thread ( VikWindow *vw ) { - return vw->thread; + if ( vw ) + return vw->thread; + return NULL; }