[Rawstudio-commit] r2210 - trunk/src
Anders Brander
anders at brander.dk
Sun Feb 22 17:23:10 CET 2009
Author: abrander
Date: 2009-02-22 17:23:10 +0100 (Sun, 22 Feb 2009)
New Revision: 2210
Added:
trunk/src/rs-save-dialog.c
trunk/src/rs-save-dialog.h
Removed:
trunk/src/gtk-save-dialog.c
trunk/src/gtk-save-dialog.h
Modified:
trunk/src/Makefile.am
trunk/src/application.c
trunk/src/gtk-interface.c
trunk/src/rs-actions.c
Log:
Refactored save-dialog and ported it to RSOutput.
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2009-02-22 16:06:59 UTC (rev 2209)
+++ trunk/src/Makefile.am 2009-02-22 16:23:10 UTC (rev 2210)
@@ -30,7 +30,7 @@
rs-preload.c rs-preload.h \
gtk-helper.c gtk-helper.h \
gtk-interface.c gtk-interface.h \
- gtk-save-dialog.c gtk-save-dialog.h \
+ rs-save-dialog.c rs-save-dialog.h \
gtk-progress.c gtk-progress.h \
conf_interface.c conf_interface.h \
rs-cms.c rs-cms.h \
Modified: trunk/src/application.c
===================================================================
--- trunk/src/application.c 2009-02-22 16:06:59 UTC (rev 2209)
+++ trunk/src/application.c 2009-02-22 16:23:10 UTC (rev 2210)
@@ -31,7 +31,6 @@
#include "gettext.h"
#include "conf_interface.h"
#include "filename.h"
-#include "rs-jpeg.h"
#include "rs-tiff.h"
#include "rs-arch.h"
#include "rs-batch.h"
@@ -210,6 +209,7 @@
void *transform = NULL;
RS_EXIF_DATA *exif;
gfloat actual_scale;
+ RSOutput *output;
g_assert(RS_IS_PHOTO(photo));
g_assert(filename != NULL);
@@ -255,14 +255,23 @@
else if (quality < 0)
quality = 0;
- rs_jpeg_save(pixbuf, filename, quality, rs_cms_get_profile_filename(cms, CMS_PROFILE_EXPORT));
+ output = rs_output_new("RSJpegfile");
+ g_object_set(output, "filename", filename, "quality", quality, NULL);
+ rs_output_execute(output, pixbuf);
+
+ g_object_unref(output);
g_object_unref(pixbuf);
break;
case FILETYPE_PNG:
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, rsi->w, rsi->h);
rs_color_transform_transform(rct, rsi->w, rsi->h, rsi->pixels, rsi->rowstride,
gdk_pixbuf_get_pixels(pixbuf), gdk_pixbuf_get_rowstride(pixbuf));
- gdk_pixbuf_save(pixbuf, filename, "png", NULL, NULL);
+
+ output = rs_output_new("RSPngfile");
+ g_object_set(output, "filename", filename, NULL);
+ rs_output_execute(output, pixbuf);
+
+ g_object_unref(output);
g_object_unref(pixbuf);
break;
case FILETYPE_TIFF8:
@@ -270,7 +279,12 @@
rs_conf_get_boolean(CONF_EXPORT_TIFF_UNCOMPRESSED, &uncompressed_tiff);
rs_color_transform_transform(rct, rsi->w, rsi->h, rsi->pixels,
rsi->rowstride, gdk_pixbuf_get_pixels(pixbuf), gdk_pixbuf_get_rowstride(pixbuf));
- rs_tiff8_save(pixbuf, filename, rs_cms_get_profile_filename(cms, CMS_PROFILE_EXPORT), uncompressed_tiff);
+
+ output = rs_output_new("RSTifffile");
+ g_object_set(output, "filename", filename, "uncompressed", uncompressed_tiff, NULL);
+ rs_output_execute(output, pixbuf);
+
+ g_object_unref(output);
g_object_unref(pixbuf);
break;
case FILETYPE_TIFF16:
@@ -280,6 +294,7 @@
rs_color_transform_transform(rct, rsi->w, rsi->h,
rsi->pixels, rsi->rowstride,
image16->pixels, image16->rowstride*2);
+ g_warning("Port to RSOutput");
rs_tiff16_save(image16, filename, rs_cms_get_profile_filename(cms, CMS_PROFILE_EXPORT), uncompressed_tiff);
rs_image16_free(image16);
break;
Modified: trunk/src/gtk-interface.c
===================================================================
--- trunk/src/gtk-interface.c 2009-02-22 16:06:59 UTC (rev 2209)
+++ trunk/src/gtk-interface.c 2009-02-22 16:23:10 UTC (rev 2210)
@@ -25,7 +25,6 @@
#include "application.h"
#include "gtk-helper.h"
#include "gtk-interface.h"
-#include "gtk-save-dialog.h"
#include "gtk-progress.h"
#include "toolbox.h"
#include "conf_interface.h"
Deleted: trunk/src/gtk-save-dialog.c
===================================================================
--- trunk/src/gtk-save-dialog.c 2009-02-22 16:06:59 UTC (rev 2209)
+++ trunk/src/gtk-save-dialog.c 2009-02-22 16:23:10 UTC (rev 2210)
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Anders Brander <anders at brander.dk> and
- * Anders Kvist <akv at lnxbx.dk>
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <gtk/gtk.h>
-#include <config.h>
-#include "application.h"
-#include "gettext.h"
-#include "gtk-interface.h"
-#include "gtk-save-dialog.h"
-#include "gtk-helper.h"
-#include "conf_interface.h"
-#include "rs-cms.h"
-#include <gettext.h>
-#include <config.h>
-
-static RS_FILETYPE *filetype;
-static GtkWidget *fc;
-static GtkWidget *jpeg_pref;
-static GtkWidget *tiff_pref;
-static GtkWidget *size_pref;
-
-static void
-filetype_changed(gpointer active, gpointer user_data)
-{
- gchar *filename, *newfilename;
- gint n, lastdot=0;
-
- filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
- filetype = (RS_FILETYPE *) active;
-
- if (filename)
- {
- newfilename = g_path_get_basename(filename);
- g_free(filename);
- filename = newfilename;
-
- /* find extension */
- n = 0;
- while (filename[n])
- {
- if (filename[n]=='.')
- lastdot = n;
- n++;
- }
- if (lastdot != 0)
- filename[lastdot] = '\0';
-
- newfilename = g_strconcat(filename, filetype->ext, NULL);
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc), newfilename);
-
- g_free(filename);
- }
-
- /* show relevant preferences */
- gtk_widget_hide(jpeg_pref);
- gtk_widget_hide(tiff_pref);
- switch (filetype->filetype)
- {
- case FILETYPE_JPEG:
- gtk_widget_show(jpeg_pref);
- break;
- case FILETYPE_TIFF8:
- case FILETYPE_TIFF16:
- gtk_widget_show(tiff_pref);
- break;
- }
- return;
-}
-
-static void
-jpeg_quality_changed(GtkAdjustment *adjustment, gpointer user_data)
-{
- rs_conf_set_integer(CONF_EXPORT_JPEG_QUALITY, (gint) gtk_adjustment_get_value(adjustment));
- return;
-}
-
-static GtkWidget *
-jpeg_pref_new(void)
-{
- GtkObject *jpeg_quality_adj;
- GtkWidget *jpeg_quality_label;
- GtkWidget *jpeg_quality_scale;
- GtkWidget *jpeg_quality_spin;
- GtkWidget *box;
- gint jpeg_quality=100;
-
- rs_conf_get_integer(CONF_EXPORT_JPEG_QUALITY, &jpeg_quality);
-
- jpeg_quality_adj = gtk_adjustment_new((gdouble) jpeg_quality, 10.0, 100.0, 1.0, 10.0, 0.0);
- g_signal_connect((gpointer) jpeg_quality_adj, "value-changed", G_CALLBACK(jpeg_quality_changed), NULL);
- jpeg_quality_label = gtk_label_new(_("JPEG Quality:"));
- jpeg_quality_scale = gtk_hscale_new(GTK_ADJUSTMENT(jpeg_quality_adj));
- gtk_scale_set_draw_value(GTK_SCALE(jpeg_quality_scale), FALSE);
- jpeg_quality_spin = gtk_spin_button_new(GTK_ADJUSTMENT(jpeg_quality_adj), 1.0, 0);
-
- box = gtk_hbox_new(FALSE, 2);
- gtk_box_pack_start (GTK_BOX (box), jpeg_quality_label, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (box), jpeg_quality_scale, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (box), jpeg_quality_spin, FALSE, TRUE, 0);
-
- return(box);
-}
-
-static GtkWidget *
-tiff_pref_new(void)
-{
- GtkWidget *tiff_uncompressed_checkbox;
- tiff_uncompressed_checkbox = checkbox_from_conf(
- CONF_EXPORT_TIFF_UNCOMPRESSED, _("Save uncompressed TIFF"), FALSE);
- return(tiff_uncompressed_checkbox);
-}
-
-static gdouble w_original;
-static gdouble h_original;
-static gboolean keep_aspect = TRUE;
-static GtkSpinButton *w_spin;
-static GtkSpinButton *h_spin;
-static GtkSpinButton *p_spin;
-static gulong w_signal;
-static gulong h_signal;
-
-static void
-size_pref_w_changed(GtkSpinButton *spinbutton, gpointer user_data)
-{
- double ratio;
- if (keep_aspect)
- {
- g_signal_handler_block(h_spin, h_signal);
- ratio = gtk_spin_button_get_value(spinbutton)/w_original;
- gtk_spin_button_set_value(h_spin, h_original*ratio);
- g_signal_handler_unblock(h_spin, h_signal);
- }
- return;
-}
-
-static void
-size_pref_h_changed(GtkSpinButton *spinbutton, gpointer user_data)
-{
- double ratio;
- if (keep_aspect)
- {
- g_signal_handler_block(w_spin, w_signal);
- ratio = gtk_spin_button_get_value(spinbutton)/h_original;
- gtk_spin_button_set_value(w_spin, w_original*ratio);
- g_signal_handler_unblock(w_spin, w_signal);
- }
- return;
-}
-
-static void
-size_pref_p_changed(GtkSpinButton *spinbutton, gpointer user_data)
-{
- double ratio;
- g_signal_handler_block(w_spin, w_signal);
- g_signal_handler_block(h_spin, h_signal);
- ratio = gtk_spin_button_get_value(spinbutton)/100.0;
- gtk_spin_button_set_value(w_spin, w_original*ratio);
- gtk_spin_button_set_value(h_spin, h_original*ratio);
- g_signal_handler_unblock(w_spin, w_signal);
- g_signal_handler_unblock(h_spin, h_signal);
- return;
-}
-
-static void
-size_pref_aspect_changed(GtkToggleButton *togglebutton, gpointer user_data)
-{
- keep_aspect = togglebutton->active;
- if (keep_aspect)
- {
- gtk_spin_button_set_value(w_spin, w_original);
- gtk_spin_button_set_value(h_spin, h_original);
- gtk_spin_button_set_value(p_spin, 100.0);
- }
- return;
-}
-
-static void
-spin_set_value(GtkSpinButton *spinbutton, gpointer user_data)
-{
- gint *value = (gint *) user_data;
- *value = gtk_spin_button_get_value_as_int(spinbutton);
- return;
-}
-
-static GtkWidget *
-size_pref_new(RS_PHOTO *photo, gint *w, gint *h)
-{
- GtkWidget *vbox, *hbox;
- GtkWidget *checkbox;
- w_original = *w;
- h_original = *h;
-
- checkbox = gtk_check_button_new_with_label(_("Keep aspect"));
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox),
- keep_aspect);
- g_signal_connect ((gpointer) checkbox, "toggled",
- G_CALLBACK (size_pref_aspect_changed), NULL);
-
- w_spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0, 65535.0, 1.0));
- h_spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0, 65535.0, 1.0));
- p_spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0, 200.0, 1.0));
- gtk_spin_button_set_value(w_spin, (gdouble) *w);
- gtk_spin_button_set_value(h_spin, (gdouble) *h);
- gtk_spin_button_set_value(p_spin, 100.0);
- w_signal = g_signal_connect(G_OBJECT(w_spin), "value_changed",
- G_CALLBACK(size_pref_w_changed), NULL);
- h_signal = g_signal_connect(G_OBJECT(h_spin), "value_changed",
- G_CALLBACK(size_pref_h_changed), NULL);
- g_signal_connect(G_OBJECT(p_spin), "value_changed",
- G_CALLBACK(size_pref_p_changed), NULL);
-
- g_signal_connect(G_OBJECT(w_spin), "value_changed",
- G_CALLBACK(spin_set_value), w);
- g_signal_connect(G_OBJECT(h_spin), "value_changed",
- G_CALLBACK(spin_set_value), h);
-
- hbox = gtk_hbox_new(FALSE, 3);
- gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new_with_mnemonic(_("Width:")), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(w_spin), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new_with_mnemonic(_("Height:")), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(h_spin), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new_with_mnemonic(_("Percent:")), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(p_spin), FALSE, TRUE, 0);
-
- vbox = gtk_vbox_new(FALSE, 3);
- gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(checkbox), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(hbox), FALSE, TRUE, 0);
- return(vbox);
-}
-
-void
-gui_save_file_dialog(RS_BLOB *rs)
-{
- GString *name;
- gchar *dirname;
- gchar *basename;
- GString *export_path;
- gchar *conf_export;
- RS_CONFBOX *filetype_confbox;
- GtkWidget *prefbox;
- gint w=1,h=1;
- guint msgid;
-
- if (!rs->photo) return;
-
- gui_set_busy(TRUE);
- GUI_CATCHUP();
-
- fc = gtk_file_chooser_dialog_new (_("Export File"), NULL,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
-
- /* make preference box */
- prefbox = gtk_vbox_new(FALSE, 4);
- jpeg_pref = jpeg_pref_new();
- tiff_pref = tiff_pref_new();
- rs_image16_transform_getwh(rs->photo->input, rs->photo->crop, rs->photo->angle, rs->photo->orientation, &w, &h);
- size_pref = size_pref_new(rs->photo, &w, &h);
- filetype_confbox = gui_confbox_filetype_new(CONF_SAVE_FILETYPE);
- gui_confbox_set_callback(filetype_confbox, NULL, filetype_changed);
- filetype = gui_confbox_get_active(filetype_confbox);
- gtk_box_pack_start (GTK_BOX (prefbox), gtk_hseparator_new(), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (prefbox), gui_confbox_get_widget(filetype_confbox), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (prefbox), jpeg_pref, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (prefbox), tiff_pref, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (prefbox), gtk_hseparator_new(), FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (prefbox), size_pref, FALSE, TRUE, 0);
- gtk_widget_show_all(prefbox);
- gtk_widget_hide(jpeg_pref);
- gtk_widget_hide(tiff_pref);
-
- if (g_str_equal(filetype->ext, ".jpg"))
- gtk_widget_show(jpeg_pref);
- else if (g_str_equal(filetype->ext, ".tif"))
- gtk_widget_show(tiff_pref);
-
- dirname = g_path_get_dirname(rs->photo->filename);
- basename = g_path_get_basename(rs->photo->filename);
-
- conf_export = rs_conf_get_string(CONF_DEFAULT_EXPORT_TEMPLATE);
-
- if (conf_export)
- {
- if (conf_export[0]==G_DIR_SEPARATOR)
- {
- g_free(dirname);
- dirname = conf_export;
- }
- else
- {
- export_path = g_string_new(dirname);
- g_string_append(export_path, G_DIR_SEPARATOR_S);
- g_string_append(export_path, conf_export);
- g_free(dirname);
- dirname = export_path->str;
- g_string_free(export_path, FALSE);
- g_free(conf_export);
- }
- g_mkdir_with_parents(dirname, 00755);
- }
-
- msgid = gui_status_push(_("Exporting file ..."));
-
- name = g_string_new(basename);
- g_string_append(name, filetype->ext);
-
- gtk_dialog_set_default_response(GTK_DIALOG(fc), GTK_RESPONSE_ACCEPT);
-#if GTK_CHECK_VERSION(2,8,0)
- gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE);
-#endif
- if (g_file_test(dirname, G_FILE_TEST_IS_DIR))
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fc), dirname);
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc), name->str);
- gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER (fc), prefbox);
- if (gtk_dialog_run (GTK_DIALOG (fc)) == GTK_RESPONSE_ACCEPT)
- {
- char *filename;
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fc));
- rs_photo_save(rs->photo, filename, filetype->filetype, w, h, FALSE, -1.0, rs->current_setting, rs->cms);
-
- rs_conf_set_filetype(CONF_SAVE_FILETYPE, filetype);
-
- gtk_widget_destroy(fc);
- g_free (filename);
- gui_status_pop(msgid);
- gui_status_notify(_("File exported"));
- }
- else
- {
- gtk_widget_destroy(fc);
- gui_status_pop(msgid);
- gui_status_notify(_("File export canceled"));
- }
- g_free(dirname);
- g_free(basename);
- g_string_free(name, TRUE);
- gui_set_busy(FALSE);
- return;
-}
Deleted: trunk/src/gtk-save-dialog.h
===================================================================
--- trunk/src/gtk-save-dialog.h 2009-02-22 16:06:59 UTC (rev 2209)
+++ trunk/src/gtk-save-dialog.h 2009-02-22 16:23:10 UTC (rev 2210)
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Anders Brander <anders at brander.dk> and
- * Anders Kvist <akv at lnxbx.dk>
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef GTK_SAVE_DIALOG_H
-#define GTK_SAVE_DIALOG_H
-
-extern void gui_save_file_dialog(RS_BLOB *rs);
-
-#endif /* GTK_SAVE_DIALOG_H */
Modified: trunk/src/rs-actions.c
===================================================================
--- trunk/src/rs-actions.c 2009-02-22 16:06:59 UTC (rev 2209)
+++ trunk/src/rs-actions.c 2009-02-22 16:23:10 UTC (rev 2210)
@@ -29,13 +29,13 @@
#include "rs-photo.h"
#include "filename.h"
#include "gtk-interface.h"
-#include "gtk-save-dialog.h"
#include "gtk-progress.h"
#include "gtk-helper.h"
#include "rs-external-editor.h"
#include "rs-cache.h"
#include "rs-preview-widget.h"
#include "rs-batch.h"
+#include "rs-save-dialog.h"
static GtkActionGroup *core_action_group = NULL;
GStaticMutex rs_actions_spinlock = G_STATIC_MUTEX_INIT;
@@ -223,7 +223,9 @@
ACTION(export_as)
{
- gui_save_file_dialog(rs);
+ RSSaveDialog *dialog = rs_save_dialog_new();
+ rs_save_dialog_set_photo(dialog, rs->photo, rs->current_setting);
+ gtk_widget_show_all(GTK_WIDGET(dialog));
}
ACTION(export_to_gimp)
Added: trunk/src/rs-save-dialog.c
===================================================================
--- trunk/src/rs-save-dialog.c (rev 0)
+++ trunk/src/rs-save-dialog.c 2009-02-22 16:23:10 UTC (rev 2210)
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2006-2009 Anders Brander <anders at brander.dk> and
+ * Anders Kvist <akv at lnxbx.dk>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <config.h>
+#include <gettext.h>
+#include "application.h"
+#include "gtk-helper.h"
+#include "rs-save-dialog.h"
+#include "rs-photo.h"
+
+G_DEFINE_TYPE (RSSaveDialog, rs_save_dialog, GTK_TYPE_WINDOW)
+
+static void file_type_changed(gpointer active, gpointer user_data);
+static void save_clicked(GtkButton *button, gpointer user_data);
+static void cancel_clicked(GtkButton *button, gpointer user_data);
+static GtkWidget *size_pref_new(RSSaveDialog *dialog);
+
+static void
+rs_save_dialog_dispose (GObject *object)
+{
+ RSSaveDialog *dialog = RS_SAVE_DIALOG(object);
+
+ if (!dialog->dispose_has_run)
+ {
+ if (dialog->output)
+ {
+ g_assert(G_IS_OBJECT(dialog->output));
+ g_object_unref(dialog->output);
+ }
+
+ gui_confbox_destroy(dialog->type_box);
+
+ g_object_unref(dialog->filter_input);
+ g_object_unref(dialog->filter_demosaic);
+ g_object_unref(dialog->filter_rotate);
+ g_object_unref(dialog->filter_crop);
+ g_object_unref(dialog->filter_resample);
+ g_object_unref(dialog->filter_sharpen);
+
+ if (dialog->photo)
+ g_object_unref(dialog->photo);
+
+ dialog->dispose_has_run = TRUE;
+
+ /* Chain up */
+ G_OBJECT_CLASS (rs_save_dialog_parent_class)->dispose (object);
+ }
+}
+
+static void
+rs_save_dialog_class_init (RSSaveDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = rs_save_dialog_dispose;
+}
+
+static void
+rs_save_dialog_init (RSSaveDialog *dialog)
+{
+ GtkWindow *window = GTK_WINDOW(dialog);
+ GtkWidget *button_box;
+ GType *savers;
+ guint n_savers = 0, i;
+ GtkWidget *button_save = gtk_button_new_from_stock(GTK_STOCK_SAVE);
+ GtkWidget *button_cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+
+ g_signal_connect(button_save, "clicked", G_CALLBACK(save_clicked), dialog);
+ g_signal_connect(button_cancel, "clicked", G_CALLBACK(cancel_clicked), dialog);
+
+ gtk_window_set_type_hint(window, GDK_WINDOW_TYPE_HINT_DIALOG);
+ gtk_window_set_position(window, GTK_WIN_POS_CENTER_ON_PARENT);
+ gtk_window_resize(window, 750, 550); /* FIXME: Calculate some sensible size - maybe even remember user resizes */
+ gtk_window_set_title (window, _("Export File"));
+
+ dialog->dispose_has_run = FALSE;
+ dialog->output = NULL;
+ dialog->file_pref = NULL;
+ dialog->w_original = 666;
+ dialog->h_original = 666;
+ dialog->keep_aspect = TRUE;
+
+ dialog->vbox = gtk_vbox_new(FALSE, 0);
+ dialog->chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_SAVE);
+ dialog->type_box = gui_confbox_new((const gchar *) "DELME-filetype");
+ dialog->pref_bin = gtk_alignment_new(0.0, 0.5, 1.0, 1.0);
+
+ button_box = gtk_hbutton_box_new();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END);
+ gtk_container_add (GTK_CONTAINER(button_box), button_cancel);
+ gtk_container_add (GTK_CONTAINER(button_box), button_save);
+
+ /* Try to mimic a real GtkSaveDialog */
+ gtk_container_set_border_width(GTK_CONTAINER(window), 5);
+ gtk_container_set_border_width(GTK_CONTAINER(dialog->vbox), 2);
+ gtk_box_set_spacing(GTK_BOX(dialog->vbox), 2);
+ gtk_container_set_border_width(GTK_CONTAINER(dialog->chooser), 5);
+ gtk_container_set_border_width(GTK_CONTAINER(button_box), 5);
+ gtk_box_set_spacing(GTK_BOX(button_box), 6);
+ gtk_container_set_border_width(GTK_CONTAINER(dialog->pref_bin), 5);
+
+ /* Pack everything nicely */
+ gtk_container_add(GTK_CONTAINER(window), dialog->vbox);
+ gtk_box_pack_start(GTK_BOX(dialog->vbox), dialog->chooser, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(dialog->vbox), gui_confbox_get_widget(dialog->type_box), FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(dialog->vbox), dialog->pref_bin, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(dialog->vbox), size_pref_new(dialog), FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(dialog->vbox), button_box, FALSE, TRUE, 0);
+
+ /* Set default action */
+ GTK_WIDGET_SET_FLAGS(button_save, GTK_CAN_DEFAULT);
+ gtk_window_set_default(window, button_save);
+
+ gui_confbox_set_callback(dialog->type_box, dialog, file_type_changed);
+ savers = g_type_children (RS_TYPE_OUTPUT, &n_savers);
+ for (i = 0; i < n_savers; i++)
+ {
+ RSOutputClass *klass;
+ gchar *name = g_strdup(g_type_name(savers[i]));
+ klass = g_type_class_ref(savers[i]);
+ gui_confbox_add_entry(dialog->type_box, name, klass->display_name, GINT_TO_POINTER(savers[i]));
+ g_type_class_unref(klass);
+ }
+ g_free(savers);
+
+ /* Load default fromconf, or use RSJpegfile */
+ gui_confbox_load_conf(dialog->type_box, "RSJpegfile");
+
+ /* Setup our filter chain for saving */
+ dialog->filter_input = rs_filter_new("RSInputImage16", NULL);
+ dialog->filter_demosaic = rs_filter_new("RSDemosaic", dialog->filter_input);
+ dialog->filter_rotate = rs_filter_new("RSRotate", dialog->filter_demosaic);
+ dialog->filter_crop = rs_filter_new("RSCrop", dialog->filter_rotate);
+ dialog->filter_resample = rs_filter_new("RSResample", dialog->filter_crop);
+ dialog->filter_sharpen = rs_filter_new("RSSharpen", dialog->filter_resample);
+}
+
+RSSaveDialog *
+rs_save_dialog_new (void)
+{
+ return g_object_new (RS_TYPE_SAVE_DIALOG, NULL);
+}
+
+void
+rs_save_dialog_set_photo(RSSaveDialog *dialog, RS_PHOTO *photo, gint snapshot)
+{
+ g_assert(RS_IS_SAVE_DIALOG(dialog));
+ g_assert(RS_IS_PHOTO(photo));
+
+ /* This should be enough to calculate "original" size */
+ g_object_set(dialog->filter_input, "image", photo->input, NULL);
+ g_object_set(dialog->filter_rotate, "angle", photo->angle, "orientation", photo->orientation, NULL);
+ g_object_set(dialog->filter_crop, "rectangle", photo->crop, NULL);
+
+ if (dialog->photo)
+ g_object_unref(dialog->photo);
+ dialog->photo = g_object_ref(photo);
+
+ dialog->w_original = rs_filter_get_width(dialog->filter_crop);
+ dialog->h_original = rs_filter_get_height(dialog->filter_crop);
+
+ gtk_spin_button_set_value(dialog->w_spin, dialog->w_original);
+ gtk_spin_button_set_value(dialog->h_spin, dialog->h_original);
+ gtk_spin_button_set_value(dialog->p_spin, 100.0);
+
+ dialog->snapshot = snapshot;
+}
+
+static void
+file_type_changed(gpointer active, gpointer user_data)
+{
+ RSSaveDialog *dialog = RS_SAVE_DIALOG(user_data);
+ const gchar *identifier = g_type_name(GPOINTER_TO_INT(active));
+
+ if (dialog->output)
+ g_object_unref(dialog->output);
+ dialog->output = rs_output_new(identifier);
+
+ if (dialog->file_pref)
+ gtk_widget_destroy(dialog->file_pref);
+ dialog->file_pref = rs_output_get_parameter_widget(dialog->output, "save-as");
+
+ gtk_container_add(GTK_CONTAINER(dialog->pref_bin), dialog->file_pref);
+ gtk_widget_show_all(dialog->file_pref);
+}
+
+static void
+save_clicked(GtkButton *button, gpointer user_data)
+{
+ GdkPixbuf *pixbuf;
+ RS_IMAGE16 *image16;
+ gfloat actual_scale;
+ RSColorTransform *rct;
+ RSSaveDialog *dialog = RS_SAVE_DIALOG(user_data);
+
+ actual_scale = ((gdouble) dialog->save_width / (gdouble) rs_filter_get_width(dialog->filter_crop));
+
+ g_object_set(dialog->filter_resample, "width", dialog->save_width, "height", dialog->save_height, NULL);
+ g_object_set(dialog->filter_sharpen, "amount", actual_scale * dialog->photo->settings[dialog->snapshot]->sharpen, NULL);
+
+ image16 = rs_filter_get_image(dialog->filter_sharpen);
+
+ /* Initialize color transform */
+ rct = rs_color_transform_new();
+ rs_color_transform_set_cms_transform(rct, NULL);
+ rs_color_transform_set_adobe_matrix(rct, &dialog->photo->metadata->adobe_coeff);
+ rs_color_transform_set_from_settings(rct, dialog->photo->settings[dialog->snapshot], MASK_ALL);
+ rs_color_transform_set_output_format(rct, 8);
+
+ pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, image16->w, image16->h);
+ rs_color_transform_transform(rct, image16->w, image16->h, image16->pixels,
+ image16->rowstride, gdk_pixbuf_get_pixels(pixbuf), gdk_pixbuf_get_rowstride(pixbuf));
+
+ g_object_set(dialog->output, "filename", gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog->chooser)), NULL);
+ rs_output_execute(dialog->output, pixbuf);
+
+ g_object_unref(pixbuf);
+ g_object_unref(rct);
+ g_object_unref(image16);
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+}
+
+static void
+cancel_clicked(GtkButton *button, gpointer user_data)
+{
+ RSSaveDialog *dialog = RS_SAVE_DIALOG(user_data);
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+}
+
+static void
+size_pref_aspect_changed(GtkToggleButton *togglebutton, gpointer user_data)
+{
+ RSSaveDialog *dialog = RS_SAVE_DIALOG(user_data);
+ dialog->keep_aspect = togglebutton->active;
+ if (dialog->keep_aspect)
+ {
+ gtk_spin_button_set_value(dialog->w_spin, dialog->w_original);
+ gtk_spin_button_set_value(dialog->h_spin, dialog->h_original);
+ gtk_spin_button_set_value(dialog->p_spin, 100.0);
+ }
+ return;
+}
+
+static void
+size_pref_w_changed(GtkSpinButton *spinbutton, gpointer user_data)
+{
+ RSSaveDialog *dialog = RS_SAVE_DIALOG(user_data);
+ gdouble ratio;
+ if (dialog->keep_aspect)
+ {
+ g_signal_handler_block(dialog->h_spin, dialog->h_signal);
+ ratio = gtk_spin_button_get_value(spinbutton)/dialog->w_original;
+ gtk_spin_button_set_value(dialog->h_spin, dialog->h_original*ratio);
+ g_signal_handler_unblock(dialog->h_spin, dialog->h_signal);
+ }
+ return;
+}
+
+static void
+size_pref_h_changed(GtkSpinButton *spinbutton, gpointer user_data)
+{
+ RSSaveDialog *dialog = RS_SAVE_DIALOG(user_data);
+ gdouble ratio;
+ if (dialog->keep_aspect)
+ {
+ g_signal_handler_block(dialog->w_spin, dialog->w_signal);
+ ratio = gtk_spin_button_get_value(spinbutton)/dialog->h_original;
+ gtk_spin_button_set_value(dialog->w_spin, dialog->w_original*ratio);
+ g_signal_handler_unblock(dialog->w_spin, dialog->w_signal);
+ }
+ return;
+}
+
+static void
+size_pref_p_changed(GtkSpinButton *spinbutton, gpointer user_data)
+{
+ RSSaveDialog *dialog = RS_SAVE_DIALOG(user_data);
+ gdouble ratio;
+ g_signal_handler_block(dialog->w_spin, dialog->w_signal);
+ g_signal_handler_block(dialog->h_spin, dialog->h_signal);
+ ratio = gtk_spin_button_get_value(spinbutton)/100.0;
+ gtk_spin_button_set_value(dialog->w_spin, dialog->w_original*ratio);
+ gtk_spin_button_set_value(dialog->h_spin, dialog->h_original*ratio);
+ g_signal_handler_unblock(dialog->w_spin, dialog->w_signal);
+ g_signal_handler_unblock(dialog->h_spin, dialog->h_signal);
+ return;
+}
+
+static void
+spin_set_value(GtkSpinButton *spinbutton, gpointer user_data)
+{
+ gint *value = (gint *) user_data;
+ *value = gtk_spin_button_get_value_as_int(spinbutton);
+ return;
+}
+
+static GtkWidget *
+size_pref_new(RSSaveDialog *dialog)
+{
+ GtkWidget *vbox, *hbox;
+ GtkWidget *checkbox;
+
+ checkbox = gtk_check_button_new_with_label(_("Keep aspect"));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), dialog->keep_aspect);
+ g_signal_connect ((gpointer) checkbox, "toggled", G_CALLBACK (size_pref_aspect_changed), dialog);
+
+ dialog->w_spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0, 65535.0, 1.0));
+ dialog->h_spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0, 65535.0, 1.0));
+ dialog->p_spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0, 200.0, 1.0));
+ gtk_spin_button_set_value(dialog->w_spin, (gdouble) dialog->save_width);
+ gtk_spin_button_set_value(dialog->h_spin, (gdouble) dialog->save_height);
+ gtk_spin_button_set_value(dialog->p_spin, 100.0);
+ dialog->w_signal = g_signal_connect(G_OBJECT(dialog->w_spin), "value_changed", G_CALLBACK(size_pref_w_changed), dialog);
+ dialog->h_signal = g_signal_connect(G_OBJECT(dialog->h_spin), "value_changed", G_CALLBACK(size_pref_h_changed), dialog);
+ g_signal_connect(G_OBJECT(dialog->p_spin), "value_changed", G_CALLBACK(size_pref_p_changed), dialog);
+
+ g_signal_connect(G_OBJECT(dialog->w_spin), "value_changed", G_CALLBACK(spin_set_value), &dialog->save_width);
+ g_signal_connect(G_OBJECT(dialog->h_spin), "value_changed", G_CALLBACK(spin_set_value), &dialog->save_height);
+
+ hbox = gtk_hbox_new(FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new_with_mnemonic(_("Width:")), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(dialog->w_spin), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new_with_mnemonic(_("Height:")), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(dialog->h_spin), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new_with_mnemonic(_("Percent:")), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(dialog->p_spin), FALSE, TRUE, 0);
+
+ vbox = gtk_vbox_new(FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(checkbox), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(hbox), FALSE, TRUE, 0);
+ return(vbox);
+}
Added: trunk/src/rs-save-dialog.h
===================================================================
--- trunk/src/rs-save-dialog.h (rev 0)
+++ trunk/src/rs-save-dialog.h 2009-02-22 16:23:10 UTC (rev 2210)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006-2009 Anders Brander <anders at brander.dk> and
+ * Anders Kvist <akv at lnxbx.dk>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef RS_SAVE_DIALOG_H
+#define RS_SAVE_DIALOG_H
+
+#include <rawstudio.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define RS_TYPE_SAVE_DIALOG rs_save_dialog_get_type()
+#define RS_SAVE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_SAVE_DIALOG, RSSaveDialog))
+#define RS_SAVE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RS_TYPE_SAVE_DIALOG, RSSaveDialogClass))
+#define RS_IS_SAVE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_SAVE_DIALOG))
+#define RS_IS_SAVE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RS_TYPE_SAVE_DIALOG))
+#define RS_SAVE_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RS_TYPE_SAVE_DIALOG, RSSaveDialogClass))
+
+typedef struct {
+ GtkWindow parent;
+
+ RSOutput *output;
+ GtkWidget *vbox;
+ GtkWidget *chooser;
+ RS_CONFBOX *type_box;
+ GtkWidget *file_pref;
+ GtkWidget *pref_bin;
+ gdouble w_original;
+ gdouble h_original;
+ gboolean keep_aspect;
+ GtkSpinButton *w_spin;
+ GtkSpinButton *h_spin;
+ GtkSpinButton *p_spin;
+ gulong w_signal;
+ gulong h_signal;
+ gint save_width;
+ gint save_height;
+
+ gboolean dispose_has_run;
+
+ RSFilter *filter_input;
+ RSFilter *filter_demosaic;
+ RSFilter *filter_rotate;
+ RSFilter *filter_crop;
+ RSFilter *filter_resample;
+ RSFilter *filter_sharpen;
+
+ RS_PHOTO *photo;
+ gint snapshot;
+} RSSaveDialog;
+
+typedef struct {
+ GtkWindowClass parent_class;
+} RSSaveDialogClass;
+
+GType rs_save_dialog_get_type (void);
+
+RSSaveDialog* rs_save_dialog_new (void);
+
+void rs_save_dialog_set_photo(RSSaveDialog *dialog, RS_PHOTO *photo, gint snapshot);
+
+G_END_DECLS
+
+#endif /* RS_SAVE_DIALOG_H */
More information about the Rawstudio-commit
mailing list