[shotwell] Extract Export dialog
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell] Extract Export dialog
- Date: Wed, 20 Dec 2017 21:49:55 +0000 (UTC)
commit 7351d786f3256e7fa535cef906785a473fb37e67
Author: Jens Georg <mail jensge org>
Date: Tue Dec 19 20:41:14 2017 +0100
Extract Export dialog
src/Dialogs.vala | 339 ----------------------------------------
src/dialogs/ExportDialog.vala | 345 +++++++++++++++++++++++++++++++++++++++++
src/meson.build | 1 +
3 files changed, 346 insertions(+), 339 deletions(-)
---
diff --git a/src/Dialogs.vala b/src/Dialogs.vala
index 3aa31b6..3916b08 100644
--- a/src/Dialogs.vala
+++ b/src/Dialogs.vala
@@ -134,345 +134,6 @@ public Gtk.ResponseType export_error_dialog(File dest, bool photos_remaining) {
}
-public class ExportDialog : Gtk.Dialog {
- public const int DEFAULT_SCALE = 1200;
-
- // "Unmodified" and "Current," though they appear in the "Format:" popup menu, really
- // aren't formats so much as they are operating modes that determine specific formats.
- // Hereafter we'll refer to these as "special formats."
- public const int NUM_SPECIAL_FORMATS = 2;
- public const string UNMODIFIED_FORMAT_LABEL = _("Unmodified");
- public const string CURRENT_FORMAT_LABEL = _("Current");
-
- public const ScaleConstraint[] CONSTRAINT_ARRAY = { ScaleConstraint.ORIGINAL,
- ScaleConstraint.DIMENSIONS, ScaleConstraint.WIDTH, ScaleConstraint.HEIGHT };
-
- public const Jpeg.Quality[] QUALITY_ARRAY = { Jpeg.Quality.LOW, Jpeg.Quality.MEDIUM,
- Jpeg.Quality.HIGH, Jpeg.Quality.MAXIMUM };
-
- private static ScaleConstraint current_constraint = ScaleConstraint.ORIGINAL;
- private static ExportFormatParameters current_parameters = ExportFormatParameters.current();
- private static int current_scale = DEFAULT_SCALE;
-
- private Gtk.Grid table = new Gtk.Grid();
- private Gtk.ComboBoxText quality_combo;
- private Gtk.ComboBoxText constraint_combo;
- private Gtk.ComboBoxText format_combo;
- private Gtk.Switch export_metadata;
- private Gee.ArrayList<string> format_options = new Gee.ArrayList<string>();
- private Gtk.Entry pixels_entry;
- private Gtk.Widget ok_button;
- private bool in_insert = false;
-
- public ExportDialog(string title) {
- bool use_header;
- Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header);
- Object (use_header_bar: use_header ? 1 : 0);
-
- this.title = title;
- resizable = false;
-
- //get information about the export settings out of our config backend
- Config.Facade config = Config.Facade.get_instance();
- current_parameters.mode = config.get_export_export_format_mode(); //ExportFormatMode
- current_parameters.specified_format = config.get_export_photo_file_format(); //PhotoFileFormat
- current_parameters.quality = config.get_export_quality(); //quality
- current_parameters.export_metadata = config.get_export_export_metadata(); //export metadata
- current_constraint = config.get_export_constraint(); //constraint
- current_scale = config.get_export_scale(); //scale
-
- quality_combo = new Gtk.ComboBoxText();
- int ctr = 0;
- foreach (Jpeg.Quality quality in QUALITY_ARRAY) {
- quality_combo.append_text(quality.to_string());
- if (quality == current_parameters.quality)
- quality_combo.set_active(ctr);
- ctr++;
- }
-
- constraint_combo = new Gtk.ComboBoxText();
- ctr = 0;
- foreach (ScaleConstraint constraint in CONSTRAINT_ARRAY) {
- constraint_combo.append_text(constraint.to_string());
- if (constraint == current_constraint)
- constraint_combo.set_active(ctr);
- ctr++;
- }
-
- format_combo = new Gtk.ComboBoxText();
- format_add_option(UNMODIFIED_FORMAT_LABEL);
- format_add_option(CURRENT_FORMAT_LABEL);
- foreach (PhotoFileFormat format in PhotoFileFormat.get_writeable()) {
- format_add_option(format.get_properties().get_user_visible_name());
- }
-
- pixels_entry = new Gtk.Entry();
- pixels_entry.set_max_length(6);
- pixels_entry.set_text("%d".printf(current_scale));
-
- // register after preparation to avoid signals during init
- constraint_combo.changed.connect(on_constraint_changed);
- format_combo.changed.connect(on_format_changed);
- pixels_entry.changed.connect(on_pixels_changed);
- pixels_entry.insert_text.connect(on_pixels_insert_text);
- pixels_entry.activate.connect(on_activate);
-
- // layout controls
- add_label(_("_Format:"), 0, 0, format_combo);
- add_control(format_combo, 1, 0);
-
- add_label(_("_Quality:"), 0, 1, quality_combo);
- add_control(quality_combo, 1, 1);
-
- add_label(_("_Scaling constraint:"), 0, 2, constraint_combo);
- add_control(constraint_combo, 1, 2);
-
- add_label(_("_Pixels:"), 0, 3, pixels_entry);
- add_control(pixels_entry, 1, 3);
-
- export_metadata = new Gtk.Switch ();
- add_label(_("Export _metadata:"), 0, 4, export_metadata);
- add_control(export_metadata, 1, 4);
- export_metadata.active = true;
- export_metadata.halign = Gtk.Align.START;
-
- table.set_row_spacing(6);
- table.set_column_spacing(12);
- table.set_border_width(18);
-
- ((Gtk.Box) get_content_area()).add(table);
-
- // add buttons to action area
- add_button(Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL);
- ok_button = add_button(Resources.OK_LABEL, Gtk.ResponseType.OK);
- set_default_response(Gtk.ResponseType.OK);
-
- ok_button.set_can_default(true);
- ok_button.has_default = true;
- set_default(ok_button);
-
- if (current_constraint == ScaleConstraint.ORIGINAL) {
- pixels_entry.sensitive = false;
- quality_combo.sensitive = false;
- }
-
- ok_button.grab_focus();
- }
-
- private void format_add_option(string format_name) {
- format_options.add(format_name);
- format_combo.append_text(format_name);
- }
-
- private void format_set_active_text(string text) {
- int selection_ticker = 0;
-
- foreach (string current_text in format_options) {
- if (current_text == text) {
- format_combo.set_active(selection_ticker);
- return;
- }
- selection_ticker++;
- }
-
- error("format_set_active_text: text '%s' isn't in combo box", text);
- }
-
- private PhotoFileFormat get_specified_format() {
- int index = format_combo.get_active();
- if (index < NUM_SPECIAL_FORMATS)
- index = NUM_SPECIAL_FORMATS;
-
- index -= NUM_SPECIAL_FORMATS;
- PhotoFileFormat[] writeable_formats = PhotoFileFormat.get_writeable();
- return writeable_formats[index];
- }
-
- private string get_label_for_parameters(ExportFormatParameters params) {
- switch(params.mode) {
- case ExportFormatMode.UNMODIFIED:
- return UNMODIFIED_FORMAT_LABEL;
-
- case ExportFormatMode.CURRENT:
- return CURRENT_FORMAT_LABEL;
-
- case ExportFormatMode.SPECIFIED:
- return params.specified_format.get_properties().get_user_visible_name();
-
- default:
- error("get_label_for_parameters: unrecognized export format mode");
- }
- }
-
- // unlike other parameters, which should be persisted across dialog executions, the
- // format parameters must be set each time the dialog is executed -- this is why
- // it's passed qualified as ref and not as out
- public bool execute(out int scale, out ScaleConstraint constraint,
- ref ExportFormatParameters parameters) {
- show_all();
-
- // if the export format mode isn't set to last (i.e., don't use the persisted settings),
- // reset the scale constraint to original size
- if (parameters.mode != ExportFormatMode.LAST) {
- current_constraint = constraint = ScaleConstraint.ORIGINAL;
- constraint_combo.set_active(0);
- }
-
- if (parameters.mode == ExportFormatMode.LAST)
- parameters = current_parameters;
- else if (parameters.mode == ExportFormatMode.SPECIFIED && !parameters.specified_format.can_write())
- parameters.specified_format = PhotoFileFormat.get_system_default_format();
-
- format_set_active_text(get_label_for_parameters(parameters));
- on_format_changed();
-
- bool ok = (run() == Gtk.ResponseType.OK);
- if (ok) {
- int index = constraint_combo.get_active();
- assert(index >= 0);
- constraint = CONSTRAINT_ARRAY[index];
- current_constraint = constraint;
-
- scale = int.parse(pixels_entry.get_text());
- if (constraint != ScaleConstraint.ORIGINAL)
- assert(scale > 0);
- current_scale = scale;
-
- parameters.export_metadata = export_metadata.sensitive ? export_metadata.active : false;
-
- if (format_combo.get_active_text() == UNMODIFIED_FORMAT_LABEL) {
- parameters.mode = current_parameters.mode = ExportFormatMode.UNMODIFIED;
- } else if (format_combo.get_active_text() == CURRENT_FORMAT_LABEL) {
- parameters.mode = current_parameters.mode = ExportFormatMode.CURRENT;
- } else {
- parameters.mode = current_parameters.mode = ExportFormatMode.SPECIFIED;
- parameters.specified_format = current_parameters.specified_format = get_specified_format();
- if (current_parameters.specified_format == PhotoFileFormat.JFIF)
- parameters.quality = current_parameters.quality =
QUALITY_ARRAY[quality_combo.get_active()];
- }
-
- //save current settings in config backend for reusing later
- Config.Facade config = Config.Facade.get_instance();
- config.set_export_export_format_mode(current_parameters.mode); //ExportFormatMode
- config.set_export_photo_file_format(current_parameters.specified_format); //PhotoFileFormat
- config.set_export_quality(current_parameters.quality); //quality
- config.set_export_export_metadata(current_parameters.export_metadata); //export metadata
- config.set_export_constraint(current_constraint); //constraint
- config.set_export_scale(current_scale); //scale
- } else {
- scale = 0;
- constraint = ScaleConstraint.ORIGINAL;
- }
-
- destroy();
-
- return ok;
- }
-
- private void add_label(string text, int x, int y, Gtk.Widget? widget = null) {
- Gtk.Label new_label = new Gtk.Label.with_mnemonic(text);
- new_label.halign = Gtk.Align.END;
- new_label.valign = Gtk.Align.CENTER;
- new_label.set_use_underline(true);
-
- if (widget != null)
- new_label.set_mnemonic_widget(widget);
-
- table.attach(new_label, x, y, 1, 1);
- }
-
- private void add_control(Gtk.Widget widget, int x, int y) {
- widget.halign = Gtk.Align.FILL;
- widget.valign = Gtk.Align.CENTER;
- widget.hexpand = true;
- widget.vexpand = true;
-
- table.attach(widget, x, y, 1, 1);
- }
-
- private void on_constraint_changed() {
- bool original = CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL;
- bool jpeg = format_combo.get_active_text() ==
- PhotoFileFormat.JFIF.get_properties().get_user_visible_name();
- pixels_entry.sensitive = !original;
- quality_combo.sensitive = !original && jpeg;
- if (original)
- ok_button.sensitive = true;
- else
- on_pixels_changed();
- }
-
- private void on_format_changed() {
- bool original = CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL;
-
- if (format_combo.get_active_text() == UNMODIFIED_FORMAT_LABEL) {
- // if the user wishes to export the media unmodified, then we just copy the original
- // files, so parameterizing size, quality, etc. is impossible -- these are all
- // just as they are in the original file. In this case, we set the scale constraint to
- // original and lock out all the controls
- constraint_combo.set_active(0); /* 0 == original size */
- constraint_combo.set_sensitive(false);
- quality_combo.set_sensitive(false);
- pixels_entry.sensitive = false;
- export_metadata.active = false;
- export_metadata.sensitive = false;
- } else if (format_combo.get_active_text() == CURRENT_FORMAT_LABEL) {
- // if the user wishes to export the media in its current format, we allow sizing but
- // not JPEG quality customization, because in a batch of many photos, it's not
- // guaranteed that all of them will be JPEGs or RAWs that get converted to JPEGs. Some
- // could be PNGs, and PNG has no notion of quality. So lock out the quality control.
- // If the user wants to set JPEG quality, he or she can explicitly specify the JPEG
- // format.
- constraint_combo.set_sensitive(true);
- quality_combo.set_sensitive(false);
- pixels_entry.sensitive = !original;
- export_metadata.sensitive = true;
- } else {
- // if the user has chosen a specific format, then allow JPEG quality customization if
- // the format is JPEG and the user is re-sizing the image, otherwise, disallow JPEG
- // quality customization; always allow scaling.
- constraint_combo.set_sensitive(true);
- bool jpeg = get_specified_format() == PhotoFileFormat.JFIF;
- quality_combo.sensitive = !original && jpeg;
- export_metadata.sensitive = true;
- }
- }
-
- private void on_activate() {
- response(Gtk.ResponseType.OK);
- }
-
- private void on_pixels_changed() {
- ok_button.sensitive = (pixels_entry.get_text_length() > 0) && (int.parse(pixels_entry.get_text()) >
0);
- }
-
- private void on_pixels_insert_text(string text, int length, ref int position) {
- // This is necessary because SignalHandler.block_by_func() is not properly bound
- if (in_insert)
- return;
-
- in_insert = true;
-
- if (length == -1)
- length = (int) text.length;
-
- // only permit numeric text
- string new_text = "";
- for (int ctr = 0; ctr < length; ctr++) {
- if (text[ctr].isdigit()) {
- new_text += ((char) text[ctr]).to_string();
- }
- }
-
- if (new_text.length > 0)
- pixels_entry.insert_text(new_text, (int) new_text.length, ref position);
-
- Signal.stop_emission_by_name(pixels_entry, "insert-text");
-
- in_insert = false;
- }
-}
-
namespace ImportUI {
private const int REPORT_FAILURE_COUNT = 4;
internal const string SAVE_RESULTS_BUTTON_NAME = _("Save Details…");
diff --git a/src/dialogs/ExportDialog.vala b/src/dialogs/ExportDialog.vala
new file mode 100644
index 0000000..2366ce9
--- /dev/null
+++ b/src/dialogs/ExportDialog.vala
@@ -0,0 +1,345 @@
+/* Copyright 2016 Software Freedom Conservancy Inc.
+ * Copyright 2017 Jens Georg <mail jensge org>
+ *
+ * This software is licensed under the GNU LGPL (version 2.1 or later).
+ * See the COPYING file in this distribution.
+ */
+
+public class ExportDialog : Gtk.Dialog {
+ public const int DEFAULT_SCALE = 1200;
+
+ // "Unmodified" and "Current," though they appear in the "Format:" popup menu, really
+ // aren't formats so much as they are operating modes that determine specific formats.
+ // Hereafter we'll refer to these as "special formats."
+ public const int NUM_SPECIAL_FORMATS = 2;
+ public const string UNMODIFIED_FORMAT_LABEL = _("Unmodified");
+ public const string CURRENT_FORMAT_LABEL = _("Current");
+
+ public const ScaleConstraint[] CONSTRAINT_ARRAY = { ScaleConstraint.ORIGINAL,
+ ScaleConstraint.DIMENSIONS, ScaleConstraint.WIDTH, ScaleConstraint.HEIGHT };
+
+ public const Jpeg.Quality[] QUALITY_ARRAY = { Jpeg.Quality.LOW, Jpeg.Quality.MEDIUM,
+ Jpeg.Quality.HIGH, Jpeg.Quality.MAXIMUM };
+
+ private static ScaleConstraint current_constraint = ScaleConstraint.ORIGINAL;
+ private static ExportFormatParameters current_parameters = ExportFormatParameters.current();
+ private static int current_scale = DEFAULT_SCALE;
+
+ private Gtk.Grid table = new Gtk.Grid();
+ private Gtk.ComboBoxText quality_combo;
+ private Gtk.ComboBoxText constraint_combo;
+ private Gtk.ComboBoxText format_combo;
+ private Gtk.Switch export_metadata;
+ private Gee.ArrayList<string> format_options = new Gee.ArrayList<string>();
+ private Gtk.Entry pixels_entry;
+ private Gtk.Widget ok_button;
+ private bool in_insert = false;
+
+ public ExportDialog(string title) {
+ bool use_header;
+ Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header);
+ Object (use_header_bar: use_header ? 1 : 0);
+
+ this.title = title;
+ resizable = false;
+
+ //get information about the export settings out of our config backend
+ Config.Facade config = Config.Facade.get_instance();
+ current_parameters.mode = config.get_export_export_format_mode(); //ExportFormatMode
+ current_parameters.specified_format = config.get_export_photo_file_format(); //PhotoFileFormat
+ current_parameters.quality = config.get_export_quality(); //quality
+ current_parameters.export_metadata = config.get_export_export_metadata(); //export metadata
+ current_constraint = config.get_export_constraint(); //constraint
+ current_scale = config.get_export_scale(); //scale
+
+ quality_combo = new Gtk.ComboBoxText();
+ int ctr = 0;
+ foreach (Jpeg.Quality quality in QUALITY_ARRAY) {
+ quality_combo.append_text(quality.to_string());
+ if (quality == current_parameters.quality)
+ quality_combo.set_active(ctr);
+ ctr++;
+ }
+
+ constraint_combo = new Gtk.ComboBoxText();
+ ctr = 0;
+ foreach (ScaleConstraint constraint in CONSTRAINT_ARRAY) {
+ constraint_combo.append_text(constraint.to_string());
+ if (constraint == current_constraint)
+ constraint_combo.set_active(ctr);
+ ctr++;
+ }
+
+ format_combo = new Gtk.ComboBoxText();
+ format_add_option(UNMODIFIED_FORMAT_LABEL);
+ format_add_option(CURRENT_FORMAT_LABEL);
+ foreach (PhotoFileFormat format in PhotoFileFormat.get_writeable()) {
+ format_add_option(format.get_properties().get_user_visible_name());
+ }
+
+ pixels_entry = new Gtk.Entry();
+ pixels_entry.set_max_length(6);
+ pixels_entry.set_text("%d".printf(current_scale));
+
+ // register after preparation to avoid signals during init
+ constraint_combo.changed.connect(on_constraint_changed);
+ format_combo.changed.connect(on_format_changed);
+ pixels_entry.changed.connect(on_pixels_changed);
+ pixels_entry.insert_text.connect(on_pixels_insert_text);
+ pixels_entry.activate.connect(on_activate);
+
+ // layout controls
+ add_label(_("_Format:"), 0, 0, format_combo);
+ add_control(format_combo, 1, 0);
+
+ add_label(_("_Quality:"), 0, 1, quality_combo);
+ add_control(quality_combo, 1, 1);
+
+ add_label(_("_Scaling constraint:"), 0, 2, constraint_combo);
+ add_control(constraint_combo, 1, 2);
+
+ add_label(_("_Pixels:"), 0, 3, pixels_entry);
+ add_control(pixels_entry, 1, 3);
+
+ export_metadata = new Gtk.Switch ();
+ add_label(_("Export _metadata:"), 0, 4, export_metadata);
+ add_control(export_metadata, 1, 4);
+ export_metadata.active = true;
+ export_metadata.halign = Gtk.Align.START;
+
+ table.set_row_spacing(6);
+ table.set_column_spacing(12);
+ table.set_border_width(18);
+
+ ((Gtk.Box) get_content_area()).add(table);
+
+ // add buttons to action area
+ add_button(Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL);
+ ok_button = add_button(Resources.OK_LABEL, Gtk.ResponseType.OK);
+ set_default_response(Gtk.ResponseType.OK);
+
+ ok_button.set_can_default(true);
+ ok_button.has_default = true;
+ set_default(ok_button);
+
+ if (current_constraint == ScaleConstraint.ORIGINAL) {
+ pixels_entry.sensitive = false;
+ quality_combo.sensitive = false;
+ }
+
+ ok_button.grab_focus();
+ }
+
+ private void format_add_option(string format_name) {
+ format_options.add(format_name);
+ format_combo.append_text(format_name);
+ }
+
+ private void format_set_active_text(string text) {
+ int selection_ticker = 0;
+
+ foreach (string current_text in format_options) {
+ if (current_text == text) {
+ format_combo.set_active(selection_ticker);
+ return;
+ }
+ selection_ticker++;
+ }
+
+ error("format_set_active_text: text '%s' isn't in combo box", text);
+ }
+
+ private PhotoFileFormat get_specified_format() {
+ int index = format_combo.get_active();
+ if (index < NUM_SPECIAL_FORMATS)
+ index = NUM_SPECIAL_FORMATS;
+
+ index -= NUM_SPECIAL_FORMATS;
+ PhotoFileFormat[] writeable_formats = PhotoFileFormat.get_writeable();
+ return writeable_formats[index];
+ }
+
+ private string get_label_for_parameters(ExportFormatParameters params) {
+ switch(params.mode) {
+ case ExportFormatMode.UNMODIFIED:
+ return UNMODIFIED_FORMAT_LABEL;
+
+ case ExportFormatMode.CURRENT:
+ return CURRENT_FORMAT_LABEL;
+
+ case ExportFormatMode.SPECIFIED:
+ return params.specified_format.get_properties().get_user_visible_name();
+
+ default:
+ error("get_label_for_parameters: unrecognized export format mode");
+ }
+ }
+
+ // unlike other parameters, which should be persisted across dialog executions, the
+ // format parameters must be set each time the dialog is executed -- this is why
+ // it's passed qualified as ref and not as out
+ public bool execute(out int scale, out ScaleConstraint constraint,
+ ref ExportFormatParameters parameters) {
+ show_all();
+
+ // if the export format mode isn't set to last (i.e., don't use the persisted settings),
+ // reset the scale constraint to original size
+ if (parameters.mode != ExportFormatMode.LAST) {
+ current_constraint = constraint = ScaleConstraint.ORIGINAL;
+ constraint_combo.set_active(0);
+ }
+
+ if (parameters.mode == ExportFormatMode.LAST)
+ parameters = current_parameters;
+ else if (parameters.mode == ExportFormatMode.SPECIFIED && !parameters.specified_format.can_write())
+ parameters.specified_format = PhotoFileFormat.get_system_default_format();
+
+ format_set_active_text(get_label_for_parameters(parameters));
+ on_format_changed();
+
+ bool ok = (run() == Gtk.ResponseType.OK);
+ if (ok) {
+ int index = constraint_combo.get_active();
+ assert(index >= 0);
+ constraint = CONSTRAINT_ARRAY[index];
+ current_constraint = constraint;
+
+ scale = int.parse(pixels_entry.get_text());
+ if (constraint != ScaleConstraint.ORIGINAL)
+ assert(scale > 0);
+ current_scale = scale;
+
+ parameters.export_metadata = export_metadata.sensitive ? export_metadata.active : false;
+
+ if (format_combo.get_active_text() == UNMODIFIED_FORMAT_LABEL) {
+ parameters.mode = current_parameters.mode = ExportFormatMode.UNMODIFIED;
+ } else if (format_combo.get_active_text() == CURRENT_FORMAT_LABEL) {
+ parameters.mode = current_parameters.mode = ExportFormatMode.CURRENT;
+ } else {
+ parameters.mode = current_parameters.mode = ExportFormatMode.SPECIFIED;
+ parameters.specified_format = current_parameters.specified_format = get_specified_format();
+ if (current_parameters.specified_format == PhotoFileFormat.JFIF)
+ parameters.quality = current_parameters.quality =
QUALITY_ARRAY[quality_combo.get_active()];
+ }
+
+ //save current settings in config backend for reusing later
+ Config.Facade config = Config.Facade.get_instance();
+ config.set_export_export_format_mode(current_parameters.mode); //ExportFormatMode
+ config.set_export_photo_file_format(current_parameters.specified_format); //PhotoFileFormat
+ config.set_export_quality(current_parameters.quality); //quality
+ config.set_export_export_metadata(current_parameters.export_metadata); //export metadata
+ config.set_export_constraint(current_constraint); //constraint
+ config.set_export_scale(current_scale); //scale
+ } else {
+ scale = 0;
+ constraint = ScaleConstraint.ORIGINAL;
+ }
+
+ destroy();
+
+ return ok;
+ }
+
+ private void add_label(string text, int x, int y, Gtk.Widget? widget = null) {
+ Gtk.Label new_label = new Gtk.Label.with_mnemonic(text);
+ new_label.halign = Gtk.Align.END;
+ new_label.valign = Gtk.Align.CENTER;
+ new_label.set_use_underline(true);
+
+ if (widget != null)
+ new_label.set_mnemonic_widget(widget);
+
+ table.attach(new_label, x, y, 1, 1);
+ }
+
+ private void add_control(Gtk.Widget widget, int x, int y) {
+ widget.halign = Gtk.Align.FILL;
+ widget.valign = Gtk.Align.CENTER;
+ widget.hexpand = true;
+ widget.vexpand = true;
+
+ table.attach(widget, x, y, 1, 1);
+ }
+
+ private void on_constraint_changed() {
+ bool original = CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL;
+ bool jpeg = format_combo.get_active_text() ==
+ PhotoFileFormat.JFIF.get_properties().get_user_visible_name();
+ pixels_entry.sensitive = !original;
+ quality_combo.sensitive = !original && jpeg;
+ if (original)
+ ok_button.sensitive = true;
+ else
+ on_pixels_changed();
+ }
+
+ private void on_format_changed() {
+ bool original = CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL;
+
+ if (format_combo.get_active_text() == UNMODIFIED_FORMAT_LABEL) {
+ // if the user wishes to export the media unmodified, then we just copy the original
+ // files, so parameterizing size, quality, etc. is impossible -- these are all
+ // just as they are in the original file. In this case, we set the scale constraint to
+ // original and lock out all the controls
+ constraint_combo.set_active(0); /* 0 == original size */
+ constraint_combo.set_sensitive(false);
+ quality_combo.set_sensitive(false);
+ pixels_entry.sensitive = false;
+ export_metadata.active = false;
+ export_metadata.sensitive = false;
+ } else if (format_combo.get_active_text() == CURRENT_FORMAT_LABEL) {
+ // if the user wishes to export the media in its current format, we allow sizing but
+ // not JPEG quality customization, because in a batch of many photos, it's not
+ // guaranteed that all of them will be JPEGs or RAWs that get converted to JPEGs. Some
+ // could be PNGs, and PNG has no notion of quality. So lock out the quality control.
+ // If the user wants to set JPEG quality, he or she can explicitly specify the JPEG
+ // format.
+ constraint_combo.set_sensitive(true);
+ quality_combo.set_sensitive(false);
+ pixels_entry.sensitive = !original;
+ export_metadata.sensitive = true;
+ } else {
+ // if the user has chosen a specific format, then allow JPEG quality customization if
+ // the format is JPEG and the user is re-sizing the image, otherwise, disallow JPEG
+ // quality customization; always allow scaling.
+ constraint_combo.set_sensitive(true);
+ bool jpeg = get_specified_format() == PhotoFileFormat.JFIF;
+ quality_combo.sensitive = !original && jpeg;
+ export_metadata.sensitive = true;
+ }
+ }
+
+ private void on_activate() {
+ response(Gtk.ResponseType.OK);
+ }
+
+ private void on_pixels_changed() {
+ ok_button.sensitive = (pixels_entry.get_text_length() > 0) && (int.parse(pixels_entry.get_text()) >
0);
+ }
+
+ private void on_pixels_insert_text(string text, int length, ref int position) {
+ // This is necessary because SignalHandler.block_by_func() is not properly bound
+ if (in_insert)
+ return;
+
+ in_insert = true;
+
+ if (length == -1)
+ length = (int) text.length;
+
+ // only permit numeric text
+ string new_text = "";
+ for (int ctr = 0; ctr < length; ctr++) {
+ if (text[ctr].isdigit()) {
+ new_text += ((char) text[ctr]).to_string();
+ }
+ }
+
+ if (new_text.length > 0)
+ pixels_entry.insert_text(new_text, (int) new_text.length, ref position);
+
+ Signal.stop_emission_by_name(pixels_entry, "insert-text");
+
+ in_insert = false;
+ }
+}
diff --git a/src/meson.build b/src/meson.build
index a41a408..9af2da7 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -197,6 +197,7 @@ executable('shotwell',
'dialogs/SetBackgroundSlideshow.vala',
'dialogs/SetBackground.vala',
'dialogs/TextEntry.vala',
+ 'dialogs/ExportDialog.vala',
'.unitize/_UnitInternals.vala',
'.unitize/_UtilInternals.vala',
'.unitize/_ThreadsInternals.vala',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]