[shotwell] Extract Preferences Dialog
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell] Extract Preferences Dialog
- Date: Wed, 20 Dec 2017 21:49:50 +0000 (UTC)
commit d783672bf514ec85c8f73f041f65f5bbb59d10ca
Author: Jens Georg <mail jensge org>
Date: Wed Dec 20 16:42:26 2017 +0100
Extract Preferences Dialog
src/Dialogs.vala | 464 -----------------------------------------
src/dialogs/Preferences.vala | 470 ++++++++++++++++++++++++++++++++++++++++++
src/meson.build | 1 +
3 files changed, 471 insertions(+), 464 deletions(-)
---
diff --git a/src/Dialogs.vala b/src/Dialogs.vala
index 80c4fc0..3aa31b6 100644
--- a/src/Dialogs.vala
+++ b/src/Dialogs.vala
@@ -2008,470 +2008,6 @@ public class WelcomeDialog : Gtk.Dialog {
}
}
-[GtkTemplate (ui = "/org/gnome/Shotwell/ui/preferences_dialog.ui")]
-public class PreferencesDialog : Gtk.Dialog {
- private class PathFormat {
- public PathFormat(string name, string? pattern) {
- this.name = name;
- this.pattern = pattern;
- }
- public string name;
- public string? pattern;
- }
-
- private static PreferencesDialog preferences_dialog;
-
- [GtkChild]
- private Gtk.Adjustment bg_color_adjustment;
- [GtkChild]
- private Gtk.Scale bg_color_slider;
- [GtkChild]
- private Gtk.ComboBox photo_editor_combo;
- [GtkChild]
- private Gtk.ComboBox raw_editor_combo;
- private SortedList<AppInfo> external_raw_apps;
- private SortedList<AppInfo> external_photo_apps;
- [GtkChild]
- private Gtk.FileChooserButton library_dir_button;
- [GtkChild]
- private Gtk.ComboBoxText dir_pattern_combo;
- [GtkChild]
- private Gtk.Entry dir_pattern_entry;
- [GtkChild]
- private Gtk.Label dir_pattern_example;
- private bool allow_closing = false;
- private string? lib_dir = null;
- private Gee.ArrayList<PathFormat> path_formats = new Gee.ArrayList<PathFormat>();
- private GLib.DateTime example_date = new GLib.DateTime.local(2009, 3, 10, 18, 16, 11);
- [GtkChild]
- private Gtk.CheckButton lowercase;
- private Plugins.ManifestWidgetMediator plugins_mediator = new Plugins.ManifestWidgetMediator();
- [GtkChild]
- private Gtk.ComboBoxText default_raw_developer_combo;
-
- [GtkChild]
- private Gtk.CheckButton autoimport;
- [GtkChild]
- private Gtk.CheckButton write_metadata;
- [GtkChild]
- private Gtk.Label pattern_help;
- [GtkChild]
- private Gtk.Notebook preferences_notebook;
-
- [GtkChild]
- private Gtk.RadioButton transparent_checker_radio;
- [GtkChild]
- private Gtk.RadioButton transparent_solid_radio;
- [GtkChild]
- private Gtk.ColorButton transparent_solid_color;
- [GtkChild]
- private Gtk.RadioButton transparent_none_radio;
-
- private PreferencesDialog() {
- bool use_header;
- Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header);
- Object (use_header_bar: use_header ? 1 : 0);
-
- set_parent_window(AppWindow.get_instance().get_parent_window());
- set_transient_for(AppWindow.get_instance());
- delete_event.connect(on_delete);
- response.connect(on_close);
-
- bg_color_adjustment.set_value(bg_color_adjustment.get_upper() -
- (Config.Facade.get_instance().get_bg_color().red * 65535.0));
- bg_color_adjustment.value_changed.connect(on_value_changed);
-
- bg_color_slider.button_press_event.connect(on_bg_color_reset);
-
- transparent_checker_radio.toggled.connect(on_radio_changed);
- transparent_solid_radio.toggled.connect(on_radio_changed);
- transparent_none_radio.toggled.connect(on_radio_changed);
-
- transparent_solid_radio.bind_property("active",
- transparent_solid_color,
- "sensitive");
-
- Gdk.RGBA color = Gdk.RGBA();
- color.parse(Config.Facade.get_instance().get_transparent_background_color());
- (transparent_solid_color as Gtk.ColorChooser).rgba = color;
- transparent_solid_color.color_set.connect(on_color_changed);
-
- switch (Config.Facade.get_instance().get_transparent_background_type()) {
- case "checkered":
- transparent_checker_radio.active = true;
- break;
- case "solid":
- transparent_solid_radio.active = true;
- break;
- default:
- transparent_none_radio.active = true;
- break;
- }
-
- // Ticket #3162 - Move dir pattern blurb into Gnome help.
- // Because specifying a particular snippet of the help requires
- // us to know where its located, we can't hardcode a URL anymore;
- // instead, we ask for the help path, and if we find it, we tell
- // yelp to read from there, otherwise, we read from system-wide.
- string help_path = Resources.get_help_path();
-
- if (help_path == null) {
- // We're installed system-wide, so use the system help.
- pattern_help.set_markup("<a href=\"" + Resources.DIR_PATTERN_URI_SYSWIDE + "\">" + _("(Help)") +
"</a>");
- } else {
- // We're being run from the build directory; we'll have to handle clicks to this
- // link manually ourselves, due to a limitation of help: URIs.
- pattern_help.set_markup("<a href=\"dummy:\">" + _("(Help)") + "</a>");
- pattern_help.activate_link.connect(on_local_pattern_help);
- }
-
- add_to_dir_formats(_("Year%sMonth%sDay").printf(Path.DIR_SEPARATOR_S, Path.DIR_SEPARATOR_S),
- "%Y" + Path.DIR_SEPARATOR_S + "%m" + Path.DIR_SEPARATOR_S + "%d");
- add_to_dir_formats(_("Year%sMonth").printf(Path.DIR_SEPARATOR_S), "%Y" +
- Path.DIR_SEPARATOR_S + "%m");
- add_to_dir_formats(_("Year%sMonth-Day").printf(Path.DIR_SEPARATOR_S),
- "%Y" + Path.DIR_SEPARATOR_S + "%m-%d");
- add_to_dir_formats(_("Year-Month-Day"), "%Y-%m-%d");
- add_to_dir_formats(_("Custom"), null); // Custom must always be last.
- dir_pattern_combo.changed.connect(on_dir_pattern_combo_changed);
- dir_pattern_entry.changed.connect(on_dir_pattern_entry_changed);
-
- lowercase.toggled.connect(on_lowercase_toggled);
-
- (preferences_notebook.get_nth_page (2) as Gtk.Container).add (plugins_mediator.widget);
-
- populate_preference_options();
-
- photo_editor_combo.changed.connect(on_photo_editor_changed);
- raw_editor_combo.changed.connect(on_raw_editor_changed);
-
- autoimport.set_active(Config.Facade.get_instance().get_auto_import_from_library());
-
- write_metadata.set_active(Config.Facade.get_instance().get_commit_metadata_to_masters());
-
- default_raw_developer_combo.append_text(RawDeveloper.CAMERA.get_label());
- default_raw_developer_combo.append_text(RawDeveloper.SHOTWELL.get_label());
- set_raw_developer_combo(Config.Facade.get_instance().get_default_raw_developer());
- default_raw_developer_combo.changed.connect(on_default_raw_developer_changed);
- }
-
- public void populate_preference_options() {
- populate_app_combo_box(photo_editor_combo, PhotoFileFormat.get_editable_mime_types(),
- Config.Facade.get_instance().get_external_photo_app(), out external_photo_apps);
-
- populate_app_combo_box(raw_editor_combo, PhotoFileFormat.RAW.get_mime_types(),
- Config.Facade.get_instance().get_external_raw_app(), out external_raw_apps);
-
- setup_dir_pattern(dir_pattern_combo, dir_pattern_entry);
-
- lowercase.set_active(Config.Facade.get_instance().get_use_lowercase_filenames());
- }
-
- private void on_radio_changed() {
- var config = Config.Facade.get_instance();
-
- if (transparent_checker_radio.active) {
- config.set_transparent_background_type("checkered");
- } else if (transparent_solid_radio.active) {
- config.set_transparent_background_type("solid");
- } else {
- config.set_transparent_background_type("none");
- }
- }
-
- private void on_color_changed() {
- var color = (transparent_solid_color as Gtk.ColorChooser).rgba.to_string();
- Config.Facade.get_instance().set_transparent_background_color(color);
- }
-
- // Ticket #3162, part II - if we're not yet installed, then we have to manually launch
- // the help viewer and specify the full path to the subsection we want...
- private bool on_local_pattern_help(string ignore) {
- try {
- Resources.launch_help(AppWindow.get_instance().get_screen(), "other-files.page");
- } catch (Error e) {
- message("Unable to launch help: %s", e.message);
- }
- return true;
- }
-
- private void populate_app_combo_box(Gtk.ComboBox combo_box, string[] mime_types,
- string current_app_executable, out SortedList<AppInfo> external_apps) {
- // get list of all applications for the given mime types
- assert(mime_types.length != 0);
- external_apps = DesktopIntegration.get_apps_for_mime_types(mime_types);
-
- if (external_apps.size == 0)
- return;
-
- // populate application ComboBox with app names and icons
- Gtk.CellRendererPixbuf pixbuf_renderer = new Gtk.CellRendererPixbuf();
- Gtk.CellRendererText text_renderer = new Gtk.CellRendererText();
- combo_box.clear();
- combo_box.pack_start(pixbuf_renderer, false);
- combo_box.pack_start(text_renderer, false);
- combo_box.add_attribute(pixbuf_renderer, "pixbuf", 0);
- combo_box.add_attribute(text_renderer, "text", 1);
-
- // TODO: need more space between icons and text
- Gtk.ListStore combo_store = new Gtk.ListStore(2, typeof(Gdk.Pixbuf), typeof(string));
- Gtk.TreeIter iter;
-
- int current_app = -1;
-
- foreach (AppInfo app in external_apps) {
- combo_store.append(out iter);
-
- Icon app_icon = app.get_icon();
- try {
- if (app_icon is FileIcon) {
- combo_store.set_value(iter, 0, scale_pixbuf(new Gdk.Pixbuf.from_file(
- ((FileIcon) app_icon).get_file().get_path()), Resources.DEFAULT_ICON_SCALE,
- Gdk.InterpType.BILINEAR, false));
- } else if (app_icon is ThemedIcon) {
- Gdk.Pixbuf icon_pixbuf =
- Gtk.IconTheme.get_default().load_icon(((ThemedIcon) app_icon).get_names()[0],
- Resources.DEFAULT_ICON_SCALE, Gtk.IconLookupFlags.FORCE_SIZE);
-
- combo_store.set_value(iter, 0, icon_pixbuf);
- }
- } catch (GLib.Error error) {
- warning("Error loading icon pixbuf: " + error.message);
- }
-
- combo_store.set_value(iter, 1, app.get_name());
-
- if (app.get_commandline() == current_app_executable)
- current_app = external_apps.index_of(app);
- }
-
- // TODO: allow users to choose unlisted applications like Nautilus's "Open with -> Other
Application..."
-
- combo_box.set_model(combo_store);
-
- if (current_app != -1)
- combo_box.set_active(current_app);
- }
-
- private void setup_dir_pattern(Gtk.ComboBox combo_box, Gtk.Entry entry) {
- string? pattern = Config.Facade.get_instance().get_directory_pattern();
- bool found = false;
- if (null != pattern) {
- // Locate pre-built text.
- int i = 0;
- foreach (PathFormat pf in path_formats) {
- if (pf.pattern == pattern) {
- combo_box.set_active(i);
- found = true;
- break;
- }
- i++;
- }
- } else {
- // Custom path.
- string? s = Config.Facade.get_instance().get_directory_pattern_custom();
- if (!is_string_empty(s)) {
- combo_box.set_active(path_formats.size - 1); // Assume "custom" is last.
- found = true;
- }
- }
-
- if (!found) {
- combo_box.set_active(0);
- }
-
- on_dir_pattern_combo_changed();
- }
-
- public static void show_preferences() {
- if (preferences_dialog == null)
- preferences_dialog = new PreferencesDialog();
-
- preferences_dialog.populate_preference_options();
- preferences_dialog.show_all();
- preferences_dialog.library_dir_button.set_current_folder(AppDirs.get_import_dir().get_path());
-
- // Ticket #3001: Cause the dialog to become active if the user chooses 'Preferences'
- // from the menus a second time.
- preferences_dialog.present();
- }
-
- // For items that should only be committed when the dialog is closed, not as soon as the change
- // is made.
- private void commit_on_close() {
- Config.Facade.get_instance().commit_bg_color();
- Config.Facade.get_instance().set_auto_import_from_library(autoimport.active);
- Config.Facade.get_instance().set_commit_metadata_to_masters(write_metadata.active);
-
- if (lib_dir != null)
- AppDirs.set_import_dir(lib_dir);
-
- PathFormat pf = path_formats.get(dir_pattern_combo.get_active());
- if (null == pf.pattern) {
- Config.Facade.get_instance().set_directory_pattern_custom(dir_pattern_entry.text);
- Config.Facade.get_instance().set_directory_pattern(null);
- } else {
- Config.Facade.get_instance().set_directory_pattern(pf.pattern);
- }
- }
-
- private bool on_delete() {
- if (!get_allow_closing())
- return true;
-
- commit_on_close();
- return hide_on_delete(); //prevent widgets from getting destroyed
- }
-
- private void on_close() {
- if (!get_allow_closing())
- return;
-
- hide();
- commit_on_close();
- }
-
- private void on_value_changed() {
- set_background_color((double)(bg_color_adjustment.get_upper() -
- bg_color_adjustment.get_value()) / 65535.0);
- }
-
- private bool on_bg_color_reset(Gdk.EventButton event) {
- if (event.button == 1 && event.type == Gdk.EventType.BUTTON_PRESS
- && has_only_key_modifier(event.state, Gdk.ModifierType.CONTROL_MASK)) {
- // Left Mouse Button and CTRL pressed
- bg_color_slider.set_value(bg_color_adjustment.get_upper() -
- (parse_color(Config.Facade.DEFAULT_BG_COLOR).red * 65536.0f));
- on_value_changed();
-
- return true;
- }
-
- return false;
- }
-
- private void on_dir_pattern_combo_changed() {
- PathFormat pf = path_formats.get(dir_pattern_combo.get_active());
- if (null == pf.pattern) {
- // Custom format.
- string? dir_pattern = Config.Facade.get_instance().get_directory_pattern_custom();
- if (is_string_empty(dir_pattern))
- dir_pattern = "";
- dir_pattern_entry.set_text(dir_pattern);
- dir_pattern_entry.editable = true;
- dir_pattern_entry.sensitive = true;
- } else {
- dir_pattern_entry.set_text(pf.pattern);
- dir_pattern_entry.editable = false;
- dir_pattern_entry.sensitive = false;
- }
- }
-
- private void on_dir_pattern_entry_changed() {
- string example = example_date.format(dir_pattern_entry.text);
- if (is_string_empty(example) && !is_string_empty(dir_pattern_entry.text)) {
- // Invalid pattern.
- dir_pattern_example.set_text(_("Invalid pattern"));
- dir_pattern_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "dialog-error");
- dir_pattern_entry.set_icon_activatable(Gtk.EntryIconPosition.SECONDARY, false);
- set_allow_closing(false);
- } else {
- // Valid pattern.
- dir_pattern_example.set_text(example);
- dir_pattern_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, null);
- set_allow_closing(true);
- }
- }
-
- private void set_allow_closing(bool allow) {
- set_deletable(allow);
- allow_closing = allow;
- }
-
- private bool get_allow_closing() {
- return allow_closing;
- }
-
- private void set_background_color(double bg_color_value) {
- Config.Facade.get_instance().set_bg_color(to_grayscale(bg_color_value));
- }
-
- private Gdk.RGBA to_grayscale(double color_value) {
- Gdk.RGBA color = Gdk.RGBA();
-
- color.red = color_value;
- color.green = color_value;
- color.blue = color_value;
- color.alpha = 1.0;
-
- return color;
- }
-
- private void on_photo_editor_changed() {
- int photo_app_choice_index = (photo_editor_combo.get_active() < external_photo_apps.size) ?
- photo_editor_combo.get_active() : external_photo_apps.size;
-
- AppInfo app = external_photo_apps.get_at(photo_app_choice_index);
-
- Config.Facade.get_instance().set_external_photo_app(DesktopIntegration.get_app_open_command(app));
-
- debug("setting external photo editor to: %s", DesktopIntegration.get_app_open_command(app));
- }
-
- private void on_raw_editor_changed() {
- int raw_app_choice_index = (raw_editor_combo.get_active() < external_raw_apps.size) ?
- raw_editor_combo.get_active() : external_raw_apps.size;
-
- AppInfo app = external_raw_apps.get_at(raw_app_choice_index);
-
- Config.Facade.get_instance().set_external_raw_app(app.get_commandline());
-
- debug("setting external raw editor to: %s", app.get_commandline());
- }
-
- private RawDeveloper raw_developer_from_combo() {
- if (default_raw_developer_combo.get_active() == 0)
- return RawDeveloper.CAMERA;
- return RawDeveloper.SHOTWELL;
- }
-
- private void set_raw_developer_combo(RawDeveloper d) {
- if (d == RawDeveloper.CAMERA)
- default_raw_developer_combo.set_active(0);
- else
- default_raw_developer_combo.set_active(1);
- }
-
- private void on_default_raw_developer_changed() {
- Config.Facade.get_instance().set_default_raw_developer(raw_developer_from_combo());
- }
-
- private void on_current_folder_changed() {
- lib_dir = library_dir_button.get_filename();
- }
-
- public override bool map_event(Gdk.EventAny event) {
- var result = base.map_event(event);
- // Set the signal for the lib dir button after the dialog is displayed,
- // because the FileChooserButton has a nasty habit of selecting a
- // different folder when displayed if the provided path doesn't exist.
- // See ticket #3000 for more info.
- library_dir_button.current_folder_changed.connect(on_current_folder_changed);
-
- return result;
- }
-
- private void add_to_dir_formats(string name, string? pattern) {
- PathFormat pf = new PathFormat(name, pattern);
- path_formats.add(pf);
- dir_pattern_combo.append_text(name);
- }
-
- private void on_lowercase_toggled() {
- Config.Facade.get_instance().set_use_lowercase_filenames(lowercase.get_active());
- }
-}
-
// This function is used to determine whether or not files should be copied or linked when imported.
// Returns ACCEPT for copy, REJECT for link, and CANCEL for (drum-roll) cancel.
public Gtk.ResponseType copy_files_dialog() {
diff --git a/src/dialogs/Preferences.vala b/src/dialogs/Preferences.vala
new file mode 100644
index 0000000..6bbe28a
--- /dev/null
+++ b/src/dialogs/Preferences.vala
@@ -0,0 +1,470 @@
+/* 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.
+ */
+
+[GtkTemplate (ui = "/org/gnome/Shotwell/ui/preferences_dialog.ui")]
+public class PreferencesDialog : Gtk.Dialog {
+ private class PathFormat {
+ public PathFormat(string name, string? pattern) {
+ this.name = name;
+ this.pattern = pattern;
+ }
+ public string name;
+ public string? pattern;
+ }
+
+ private static PreferencesDialog preferences_dialog;
+
+ [GtkChild]
+ private Gtk.Adjustment bg_color_adjustment;
+ [GtkChild]
+ private Gtk.Scale bg_color_slider;
+ [GtkChild]
+ private Gtk.ComboBox photo_editor_combo;
+ [GtkChild]
+ private Gtk.ComboBox raw_editor_combo;
+ private SortedList<AppInfo> external_raw_apps;
+ private SortedList<AppInfo> external_photo_apps;
+ [GtkChild]
+ private Gtk.FileChooserButton library_dir_button;
+ [GtkChild]
+ private Gtk.ComboBoxText dir_pattern_combo;
+ [GtkChild]
+ private Gtk.Entry dir_pattern_entry;
+ [GtkChild]
+ private Gtk.Label dir_pattern_example;
+ private bool allow_closing = false;
+ private string? lib_dir = null;
+ private Gee.ArrayList<PathFormat> path_formats = new Gee.ArrayList<PathFormat>();
+ private GLib.DateTime example_date = new GLib.DateTime.local(2009, 3, 10, 18, 16, 11);
+ [GtkChild]
+ private Gtk.CheckButton lowercase;
+ private Plugins.ManifestWidgetMediator plugins_mediator = new Plugins.ManifestWidgetMediator();
+ [GtkChild]
+ private Gtk.ComboBoxText default_raw_developer_combo;
+
+ [GtkChild]
+ private Gtk.CheckButton autoimport;
+ [GtkChild]
+ private Gtk.CheckButton write_metadata;
+ [GtkChild]
+ private Gtk.Label pattern_help;
+ [GtkChild]
+ private Gtk.Notebook preferences_notebook;
+
+ [GtkChild]
+ private Gtk.RadioButton transparent_checker_radio;
+ [GtkChild]
+ private Gtk.RadioButton transparent_solid_radio;
+ [GtkChild]
+ private Gtk.ColorButton transparent_solid_color;
+ [GtkChild]
+ private Gtk.RadioButton transparent_none_radio;
+
+ private PreferencesDialog() {
+ bool use_header;
+ Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header);
+ Object (use_header_bar: use_header ? 1 : 0);
+
+ set_parent_window(AppWindow.get_instance().get_parent_window());
+ set_transient_for(AppWindow.get_instance());
+ delete_event.connect(on_delete);
+ response.connect(on_close);
+
+ bg_color_adjustment.set_value(bg_color_adjustment.get_upper() -
+ (Config.Facade.get_instance().get_bg_color().red * 65535.0));
+ bg_color_adjustment.value_changed.connect(on_value_changed);
+
+ bg_color_slider.button_press_event.connect(on_bg_color_reset);
+
+ transparent_checker_radio.toggled.connect(on_radio_changed);
+ transparent_solid_radio.toggled.connect(on_radio_changed);
+ transparent_none_radio.toggled.connect(on_radio_changed);
+
+ transparent_solid_radio.bind_property("active",
+ transparent_solid_color,
+ "sensitive");
+
+ Gdk.RGBA color = Gdk.RGBA();
+ color.parse(Config.Facade.get_instance().get_transparent_background_color());
+ (transparent_solid_color as Gtk.ColorChooser).rgba = color;
+ transparent_solid_color.color_set.connect(on_color_changed);
+
+ switch (Config.Facade.get_instance().get_transparent_background_type()) {
+ case "checkered":
+ transparent_checker_radio.active = true;
+ break;
+ case "solid":
+ transparent_solid_radio.active = true;
+ break;
+ default:
+ transparent_none_radio.active = true;
+ break;
+ }
+
+ // Ticket #3162 - Move dir pattern blurb into Gnome help.
+ // Because specifying a particular snippet of the help requires
+ // us to know where its located, we can't hardcode a URL anymore;
+ // instead, we ask for the help path, and if we find it, we tell
+ // yelp to read from there, otherwise, we read from system-wide.
+ string help_path = Resources.get_help_path();
+
+ if (help_path == null) {
+ // We're installed system-wide, so use the system help.
+ pattern_help.set_markup("<a href=\"" + Resources.DIR_PATTERN_URI_SYSWIDE + "\">" + _("(Help)") +
"</a>");
+ } else {
+ // We're being run from the build directory; we'll have to handle clicks to this
+ // link manually ourselves, due to a limitation of help: URIs.
+ pattern_help.set_markup("<a href=\"dummy:\">" + _("(Help)") + "</a>");
+ pattern_help.activate_link.connect(on_local_pattern_help);
+ }
+
+ add_to_dir_formats(_("Year%sMonth%sDay").printf(Path.DIR_SEPARATOR_S, Path.DIR_SEPARATOR_S),
+ "%Y" + Path.DIR_SEPARATOR_S + "%m" + Path.DIR_SEPARATOR_S + "%d");
+ add_to_dir_formats(_("Year%sMonth").printf(Path.DIR_SEPARATOR_S), "%Y" +
+ Path.DIR_SEPARATOR_S + "%m");
+ add_to_dir_formats(_("Year%sMonth-Day").printf(Path.DIR_SEPARATOR_S),
+ "%Y" + Path.DIR_SEPARATOR_S + "%m-%d");
+ add_to_dir_formats(_("Year-Month-Day"), "%Y-%m-%d");
+ add_to_dir_formats(_("Custom"), null); // Custom must always be last.
+ dir_pattern_combo.changed.connect(on_dir_pattern_combo_changed);
+ dir_pattern_entry.changed.connect(on_dir_pattern_entry_changed);
+
+ lowercase.toggled.connect(on_lowercase_toggled);
+
+ (preferences_notebook.get_nth_page (2) as Gtk.Container).add (plugins_mediator.widget);
+
+ populate_preference_options();
+
+ photo_editor_combo.changed.connect(on_photo_editor_changed);
+ raw_editor_combo.changed.connect(on_raw_editor_changed);
+
+ autoimport.set_active(Config.Facade.get_instance().get_auto_import_from_library());
+
+ write_metadata.set_active(Config.Facade.get_instance().get_commit_metadata_to_masters());
+
+ default_raw_developer_combo.append_text(RawDeveloper.CAMERA.get_label());
+ default_raw_developer_combo.append_text(RawDeveloper.SHOTWELL.get_label());
+ set_raw_developer_combo(Config.Facade.get_instance().get_default_raw_developer());
+ default_raw_developer_combo.changed.connect(on_default_raw_developer_changed);
+ }
+
+ public void populate_preference_options() {
+ populate_app_combo_box(photo_editor_combo, PhotoFileFormat.get_editable_mime_types(),
+ Config.Facade.get_instance().get_external_photo_app(), out external_photo_apps);
+
+ populate_app_combo_box(raw_editor_combo, PhotoFileFormat.RAW.get_mime_types(),
+ Config.Facade.get_instance().get_external_raw_app(), out external_raw_apps);
+
+ setup_dir_pattern(dir_pattern_combo, dir_pattern_entry);
+
+ lowercase.set_active(Config.Facade.get_instance().get_use_lowercase_filenames());
+ }
+
+ private void on_radio_changed() {
+ var config = Config.Facade.get_instance();
+
+ if (transparent_checker_radio.active) {
+ config.set_transparent_background_type("checkered");
+ } else if (transparent_solid_radio.active) {
+ config.set_transparent_background_type("solid");
+ } else {
+ config.set_transparent_background_type("none");
+ }
+ }
+
+ private void on_color_changed() {
+ var color = (transparent_solid_color as Gtk.ColorChooser).rgba.to_string();
+ Config.Facade.get_instance().set_transparent_background_color(color);
+ }
+
+ // Ticket #3162, part II - if we're not yet installed, then we have to manually launch
+ // the help viewer and specify the full path to the subsection we want...
+ private bool on_local_pattern_help(string ignore) {
+ try {
+ Resources.launch_help(AppWindow.get_instance().get_screen(), "other-files.page");
+ } catch (Error e) {
+ message("Unable to launch help: %s", e.message);
+ }
+ return true;
+ }
+
+ private void populate_app_combo_box(Gtk.ComboBox combo_box, string[] mime_types,
+ string current_app_executable, out SortedList<AppInfo> external_apps) {
+ // get list of all applications for the given mime types
+ assert(mime_types.length != 0);
+ external_apps = DesktopIntegration.get_apps_for_mime_types(mime_types);
+
+ if (external_apps.size == 0)
+ return;
+
+ // populate application ComboBox with app names and icons
+ Gtk.CellRendererPixbuf pixbuf_renderer = new Gtk.CellRendererPixbuf();
+ Gtk.CellRendererText text_renderer = new Gtk.CellRendererText();
+ combo_box.clear();
+ combo_box.pack_start(pixbuf_renderer, false);
+ combo_box.pack_start(text_renderer, false);
+ combo_box.add_attribute(pixbuf_renderer, "pixbuf", 0);
+ combo_box.add_attribute(text_renderer, "text", 1);
+
+ // TODO: need more space between icons and text
+ Gtk.ListStore combo_store = new Gtk.ListStore(2, typeof(Gdk.Pixbuf), typeof(string));
+ Gtk.TreeIter iter;
+
+ int current_app = -1;
+
+ foreach (AppInfo app in external_apps) {
+ combo_store.append(out iter);
+
+ Icon app_icon = app.get_icon();
+ try {
+ if (app_icon is FileIcon) {
+ combo_store.set_value(iter, 0, scale_pixbuf(new Gdk.Pixbuf.from_file(
+ ((FileIcon) app_icon).get_file().get_path()), Resources.DEFAULT_ICON_SCALE,
+ Gdk.InterpType.BILINEAR, false));
+ } else if (app_icon is ThemedIcon) {
+ Gdk.Pixbuf icon_pixbuf =
+ Gtk.IconTheme.get_default().load_icon(((ThemedIcon) app_icon).get_names()[0],
+ Resources.DEFAULT_ICON_SCALE, Gtk.IconLookupFlags.FORCE_SIZE);
+
+ combo_store.set_value(iter, 0, icon_pixbuf);
+ }
+ } catch (GLib.Error error) {
+ warning("Error loading icon pixbuf: " + error.message);
+ }
+
+ combo_store.set_value(iter, 1, app.get_name());
+
+ if (app.get_commandline() == current_app_executable)
+ current_app = external_apps.index_of(app);
+ }
+
+ // TODO: allow users to choose unlisted applications like Nautilus's "Open with -> Other
Application..."
+
+ combo_box.set_model(combo_store);
+
+ if (current_app != -1)
+ combo_box.set_active(current_app);
+ }
+
+ private void setup_dir_pattern(Gtk.ComboBox combo_box, Gtk.Entry entry) {
+ string? pattern = Config.Facade.get_instance().get_directory_pattern();
+ bool found = false;
+ if (null != pattern) {
+ // Locate pre-built text.
+ int i = 0;
+ foreach (PathFormat pf in path_formats) {
+ if (pf.pattern == pattern) {
+ combo_box.set_active(i);
+ found = true;
+ break;
+ }
+ i++;
+ }
+ } else {
+ // Custom path.
+ string? s = Config.Facade.get_instance().get_directory_pattern_custom();
+ if (!is_string_empty(s)) {
+ combo_box.set_active(path_formats.size - 1); // Assume "custom" is last.
+ found = true;
+ }
+ }
+
+ if (!found) {
+ combo_box.set_active(0);
+ }
+
+ on_dir_pattern_combo_changed();
+ }
+
+ public static void show_preferences() {
+ if (preferences_dialog == null)
+ preferences_dialog = new PreferencesDialog();
+
+ preferences_dialog.populate_preference_options();
+ preferences_dialog.show_all();
+ preferences_dialog.library_dir_button.set_current_folder(AppDirs.get_import_dir().get_path());
+
+ // Ticket #3001: Cause the dialog to become active if the user chooses 'Preferences'
+ // from the menus a second time.
+ preferences_dialog.present();
+ }
+
+ // For items that should only be committed when the dialog is closed, not as soon as the change
+ // is made.
+ private void commit_on_close() {
+ Config.Facade.get_instance().commit_bg_color();
+ Config.Facade.get_instance().set_auto_import_from_library(autoimport.active);
+ Config.Facade.get_instance().set_commit_metadata_to_masters(write_metadata.active);
+
+ if (lib_dir != null)
+ AppDirs.set_import_dir(lib_dir);
+
+ PathFormat pf = path_formats.get(dir_pattern_combo.get_active());
+ if (null == pf.pattern) {
+ Config.Facade.get_instance().set_directory_pattern_custom(dir_pattern_entry.text);
+ Config.Facade.get_instance().set_directory_pattern(null);
+ } else {
+ Config.Facade.get_instance().set_directory_pattern(pf.pattern);
+ }
+ }
+
+ private bool on_delete() {
+ if (!get_allow_closing())
+ return true;
+
+ commit_on_close();
+ return hide_on_delete(); //prevent widgets from getting destroyed
+ }
+
+ private void on_close() {
+ if (!get_allow_closing())
+ return;
+
+ hide();
+ commit_on_close();
+ }
+
+ private void on_value_changed() {
+ set_background_color((double)(bg_color_adjustment.get_upper() -
+ bg_color_adjustment.get_value()) / 65535.0);
+ }
+
+ private bool on_bg_color_reset(Gdk.EventButton event) {
+ if (event.button == 1 && event.type == Gdk.EventType.BUTTON_PRESS
+ && has_only_key_modifier(event.state, Gdk.ModifierType.CONTROL_MASK)) {
+ // Left Mouse Button and CTRL pressed
+ bg_color_slider.set_value(bg_color_adjustment.get_upper() -
+ (parse_color(Config.Facade.DEFAULT_BG_COLOR).red * 65536.0f));
+ on_value_changed();
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private void on_dir_pattern_combo_changed() {
+ PathFormat pf = path_formats.get(dir_pattern_combo.get_active());
+ if (null == pf.pattern) {
+ // Custom format.
+ string? dir_pattern = Config.Facade.get_instance().get_directory_pattern_custom();
+ if (is_string_empty(dir_pattern))
+ dir_pattern = "";
+ dir_pattern_entry.set_text(dir_pattern);
+ dir_pattern_entry.editable = true;
+ dir_pattern_entry.sensitive = true;
+ } else {
+ dir_pattern_entry.set_text(pf.pattern);
+ dir_pattern_entry.editable = false;
+ dir_pattern_entry.sensitive = false;
+ }
+ }
+
+ private void on_dir_pattern_entry_changed() {
+ string example = example_date.format(dir_pattern_entry.text);
+ if (is_string_empty(example) && !is_string_empty(dir_pattern_entry.text)) {
+ // Invalid pattern.
+ dir_pattern_example.set_text(_("Invalid pattern"));
+ dir_pattern_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "dialog-error");
+ dir_pattern_entry.set_icon_activatable(Gtk.EntryIconPosition.SECONDARY, false);
+ set_allow_closing(false);
+ } else {
+ // Valid pattern.
+ dir_pattern_example.set_text(example);
+ dir_pattern_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, null);
+ set_allow_closing(true);
+ }
+ }
+
+ private void set_allow_closing(bool allow) {
+ set_deletable(allow);
+ allow_closing = allow;
+ }
+
+ private bool get_allow_closing() {
+ return allow_closing;
+ }
+
+ private void set_background_color(double bg_color_value) {
+ Config.Facade.get_instance().set_bg_color(to_grayscale(bg_color_value));
+ }
+
+ private Gdk.RGBA to_grayscale(double color_value) {
+ Gdk.RGBA color = Gdk.RGBA();
+
+ color.red = color_value;
+ color.green = color_value;
+ color.blue = color_value;
+ color.alpha = 1.0;
+
+ return color;
+ }
+
+ private void on_photo_editor_changed() {
+ int photo_app_choice_index = (photo_editor_combo.get_active() < external_photo_apps.size) ?
+ photo_editor_combo.get_active() : external_photo_apps.size;
+
+ AppInfo app = external_photo_apps.get_at(photo_app_choice_index);
+
+ Config.Facade.get_instance().set_external_photo_app(DesktopIntegration.get_app_open_command(app));
+
+ debug("setting external photo editor to: %s", DesktopIntegration.get_app_open_command(app));
+ }
+
+ private void on_raw_editor_changed() {
+ int raw_app_choice_index = (raw_editor_combo.get_active() < external_raw_apps.size) ?
+ raw_editor_combo.get_active() : external_raw_apps.size;
+
+ AppInfo app = external_raw_apps.get_at(raw_app_choice_index);
+
+ Config.Facade.get_instance().set_external_raw_app(app.get_commandline());
+
+ debug("setting external raw editor to: %s", app.get_commandline());
+ }
+
+ private RawDeveloper raw_developer_from_combo() {
+ if (default_raw_developer_combo.get_active() == 0)
+ return RawDeveloper.CAMERA;
+ return RawDeveloper.SHOTWELL;
+ }
+
+ private void set_raw_developer_combo(RawDeveloper d) {
+ if (d == RawDeveloper.CAMERA)
+ default_raw_developer_combo.set_active(0);
+ else
+ default_raw_developer_combo.set_active(1);
+ }
+
+ private void on_default_raw_developer_changed() {
+ Config.Facade.get_instance().set_default_raw_developer(raw_developer_from_combo());
+ }
+
+ private void on_current_folder_changed() {
+ lib_dir = library_dir_button.get_filename();
+ }
+
+ public override bool map_event(Gdk.EventAny event) {
+ var result = base.map_event(event);
+ // Set the signal for the lib dir button after the dialog is displayed,
+ // because the FileChooserButton has a nasty habit of selecting a
+ // different folder when displayed if the provided path doesn't exist.
+ // See ticket #3000 for more info.
+ library_dir_button.current_folder_changed.connect(on_current_folder_changed);
+
+ return result;
+ }
+
+ private void add_to_dir_formats(string name, string? pattern) {
+ PathFormat pf = new PathFormat(name, pattern);
+ path_formats.add(pf);
+ dir_pattern_combo.append_text(name);
+ }
+
+ private void on_lowercase_toggled() {
+ Config.Facade.get_instance().set_use_lowercase_filenames(lowercase.get_active());
+ }
+}
diff --git a/src/meson.build b/src/meson.build
index d539586..a41a408 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -193,6 +193,7 @@ executable('shotwell',
'UnityProgressBar.vala',
'Upgrades.vala',
'dialogs/EntryMultiCompletion.vala',
+ 'dialogs/Preferences.vala',
'dialogs/SetBackgroundSlideshow.vala',
'dialogs/SetBackground.vala',
'dialogs/TextEntry.vala',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]