1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 13:42:40 +02:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Jehan
9b20d97df3 app: add a "Scale Image for Export" feature in the export dialog.
Based on the previous refactoring work, we can provide on-export
specific features. This first feature allows user to resize images
on export without touching the original image.
2015-09-02 20:01:44 +02:00
Jehan
f3f78d2b2d app: GimpFileDialog state saving now implemented as a class method.
By default, it only saves the current file filter, but it allows a child
to implement its own state. It has been implemented by GimpSaveDialog to
save the preferred compatibility mode as well.
2015-09-02 20:00:48 +02:00
Jehan
6aafdeceff app: split GimpFileDialog into Gimp(Open|Save|Export)Dialog subclasses.
The code refactoring allows better readability which will allow in turn
to add more complex specific features making good use of the save/export
split concept.
2015-09-02 20:00:41 +02:00
21 changed files with 1894 additions and 688 deletions

View File

@@ -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,7 +599,7 @@ 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),
gimp_open_dialog_set_image (GIMP_OPEN_DIALOG (dialog),
image, open_as_layers);
gtk_window_set_transient_for (GTK_WINDOW (dialog),
@@ -649,8 +652,8 @@ 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,
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);

View File

@@ -65,6 +65,14 @@ struct _GimpImagePrivate
GFile *save_a_copy_file; /* the image's save-a-copy file */
GFile *untitled_file; /* a file saying "Untitled" */
gint export_width; /* width in pixels for export */
gint export_height; /* height in pixels for export */
GimpUnit export_unit; /* width/height display unit */
gdouble export_xresolution; /* x-res in ppi for export */
gdouble export_yresolution; /* y-res in ppi for export */
GimpUnit export_res_unit; /* resolution display unit */
GimpInterpolationType export_interpolation; /* interpolation for export */
gboolean xcf_compat_mode; /* if possible, save compat XCF */
gint dirty; /* dirty flag -- # of ops */

View File

@@ -2364,6 +2364,56 @@ gimp_image_get_xcf_version (GimpImage *image,
return version;
}
void
gimp_image_set_export_dimensions (GimpImage *image,
gint width,
gint height,
GimpUnit unit,
gdouble xresolution,
gdouble yresolution,
GimpUnit resolution_unit,
GimpInterpolationType interpolation)
{
GimpImagePrivate *private;
g_return_if_fail (GIMP_IS_IMAGE (image));
private = GIMP_IMAGE_GET_PRIVATE (image);
private->export_width = width;
private->export_height = height;
private->export_unit = unit;
private->export_xresolution = xresolution;
private->export_yresolution = yresolution;
private->export_res_unit = resolution_unit;
private->export_interpolation = interpolation;
}
void
gimp_image_get_export_dimensions (GimpImage *image,
gint *width,
gint *height,
GimpUnit *unit,
gdouble *xresolution,
gdouble *yresolution,
GimpUnit *resolution_unit,
GimpInterpolationType *interpolation)
{
GimpImagePrivate *private;
g_return_if_fail (GIMP_IS_IMAGE (image));
private = GIMP_IMAGE_GET_PRIVATE (image);
*width = private->export_width;
*height = private->export_height;
*unit = private->export_unit;
*xresolution = private->export_xresolution;
*yresolution = private->export_yresolution;
*resolution_unit = private->export_res_unit;
*interpolation = private->export_interpolation;
}
void
gimp_image_set_xcf_compat_mode (GimpImage *image,
gboolean compat_mode)

View File

@@ -171,6 +171,23 @@ gint gimp_image_get_xcf_version (GimpImage *image,
gint *gimp_version,
const gchar **version_string);
void gimp_image_set_export_dimensions (GimpImage *image,
gint width,
gint height,
GimpUnit unit,
gdouble xresolution,
gdouble yresolution,
GimpUnit resolution_unit,
GimpInterpolationType interpolation);
void gimp_image_get_export_dimensions (GimpImage *image,
gint *width,
gint *height,
GimpUnit *unit,
gdouble *xresolution,
gdouble *yresolution,
GimpUnit *resolution_unit,
GimpInterpolationType *interpolation);
void gimp_image_set_xcf_compat_mode (GimpImage *image,
gboolean compat_mode);
gboolean gimp_image_get_xcf_compat_mode (const GimpImage *image);

View File

