static void file_open_dialog_show (Gimp *gimp, GtkWidget *parent, const gchar *title, GimpImage *image, const gchar *uri, gboolean open_as_layers) { GtkWidget *dialog; dialog = gimp_dialog_factory_dialog_new (gimp_dialog_factory_get_singleton (), gtk_widget_get_screen (parent), NULL /*ui_manager*/, "gimp-file-open-dialog", -1, FALSE); if (dialog) { if (! uri && image) uri = gimp_image_get_uri (image); if (! uri) uri = g_object_get_data (G_OBJECT (gimp), GIMP_FILE_OPEN_LAST_URI_KEY); if (uri) gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), uri); gimp_file_dialog_set_open_image (GIMP_FILE_DIALOG (dialog), image, open_as_layers); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (parent))); gtk_window_present (GTK_WINDOW (dialog)); } }
gboolean file_utils_save_thumbnail (GimpImage *image, const gchar *filename) { const gchar *image_uri; gboolean success = FALSE; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (filename != NULL, FALSE); image_uri = gimp_image_get_uri (image); if (image_uri) { gchar *uri = g_filename_to_uri (filename, NULL, NULL); if (uri) { if ( ! strcmp (uri, image_uri)) { GimpImagefile *imagefile; imagefile = gimp_imagefile_new (image->gimp, uri); success = gimp_imagefile_save_thumbnail (imagefile, NULL, image); g_object_unref (imagefile); } g_free (uri); } } return success; }
static void gimp_image_duplicate_save_source_uri (GimpImage *image, GimpImage *new_image) { g_object_set_data_full (G_OBJECT (new_image), "gimp-image-source-uri", g_strdup (gimp_image_get_uri (image)), (GDestroyNotify) g_free); }
static void gimp_image_prop_view_label_set_filename (GtkWidget *label, GimpImage *image) { const gchar *uri = gimp_image_get_uri (image); if (uri) { gchar *name = file_utils_uri_display_name (uri); gtk_label_set_text (GTK_LABEL (label), name); g_free (name); } else { gtk_label_set_text (GTK_LABEL (label), NULL); gimp_help_set_help_data (gtk_widget_get_parent (label), NULL, NULL); } }
static void gimp_display_shell_close_name_changed (GimpImage *image, GimpMessageBox *box) { GtkWidget *window = gtk_widget_get_toplevel (GTK_WIDGET (box)); gchar *name; name = file_utils_uri_display_basename (gimp_image_get_uri (image)); if (window) { gchar *title = g_strdup_printf (_("Close %s"), name); gtk_window_set_title (GTK_WINDOW (window), title); g_free (title); } gimp_message_box_set_primary_text (box, _("Save the changes to image '%s' " "before closing?"), name); g_free (name); }
static void gimp_display_shell_close_dialog (GimpDisplayShell *shell, GimpImage *image) { GtkWidget *dialog; GtkWidget *button; GimpMessageBox *box; GClosure *closure; GSource *source; gchar *name; gchar *title; if (shell->close_dialog) { gtk_window_present (GTK_WINDOW (shell->close_dialog)); return; } name = file_utils_uri_display_basename (gimp_image_get_uri (image)); title = g_strdup_printf (_("Close %s"), name); g_free (name); shell->close_dialog = dialog = gimp_message_dialog_new (title, GTK_STOCK_SAVE, GTK_WIDGET (shell), GTK_DIALOG_DESTROY_WITH_PARENT, gimp_standard_help_func, NULL, NULL); g_free (title); button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Do_n't Save"), GTK_RESPONSE_CLOSE); gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON)); gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, RESPONSE_SAVE, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), RESPONSE_SAVE, GTK_RESPONSE_CLOSE, GTK_RESPONSE_CANCEL, -1); g_signal_connect (dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &shell->close_dialog); g_signal_connect (dialog, "response", G_CALLBACK (gimp_display_shell_close_response), shell); box = GIMP_MESSAGE_DIALOG (dialog)->box; g_signal_connect_object (image, "name-changed", G_CALLBACK (gimp_display_shell_close_name_changed), box, 0); gimp_display_shell_close_name_changed (image, box); closure = g_cclosure_new_object (G_CALLBACK (gimp_display_shell_close_time_changed), G_OBJECT (box)); /* update every 10 seconds */ source = g_timeout_source_new (10 * 1000); g_source_set_closure (source, closure); g_source_attach (source, NULL); g_source_unref (source); /* The dialog is destroyed with the shell, so it should be safe * to hold an image pointer for the lifetime of the dialog. */ g_object_set_data (G_OBJECT (box), "gimp-image", image); gimp_display_shell_close_time_changed (box); gtk_widget_show (dialog); }
void file_revert_cmd_callback (GtkAction *action, gpointer data) { GimpDisplay *display; GimpImage *image; GtkWidget *dialog; const gchar *uri; return_if_no_display (display, data); image = gimp_display_get_image (display); uri = gimp_image_get_uri (image); if (! uri) uri = gimp_image_get_imported_uri (image); dialog = g_object_get_data (G_OBJECT (image), REVERT_DATA_KEY); if (! uri) { gimp_message_literal (image->gimp, G_OBJECT (display), GIMP_MESSAGE_ERROR, _("Revert failed. " "No file name associated with this image.")); } else if (dialog) { gtk_window_present (GTK_WINDOW (dialog)); } else { gchar *filename; dialog = gimp_message_dialog_new (_("Revert Image"), GTK_STOCK_REVERT_TO_SAVED, GTK_WIDGET (gimp_display_get_shell (display)), 0, gimp_standard_help_func, GIMP_HELP_FILE_REVERT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_REVERT_TO_SAVED, GTK_RESPONSE_OK, NULL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); g_signal_connect_object (display, "disconnect", G_CALLBACK (gtk_widget_destroy), dialog, G_CONNECT_SWAPPED); g_signal_connect (dialog, "response", G_CALLBACK (file_revert_confirm_response), display); filename = file_utils_uri_display_name (uri); gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box, _("Revert '%s' to '%s'?"), gimp_image_get_display_name (image), filename); g_free (filename); gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box, _("By reverting the image to the state saved " "on disk, you will lose all changes, " "including all undo information.")); g_object_set_data (G_OBJECT (image), REVERT_DATA_KEY, dialog); gtk_widget_show (dialog); } }
void file_save_cmd_callback (GtkAction *action, gint value, gpointer data) { Gimp *gimp; GimpDisplay *display; GimpImage *image; GtkWidget *widget; GimpSaveMode save_mode; const gchar *uri; gboolean saved = FALSE; return_if_no_gimp (gimp, data); return_if_no_display (display, data); return_if_no_widget (widget, data); image = gimp_display_get_image (display); save_mode = (GimpSaveMode) value; if (! gimp_image_get_active_drawable (image)) return; uri = gimp_image_get_uri (image); switch (save_mode) { case GIMP_SAVE_MODE_SAVE: case GIMP_SAVE_MODE_SAVE_AND_CLOSE: /* Only save if the image has been modified, or if it is new. */ if ((gimp_image_is_dirty (image) || ! GIMP_GUI_CONFIG (image->gimp->config)->trust_dirty_flag) || uri == NULL) { GimpPlugInProcedure *save_proc = gimp_image_get_save_proc (image); if (uri && ! save_proc) { save_proc = file_procedure_find (image->gimp->plug_in_manager->save_procs, uri, NULL); } if (uri && save_proc) { saved = file_save_dialog_save_image (GIMP_PROGRESS (display), gimp, image, uri, save_proc, GIMP_RUN_WITH_LAST_VALS, TRUE, FALSE, FALSE, TRUE); break; } /* fall thru */ } else { gimp_message_literal (image->gimp, G_OBJECT (display), GIMP_MESSAGE_INFO, _("No changes need to be saved")); saved = TRUE; break; } case GIMP_SAVE_MODE_SAVE_AS: file_save_dialog_show (gimp, image, widget, _("Save Image"), FALSE, save_mode == GIMP_SAVE_MODE_SAVE_AND_CLOSE, display); break; case GIMP_SAVE_MODE_SAVE_A_COPY: file_save_dialog_show (gimp, image, widget, _("Save a Copy of the Image"), TRUE, FALSE, display); break; case GIMP_SAVE_MODE_EXPORT: file_export_dialog_show (gimp, image, widget); break; case GIMP_SAVE_MODE_EXPORT_TO: case GIMP_SAVE_MODE_OVERWRITE: { const gchar *uri = NULL; GimpPlugInProcedure *export_proc; gboolean overwrite; if (save_mode == GIMP_SAVE_MODE_EXPORT_TO) { uri = gimp_image_get_exported_uri (image); if (! uri) { /* Behave as if Export... was invoked */ file_export_dialog_show (gimp, image, widget); break; } overwrite = FALSE; } else if (save_mode == GIMP_SAVE_MODE_OVERWRITE) { uri = gimp_image_get_imported_uri (image); overwrite = TRUE; } if (uri) { export_proc = file_procedure_find (image->gimp->plug_in_manager->export_procs, uri, NULL); } if (uri && export_proc) { char *uri_copy; /* The memory that 'uri' points to can be freed by file_save_dialog_save_image(), when it eventually calls gimp_image_set_imported_uri() to reset the imported uri, resulting in garbage. So make a duplicate of it here. */ uri_copy = g_strdup (uri); saved = file_save_dialog_save_image (GIMP_PROGRESS (display), gimp, image, uri_copy, export_proc, GIMP_RUN_WITH_LAST_VALS, FALSE, overwrite, ! overwrite, TRUE); g_free (uri_copy); } } break; } if (save_mode == GIMP_SAVE_MODE_SAVE_AND_CLOSE && saved && ! gimp_image_is_dirty (image)) { gimp_display_close (display); } }
static void gimp_display_shell_format_title (GimpDisplayShell *shell, gchar *title, gint title_len, const gchar *format) { Gimp *gimp; GimpImage *image; gint num, denom; gint i = 0; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); image = shell->display->image; gimp = image->gimp; gimp_zoom_model_get_fraction (shell->zoom, &num, &denom); while (i < title_len && *format) { switch (*format) { case '%': format++; switch (*format) { case 0: /* format string ends within %-sequence, print literal '%' */ case '%': title[i++] = '%'; break; case 'f': /* pruned filename */ { const gchar *uri = gimp_image_get_uri (image); gchar *basename; basename = file_utils_uri_display_basename (uri); i += print (title, title_len, i, "%s", basename); g_free (basename); } break; case 'F': /* full filename */ { gchar *filename; const gchar *uri = gimp_image_get_uri (image); filename = file_utils_uri_display_name (uri); i += print (title, title_len, i, "%s", filename); g_free (filename); } break; case 'p': /* PDB id */ i += print (title, title_len, i, "%d", gimp_image_get_ID (image)); break; case 'i': /* instance */ i += print (title, title_len, i, "%d", shell->display->instance); break; case 't': /* type */ { const gchar *image_type_str = NULL; gboolean empty = gimp_image_is_empty (image); switch (gimp_image_base_type (image)) { case GIMP_RGB: image_type_str = empty ? _("RGB-empty") : _("RGB"); break; case GIMP_GRAY: image_type_str = empty ? _("grayscale-empty") : _("grayscale"); break; case GIMP_INDEXED: image_type_str = empty ? _("indexed-empty") : _("indexed"); break; default: g_assert_not_reached (); break; } i += print (title, title_len, i, "%s", image_type_str); } break; case 's': /* user source zoom factor */ i += print (title, title_len, i, "%d", denom); break; case 'd': /* user destination zoom factor */ i += print (title, title_len, i, "%d", num); break; case 'z': /* user zoom factor (percentage) */ { gdouble scale = gimp_zoom_model_get_factor (shell->zoom); i += print (title, title_len, i, scale >= 0.15 ? "%.0f" : "%.2f", 100.0 * scale); } break; case 'D': /* dirty flag */ if (format[1] == 0) { /* format string ends within %D-sequence, print literal '%D' */ i += print (title, title_len, i, "%%D"); break; } if (image->dirty) title[i++] = format[1]; format++; break; case 'C': /* clean flag */ if (format[1] == 0) { /* format string ends within %C-sequence, print literal '%C' */ i += print (title, title_len, i, "%%C"); break; } if (! image->dirty) title[i++] = format[1]; format++; break; case 'B': /* dirty flag (long) */ if (image->dirty) i += print (title, title_len, i, "%s", _("(modified)")); break; case 'A': /* clean flag (long) */ if (! image->dirty) i += print (title, title_len, i, "%s", _("(clean)")); break; case 'm': /* memory used by image */ { GimpObject *object = GIMP_OBJECT (image); gchar *str; str = gimp_memsize_to_string (gimp_object_get_memsize (object, NULL)); i += print (title, title_len, i, "%s", str); g_free (str); } break; case 'l': /* number of layers */ i += print (title, title_len, i, "%d", gimp_container_num_children (image->layers)); break; case 'L': /* number of layers (long) */ { gint num = gimp_container_num_children (image->layers); i += print (title, title_len, i, ngettext ("%d layer", "%d layers", num), num); } break; case 'n': /* active drawable name */ { GimpDrawable *drawable = gimp_image_get_active_drawable (image); if (drawable) i += print (title, title_len, i, "%s", gimp_object_get_name (GIMP_OBJECT (drawable))); else i += print (title, title_len, i, "%s", _("(none)")); } break; case 'P': /* active drawable PDB id */ { GimpDrawable *drawable = gimp_image_get_active_drawable (image); if (drawable) i += print (title, title_len, i, "%d", gimp_item_get_ID (GIMP_ITEM (drawable))); else i += print (title, title_len, i, "%s", _("(none)")); } break; case 'W': /* width in real-world units */ if (shell->unit != GIMP_UNIT_PIXEL) { gchar unit_format[8]; g_snprintf (unit_format, sizeof (unit_format), "%%.%df", _gimp_unit_get_digits (gimp, shell->unit) + 1); i += print (title, title_len, i, unit_format, (image->width * _gimp_unit_get_factor (gimp, shell->unit) / image->xresolution)); break; } /* else fallthru */ case 'w': /* width in pixels */ i += print (title, title_len, i, "%d", image->width); break; case 'H': /* height in real-world units */ if (shell->unit != GIMP_UNIT_PIXEL) { gchar unit_format[8]; g_snprintf (unit_format, sizeof (unit_format), "%%.%df", _gimp_unit_get_digits (gimp, shell->unit) + 1); i += print (title, title_len, i, unit_format, (image->height * _gimp_unit_get_factor (gimp, shell->unit) / image->yresolution)); break; } /* else fallthru */ case 'h': /* height in pixels */ i += print (title, title_len, i, "%d", image->height); break; case 'u': /* unit symbol */ i += print (title, title_len, i, "%s", _gimp_unit_get_symbol (gimp, shell->unit)); break; case 'U': /* unit abbreviation */ i += print (title, title_len, i, "%s", _gimp_unit_get_abbreviation (gimp, shell->unit)); break; /* Other cool things to be added: * %r = xresolution * %R = yresolution * %ø = image's fractal dimension * %þ = the answer to everything */ default: /* format string contains unknown %-sequence, print it literally */ i += print (title, title_len, i, "%%%c", *format); break; } break; default: title[i++] = *format; break; } format++; } title[MIN (i, title_len - 1)] = '\0'; }
GimpPDBStatusType file_save (GimpImage *image, GimpContext *context, GimpProgress *progress, const gchar *uri, GimpPlugInProcedure *file_proc, GimpRunMode run_mode, gboolean save_a_copy, GError **error) { GimpDrawable *drawable; GValueArray *return_vals; GimpPDBStatusType status; gchar *filename; gint32 image_ID; gint32 drawable_ID; g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (error == NULL || *error == NULL, GIMP_PDB_CALLING_ERROR); drawable = gimp_image_get_active_drawable (image); if (! drawable) return GIMP_PDB_EXECUTION_ERROR; filename = file_utils_filename_from_uri (uri); if (filename) { /* check if we are saving to a file */ if (g_file_test (filename, G_FILE_TEST_EXISTS)) { if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s", _("Not a regular file")); status = GIMP_PDB_EXECUTION_ERROR; goto out; } if (g_access (filename, W_OK) != 0) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES, "%s", g_strerror (errno)); status = GIMP_PDB_EXECUTION_ERROR; goto out; } } } else { filename = g_strdup (uri); } /* ref the image, so it can't get deleted during save */ g_object_ref (image); image_ID = gimp_image_get_ID (image); drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable)); return_vals = gimp_pdb_execute_procedure_by_name (image->gimp->pdb, context, progress, error, GIMP_OBJECT (file_proc)->name, GIMP_TYPE_INT32, run_mode, GIMP_TYPE_IMAGE_ID, image_ID, GIMP_TYPE_DRAWABLE_ID, drawable_ID, G_TYPE_STRING, filename, G_TYPE_STRING, uri, G_TYPE_NONE); status = g_value_get_enum (&return_vals->values[0]); g_value_array_free (return_vals); if (status == GIMP_PDB_SUCCESS) { GimpDocumentList *documents; GimpImagefile *imagefile; if (save_a_copy) { /* remember the "save-a-copy" filename for the next invocation */ g_object_set_data_full (G_OBJECT (image), "gimp-image-save-a-copy", g_strdup (uri), (GDestroyNotify) g_free); } else { /* reset the "save-a-copy" filename when the image URI changes */ if (strcmp (uri, gimp_image_get_uri (image))) g_object_set_data (G_OBJECT (image), "gimp-image-save-a-copy", NULL); gimp_image_set_uri (image, uri); gimp_image_set_save_proc (image, file_proc); gimp_image_clean_all (image); } gimp_image_saved (image, uri); documents = GIMP_DOCUMENT_LIST (image->gimp->documents); imagefile = gimp_document_list_add_uri (documents, uri, file_proc->mime_type); /* only save a thumbnail if we are saving as XCF, see bug #25272 */ if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL) gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, image); } else if (status != GIMP_PDB_CANCEL) { if (error && *error == NULL) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("%s plug-in could not save image"), gimp_plug_in_procedure_get_label (file_proc)); } } gimp_image_flush (image); g_object_unref (image); out: g_free (filename); return status; }
static void gimp_display_shell_close_dialog (GimpDisplayShell *shell, GimpImage *image) { GtkWidget *dialog; GimpMessageBox *box; GtkWidget *label; GtkAccelGroup *accel_group; GClosure *closure; GSource *source; guint accel_key; GdkModifierType accel_mods; gchar *title; gchar *accel_string; gchar *hint; gchar *markup; const gchar *uri; if (shell->close_dialog) { gtk_window_present (GTK_WINDOW (shell->close_dialog)); return; } uri = gimp_image_get_uri (image); title = g_strdup_printf (_("Close %s"), gimp_image_get_display_name (image)); shell->close_dialog = dialog = gimp_message_dialog_new (title, "document-save", GTK_WIDGET (shell), GTK_DIALOG_DESTROY_WITH_PARENT, gimp_standard_help_func, NULL, NULL); g_free (title); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Discard Changes"), GTK_RESPONSE_CLOSE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, (uri ? GTK_STOCK_SAVE : GTK_STOCK_SAVE_AS), RESPONSE_SAVE, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), RESPONSE_SAVE, GTK_RESPONSE_CLOSE, GTK_RESPONSE_CANCEL, -1); g_signal_connect (dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &shell->close_dialog); g_signal_connect (dialog, "response", G_CALLBACK (gimp_display_shell_close_response), shell); /* connect <Primary>D to the quit/close button */ accel_group = gtk_accel_group_new (); gtk_window_add_accel_group (GTK_WINDOW (shell->close_dialog), accel_group); g_object_unref (accel_group); closure = g_closure_new_object (sizeof (GClosure), G_OBJECT (shell->close_dialog)); g_closure_set_marshal (closure, gimp_display_shell_close_accel_marshal); gtk_accelerator_parse ("<Primary>D", &accel_key, &accel_mods); gtk_accel_group_connect (accel_group, accel_key, accel_mods, 0, closure); box = GIMP_MESSAGE_DIALOG (dialog)->box; accel_string = gtk_accelerator_get_label (accel_key, accel_mods); hint = g_strdup_printf (_("Press %s to discard all changes and close the image."), accel_string); markup = g_strdup_printf ("<i><small>%s</small></i>", hint); label = gtk_label_new (NULL); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_markup (GTK_LABEL (label), markup); gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); gtk_widget_show (label); g_free (markup); g_free (hint); g_free (accel_string); g_signal_connect_object (image, "name-changed", G_CALLBACK (gimp_display_shell_close_name_changed), box, 0); g_signal_connect_object (image, "exported", G_CALLBACK (gimp_display_shell_close_exported), box, 0); gimp_display_shell_close_name_changed (image, box); closure = g_cclosure_new_object (G_CALLBACK (gimp_display_shell_close_time_changed), G_OBJECT (box)); /* update every 10 seconds */ source = g_timeout_source_new_seconds (10); g_source_set_closure (source, closure); g_source_attach (source, NULL); g_source_unref (source); /* The dialog is destroyed with the shell, so it should be safe * to hold an image pointer for the lifetime of the dialog. */ g_object_set_data (G_OBJECT (box), "gimp-image", image); gimp_display_shell_close_time_changed (box); gtk_widget_show (dialog); }
void gimp_file_dialog_set_image (GimpFileDialog *dialog, GimpImage *image, gboolean save_a_copy, gboolean close_after_saving) { const gchar *uri = NULL; gchar *dirname; gchar *basename; g_return_if_fail (GIMP_IS_FILE_DIALOG (dialog)); g_return_if_fail (GIMP_IS_IMAGE (image)); dialog->image = image; dialog->save_a_copy = save_a_copy; dialog->close_after_saving = close_after_saving; if (save_a_copy) uri = g_object_get_data (G_OBJECT (image), "gimp-image-save-a-copy"); if (! uri) uri = gimp_image_get_uri (image); gimp_file_dialog_set_file_proc (dialog, NULL); #ifndef G_OS_WIN32 dirname = g_path_get_dirname (uri); #else /* g_path_get_dirname() is supposed to work on pathnames, not URIs. * * If uri points to a file on the root of a drive * "file:///d:/foo.png", g_path_get_dirname() would return * "file:///d:". (What we really would want is "file:///d:/".) When * this then is passed inside gtk+ to g_filename_from_uri() we get * "d:" which is not an absolute pathname. This currently causes an * assertion failure in gtk+. This scenario occurs if we have opened * an image from the root of a drive and then do Save As. * * Of course, gtk+ shouldn't assert even if we feed it slighly bogus * data, and that problem should be fixed, too. But to get the * correct default current folder in the filechooser combo box, we * need to pass it the proper URI for an absolute path anyway. So * don't use g_path_get_dirname() on file: URIs. */ if (g_str_has_prefix (uri, "file:///")) { gchar *filepath = g_filename_from_uri (uri, NULL, NULL); gchar *dirpath = NULL; if (filepath != NULL) { dirpath = g_path_get_dirname (filepath); g_free (filepath); } if (dirpath != NULL) { dirname = g_filename_to_uri (dirpath, NULL, NULL); g_free (dirpath); } else { dirname = NULL; } } else { dirname = g_path_get_dirname (uri); } #endif if (dirname && strlen (dirname) && strcmp (dirname, ".")) { gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), dirname); } else { const gchar *folder; folder = g_object_get_data (G_OBJECT (image), "gimp-image-dirname"); if (folder) gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), folder); } g_free (dirname); basename = file_utils_uri_display_basename (uri); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), basename); g_free (basename); }
} show_overwrite = (source && gimp_plug_in_manager_uri_has_exporter (gimp->plug_in_manager, source)); #define SET_VISIBLE(action,condition) \ gimp_action_group_set_action_visible (group, action, (condition) != 0) #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0) SET_SENSITIVE ("file-save", drawable); SET_SENSITIVE ("file-save-as", drawable); SET_SENSITIVE ("file-save-a-copy", drawable); SET_SENSITIVE ("file-revert", image && (gimp_image_get_uri (image) || source)); SET_SENSITIVE ("file-export-to", drawable); SET_VISIBLE ("file-export-to", ! show_overwrite); SET_SENSITIVE ("file-overwrite", show_overwrite); SET_VISIBLE ("file-overwrite", show_overwrite); SET_SENSITIVE ("file-export", drawable); SET_SENSITIVE ("file-create-template", image); if (export) { gchar *label = file_actions_create_label (_("Export to %s"), export); gimp_action_group_set_action_label (group, "file-export-to", label); g_free (label); } else if (show_overwrite) {