diff --git a/app/actions/file-commands.c b/app/actions/file-commands.c index 2ed08b5118..33ae8ee4a7 100644 --- a/app/actions/file-commands.c +++ b/app/actions/file-commands.c @@ -46,10 +46,13 @@ #include "widgets/gimpactiongroup.h" #include "widgets/gimpclipboard.h" #include "widgets/gimpdialogfactory.h" +#include "widgets/gimpexportdialog.h" #include "widgets/gimpfiledialog.h" #include "widgets/gimphelp-ids.h" #include "widgets/gimpmessagebox.h" #include "widgets/gimpmessagedialog.h" +#include "widgets/gimpopendialog.h" +#include "widgets/gimpsavedialog.h" #include "widgets/gimpwidgets-utils.h" #include "display/gimpdisplay.h" @@ -596,8 +599,8 @@ file_open_dialog_show (Gimp *gimp, gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), gimp->default_folder, NULL); - gimp_file_dialog_set_open_image (GIMP_FILE_DIALOG (dialog), - image, open_as_layers); + gimp_open_dialog_set_image (GIMP_OPEN_DIALOG (dialog), + image, open_as_layers); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (parent))); @@ -649,9 +652,9 @@ file_save_dialog_show (Gimp *gimp, { gtk_window_set_title (GTK_WINDOW (dialog), title); - gimp_file_dialog_set_save_image (GIMP_FILE_DIALOG (dialog), - gimp, image, save_a_copy, FALSE, - close_after_saving, GIMP_OBJECT (display)); + gimp_save_dialog_set_image (GIMP_SAVE_DIALOG (dialog), + gimp, image, save_a_copy, + close_after_saving, GIMP_OBJECT (display)); gtk_window_present (GTK_WINDOW (dialog)); } @@ -679,8 +682,8 @@ file_save_dialog_response (GtkWidget *dialog, basename = g_path_get_basename (gimp_file_get_utf8_name (file)); g_object_unref (file); - other = file_export_dialog_show (file_dialog->image->gimp, - file_dialog->image, + other = file_export_dialog_show (GIMP_FILE_DIALOG (file_dialog)->image->gimp, + GIMP_FILE_DIALOG (file_dialog)->image, GTK_WIDGET (parent)); gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (other), @@ -737,9 +740,8 @@ file_export_dialog_show (Gimp *gimp, if (dialog) { - gimp_file_dialog_set_save_image (GIMP_FILE_DIALOG (dialog), - gimp, image, FALSE, TRUE, - FALSE, NULL); + gimp_export_dialog_set_image (GIMP_EXPORT_DIALOG (dialog), + gimp, image); gtk_window_present (GTK_WINDOW (dialog)); } @@ -767,8 +769,8 @@ file_export_dialog_response (GtkWidget *dialog, basename = g_path_get_basename (gimp_file_get_utf8_name (file)); g_object_unref (file); - other = file_save_dialog_show (file_dialog->image->gimp, - file_dialog->image, + other = file_save_dialog_show (GIMP_FILE_DIALOG (file_dialog)->image->gimp, + GIMP_FILE_DIALOG (file_dialog)->image, GTK_WIDGET (parent), _("Save Image"), FALSE, FALSE, NULL); diff --git a/app/dialogs/file-open-dialog.c b/app/dialogs/file-open-dialog.c index d250627f6f..362025b4ee 100644 --- a/app/dialogs/file-open-dialog.c +++ b/app/dialogs/file-open-dialog.c @@ -40,6 +40,7 @@ #include "widgets/gimpfiledialog.h" #include "widgets/gimphelp-ids.h" +#include "widgets/gimpopendialog.h" #include "widgets/gimpwidgets-utils.h" #include "file-open-dialog.h" @@ -72,11 +73,7 @@ file_open_dialog_new (Gimp *gimp) g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); - dialog = gimp_file_dialog_new (gimp, - GIMP_FILE_CHOOSER_ACTION_OPEN, - _("Open Image"), "gimp-file-open", - GTK_STOCK_OPEN, - GIMP_HELP_FILE_OPEN); + dialog = gimp_open_dialog_new (gimp); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); @@ -132,27 +129,27 @@ file_open_dialog_response (GtkWidget *open_dialog, * will pull the image window it was invoked from on top of all the * new opened image windows, and we don't want that to happen. */ - if (! dialog->open_as_layers) + if (! GIMP_OPEN_DIALOG (dialog)->open_as_layers) gtk_window_set_transient_for (GTK_WINDOW (open_dialog), NULL); for (list = files; list; list = g_slist_next (list)) { GFile *file = list->data; - if (dialog->open_as_layers) + if (GIMP_OPEN_DIALOG (dialog)->open_as_layers) { - if (! dialog->image) + if (! GIMP_FILE_DIALOG (dialog)->image) { - dialog->image = file_open_dialog_open_image (open_dialog, + GIMP_FILE_DIALOG (dialog)->image = file_open_dialog_open_image (open_dialog, gimp, file, dialog->file_proc); - if (dialog->image) + if (GIMP_FILE_DIALOG (dialog)->image) success = TRUE; } else if (file_open_dialog_open_layers (open_dialog, - dialog->image, + GIMP_FILE_DIALOG (dialog)->image, file, dialog->file_proc)) { @@ -181,8 +178,8 @@ file_open_dialog_response (GtkWidget *open_dialog, if (success) { - if (dialog->open_as_layers && dialog->image) - gimp_image_flush (dialog->image); + if (GIMP_OPEN_DIALOG (dialog)->open_as_layers && GIMP_FILE_DIALOG (dialog)->image) + gimp_image_flush (GIMP_FILE_DIALOG (dialog)->image); gtk_widget_destroy (open_dialog); } diff --git a/app/dialogs/file-save-dialog.c b/app/dialogs/file-save-dialog.c index e922d44283..aa48a662fb 100644 --- a/app/dialogs/file-save-dialog.c +++ b/app/dialogs/file-save-dialog.c @@ -40,10 +40,11 @@ #include "file/gimp-file.h" #include "widgets/gimpactiongroup.h" -#include "widgets/gimpfiledialog.h" +#include "widgets/gimpexportdialog.h" #include "widgets/gimphelp-ids.h" #include "widgets/gimpmessagebox.h" #include "widgets/gimpmessagedialog.h" +#include "widgets/gimpsavedialog.h" #include "display/gimpdisplay.h" #include "display/gimpdisplayshell.h" @@ -97,21 +98,13 @@ file_save_dialog_new (Gimp *gimp, if (! export) { - dialog = gimp_file_dialog_new (gimp, - GIMP_FILE_CHOOSER_ACTION_SAVE, - _("Save Image"), "gimp-file-save", - GTK_STOCK_SAVE, - GIMP_HELP_FILE_SAVE); + dialog = gimp_save_dialog_new (gimp); state = g_object_get_data (G_OBJECT (gimp), "gimp-file-save-dialog-state"); } else { - dialog = gimp_file_dialog_new (gimp, - GIMP_FILE_CHOOSER_ACTION_EXPORT, - _("Export Image"), "gimp-file-export", - _("_Export"), - GIMP_HELP_FILE_EXPORT_AS); + dialog = gimp_export_dialog_new (gimp); state = g_object_get_data (G_OBJECT (gimp), "gimp-file-export-dialog-state"); } @@ -160,13 +153,13 @@ file_save_dialog_response (GtkWidget *save_dialog, gchar *basename; GimpPlugInProcedure *save_proc; - if (! dialog->export) + if (GIMP_IS_SAVE_DIALOG (dialog)) { g_object_set_data_full (G_OBJECT (gimp), "gimp-file-save-dialog-state", gimp_file_dialog_get_state (dialog), (GDestroyNotify) gimp_file_dialog_state_destroy); } - else + else /* GIMP_IS_EXPORT_DIALOG (dialog) */ { g_object_set_data_full (G_OBJECT (gimp), "gimp-file-export-dialog-state", gimp_file_dialog_get_state (dialog), @@ -199,10 +192,12 @@ file_save_dialog_response (GtkWidget *save_dialog, file, save_proc, GIMP_RUN_INTERACTIVE, - ! dialog->save_a_copy && ! dialog->export, + GIMP_IS_SAVE_DIALOG (dialog) && + ! GIMP_SAVE_DIALOG (dialog)->save_a_copy, FALSE, - dialog->export, - ! dialog->export && dialog->compat, + GIMP_IS_EXPORT_DIALOG (dialog), + GIMP_IS_SAVE_DIALOG (dialog) && + GIMP_SAVE_DIALOG (dialog)->compat, FALSE)) { /* Save was successful, now store the URI in a couple of @@ -210,30 +205,37 @@ file_save_dialog_response (GtkWidget *save_dialog, * save. Lower-level URI management is handled in * file_save() */ - if (dialog->save_a_copy) - gimp_image_set_save_a_copy_file (dialog->image, file); + if (GIMP_IS_SAVE_DIALOG (dialog)) + { + GimpSaveDialog *save_dialog = GIMP_SAVE_DIALOG (dialog); - if (! dialog->export) - g_object_set_data_full (G_OBJECT (dialog->image->gimp), - GIMP_FILE_SAVE_LAST_FILE_KEY, - g_object_ref (file), - (GDestroyNotify) g_object_unref); + if (save_dialog->save_a_copy) + gimp_image_set_save_a_copy_file (dialog->image, file); + + g_object_set_data_full (G_OBJECT (dialog->image->gimp), + GIMP_FILE_SAVE_LAST_FILE_KEY, + g_object_ref (file), + (GDestroyNotify) g_object_unref); + } else - g_object_set_data_full (G_OBJECT (dialog->image->gimp), - GIMP_FILE_EXPORT_LAST_FILE_KEY, - g_object_ref (file), - (GDestroyNotify) g_object_unref); + { + g_object_set_data_full (G_OBJECT (dialog->image->gimp), + GIMP_FILE_EXPORT_LAST_FILE_KEY, + g_object_ref (file), + (GDestroyNotify) g_object_unref); + } /* make sure the menus are updated with the keys we've just set */ gimp_image_flush (dialog->image); /* Handle close-after-saving */ - if (dialog->close_after_saving && dialog->display_to_close) + if (GIMP_IS_SAVE_DIALOG (dialog) && + GIMP_SAVE_DIALOG (dialog)->close_after_saving && + GIMP_SAVE_DIALOG (dialog)->display_to_close) { - GimpDisplay *display = GIMP_DISPLAY (dialog->display_to_close); + GimpDisplay *display = GIMP_DISPLAY (GIMP_SAVE_DIALOG (dialog)->display_to_close); - if (display && - ! gimp_image_is_dirty (gimp_display_get_image (display))) + if (! gimp_image_is_dirty (gimp_display_get_image (display))) { gimp_display_close (display); } @@ -324,7 +326,7 @@ file_save_dialog_check_file (GtkWidget *save_dialog, GIMP_LOG (SAVE_DIALOG, "basename has no '.', trying to add extension"); - if (! save_proc && ! dialog->export) + if (! save_proc && GIMP_IS_SAVE_DIALOG (dialog)) { ext = "xcf"; } @@ -554,7 +556,7 @@ static GSList * file_save_dialog_get_procs (GimpFileDialog *dialog, Gimp *gimp) { - return (! dialog->export ? + return (GIMP_IS_SAVE_DIALOG (dialog) ? gimp->plug_in_manager->save_procs : gimp->plug_in_manager->export_procs); } @@ -581,7 +583,7 @@ file_save_dialog_switch_dialogs (GimpFileDialog *file_dialog, file = g_file_new_for_uri (basename); proc_in_other_group = - file_procedure_find (file_dialog->export ? + file_procedure_find (GIMP_IS_EXPORT_DIALOG (file_dialog) ? gimp->plug_in_manager->save_procs : gimp->plug_in_manager->export_procs, file, NULL); @@ -595,7 +597,7 @@ file_save_dialog_switch_dialogs (GimpFileDialog *file_dialog, const gchar *message; const gchar *link; - if (file_dialog->export) + if (GIMP_IS_EXPORT_DIALOG (file_dialog)) { primary = _("The given filename cannot be used for exporting"); message = _("You can use this dialog to export to various file formats. " @@ -627,7 +629,9 @@ file_save_dialog_switch_dialogs (GimpFileDialog *file_dialog, gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box, "%s", message); - if (! file_dialog->save_a_copy && ! file_dialog->close_after_saving) + if (GIMP_IS_EXPORT_DIALOG (file_dialog) || + (! GIMP_SAVE_DIALOG (file_dialog)->save_a_copy && + ! GIMP_SAVE_DIALOG (file_dialog)->close_after_saving)) { GtkWidget *label; gchar *markup; diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am index cc85911cdf..a352bba8b7 100644 --- a/app/widgets/Makefile.am +++ b/app/widgets/Makefile.am @@ -175,6 +175,8 @@ libappwidgets_a_sources = \ gimperrorconsole.h \ gimperrordialog.c \ gimperrordialog.h \ + gimpexportdialog.c \ + gimpexportdialog.h \ gimpfgbgeditor.c \ gimpfgbgeditor.h \ gimpfgbgview.c \ @@ -242,6 +244,8 @@ libappwidgets_a_sources = \ gimpmessagedialog.h \ gimpnavigationview.c \ gimpnavigationview.h \ + gimpopendialog.c \ + gimpopendialog.h \ gimpoverlaybox.c \ gimpoverlaybox.h \ gimpoverlaychild.c \ @@ -294,6 +298,8 @@ libappwidgets_a_sources = \ gimprender.h \ gimpsamplepointeditor.c \ gimpsamplepointeditor.h \ + gimpsavedialog.c \ + gimpsavedialog.h \ gimpscalebutton.c \ gimpscalebutton.h \ gimpselectiondata.c \ diff --git a/app/widgets/gimpexportdialog.c b/app/widgets/gimpexportdialog.c new file mode 100644 index 0000000000..897c205e8f --- /dev/null +++ b/app/widgets/gimpexportdialog.c @@ -0,0 +1,258 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpexportdialog.c + * Copyright (C) 2015 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include + +#include +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "widgets-types.h" + +#include "core/gimp.h" +#include "core/gimpimage.h" + +#include "file/file-utils.h" +#include "file/gimp-file.h" + +#include "pdb/gimppdb.h" + +#include "plug-in/gimppluginmanager.h" + +#include "gimpexportdialog.h" +#include "gimpfiledialog.h" +#include "gimphelp-ids.h" + +#include "gimp-intl.h" + + +static GFile * gimp_export_dialog_get_default_folder (Gimp *gimp); + +G_DEFINE_TYPE (GimpExportDialog, gimp_export_dialog, + GIMP_TYPE_FILE_DIALOG) + +#define parent_class gimp_export_dialog_parent_class + +static void +gimp_export_dialog_class_init (GimpExportDialogClass *klass) +{ +} + +static void +gimp_export_dialog_init (GimpExportDialog *dialog) +{ +} + +/* public functions */ + +GtkWidget * +gimp_export_dialog_new (Gimp *gimp) +{ + GimpExportDialog *dialog; + + g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); + + dialog = g_object_new (GIMP_TYPE_EXPORT_DIALOG, + "gimp", gimp, + "title", _("Export Image"), + "role", "gimp-file-export", + "help-id", GIMP_HELP_FILE_EXPORT_AS, + "stock-id", _("_Export"), + + "automatic-label", _("By Extension"), + "automatic-help-id", GIMP_HELP_FILE_SAVE_BY_EXTENSION, + + "action", GTK_FILE_CHOOSER_ACTION_SAVE, + "file-procs", gimp->plug_in_manager->export_procs, + "file-procs-all-images", gimp->plug_in_manager->save_procs, + "file-filter-label", _("All export images"), + "local-only", FALSE, + "do-overwrite-confirmation", TRUE, + NULL); + + return GTK_WIDGET (dialog); +} + +void +gimp_export_dialog_set_image (GimpExportDialog *dialog, + Gimp *gimp, + GimpImage *image) +{ + GFile *dir_file = NULL; + GFile *name_file = NULL; + GFile *ext_file = NULL; + gchar *basename; + + g_return_if_fail (GIMP_IS_EXPORT_DIALOG (dialog)); + g_return_if_fail (GIMP_IS_IMAGE (image)); + + GIMP_FILE_DIALOG (dialog)->image = image; + + gimp_file_dialog_set_file_proc (GIMP_FILE_DIALOG (dialog), NULL); + + /* + * Priority of default paths for Export: + * + * 1. Last Export path + * 2. Path of import source + * 3. Path of XCF source + * 4. Last path of any save to XCF + * 5. Last Export path of any document + * 6. The default path (usually the OS 'Documents' path) + */ + + dir_file = gimp_image_get_exported_file (image); + + if (! dir_file) + dir_file = g_object_get_data (G_OBJECT (image), + "gimp-image-source-file"); + + if (! dir_file) + dir_file = gimp_image_get_imported_file (image); + + if (! dir_file) + dir_file = gimp_image_get_file (image); + + if (! dir_file) + dir_file = g_object_get_data (G_OBJECT (gimp), + GIMP_FILE_SAVE_LAST_FILE_KEY); + + if (! dir_file) + dir_file = g_object_get_data (G_OBJECT (gimp), + GIMP_FILE_EXPORT_LAST_FILE_KEY); + + if (! dir_file) + dir_file = gimp_export_dialog_get_default_folder (gimp); + + /* Priority of default basenames for Export: + * + * 1. Last Export name + * 3. Save URI + * 2. Source file name + * 3. 'Untitled' + */ + + name_file = gimp_image_get_exported_file (image); + + if (! name_file) + name_file = gimp_image_get_file (image); + + if (! name_file) + name_file = gimp_image_get_imported_file (image); + + if (! name_file) + name_file = gimp_image_get_untitled_file (image); + + + /* Priority of default type/extension for Export: + * + * 1. Type of last Export + * 2. Type of the image Import + * 3. Type of latest Export of any document + * 4. .png + */ + ext_file = gimp_image_get_exported_file (image); + + if (! ext_file) + ext_file = gimp_image_get_imported_file (image); + + if (! ext_file) + ext_file = g_object_get_data (G_OBJECT (gimp), + GIMP_FILE_EXPORT_LAST_FILE_KEY); + + if (ext_file) + g_object_ref (ext_file); + else + ext_file = g_file_new_for_uri ("file:///we/only/care/about/extension.png"); + + if (ext_file) + { + GFile *tmp_file = file_utils_file_with_new_ext (name_file, ext_file); + basename = g_path_get_basename (gimp_file_get_utf8_name (tmp_file)); + g_object_unref (tmp_file); + g_object_unref (ext_file); + } + else + { + basename = g_path_get_basename (gimp_file_get_utf8_name (name_file)); + } + + if (g_file_query_file_type (dir_file, G_FILE_QUERY_INFO_NONE, NULL) == + G_FILE_TYPE_DIRECTORY) + { + gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), + dir_file, NULL); + } + else + { + GFile *parent_file = g_file_get_parent (dir_file); + gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), + parent_file, NULL); + g_object_unref (parent_file); + } + + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), basename); +} + +/* private functions */ + +static GFile * +gimp_export_dialog_get_default_folder (Gimp *gimp) +{ + if (gimp->default_folder) + { + return gimp->default_folder; + } + else + { + GFile *file = g_object_get_data (G_OBJECT (gimp), + "gimp-documents-folder"); + + if (! file) + { + gchar *path; + + /* Make sure it ends in '/' */ + path = g_build_path (G_DIR_SEPARATOR_S, + g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS), + G_DIR_SEPARATOR_S, + NULL); + + /* Paranoia fallback, see bug #722400 */ + if (! path) + path = g_build_path (G_DIR_SEPARATOR_S, + g_get_home_dir (), + G_DIR_SEPARATOR_S, + NULL); + + file = g_file_new_for_path (path); + g_free (path); + + g_object_set_data_full (G_OBJECT (gimp), "gimp-documents-folder", + file, (GDestroyNotify) g_object_unref); + } + + return file; + } +} diff --git a/app/widgets/gimpexportdialog.h b/app/widgets/gimpexportdialog.h new file mode 100644 index 0000000000..1280c7434f --- /dev/null +++ b/app/widgets/gimpexportdialog.h @@ -0,0 +1,59 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpexportdialog.h + * Copyright (C) 2015 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_EXPORT_DIALOG_H__ +#define __GIMP_EXPORT_DIALOG_H__ + +#include "gimpfiledialog.h" + +G_BEGIN_DECLS + +#define GIMP_TYPE_EXPORT_DIALOG (gimp_export_dialog_get_type ()) +#define GIMP_EXPORT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_EXPORT_DIALOG, GimpExportDialog)) +#define GIMP_EXPORT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_EXPORT_DIALOG, GimpExportDialogClass)) +#define GIMP_IS_EXPORT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_EXPORT_DIALOG)) +#define GIMP_IS_EXPORT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_EXPORT_DIALOG)) +#define GIMP_EXPORT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_EXPORT_DIALOG, GimpExportDialogClass)) + + +typedef struct _GimpExportDialogClass GimpExportDialogClass; + +struct _GimpExportDialog +{ + GimpFileDialog parent_instance; +}; + +struct _GimpExportDialogClass +{ + GimpFileDialogClass parent_class; +}; + + +GType gimp_export_dialog_get_type (void) G_GNUC_CONST; + +GtkWidget * gimp_export_dialog_new (Gimp *gimp); + +void gimp_export_dialog_set_image (GimpExportDialog *dialog, + Gimp *gimp, + GimpImage *image); + +G_END_DECLS + +#endif /* __GIMP_EXPORT_DIALOG_H__ */ diff --git a/app/widgets/gimpfiledialog.c b/app/widgets/gimpfiledialog.c index a1e8c5f00e..fc61abdc37 100644 --- a/app/widgets/gimpfiledialog.c +++ b/app/widgets/gimpfiledialog.c @@ -26,6 +26,7 @@ #include #include "libgimpbase/gimpbase.h" +#include "libgimpconfig/gimpconfig.h" #include "libgimpwidgets/gimpwidgets.h" #include "widgets-types.h" @@ -36,97 +37,95 @@ #include "config/gimpguiconfig.h" -#include "file/file-utils.h" -#include "file/gimp-file.h" - #include "pdb/gimppdb.h" -#include "plug-in/gimppluginmanager.h" #include "plug-in/gimppluginprocedure.h" #include "gimpfiledialog.h" #include "gimpfileprocview.h" -#include "gimphelp-ids.h" #include "gimpprogressbox.h" -#include "gimpview.h" -#include "gimpviewrendererimagefile.h" #include "gimpthumbbox.h" #include "gimpwidgets-utils.h" #include "gimp-intl.h" - /* an arbitrary limit to keep the file dialog from becoming too wide */ #define MAX_EXTENSIONS 4 - struct _GimpFileDialogState { gchar *filter_name; }; +enum +{ + PROP_0, + PROP_GIMP, + PROP_HELP_ID, + PROP_STOCK_ID, + PROP_AUTOMATIC_HELP_ID, + PROP_AUTOMATIC_LABEL, + PROP_FILE_FILTER_LABEL, + PROP_FILE_PROCS, + PROP_FILE_PROCS_ALL_IMAGES +}; static void gimp_file_dialog_progress_iface_init (GimpProgressInterface *iface); -static void gimp_file_dialog_dispose (GObject *object); -static gboolean gimp_file_dialog_delete_event (GtkWidget *widget, - GdkEventAny *event); -static void gimp_file_dialog_response (GtkDialog *dialog, - gint response_id); +static void gimp_file_dialog_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_file_dialog_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void gimp_file_dialog_constructed (GObject *object); +static void gimp_file_dialog_dispose (GObject *object); + +static gboolean gimp_file_dialog_delete_event (GtkWidget *widget, + GdkEventAny *event); +static void gimp_file_dialog_response (GtkDialog *dialog, + gint response_id); static GimpProgress * - gimp_file_dialog_progress_start (GimpProgress *progress, - gboolean cancellable, - const gchar *message); -static void gimp_file_dialog_progress_end (GimpProgress *progress); -static gboolean gimp_file_dialog_progress_is_active (GimpProgress *progress); -static void gimp_file_dialog_progress_set_text (GimpProgress *progress, - const gchar *message); -static void gimp_file_dialog_progress_set_value (GimpProgress *progress, - gdouble percentage); -static gdouble gimp_file_dialog_progress_get_value (GimpProgress *progress); -static void gimp_file_dialog_progress_pulse (GimpProgress *progress); -static guint32 gimp_file_dialog_progress_get_window_id (GimpProgress *progress); + gimp_file_dialog_progress_start (GimpProgress *progress, + gboolean cancellable, + const gchar *message); +static void gimp_file_dialog_progress_end (GimpProgress *progress); +static gboolean gimp_file_dialog_progress_is_active (GimpProgress *progress); +static void gimp_file_dialog_progress_set_text (GimpProgress *progress, + const gchar *message); +static void gimp_file_dialog_progress_set_value (GimpProgress *progress, + gdouble percentage); +static gdouble gimp_file_dialog_progress_get_value (GimpProgress *progress); +static void gimp_file_dialog_progress_pulse (GimpProgress *progress); +static guint32 gimp_file_dialog_progress_get_window_id (GimpProgress *progress); -static void gimp_file_dialog_add_user_dir (GimpFileDialog *dialog, - GUserDirectory directory); -static void gimp_file_dialog_add_preview (GimpFileDialog *dialog, - Gimp *gimp); -static void gimp_file_dialog_add_filters (GimpFileDialog *dialog, - Gimp *gimp, - GimpFileChooserAction - action, - GSList *file_procs, - GSList *file_procs_all_images); -static void gimp_file_dialog_add_compat_toggle (GimpFileDialog *dialog); -static void gimp_file_dialog_process_procedure (GimpPlugInProcedure - *file_proc, - GtkFileFilter **filter_out, - GtkFileFilter *all, - GtkFileFilter *all_savable); -static void gimp_file_dialog_add_proc_selection (GimpFileDialog *dialog, - Gimp *gimp, - GSList *file_procs, - const gchar *automatic, - const gchar *automatic_help_id); +static void gimp_file_dialog_add_user_dir (GimpFileDialog *dialog, + GUserDirectory directory); +static void gimp_file_dialog_add_preview (GimpFileDialog *dialog); +static void gimp_file_dialog_add_filters (GimpFileDialog *dialog); +static void gimp_file_dialog_process_procedure (GimpPlugInProcedure *file_proc, + GtkFileFilter **filter_out, + GtkFileFilter *all, + GtkFileFilter *all_savable); +static void gimp_file_dialog_add_proc_selection (GimpFileDialog *dialog); -static void gimp_file_dialog_selection_changed (GtkFileChooser *chooser, - GimpFileDialog *dialog); -static void gimp_file_dialog_update_preview (GtkFileChooser *chooser, - GimpFileDialog *dialog); +static void gimp_file_dialog_selection_changed (GtkFileChooser *chooser, + GimpFileDialog *dialog); +static void gimp_file_dialog_update_preview (GtkFileChooser *chooser, + GimpFileDialog *dialog); -static void gimp_file_dialog_compat_toggled (GtkToggleButton *button, - GimpFileDialog *dialog); -static void gimp_file_dialog_proc_changed (GimpFileProcView *view, - GimpFileDialog *dialog); +static void gimp_file_dialog_proc_changed (GimpFileProcView *view, + GimpFileDialog *dialog); -static void gimp_file_dialog_help_func (const gchar *help_id, - gpointer help_data); -static void gimp_file_dialog_help_clicked (GtkWidget *widget, - gpointer dialog); +static void gimp_file_dialog_help_func (const gchar *help_id, + gpointer help_data); +static void gimp_file_dialog_help_clicked (GtkWidget *widget, + gpointer dialog); -static gchar * gimp_file_dialog_pattern_from_extension (const gchar *extension); -static GFile * gimp_file_dialog_get_default_folder (Gimp *gimp); +static gchar * gimp_file_dialog_pattern_from_extension (const gchar *extension); G_DEFINE_TYPE_WITH_CODE (GimpFileDialog, gimp_file_dialog, @@ -144,16 +143,61 @@ gimp_file_dialog_class_init (GimpFileDialogClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass); + object_class->set_property = gimp_file_dialog_set_property; + object_class->get_property = gimp_file_dialog_get_property; + object_class->constructed = gimp_file_dialog_constructed; object_class->dispose = gimp_file_dialog_dispose; widget_class->delete_event = gimp_file_dialog_delete_event; dialog_class->response = gimp_file_dialog_response; + + g_object_class_install_property (object_class, PROP_GIMP, + g_param_spec_object ("gimp", NULL, NULL, + GIMP_TYPE_GIMP, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_HELP_ID, + g_param_spec_string ("help-id", NULL, NULL, + NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_STOCK_ID, + g_param_spec_string ("stock-id", NULL, NULL, + NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_AUTOMATIC_HELP_ID, + g_param_spec_string ("automatic-help-id", NULL, NULL, + NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_AUTOMATIC_LABEL, + g_param_spec_string ("automatic-label", NULL, NULL, + NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_FILE_FILTER_LABEL, + g_param_spec_string ("file-filter-label", NULL, NULL, + NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_FILE_PROCS, + g_param_spec_pointer ("file-procs", NULL, NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_FILE_PROCS_ALL_IMAGES, + g_param_spec_pointer ("file-procs-all-images", NULL, NULL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); } static void gimp_file_dialog_init (GimpFileDialog *dialog) { + dialog->stock_id = GTK_STOCK_OK; } static void @@ -169,6 +213,133 @@ gimp_file_dialog_progress_iface_init (GimpProgressInterface *iface) iface->get_window_id = gimp_file_dialog_progress_get_window_id; } +static void +gimp_file_dialog_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpFileDialog *dialog = GIMP_FILE_DIALOG (object); + + switch (property_id) + { + case PROP_GIMP: + dialog->gimp = g_value_get_object (value); + break; + case PROP_HELP_ID: + dialog->help_id = g_value_dup_string (value); + break; + case PROP_STOCK_ID: + dialog->stock_id = g_value_dup_string (value); + break; + case PROP_AUTOMATIC_HELP_ID: + dialog->automatic_help_id = g_value_dup_string (value); + break; + case PROP_AUTOMATIC_LABEL: + dialog->automatic_label = g_value_dup_string (value); + break; + case PROP_FILE_FILTER_LABEL: + dialog->file_filter_label = g_value_dup_string (value); + break; + case PROP_FILE_PROCS: + dialog->file_procs = g_value_get_pointer (value); + break; + case PROP_FILE_PROCS_ALL_IMAGES: + dialog->file_procs_all_images = g_value_get_pointer (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_file_dialog_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpFileDialog *dialog = GIMP_FILE_DIALOG (object); + + switch (property_id) + { + case PROP_GIMP: + g_value_set_object (value, dialog->gimp); + break; + case PROP_HELP_ID: + g_value_set_string (value, dialog->help_id); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_file_dialog_constructed (GObject *object) +{ + GimpFileDialog *dialog = GIMP_FILE_DIALOG (object); + + G_OBJECT_CLASS (parent_class)->constructed (object); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + dialog->stock_id, GTK_RESPONSE_OK, + NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + if (dialog->help_id) + { + gimp_help_connect (GTK_WIDGET (dialog), + gimp_file_dialog_help_func, dialog->help_id, dialog); + + if (GIMP_GUI_CONFIG (dialog->gimp->config)->show_help_button) + { + GtkWidget *action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); + GtkWidget *button = gtk_button_new_from_stock (GTK_STOCK_HELP); + + gtk_box_pack_end (GTK_BOX (action_area), button, FALSE, TRUE, 0); + gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), + button, TRUE); + gtk_widget_show (button); + + g_object_set_data_full (G_OBJECT (dialog), "gimp-dialog-help-id", + g_strdup (dialog->help_id), + (GDestroyNotify) g_free); + + g_signal_connect (button, "clicked", + G_CALLBACK (gimp_file_dialog_help_clicked), + dialog); + + g_object_set_data (G_OBJECT (dialog), "gimp-dialog-help-button", button); + } + } + + /* All classes derivated from GimpFileDialog should show these. */ + gimp_file_dialog_add_user_dir (dialog, G_USER_DIRECTORY_PICTURES); + gimp_file_dialog_add_user_dir (dialog, G_USER_DIRECTORY_DOCUMENTS); + + gimp_file_dialog_add_preview (dialog); + gimp_file_dialog_add_filters (dialog); + + dialog->extra_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4); + gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), + dialog->extra_vbox); + gtk_widget_show (dialog->extra_vbox); + + gimp_file_dialog_add_proc_selection (dialog); + + dialog->progress = gimp_progress_box_new (); + gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + dialog->progress, FALSE, FALSE, 0); +} + static void gimp_file_dialog_dispose (GObject *object) { @@ -177,6 +348,26 @@ gimp_file_dialog_dispose (GObject *object) G_OBJECT_CLASS (parent_class)->dispose (object); dialog->progress = NULL; + + if (dialog->help_id) + g_free (dialog->help_id); + dialog->help_id = NULL; + + if (dialog->stock_id) + g_free (dialog->stock_id); + dialog->stock_id = NULL; + + if (dialog->automatic_help_id) + g_free (dialog->automatic_help_id); + dialog->automatic_help_id = NULL; + + if (dialog->automatic_label) + g_free (dialog->automatic_label); + dialog->automatic_label = NULL; + + if (dialog->file_filter_label) + g_free (dialog->file_filter_label); + dialog->file_filter_label = NULL; } static gboolean @@ -300,122 +491,15 @@ gimp_file_dialog_progress_get_window_id (GimpProgress *progress) /* public functions */ -GtkWidget * -gimp_file_dialog_new (Gimp *gimp, - GimpFileChooserAction action, - const gchar *title, - const gchar *role, - const gchar *icon_name, - const gchar *help_id) +void +gimp_file_dialog_add_extra_widget (GimpFileDialog *dialog, + GtkWidget *widget, + gboolean expand, + gboolean fill, + guint padding) { - GimpFileDialog *dialog = NULL; - GSList *file_procs = NULL; - GSList *file_procs_all_images = NULL; - const gchar *automatic = NULL; - const gchar *automatic_help_id = NULL; - GtkFileChooserAction gtk_action = 0; - - g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); - g_return_val_if_fail (title != NULL, NULL); - g_return_val_if_fail (role != NULL, NULL); - g_return_val_if_fail (icon_name != NULL, NULL); - g_return_val_if_fail (help_id != NULL, NULL); - - switch (action) - { - case GIMP_FILE_CHOOSER_ACTION_OPEN: - gtk_action = GTK_FILE_CHOOSER_ACTION_OPEN; - file_procs = gimp->plug_in_manager->load_procs; - file_procs_all_images = NULL; - automatic = _("Automatically Detected"); - automatic_help_id = GIMP_HELP_FILE_OPEN_BY_EXTENSION; - break; - - case GIMP_FILE_CHOOSER_ACTION_SAVE: - case GIMP_FILE_CHOOSER_ACTION_EXPORT: - gtk_action = GTK_FILE_CHOOSER_ACTION_SAVE; - file_procs = (action == GIMP_FILE_CHOOSER_ACTION_SAVE ? - gimp->plug_in_manager->save_procs : - gimp->plug_in_manager->export_procs); - file_procs_all_images = (action == GIMP_FILE_CHOOSER_ACTION_SAVE ? - gimp->plug_in_manager->export_procs : - gimp->plug_in_manager->save_procs); - automatic = _("By Extension"); - automatic_help_id = GIMP_HELP_FILE_SAVE_BY_EXTENSION; - break; - - default: - g_return_val_if_reached (NULL); - return NULL; - } - - dialog = g_object_new (GIMP_TYPE_FILE_DIALOG, - "title", title, - "role", role, - "action", gtk_action, - "local-only", FALSE, - "do-overwrite-confirmation", TRUE, - NULL); - - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - icon_name, GTK_RESPONSE_OK, - NULL); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), - GTK_RESPONSE_OK, - GTK_RESPONSE_CANCEL, - -1); - - gimp_help_connect (GTK_WIDGET (dialog), - gimp_file_dialog_help_func, help_id, dialog); - - if (GIMP_GUI_CONFIG (gimp->config)->show_help_button && help_id) - { - GtkWidget *action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); - GtkWidget *button = gtk_button_new_from_stock (GTK_STOCK_HELP); - - gtk_box_pack_end (GTK_BOX (action_area), button, FALSE, TRUE, 0); - gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), - button, TRUE); - gtk_widget_show (button); - - g_object_set_data_full (G_OBJECT (dialog), "gimp-dialog-help-id", - g_strdup (help_id), - (GDestroyNotify) g_free); - - g_signal_connect (button, "clicked", - G_CALLBACK (gimp_file_dialog_help_clicked), - dialog); - - g_object_set_data (G_OBJECT (dialog), "gimp-dialog-help-button", button); - } - - gimp_file_dialog_add_user_dir (dialog, G_USER_DIRECTORY_PICTURES); - gimp_file_dialog_add_user_dir (dialog, G_USER_DIRECTORY_DOCUMENTS); - - gimp_file_dialog_add_preview (dialog, gimp); - - gimp_file_dialog_add_filters (dialog, gimp, action, - file_procs, - file_procs_all_images); - - dialog->extra_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4); - gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), - dialog->extra_vbox); - gtk_widget_show (dialog->extra_vbox); - - gimp_file_dialog_add_compat_toggle (dialog); - - gimp_file_dialog_add_proc_selection (dialog, gimp, file_procs, automatic, - automatic_help_id); - - dialog->progress = gimp_progress_box_new (); - gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), - dialog->progress, FALSE, FALSE, 0); - - return GTK_WIDGET (dialog); + gtk_box_pack_start (GTK_BOX (dialog->extra_vbox), + widget, expand, fill, padding); } void @@ -467,259 +551,6 @@ gimp_file_dialog_set_file_proc (GimpFileDialog *dialog, file_proc); } -void -gimp_file_dialog_set_open_image (GimpFileDialog *dialog, - GimpImage *image, - gboolean open_as_layers) -{ - g_return_if_fail (GIMP_IS_FILE_DIALOG (dialog)); - g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image)); - - dialog->image = image; - dialog->open_as_layers = open_as_layers; -} - -void -gimp_file_dialog_set_save_image (GimpFileDialog *dialog, - Gimp *gimp, - GimpImage *image, - gboolean save_a_copy, - gboolean export, - gboolean close_after_saving, - GimpObject *display) -{ - GFile *dir_file = NULL; - GFile *name_file = NULL; - GFile *ext_file = NULL; - 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->export = export; - dialog->close_after_saving = close_after_saving; - dialog->display_to_close = display; - - gimp_file_dialog_set_file_proc (dialog, NULL); - - if (! export) - { - gint rle_version; - gint zlib_version; - const gchar *version_string; - gchar *tooltip; - - /* - * Priority of default paths for Save: - * - * 1. Last Save a copy-path (applies only to Save a copy) - * 2. Last Save path - * 3. Path of source XCF - * 4. Path of Import source - * 5. Last Save path of any GIMP document - * 6. The default path (usually the OS 'Documents' path) - */ - - if (save_a_copy) - dir_file = gimp_image_get_save_a_copy_file (image); - - if (! dir_file) - dir_file = gimp_image_get_file (image); - - if (! dir_file) - dir_file = g_object_get_data (G_OBJECT (image), - "gimp-image-source-file"); - - if (! dir_file) - dir_file = gimp_image_get_imported_file (image); - - if (! dir_file) - dir_file = g_object_get_data (G_OBJECT (gimp), - GIMP_FILE_SAVE_LAST_FILE_KEY); - - if (! dir_file) - dir_file = gimp_file_dialog_get_default_folder (gimp); - - - /* Priority of default basenames for Save: - * - * 1. Last Save a copy-name (applies only to Save a copy) - * 2. Last Save name - * 3. Last Export name - * 3. The source image path - * 3. 'Untitled' - */ - - if (save_a_copy) - name_file = gimp_image_get_save_a_copy_file (image); - - if (! name_file) - name_file = gimp_image_get_file (image); - - if (! name_file) - name_file = gimp_image_get_exported_file (image); - - if (! name_file) - name_file = gimp_image_get_imported_file (image); - - if (! name_file) - name_file = gimp_image_get_untitled_file (image); - - - /* Priority of default type/extension for Save: - * - * 1. Type of last Save - * 2. .xcf (which we don't explicitly append) - */ - ext_file = gimp_image_get_file (image); - - if (ext_file) - g_object_ref (ext_file); - else - ext_file = g_file_new_for_uri ("file:///we/only/care/about/extension.xcf"); - - gimp_image_get_xcf_version (image, FALSE, &rle_version, &version_string); - gimp_image_get_xcf_version (image, TRUE, &zlib_version, NULL); - - if (rle_version == zlib_version) - { - gtk_widget_set_sensitive (dialog->compat_toggle, FALSE); - - tooltip = g_strdup_printf (_("The image uses features from %s and " - "cannot be saved for older GIMP " - "versions."), - version_string); - } - else - { - gtk_widget_set_sensitive (dialog->compat_toggle, TRUE); - - tooltip = g_strdup_printf (_("Disables compression to make the XCF " - "file readable by %s and later."), - version_string); - } - - gimp_help_set_help_data (dialog->compat_toggle, tooltip, NULL); - g_free (tooltip); - - gtk_widget_show (dialog->compat_toggle); - } - else /* if (export) */ - { - /* - * Priority of default paths for Export: - * - * 1. Last Export path - * 2. Path of import source - * 3. Path of XCF source - * 4. Last path of any save to XCF - * 5. Last Export path of any document - * 6. The default path (usually the OS 'Documents' path) - */ - - dir_file = gimp_image_get_exported_file (image); - - if (! dir_file) - dir_file = g_object_get_data (G_OBJECT (image), - "gimp-image-source-file"); - - if (! dir_file) - dir_file = gimp_image_get_imported_file (image); - - if (! dir_file) - dir_file = gimp_image_get_file (image); - - if (! dir_file) - dir_file = g_object_get_data (G_OBJECT (gimp), - GIMP_FILE_SAVE_LAST_FILE_KEY); - - if (! dir_file) - dir_file = g_object_get_data (G_OBJECT (gimp), - GIMP_FILE_EXPORT_LAST_FILE_KEY); - - if (! dir_file) - dir_file = gimp_file_dialog_get_default_folder (gimp); - - - /* Priority of default basenames for Export: - * - * 1. Last Export name - * 3. Save URI - * 2. Source file name - * 3. 'Untitled' - */ - - name_file = gimp_image_get_exported_file (image); - - if (! name_file) - name_file = gimp_image_get_file (image); - - if (! name_file) - name_file = gimp_image_get_imported_file (image); - - if (! name_file) - name_file = gimp_image_get_untitled_file (image); - - - /* Priority of default type/extension for Export: - * - * 1. Type of last Export - * 2. Type of the image Import - * 3. Type of latest Export of any document - * 4. .png - */ - ext_file = gimp_image_get_exported_file (image); - - if (! ext_file) - ext_file = gimp_image_get_imported_file (image); - - if (! ext_file) - ext_file = g_object_get_data (G_OBJECT (gimp), - GIMP_FILE_EXPORT_LAST_FILE_KEY); - - if (ext_file) - g_object_ref (ext_file); - else - ext_file = g_file_new_for_uri ("file:///we/only/care/about/extension.png"); - - gtk_widget_hide (dialog->compat_toggle); - } - - if (gtk_widget_get_sensitive (dialog->compat_toggle)) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->compat_toggle), - gimp_image_get_xcf_compat_mode (image)); - - if (ext_file) - { - GFile *tmp_file = file_utils_file_with_new_ext (name_file, ext_file); - basename = g_path_get_basename (gimp_file_get_utf8_name (tmp_file)); - g_object_unref (tmp_file); - g_object_unref (ext_file); - } - else - { - basename = g_path_get_basename (gimp_file_get_utf8_name (name_file)); - } - - if (g_file_query_file_type (dir_file, G_FILE_QUERY_INFO_NONE, NULL) == - G_FILE_TYPE_DIRECTORY) - { - gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), - dir_file, NULL); - } - else - { - GFile *parent_file = g_file_get_parent (dir_file); - gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), - parent_file, NULL); - g_object_unref (parent_file); - } - - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), basename); -} - GimpFileDialogState * gimp_file_dialog_get_state (GimpFileDialog *dialog) { @@ -792,10 +623,9 @@ gimp_file_dialog_add_user_dir (GimpFileDialog *dialog, } static void -gimp_file_dialog_add_preview (GimpFileDialog *dialog, - Gimp *gimp) +gimp_file_dialog_add_preview (GimpFileDialog *dialog) { - if (gimp->config->thumbnail_size <= 0) + if (dialog->gimp->config->thumbnail_size <= 0) return; gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (dialog), FALSE); @@ -807,7 +637,7 @@ gimp_file_dialog_add_preview (GimpFileDialog *dialog, G_CALLBACK (gimp_file_dialog_update_preview), dialog); - dialog->thumb_box = gimp_thumb_box_new (gimp_get_user_context (gimp)); + dialog->thumb_box = gimp_thumb_box_new (gimp_get_user_context (dialog->gimp)); gtk_widget_set_sensitive (GTK_WIDGET (dialog->thumb_box), FALSE); gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), dialog->thumb_box); @@ -830,11 +660,7 @@ gimp_file_dialog_add_preview (GimpFileDialog *dialog, * **/ static void -gimp_file_dialog_add_filters (GimpFileDialog *dialog, - Gimp *gimp, - GimpFileChooserAction action, - GSList *file_procs, - GSList *file_procs_all_images) +gimp_file_dialog_add_filters (GimpFileDialog *dialog) { GtkFileFilter *all; GtkFileFilter *all_savable = NULL; @@ -849,18 +675,15 @@ gimp_file_dialog_add_filters (GimpFileDialog *dialog, gtk_file_filter_set_name (all, _("All images")); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all); - if (file_procs_all_images) + if (dialog->file_procs_all_images) { all_savable = gtk_file_filter_new (); - if (action == GIMP_FILE_CHOOSER_ACTION_SAVE) - gtk_file_filter_set_name (all_savable, _("All XCF images")); - else - gtk_file_filter_set_name (all_savable, _("All export images")); + gtk_file_filter_set_name (all_savable, dialog->file_filter_label); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_savable); } /* Add the normal file procs */ - for (list = file_procs; list; list = g_slist_next (list)) + for (list = dialog->file_procs; list; list = g_slist_next (list)) { GimpPlugInProcedure *file_proc = list->data; GtkFileFilter *filter = NULL; @@ -879,7 +702,7 @@ gimp_file_dialog_add_filters (GimpFileDialog *dialog, /* Add the "rest" of the file procs only as filters to * "All images" */ - for (list = file_procs_all_images; list; list = g_slist_next (list)) + for (list = dialog->file_procs_all_images; list; list = g_slist_next (list)) { GimpPlugInProcedure *file_proc = list->data; @@ -894,18 +717,6 @@ gimp_file_dialog_add_filters (GimpFileDialog *dialog, gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all); } -static void -gimp_file_dialog_add_compat_toggle (GimpFileDialog *dialog) -{ - dialog->compat_toggle = gtk_check_button_new_with_label (_("Save this XCF file with maximum compatibility")); - gtk_box_pack_start (GTK_BOX (dialog->extra_vbox), dialog->compat_toggle, - FALSE, FALSE, 0); - - g_signal_connect (dialog->compat_toggle, "toggled", - G_CALLBACK (gimp_file_dialog_compat_toggled), - dialog); -} - /** * gimp_file_dialog_process_procedure: * @file_proc: @@ -988,17 +799,14 @@ gimp_file_dialog_process_procedure (GimpPlugInProcedure *file_proc, } static void -gimp_file_dialog_add_proc_selection (GimpFileDialog *dialog, - Gimp *gimp, - GSList *file_procs, - const gchar *automatic, - const gchar *automatic_help_id) +gimp_file_dialog_add_proc_selection (GimpFileDialog *dialog) { GtkWidget *scrolled_window; dialog->proc_expander = gtk_expander_new_with_mnemonic (NULL); - gtk_box_pack_start (GTK_BOX (dialog->extra_vbox), dialog->proc_expander, - TRUE, TRUE, 0); + gimp_file_dialog_add_extra_widget (dialog, + dialog->proc_expander, + TRUE, TRUE, 0); gtk_widget_show (dialog->proc_expander); scrolled_window = gtk_scrolled_window_new (NULL, NULL); @@ -1011,8 +819,9 @@ gimp_file_dialog_add_proc_selection (GimpFileDialog *dialog, gtk_widget_set_size_request (scrolled_window, -1, 200); - dialog->proc_view = gimp_file_proc_view_new (gimp, file_procs, automatic, - automatic_help_id); + dialog->proc_view = gimp_file_proc_view_new (dialog->gimp, dialog->file_procs, + dialog->automatic_label, + dialog->automatic_help_id); gtk_container_add (GTK_CONTAINER (scrolled_window), dialog->proc_view); gtk_widget_show (dialog->proc_view); @@ -1039,13 +848,6 @@ gimp_file_dialog_update_preview (GtkFileChooser *chooser, gtk_file_chooser_get_preview_file (chooser)); } -static void -gimp_file_dialog_compat_toggled (GtkToggleButton *button, - GimpFileDialog *dialog) -{ - dialog->compat = gtk_toggle_button_get_active (button); -} - static void gimp_file_dialog_proc_changed (GimpFileProcView *view, GimpFileDialog *dialog) @@ -1204,43 +1006,3 @@ gimp_file_dialog_pattern_from_extension (const gchar *extension) return pattern; } - -static GFile * -gimp_file_dialog_get_default_folder (Gimp *gimp) -{ - if (gimp->default_folder) - { - return gimp->default_folder; - } - else - { - GFile *file = g_object_get_data (G_OBJECT (gimp), - "gimp-documents-folder"); - - if (! file) - { - gchar *path; - - /* Make sure it ends in '/' */ - path = g_build_path (G_DIR_SEPARATOR_S, - g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS), - G_DIR_SEPARATOR_S, - NULL); - - /* Paranoia fallback, see bug #722400 */ - if (! path) - path = g_build_path (G_DIR_SEPARATOR_S, - g_get_home_dir (), - G_DIR_SEPARATOR_S, - NULL); - - file = g_file_new_for_path (path); - g_free (path); - - g_object_set_data_full (G_OBJECT (gimp), "gimp-documents-folder", - file, (GDestroyNotify) g_object_unref); - } - - return file; - } -} diff --git a/app/widgets/gimpfiledialog.h b/app/widgets/gimpfiledialog.h index 723dd4c47c..7dcf42026a 100644 --- a/app/widgets/gimpfiledialog.h +++ b/app/widgets/gimpfiledialog.h @@ -38,25 +38,28 @@ struct _GimpFileDialog { GtkFileChooserDialog parent_instance; - GimpPlugInProcedure *file_proc; - + Gimp *gimp; GimpImage *image; - gboolean open_as_layers; - gboolean save_a_copy; - gboolean export; - gboolean compat; - gboolean close_after_saving; - GimpObject *display_to_close; + + GimpPlugInProcedure *file_proc; GtkWidget *thumb_box; GtkWidget *extra_vbox; - GtkWidget *compat_toggle; GtkWidget *proc_expander; GtkWidget *proc_view; GtkWidget *progress; gboolean busy; gboolean canceled; + + gchar *help_id; + gchar *stock_id; + gchar *automatic_help_id; + gchar *automatic_label; + gchar *file_filter_label; + + GSList *file_procs; + GSList *file_procs_all_images; }; struct _GimpFileDialogClass @@ -70,29 +73,17 @@ typedef struct _GimpFileDialogState GimpFileDialogState; GType gimp_file_dialog_get_type (void) G_GNUC_CONST; -GtkWidget * gimp_file_dialog_new (Gimp *gimp, - GimpFileChooserAction action, - const gchar *title, - const gchar *role, - const gchar *icon_name, - const gchar *help_id); +void gimp_file_dialog_add_extra_widget (GimpFileDialog *dialog, + GtkWidget *widget, + gboolean expand, + gboolean fill, + guint padding); -void gimp_file_dialog_set_sensitive (GimpFileDialog *dialog, - gboolean sensitive); +void gimp_file_dialog_set_sensitive (GimpFileDialog *dialog, + gboolean sensitive); -void gimp_file_dialog_set_file_proc (GimpFileDialog *dialog, - GimpPlugInProcedure *file_proc); - -void gimp_file_dialog_set_open_image (GimpFileDialog *dialog, - GimpImage *image, - gboolean open_as_layers); -void gimp_file_dialog_set_save_image (GimpFileDialog *dialog, - Gimp *gimp, - GimpImage *image, - gboolean save_a_copy, - gboolean export, - gboolean close_after_saving, - GimpObject *display); +void gimp_file_dialog_set_file_proc (GimpFileDialog *dialog, + GimpPlugInProcedure *file_proc); GimpFileDialogState * gimp_file_dialog_get_state (GimpFileDialog *dialog); void gimp_file_dialog_set_state (GimpFileDialog *dialog, diff --git a/app/widgets/gimpopendialog.c b/app/widgets/gimpopendialog.c new file mode 100644 index 0000000000..a89896f824 --- /dev/null +++ b/app/widgets/gimpopendialog.c @@ -0,0 +1,104 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpopendialog.c + * Copyright (C) 2015 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include + +#include +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "widgets-types.h" + +#include "core/gimp.h" +#include "core/gimpimage.h" + +#include "pdb/gimppdb.h" + +#include "plug-in/gimppluginmanager.h" + +#include "gimpfiledialog.h" +#include "gimphelp-ids.h" +#include "gimpopendialog.h" + +#include "gimp-intl.h" + + +G_DEFINE_TYPE (GimpOpenDialog, gimp_open_dialog, + GIMP_TYPE_FILE_DIALOG) + +#define parent_class gimp_open_dialog_parent_class + +static void +gimp_open_dialog_class_init (GimpOpenDialogClass *klass) +{ +} + +static void +gimp_open_dialog_init (GimpOpenDialog *dialog) +{ +} + +/* public functions */ + +GtkWidget * +gimp_open_dialog_new (Gimp *gimp) +{ + GimpOpenDialog *dialog; + + g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); + + dialog = g_object_new (GIMP_TYPE_OPEN_DIALOG, + "gimp", gimp, + "title", _("Open Image"), + "role", "gimp-file-open", + "help-id", GIMP_HELP_FILE_OPEN, + "stock-id", GTK_STOCK_OPEN, + + "automatic-label", _("Automatically Detected"), + "automatic-help-id", GIMP_HELP_FILE_OPEN_BY_EXTENSION, + + "action", GTK_FILE_CHOOSER_ACTION_OPEN, + "file-procs", gimp->plug_in_manager->load_procs, + "file-procs-all-images", NULL, + "file-filter-label", NULL, + "local-only", FALSE, + "do-overwrite-confirmation", TRUE, + NULL); + + return GTK_WIDGET (dialog); +} + +void +gimp_open_dialog_set_image (GimpOpenDialog *dialog, + GimpImage *image, + gboolean open_as_layers) +{ + g_return_if_fail (GIMP_IS_OPEN_DIALOG (dialog)); + g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image)); + + GIMP_FILE_DIALOG (dialog)->image = image; + dialog->open_as_layers = open_as_layers; +} + +/* private functions */ diff --git a/app/widgets/gimpopendialog.h b/app/widgets/gimpopendialog.h new file mode 100644 index 0000000000..8a1c24630f --- /dev/null +++ b/app/widgets/gimpopendialog.h @@ -0,0 +1,59 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpopendialog.h + * Copyright (C) 2015 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_OPEN_DIALOG_H__ +#define __GIMP_OPEN_DIALOG_H__ + +G_BEGIN_DECLS + +#define GIMP_TYPE_OPEN_DIALOG (gimp_open_dialog_get_type ()) +#define GIMP_OPEN_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPEN_DIALOG, GimpOpenDialog)) +#define GIMP_OPEN_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_OPEN_DIALOG, GimpOpenDialogClass)) +#define GIMP_IS_OPEN_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OPEN_DIALOG)) +#define GIMP_IS_OPEN_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OPEN_DIALOG)) +#define GIMP_OPEN_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_OPEN_DIALOG, GimpOpenDialogClass)) + + +typedef struct _GimpOpenDialogClass GimpOpenDialogClass; + +struct _GimpOpenDialog +{ + GimpFileDialog parent_instance; + + gboolean open_as_layers; +}; + +struct _GimpOpenDialogClass +{ + GimpFileDialogClass parent_class; +}; + + +GType gimp_open_dialog_get_type (void) G_GNUC_CONST; + +GtkWidget * gimp_open_dialog_new (Gimp *gimp); + +void gimp_open_dialog_set_image (GimpOpenDialog *dialog, + GimpImage *image, + gboolean open_as_layers); + +G_END_DECLS + +#endif /* __GIMP_OPEN_DIALOG_H__ */ diff --git a/app/widgets/gimpsavedialog.c b/app/widgets/gimpsavedialog.c new file mode 100644 index 0000000000..e9156da389 --- /dev/null +++ b/app/widgets/gimpsavedialog.c @@ -0,0 +1,333 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpsavedialog.c + * Copyright (C) 2015 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include + +#include +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "widgets-types.h" + +#include "core/gimp.h" +#include "core/gimpimage.h" + +#include "file/file-utils.h" +#include "file/gimp-file.h" + +#include "pdb/gimppdb.h" + +#include "plug-in/gimppluginmanager.h" + +#include "gimpfiledialog.h" +#include "gimphelp-ids.h" +#include "gimpsavedialog.h" + +#include "gimp-intl.h" + + +static void gimp_save_dialog_constructed (GObject *object); + +static GFile * gimp_save_dialog_get_default_folder (Gimp *gimp); +static void gimp_save_dialog_add_compat_toggle (GimpSaveDialog *dialog); +static void gimp_save_dialog_compat_toggled (GtkToggleButton *button, + GimpSaveDialog *dialog); + +G_DEFINE_TYPE (GimpSaveDialog, gimp_save_dialog, + GIMP_TYPE_FILE_DIALOG) + +#define parent_class gimp_save_dialog_parent_class + +static void +gimp_save_dialog_class_init (GimpSaveDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = gimp_save_dialog_constructed; +} + +static void +gimp_save_dialog_init (GimpSaveDialog *dialog) +{ +} + +static void +gimp_save_dialog_constructed (GObject *object) +{ + GimpSaveDialog *dialog = GIMP_SAVE_DIALOG (object); + + /* GimpFileDialog's constructed() is doing a few initialization + * common to all file dialogs. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + gimp_save_dialog_add_compat_toggle (dialog); +} + +/* public functions */ + +GtkWidget * +gimp_save_dialog_new (Gimp *gimp) +{ + GimpSaveDialog *dialog; + + g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); + + dialog = g_object_new (GIMP_TYPE_SAVE_DIALOG, + "gimp", gimp, + "title", _("Save Image"), + "role", "gimp-file-save", + "help-id", GIMP_HELP_FILE_SAVE, + "stock-id", GTK_STOCK_SAVE, + + "automatic-label", _("By Extension"), + "automatic-help-id", GIMP_HELP_FILE_SAVE_BY_EXTENSION, + + "action", GTK_FILE_CHOOSER_ACTION_SAVE, + "file-procs", gimp->plug_in_manager->save_procs, + "file-procs-all-images", gimp->plug_in_manager->export_procs, + "file-filter-label", _("All XCF images"), + "local-only", FALSE, + "do-overwrite-confirmation", TRUE, + NULL); + + return GTK_WIDGET (dialog); +} + +void +gimp_save_dialog_set_image (GimpSaveDialog *dialog, + Gimp *gimp, + GimpImage *image, + gboolean save_a_copy, + gboolean close_after_saving, + GimpObject *display) +{ + GFile *dir_file = NULL; + GFile *name_file = NULL; + GFile *ext_file = NULL; + gchar *basename; + const gchar *version_string; + gint rle_version; + gint zlib_version; + gchar *tooltip; + + g_return_if_fail (GIMP_IS_SAVE_DIALOG (dialog)); + g_return_if_fail (GIMP_IS_IMAGE (image)); + + GIMP_FILE_DIALOG (dialog)->image = image; + dialog->save_a_copy = save_a_copy; + dialog->close_after_saving = close_after_saving; + dialog->display_to_close = display; + + gimp_file_dialog_set_file_proc (GIMP_FILE_DIALOG (dialog), NULL); + + /* + * Priority of default paths for Save: + * + * 1. Last Save a copy-path (applies only to Save a copy) + * 2. Last Save path + * 3. Path of source XCF + * 4. Path of Import source + * 5. Last Save path of any GIMP document + * 6. The default path (usually the OS 'Documents' path) + */ + + if (save_a_copy) + dir_file = gimp_image_get_save_a_copy_file (image); + + if (! dir_file) + dir_file = gimp_image_get_file (image); + + if (! dir_file) + dir_file = g_object_get_data (G_OBJECT (image), + "gimp-image-source-file"); + + if (! dir_file) + dir_file = gimp_image_get_imported_file (image); + + if (! dir_file) + dir_file = g_object_get_data (G_OBJECT (gimp), + GIMP_FILE_SAVE_LAST_FILE_KEY); + + if (! dir_file) + dir_file = gimp_save_dialog_get_default_folder (gimp); + + + /* Priority of default basenames for Save: + * + * 1. Last Save a copy-name (applies only to Save a copy) + * 2. Last Save name + * 3. Last Export name + * 3. The source image path + * 3. 'Untitled' + */ + + if (save_a_copy) + name_file = gimp_image_get_save_a_copy_file (image); + + if (! name_file) + name_file = gimp_image_get_file (image); + + if (! name_file) + name_file = gimp_image_get_exported_file (image); + + if (! name_file) + name_file = gimp_image_get_imported_file (image); + + if (! name_file) + name_file = gimp_image_get_untitled_file (image); + + + /* Priority of default type/extension for Save: + * + * 1. Type of last Save + * 2. .xcf (which we don't explicitly append) + */ + ext_file = gimp_image_get_file (image); + + if (ext_file) + g_object_ref (ext_file); + else + ext_file = g_file_new_for_uri ("file:///we/only/care/about/extension.xcf"); + + gimp_image_get_xcf_version (image, FALSE, &rle_version, &version_string); + gimp_image_get_xcf_version (image, TRUE, &zlib_version, NULL); + + if (rle_version == zlib_version) + { + gtk_widget_set_sensitive (dialog->compat_toggle, FALSE); + + tooltip = g_strdup_printf (_("The image uses features from %s and " + "cannot be saved for older GIMP " + "versions."), + version_string); + } + else + { + gtk_widget_set_sensitive (dialog->compat_toggle, TRUE); + + tooltip = g_strdup_printf (_("Disables compression to make the XCF " + "file readable by %s and later."), + version_string); + } + + gimp_help_set_help_data (dialog->compat_toggle, tooltip, NULL); + g_free (tooltip); + + gtk_widget_show (dialog->compat_toggle); + + if (gtk_widget_get_sensitive (dialog->compat_toggle)) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->compat_toggle), + gimp_image_get_xcf_compat_mode (image)); + + if (ext_file) + { + GFile *tmp_file = file_utils_file_with_new_ext (name_file, ext_file); + basename = g_path_get_basename (gimp_file_get_utf8_name (tmp_file)); + g_object_unref (tmp_file); + g_object_unref (ext_file); + } + else + { + basename = g_path_get_basename (gimp_file_get_utf8_name (name_file)); + } + + if (g_file_query_file_type (dir_file, G_FILE_QUERY_INFO_NONE, NULL) == + G_FILE_TYPE_DIRECTORY) + { + gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), + dir_file, NULL); + } + else + { + GFile *parent_file = g_file_get_parent (dir_file); + gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), + parent_file, NULL); + g_object_unref (parent_file); + } + + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), basename); +} + +/* private functions */ + +static GFile * +gimp_save_dialog_get_default_folder (Gimp *gimp) +{ + if (gimp->default_folder) + { + return gimp->default_folder; + } + else + { + GFile *file = g_object_get_data (G_OBJECT (gimp), + "gimp-documents-folder"); + + if (! file) + { + gchar *path; + + /* Make sure it ends in '/' */ + path = g_build_path (G_DIR_SEPARATOR_S, + g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS), + G_DIR_SEPARATOR_S, + NULL); + + /* Paranoia fallback, see bug #722400 */ + if (! path) + path = g_build_path (G_DIR_SEPARATOR_S, + g_get_home_dir (), + G_DIR_SEPARATOR_S, + NULL); + + file = g_file_new_for_path (path); + g_free (path); + + g_object_set_data_full (G_OBJECT (gimp), "gimp-documents-folder", + file, (GDestroyNotify) g_object_unref); + } + + return file; + } +} + +static void +gimp_save_dialog_add_compat_toggle (GimpSaveDialog *dialog) +{ + dialog->compat_toggle = gtk_check_button_new_with_label (_("Save this XCF file with maximum compatibility")); + + gimp_file_dialog_add_extra_widget (GIMP_FILE_DIALOG (dialog), + dialog->compat_toggle, + FALSE, FALSE, 0); + + g_signal_connect (dialog->compat_toggle, "toggled", + G_CALLBACK (gimp_save_dialog_compat_toggled), + dialog); +} + +static void +gimp_save_dialog_compat_toggled (GtkToggleButton *button, + GimpSaveDialog *dialog) +{ + dialog->compat = gtk_toggle_button_get_active (button); +} diff --git a/app/widgets/gimpsavedialog.h b/app/widgets/gimpsavedialog.h new file mode 100644 index 0000000000..b043d78de6 --- /dev/null +++ b/app/widgets/gimpsavedialog.h @@ -0,0 +1,69 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpsavedialog.h + * Copyright (C) 2015 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_SAVE_DIALOG_H__ +#define __GIMP_SAVE_DIALOG_H__ + +#include "gimpfiledialog.h" + +G_BEGIN_DECLS + +#define GIMP_TYPE_SAVE_DIALOG (gimp_save_dialog_get_type ()) +#define GIMP_SAVE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SAVE_DIALOG, GimpSaveDialog)) +#define GIMP_SAVE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SAVE_DIALOG, GimpSaveDialogClass)) +#define GIMP_IS_SAVE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SAVE_DIALOG)) +#define GIMP_IS_SAVE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SAVE_DIALOG)) +#define GIMP_SAVE_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SAVE_DIALOG, GimpSaveDialogClass)) + + +typedef struct _GimpSaveDialogClass GimpSaveDialogClass; + +struct _GimpSaveDialog +{ + GimpFileDialog parent_instance; + + gboolean save_a_copy; + gboolean close_after_saving; + GimpObject *display_to_close; + + GtkWidget *compat_toggle; + gboolean compat; +}; + +struct _GimpSaveDialogClass +{ + GimpFileDialogClass parent_class; +}; + + +GType gimp_save_dialog_get_type (void) G_GNUC_CONST; + +GtkWidget * gimp_save_dialog_new (Gimp *gimp); + +void gimp_save_dialog_set_image (GimpSaveDialog *dialog, + Gimp *gimp, + GimpImage *image, + gboolean save_a_copy, + gboolean close_after_saving, + GimpObject *display); + +G_END_DECLS + +#endif /* __GIMP_SAVE_DIALOG_H__ */ diff --git a/app/widgets/widgets-enums.h b/app/widgets/widgets-enums.h index 068a477152..0bd7ead60d 100644 --- a/app/widgets/widgets-enums.h +++ b/app/widgets/widgets-enums.h @@ -295,13 +295,6 @@ typedef enum /*< skip >*/ GIMP_DEVICE_VALUE_GRADIENT = 1 << 8 } GimpDeviceValues; -typedef enum /*< skip >*/ -{ - GIMP_FILE_CHOOSER_ACTION_OPEN, - GIMP_FILE_CHOOSER_ACTION_SAVE, - GIMP_FILE_CHOOSER_ACTION_EXPORT -} GimpFileChooserAction; - typedef enum /*< skip >*/ { GIMP_DIALOGS_SHOWN, diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h index b037638184..79a3beebf6 100644 --- a/app/widgets/widgets-types.h +++ b/app/widgets/widgets-types.h @@ -129,12 +129,17 @@ typedef struct _GimpPlugInAction GimpPlugInAction; typedef struct _GimpStringAction GimpStringAction; typedef struct _GimpUIManager GimpUIManager; +/* file dialogs */ + +typedef struct _GimpExportDialog GimpExportDialog; +typedef struct _GimpFileDialog GimpFileDialog; +typedef struct _GimpOpenDialog GimpOpenDialog; +typedef struct _GimpSaveDialog GimpSaveDialog; /* misc dialogs */ typedef struct _GimpColorDialog GimpColorDialog; typedef struct _GimpErrorDialog GimpErrorDialog; -typedef struct _GimpFileDialog GimpFileDialog; typedef struct _GimpMessageDialog GimpMessageDialog; typedef struct _GimpProgressDialog GimpProgressDialog; typedef struct _GimpTextEditor GimpTextEditor; diff --git a/devel-docs/app/app-sections.txt b/devel-docs/app/app-sections.txt index 96b9a420fc..f044663ec7 100644 --- a/devel-docs/app/app-sections.txt +++ b/devel-docs/app/app-sections.txt @@ -13053,7 +13053,6 @@ GimpDeviceValues GimpDialogsState GimpDndType GimpDropType -GimpFileChooserAction GimpHistogramScale GimpTabStyle GimpTagEntryMode