@@ -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"
@@ -68,22 +69,15 @@ GtkWidget *
file_open_dialog_new (Gimp *gimp)
{
GtkWidget *dialog;
GimpFileDialogState *state;
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);
state = g_object_get_data (G_OBJECT (gimp), "gimp-file-open-dialog-state");
if (state)
gimp_file_dialog_set_state (GIMP_FILE_DIALOG (dialog), state);
gimp_file_dialog_load_state (GIMP_FILE_DIALOG (dialog),
"gimp-file-open-dialog-state");
g_signal_connect (dialog, "response",
G_CALLBACK (file_open_dialog_response),
@@ -105,9 +99,8 @@ file_open_dialog_response (GtkWidget *open_dialog,
GSList *list;
gboolean success = FALSE;
g_object_set_data_full (G_OBJECT (gimp), "gimp-file-open-dialog-state",
gimp_file_dialog_get_state (dialog),
(GDestroyNotify) gimp_file_dialog_state_destroy);
gimp_file_dialog_save_state (GIMP_FILE_DIALOG (dialog),
"gimp-file-open-dialog-state");
if (response_id != GTK_RESPONSE_OK)
{
@@ -132,27 +125,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 +174,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);
}

View File

@@ -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"
@@ -93,33 +94,23 @@ file_save_dialog_new (Gimp *gimp,
gboolean export)
{
GtkWidget *dialog;
GimpFileDialogState *state;
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);
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);
state = g_object_get_data (G_OBJECT (gimp), "gimp-file-export-dialog-state");
}
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
if (state)
gimp_file_dialog_set_state (GIMP_FILE_DIALOG (dialog), state);
if (! export)
{
dialog = gimp_save_dialog_new (gimp);
gimp_file_dialog_load_state (GIMP_FILE_DIALOG (dialog),
"gimp-file-save-dialog-state");
}
else
{
dialog = gimp_export_dialog_new (gimp);
gimp_file_dialog_load_state (GIMP_FILE_DIALOG (dialog),
"gimp-file-export-dialog-state");
}
g_signal_connect (dialog, "confirm-overwrite",
G_CALLBACK (file_save_dialog_confirm_overwrite),
@@ -160,17 +151,36 @@ 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);
gimp_file_dialog_save_state (dialog, "gimp-file-save-dialog-state");
}
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),
(GDestroyNotify) gimp_file_dialog_state_destroy);
GimpExportDialog *export_dialog = GIMP_EXPORT_DIALOG (dialog);
gint width = 0.0;
gint height = 0.0;
GimpUnit unit;
gdouble xresolution = 0.0;
gdouble yresolution = 0.0;
GimpUnit resolution_unit;
GimpInterpolationType interpolation;
gimp_file_dialog_save_state (dialog, "gimp-file-export-dialog-state");
gimp_export_dialog_get_dimensions (export_dialog,
&width,
&height,
&unit,
&xresolution,
&yresolution,
&resolution_unit,
&interpolation);
gimp_image_set_export_dimensions (dialog->image,
width, height, unit,
xresolution, yresolution,
resolution_unit,
interpolation);
}
if (response_id != GTK_RESPONSE_OK)
@@ -199,10 +209,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 +222,37 @@ file_save_dialog_response (GtkWidget *save_dialog,
* save. Lower-level URI management is handled in
* file_save()
*/
if (dialog->save_a_copy)
if (GIMP_IS_SAVE_DIALOG (dialog))
{
GimpSaveDialog *save_dialog = GIMP_SAVE_DIALOG (dialog);
if (save_dialog->save_a_copy)
gimp_image_set_save_a_copy_file (dialog->image, file);
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);
}
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);
}
/* 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 +343,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 +573,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 +600,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 +614,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 +646,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;

View File

@@ -34,6 +34,8 @@
#include "core/gimpdocumentlist.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpimage-duplicate.h"
#include "core/gimpimage-scale.h"
#include "core/gimpimagefile.h"
#include "core/gimpparamspecs.h"
#include "core/gimpprogress.h"
@@ -50,6 +52,9 @@
#include "gimp-intl.h"
static GimpImage * image_duplicate_for_export (GimpImage *image,
GimpProgress *progress);
/* public functions */
GimpPDBStatusType
@@ -64,6 +69,7 @@ file_save (Gimp *gimp,
gboolean export_forward,
GError **error)
{
GimpImage *export_image = NULL;
GimpDrawable *drawable;
GimpValueArray *return_vals;
GimpPDBStatusType status = GIMP_PDB_EXECUTION_ERROR;
@@ -90,7 +96,15 @@ file_save (Gimp *gimp,
g_object_ref (image);
g_object_ref (file);
if (export_forward || export_backward)
{
export_image = image_duplicate_for_export (image, progress);
drawable = gimp_image_get_active_drawable (image);
}
else
{
drawable = gimp_image_get_active_drawable (image);
}
if (! drawable)
goto out;
@@ -168,7 +182,7 @@ file_save (Gimp *gimp,
uri = g_file_get_uri (file);
image_ID = gimp_image_get_ID (image);
image_ID = gimp_image_get_ID (export_image ? export_image : image);
drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable));
return_vals =
@@ -289,6 +303,74 @@ file_save (Gimp *gimp,
g_free (path);
g_free (uri);
if (export_image)
g_object_unref (export_image);
return status;
}
/* private functions */
/*
* image_duplicate_scale:
*
* Returns: NULL if the export dimension are the same as the original,
* or a duplicate #GimpImage scaled to the new dimensions otherwise.
* The duplicate must be freed with g_object_unref(). */
static GimpImage *
image_duplicate_for_export (GimpImage *image,
GimpProgress *progress)
{
GimpImage *new_image = NULL;
/* Current resolution. */
gdouble current_xres;
gdouble current_yres;
/* All export dimensions. */
gint width;
gint height;
GimpUnit unit;
gdouble xresolution;
gdouble yresolution;
GimpUnit resolution_unit;
GimpInterpolationType interpolation;
/* Get current resolution. */
gimp_image_get_resolution (image, &current_xres, &current_yres);
/* Get export dimensions. */
gimp_image_get_export_dimensions (image,
&width,
&height,
&unit,
&xresolution,
&yresolution,
&resolution_unit,
&interpolation);
if (width > 0 && height > 0)
{
if (width != gimp_image_get_width (image) ||
height != gimp_image_get_height (image) ||
xresolution != current_xres ||
yresolution != current_yres ||
resolution_unit != gimp_image_get_unit (image))
{
new_image = gimp_image_duplicate (image);
gimp_image_set_resolution (new_image, xresolution, yresolution);
gimp_image_set_unit (new_image, resolution_unit);
if (width != gimp_image_get_width (image) ||
height != gimp_image_get_height (image))
{
gimp_image_scale (new_image, width, height, interpolation, progress);
}
}
}
else
{
g_warning ("Scale Error: "
"Both width and height must be greater than zero.");
}
return new_image;
}

View File

@@ -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 \

View File

@@ -0,0 +1,402 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpexportdialog.c
* Copyright (C) 2015 Jehan <jehan@girinstud.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
#include "core/gimp.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "config/gimpcoreconfig.h"
#include "display/display-types.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.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 "gimpsizebox.h"
#include "gimp-intl.h"
static void gimp_export_dialog_constructed (GObject *object);
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)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gimp_export_dialog_constructed;
}
static void
gimp_export_dialog_init (GimpExportDialog *dialog)
{
}
static void
gimp_export_dialog_constructed (GObject *object)
{
GimpExportDialog *dialog = GIMP_EXPORT_DIALOG (object);
GtkWidget *frame;
GtkWidget *hbox;
GtkWidget *label;
G_OBJECT_CLASS (parent_class)->constructed (object);
dialog->size_expander = gtk_expander_new_with_mnemonic (NULL);
gtk_expander_set_label (GTK_EXPANDER (dialog->size_expander),
_("Scale Image for Export"));
dialog->resize_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_add (GTK_CONTAINER (dialog->size_expander), dialog->resize_vbox);
frame = gimp_frame_new (_("Quality"));
gtk_box_pack_end (GTK_BOX (dialog->resize_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_container_add (GTK_CONTAINER (frame), hbox);
gtk_widget_show (hbox);
label = gtk_label_new_with_mnemonic (_("I_nterpolation:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
dialog->interpolation_combo = gimp_enum_combo_box_new (GIMP_TYPE_INTERPOLATION_TYPE);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->interpolation_combo);
gtk_box_pack_start (GTK_BOX (hbox), dialog->interpolation_combo, FALSE, FALSE, 0);
gtk_widget_show (dialog->interpolation_combo);
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (dialog->interpolation_combo),
GIMP_FILE_DIALOG (dialog)->gimp->config->interpolation_type);
gimp_file_dialog_add_extra_widget (GIMP_FILE_DIALOG (dialog),
dialog->size_expander,
FALSE, FALSE, 0);
gtk_widget_show (dialog->size_expander);
}
/* 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)
{
GimpContext *context = gimp_get_user_context (gimp);
GimpDisplay *display = gimp_context_get_display (context);
GFile *dir_file = NULL;
GFile *name_file = NULL;
GFile *ext_file = NULL;
gchar *basename;
gdouble xres, yres;
gint export_width;
gint export_height;
GimpUnit export_unit;
gdouble export_xres;
gdouble export_yres;
GimpUnit export_res_unit;
GimpInterpolationType export_interpolation;
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);
/* Extra feature for resize-on-export:
* I have to destroy and recreate the size box because current code does not
* behave well if I just reset properties to other values. */
if (dialog->size_box)
gtk_widget_destroy (dialog->size_box);
gimp_image_get_resolution (image, &xres, &yres);
dialog->size_box = g_object_new (GIMP_TYPE_SIZE_BOX,
"width", gimp_image_get_width (image),
"height", gimp_image_get_height (image),
"unit", (GimpUnit) gimp_display_get_shell (display)->unit,
"xresolution", xres,
"yresolution", yres,
"resolution-unit", gimp_image_get_unit (image),
"keep-aspect", TRUE,
"edit-resolution", TRUE,
NULL);
gimp_image_get_export_dimensions (image,
&export_width,
&export_height,
&export_unit,
&export_xres,
&export_yres,
&export_res_unit,
&export_interpolation);
if (export_width != 0 && export_height != 0 &&
export_xres != 0 && export_yres != 0 &&
(export_width != gimp_image_get_width (image) ||
export_height != gimp_image_get_height (image) ||
export_xres != xres || export_yres != yres ||
export_res_unit != gimp_image_get_unit (image)))
{
/* Some values have been previously set. Keep them! */
gimp_size_box_set_size (GIMP_SIZE_BOX (dialog->size_box),
export_width,
export_height,
export_unit);
gimp_size_box_set_resolution (GIMP_SIZE_BOX (dialog->size_box),
export_xres,
export_yres,
export_res_unit);
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (dialog->interpolation_combo),
export_interpolation);
gtk_expander_set_expanded (GTK_EXPANDER (dialog->size_expander),
TRUE);
}
else
{
gtk_expander_set_expanded (GTK_EXPANDER (dialog->size_expander),
FALSE);
}
gtk_box_pack_start (GTK_BOX (dialog->resize_vbox), dialog->size_box,
FALSE, FALSE, 0);
gtk_widget_show_all (dialog->resize_vbox);
}
void
gimp_export_dialog_get_dimensions (GimpExportDialog *dialog,
gint *width,
gint *height,
GimpUnit *unit,
gdouble *xresolution,
gdouble *yresolution,
GimpUnit *resolution_unit,
GimpInterpolationType *interpolation)
{
g_object_get (dialog->size_box,
"width", width,
"height", height,
"unit", unit,
"xresolution", xresolution,
"yresolution", yresolution,
"resolution-unit", resolution_unit,
NULL);
gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (dialog->interpolation_combo),
(gint *) interpolation);
}
/* 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;
}
}

View File

@@ -0,0 +1,72 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpexportdialog.h
* Copyright (C) 2015 Jehan <jehan@girinstud.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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;
GtkWidget *size_expander;
GtkWidget *resize_vbox;
GtkWidget *size_box;
GtkWidget *interpolation_combo;
};
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);
void gimp_export_dialog_get_dimensions (GimpExportDialog *dialog,
gint *width,
gint *height,
GimpUnit *unit,
gdouble *xresolution,
gdouble *yresolution,
GimpUnit *resolution_unit,
GimpInterpolationType *interpolation);
G_END_DECLS
#endif /* __GIMP_EXPORT_DIALOG_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -38,44 +38,48 @@ 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
{
GtkFileChooserDialogClass parent_class;
void (* save_state) (GimpFileDialog *dialog,
const gchar *state_name);
void (* load_state) (GimpFileDialog *dialog,
const gchar *state_name);
};
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);
@@ -83,21 +87,10 @@ void gimp_file_dialog_set_sensitive (GimpFileDialog *dialog,
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);
GimpFileDialogState * gimp_file_dialog_get_state (GimpFileDialog *dialog);
void gimp_file_dialog_set_state (GimpFileDialog *dialog,
GimpFileDialogState *state);
void gimp_file_dialog_state_destroy (GimpFileDialogState *state);
void gimp_file_dialog_save_state (GimpFileDialog *dialog,
const gchar *state_name);
void gimp_file_dialog_load_state (GimpFileDialog *dialog,
const gchar *state_name);
G_END_DECLS

View File

@@ -0,0 +1,104 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpopendialog.c
* Copyright (C) 2015 Jehan <jehan@girinstud.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#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 */

View File

@@ -0,0 +1,59 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpopendialog.h
* Copyright (C) 2015 Jehan <jehan@girinstud.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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__ */

View File

@@ -0,0 +1,446 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpsavedialog.c
* Copyright (C) 2015 Jehan <jehan@girinstud.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#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"
typedef struct _GimpSaveDialogState GimpSaveDialogState;
struct _GimpSaveDialogState
{
gchar *filter_name;
gboolean compat;
};
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);
static GimpSaveDialogState
* gimp_save_dialog_get_state (GimpSaveDialog *dialog);
static void gimp_save_dialog_set_state (GimpSaveDialog *dialog,
GimpSaveDialogState *state);
static void gimp_save_dialog_state_destroy (GimpSaveDialogState *state);
static void gimp_save_dialog_real_save_state (GimpFileDialog *dialog,
const gchar *state_name);
static void gimp_save_dialog_real_load_state (GimpFileDialog *dialog,
const gchar *state_name);
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);
GimpFileDialogClass *fd_class = GIMP_FILE_DIALOG_CLASS (klass);
object_class->constructed = gimp_save_dialog_constructed;
fd_class->save_state = gimp_save_dialog_real_save_state;
fd_class->load_state = gimp_save_dialog_real_load_state;
}
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);
/* We set the compatibility mode by default either if the image was
* previously saved with the compatibility mode, or if it has never been
* saved and the last GimpSaveDialogState had compatibility mode ON. */
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->compat_toggle),
gtk_widget_get_sensitive (dialog->compat_toggle) &&
(gimp_image_get_xcf_compat_mode (image) ||
(! gimp_image_get_file (image) && dialog->compat)));
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);
}
static GimpSaveDialogState *
gimp_save_dialog_get_state (GimpSaveDialog *dialog)
{
GimpSaveDialogState *state;
GtkFileFilter *filter;
g_return_val_if_fail (GIMP_IS_SAVE_DIALOG (dialog), NULL);
state = g_slice_new0 (GimpSaveDialogState);
filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog));
if (filter)
state->filter_name = g_strdup (gtk_file_filter_get_name (filter));
state->compat = dialog->compat;
return state;
}
static void
gimp_save_dialog_set_state (GimpSaveDialog *dialog,
GimpSaveDialogState *state)
{
g_return_if_fail (GIMP_IS_SAVE_DIALOG (dialog));
g_return_if_fail (state != NULL);
if (state->filter_name)
{
GSList *filters;
GSList *list;
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (dialog));
for (list = filters; list; list = list->next)
{
GtkFileFilter *filter = GTK_FILE_FILTER (list->data);
const gchar *name = gtk_file_filter_get_name (filter);
if (name && strcmp (state->filter_name, name) == 0)
{
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
break;
}
}
g_slist_free (filters);
}
dialog->compat = state->compat;
}
static void
gimp_save_dialog_state_destroy (GimpSaveDialogState *state)
{
g_return_if_fail (state != NULL);
g_free (state->filter_name);
g_slice_free (GimpSaveDialogState, state);
}
static void
gimp_save_dialog_real_save_state (GimpFileDialog *dialog,
const gchar *state_name)
{
g_return_if_fail (GIMP_IS_SAVE_DIALOG (dialog));
g_object_set_data_full (G_OBJECT (dialog->gimp), state_name,
gimp_save_dialog_get_state (GIMP_SAVE_DIALOG (dialog)),
(GDestroyNotify) gimp_save_dialog_state_destroy);
}
static void
gimp_save_dialog_real_load_state (GimpFileDialog *dialog,
const gchar *state_name)
{
GimpSaveDialogState *state;
g_return_if_fail (GIMP_IS_SAVE_DIALOG (dialog));
state = g_object_get_data (G_OBJECT (dialog->gimp), state_name);
if (state)
gimp_save_dialog_set_state (GIMP_SAVE_DIALOG (dialog), state);
}

View File

@@ -0,0 +1,69 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpsavedialog.h
* Copyright (C) 2015 Jehan <jehan@girinstud.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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__ */

View File

@@ -61,7 +61,9 @@ typedef struct _GimpSizeBoxPrivate GimpSizeBoxPrivate;
struct _GimpSizeBoxPrivate
{
GimpSizeEntry *size_entry;
GimpSizeEntry *resolution_entry;
GimpChainButton *size_chain;
GimpChainButton *resolution_chain;
GtkWidget *pixel_label;
GtkWidget *res_label;
};
@@ -263,7 +265,8 @@ gimp_size_box_constructed (GObject *object)
_("_Y resolution:"),
box->yresolution, 1.0,
1, 1, 1, 10);
priv->resolution_entry = GIMP_SIZE_ENTRY (entry);
priv->resolution_chain = GIMP_COORDINATES_CHAINBUTTON (GIMP_SIZE_ENTRY (entry));
gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
gtk_widget_show (entry);
@@ -422,6 +425,66 @@ gimp_size_box_get_property (GObject *object,
}
}
/**
* gimp_size_box_set_size:
* @width: width in pixels.
* @height: height in pixels.
* @unit: #GimpUnit for @width and @height display.
*
* Sets the value for width and height. These are different from the
* initial values set through properties (which determined the ratio
* and "100%" values for instance).
*/
void
gimp_size_box_set_size (GimpSizeBox *box,
gint width,
gint height,
GimpUnit unit)
{
GimpSizeBoxPrivate *priv = GIMP_SIZE_BOX_GET_PRIVATE (box);
/* gimp_size_entry_set_value() depends on the unit. So I set
* the pixel unit first since I always want to work with pixels. */
gimp_size_entry_set_unit (priv->size_entry, GIMP_UNIT_PIXEL);
gimp_size_entry_set_value (priv->size_entry, 0, width);
if (gimp_size_entry_get_value (priv->size_entry, 1) != height)
{
gimp_chain_button_set_active (priv->size_chain,
FALSE);
gimp_size_entry_set_value (priv->size_entry, 1, height);
}
gimp_size_entry_set_unit (priv->size_entry, unit);
}
/**
* gimp_size_box_set_resolution:
* @xres: X-resolution in ppi.
* @yres: Y-resolution in ppi.
* @unit: #GimpUnit for @xres and @xres display.
*
* Sets the resolution.
*/
void
gimp_size_box_set_resolution (GimpSizeBox *box,
gdouble xres,
gdouble yres,
GimpUnit unit)
{
GimpSizeBoxPrivate *priv = GIMP_SIZE_BOX_GET_PRIVATE (box);
g_return_if_fail (box->edit_resolution);
gimp_size_entry_set_unit (priv->resolution_entry, GIMP_UNIT_INCH);
gimp_size_entry_set_value (priv->resolution_entry, 0, xres);
if (gimp_size_entry_get_value (priv->resolution_entry, 1) != yres)
{
gimp_chain_button_set_active (priv->resolution_chain,
FALSE);
gimp_size_entry_set_value (priv->resolution_entry, 1, yres);
}
gimp_size_entry_set_unit (priv->resolution_entry, unit);
}
static void
gimp_size_box_update_size (GimpSizeBox *box)
{

View File

@@ -58,6 +58,14 @@ struct _GimpSizeBoxClass
GType gimp_size_box_get_type (void) G_GNUC_CONST;
void gimp_size_box_set_size (GimpSizeBox *box,
gint width,
gint height,
GimpUnit unit);
void gimp_size_box_set_resolution (GimpSizeBox *box,
gdouble xres,
gdouble yres,
GimpUnit unit);
G_END_DECLS

View File

@@ -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,

View File

@@ -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;

View File

@@ -13053,7 +13053,6 @@ GimpDeviceValues
GimpDialogsState
GimpDndType
GimpDropType
GimpFileChooserAction
GimpHistogramScale
GimpTabStyle
GimpTagEntryMode