diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2015-04-03 13:15:00 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2015-04-03 13:15:00 +0200 |
commit | bc53b714952ceb0afd02b591403cb2bc0cb1aab9 (patch) | |
tree | 8ff57ed1a1265b2c87f37e3c8fa19876faf80990 /src | |
parent | d4c476947425c12b1984fedea16f8a8c42a07ba3 (diff) | |
parent | c43dfb815a4951b8248f4f0e98babe4f80204f03 (diff) |
Merge tag 'upstream/0.22.0'
Upstream version 0.22.0
Diffstat (limited to 'src')
175 files changed, 1235 insertions, 1147 deletions
diff --git a/src/AppDirs.vala b/src/AppDirs.vala index 6bf6759..1421314 100644 --- a/src/AppDirs.vala +++ b/src/AppDirs.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/AppWindow.vala b/src/AppWindow.vala index 5a8e9c4..d294114 100644 --- a/src/AppWindow.vala +++ b/src/AppWindow.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -10,8 +10,8 @@ public class FullscreenWindow : PageWindow { public const int TOOLBAR_CHECK_DISMISSAL_MSEC = 500; private Gtk.Window toolbar_window = new Gtk.Window(Gtk.WindowType.POPUP); - private Gtk.ToolButton close_button = new Gtk.ToolButton.from_stock(Gtk.Stock.LEAVE_FULLSCREEN); - private Gtk.ToggleToolButton pin_button = new Gtk.ToggleToolButton.from_stock(Resources.PIN_TOOLBAR); + private Gtk.ToolButton close_button = new Gtk.ToolButton(null, null); + private Gtk.ToggleToolButton pin_button = new Gtk.ToggleToolButton(); private bool is_toolbar_shown = false; private bool waiting_for_invoke = false; private time_t left_toolbar_time = 0; @@ -49,11 +49,13 @@ public class FullscreenWindow : PageWindow { // restore pin state is_toolbar_dismissal_enabled = Config.Facade.get_instance().get_pin_toolbar_state(); + pin_button.set_icon_name("pin-toolbar"); pin_button.set_label(_("Pin Toolbar")); pin_button.set_tooltip_text(_("Pin the toolbar open")); pin_button.set_active(!is_toolbar_dismissal_enabled); pin_button.clicked.connect(update_toolbar_dismissal); + close_button.set_icon_name("view-restore"); close_button.set_tooltip_text(_("Leave fullscreen")); close_button.clicked.connect(on_close); @@ -129,10 +131,10 @@ public class FullscreenWindow : PageWindow { private Gtk.ActionEntry[] create_actions() { Gtk.ActionEntry[] actions = new Gtk.ActionEntry[0]; - Gtk.ActionEntry leave_fullscreen = { "LeaveFullscreen", Gtk.Stock.LEAVE_FULLSCREEN, + Gtk.ActionEntry leave_fullscreen = { "LeaveFullscreen", Resources.LEAVE_FULLSCREEN_LABEL, TRANSLATABLE, "F11", TRANSLATABLE, on_close }; - leave_fullscreen.label = _("Leave _Fullscreen"); - leave_fullscreen.tooltip = _("Leave fullscreen"); + leave_fullscreen.label = Resources.LEAVE_FULLSCREEN_LABEL; + leave_fullscreen.tooltip = Resources.LEAVE_FULLSCREEN_LABEL; actions += leave_fullscreen; return actions; @@ -490,27 +492,35 @@ public abstract class AppWindow : PageWindow { ui.ensure_update(); add_accel_group(ui.get_accel_group()); + + Gtk.CssProvider provider = new Gtk.CssProvider(); + try { + provider.load_from_data(Resources.CUSTOM_CSS, -1); + Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + } catch (Error err) { + debug("Unable to load custom CSS: %s", err.message); + } } private Gtk.ActionEntry[] create_common_actions() { Gtk.ActionEntry[] actions = new Gtk.ActionEntry[0]; - Gtk.ActionEntry quit = { "CommonQuit", Gtk.Stock.QUIT, TRANSLATABLE, "<Ctrl>Q", + Gtk.ActionEntry quit = { "CommonQuit", Resources.QUIT_LABEL, TRANSLATABLE, "<Ctrl>Q", TRANSLATABLE, on_quit }; - quit.label = _("_Quit"); + quit.label = Resources.QUIT_LABEL; actions += quit; - Gtk.ActionEntry about = { "CommonAbout", Gtk.Stock.ABOUT, TRANSLATABLE, null, + Gtk.ActionEntry about = { "CommonAbout", Resources.ABOUT_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_about }; - about.label = _("_About"); + about.label = Resources.ABOUT_LABEL; actions += about; - Gtk.ActionEntry fullscreen = { "CommonFullscreen", Gtk.Stock.FULLSCREEN, + Gtk.ActionEntry fullscreen = { "CommonFullscreen", Resources.FULLSCREEN_LABEL, TRANSLATABLE, "F11", TRANSLATABLE, on_fullscreen }; - fullscreen.label = _("Fulls_creen"); + fullscreen.label = Resources.FULLSCREEN_LABEL; actions += fullscreen; - Gtk.ActionEntry help_contents = { "CommonHelpContents", Gtk.Stock.HELP, + Gtk.ActionEntry help_contents = { "CommonHelpContents", Resources.HELP_LABEL, TRANSLATABLE, "F1", TRANSLATABLE, on_help_contents }; help_contents.label = _("_Contents"); actions += help_contents; @@ -525,22 +535,22 @@ public abstract class AppWindow : PageWindow { help_report_problem.label = _("_Report a Problem..."); actions += help_report_problem; - Gtk.ActionEntry undo = { "CommonUndo", Gtk.Stock.UNDO, TRANSLATABLE, "<Ctrl>Z", + Gtk.ActionEntry undo = { "CommonUndo", Resources.UNDO_MENU, TRANSLATABLE, "<Ctrl>Z", TRANSLATABLE, on_undo }; undo.label = Resources.UNDO_MENU; actions += undo; - Gtk.ActionEntry redo = { "CommonRedo", Gtk.Stock.REDO, TRANSLATABLE, "<Ctrl><Shift>Z", + Gtk.ActionEntry redo = { "CommonRedo", Resources.REDO_MENU, TRANSLATABLE, "<Ctrl><Shift>Z", TRANSLATABLE, on_redo }; redo.label = Resources.REDO_MENU; actions += redo; - Gtk.ActionEntry jump_to_file = { "CommonJumpToFile", Gtk.Stock.JUMP_TO, TRANSLATABLE, + Gtk.ActionEntry jump_to_file = { "CommonJumpToFile", Resources.JUMP_TO_FILE_MENU, TRANSLATABLE, "<Ctrl><Shift>M", TRANSLATABLE, on_jump_to_file }; jump_to_file.label = Resources.JUMP_TO_FILE_MENU; actions += jump_to_file; - Gtk.ActionEntry select_all = { "CommonSelectAll", Gtk.Stock.SELECT_ALL, TRANSLATABLE, + Gtk.ActionEntry select_all = { "CommonSelectAll", Resources.SELECT_ALL_MENU, TRANSLATABLE, "<Ctrl>A", TRANSLATABLE, on_select_all }; select_all.label = Resources.SELECT_ALL_MENU; actions += select_all; diff --git a/src/Application.vala b/src/Application.vala index 95163cf..fa81832 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/BatchImport.vala b/src/BatchImport.vala index d4298ed..13feabe 100644 --- a/src/BatchImport.vala +++ b/src/BatchImport.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Box.vala b/src/Box.vala index f48bcfb..253f0b6 100644 --- a/src/Box.vala +++ b/src/Box.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/CheckerboardLayout.vala b/src/CheckerboardLayout.vala index 6d0ce61..b71870c 100644 --- a/src/CheckerboardLayout.vala +++ b/src/CheckerboardLayout.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/CollectionPage.vala b/src/CollectionPage.vala index 22dcdee..95cbf01 100644 --- a/src/CollectionPage.vala +++ b/src/CollectionPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -142,7 +142,7 @@ public abstract class CollectionPage : MediaPage { protected override Gtk.ActionEntry[] init_collect_action_entries() { Gtk.ActionEntry[] actions = base.init_collect_action_entries(); - Gtk.ActionEntry print = { "Print", Gtk.Stock.PRINT, TRANSLATABLE, "<Ctrl>P", + Gtk.ActionEntry print = { "Print", Resources.PRINT_LABEL, TRANSLATABLE, "<Ctrl>P", TRANSLATABLE, on_print }; print.label = Resources.PRINT_MENU; actions += print; @@ -193,7 +193,7 @@ public abstract class CollectionPage : MediaPage { paste_adjustments.tooltip = Resources.PASTE_ADJUSTMENTS_TOOLTIP; actions += paste_adjustments; - Gtk.ActionEntry revert = { "Revert", Gtk.Stock.REVERT_TO_SAVED, TRANSLATABLE, null, + Gtk.ActionEntry revert = { "Revert", null, TRANSLATABLE, null, TRANSLATABLE, on_revert }; revert.label = Resources.REVERT_MENU; actions += revert; @@ -215,7 +215,7 @@ public abstract class CollectionPage : MediaPage { adjust_date_time.label = Resources.ADJUST_DATE_TIME_MENU; actions += adjust_date_time; - Gtk.ActionEntry external_edit = { "ExternalEdit", Gtk.Stock.EDIT, TRANSLATABLE, "<Ctrl>Return", + Gtk.ActionEntry external_edit = { "ExternalEdit", Resources.EDIT_LABEL, TRANSLATABLE, "<Ctrl>Return", TRANSLATABLE, on_external_edit }; external_edit.label = Resources.EXTERNAL_EDIT_MENU; actions += external_edit; diff --git a/src/ColorTransformation.vala b/src/ColorTransformation.vala index 74e4cf2..1e3e4a8 100644 --- a/src/ColorTransformation.vala +++ b/src/ColorTransformation.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/CommandManager.vala b/src/CommandManager.vala index 070bc73..379b259 100644 --- a/src/CommandManager.vala +++ b/src/CommandManager.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Commands.vala b/src/Commands.vala index 04b771c..d1a0593 100644 --- a/src/Commands.vala +++ b/src/Commands.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/CustomComponents.vala b/src/CustomComponents.vala index 4ace52c..d9e4916 100644 --- a/src/CustomComponents.vala +++ b/src/CustomComponents.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Debug.vala b/src/Debug.vala index ad626f4..c8e8de5 100644 --- a/src/Debug.vala +++ b/src/Debug.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/DesktopIntegration.vala b/src/DesktopIntegration.vala index 9978803..1ee3c59 100644 --- a/src/DesktopIntegration.vala +++ b/src/DesktopIntegration.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/Dialogs.vala b/src/Dialogs.vala index 1f6a5ce..d760e73 100644 --- a/src/Dialogs.vala +++ b/src/Dialogs.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -35,7 +35,7 @@ public bool confirm_warn_developer_changed(int number) { "<span weight=\"bold\" size=\"larger\">%s</span>".printf(ngettext("Switching developers will undo all changes you have made to this photo in Shotwell", "Switching developers will undo all changes you have made to these photos in Shotwell", number))); - dialog.add_buttons(Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL); + dialog.add_buttons(Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL); dialog.add_buttons(_("_Switch Developer"), Gtk.ResponseType.YES); int response = dialog.run(); @@ -58,8 +58,8 @@ public File? choose_file(string current_file_basename) { _("Export Video") : _("Export Photo"); Gtk.FileChooserDialog chooser = new Gtk.FileChooserDialog(file_chooser_title, - AppWindow.get_instance(), Gtk.FileChooserAction.SAVE, Gtk.Stock.CANCEL, - Gtk.ResponseType.CANCEL, Gtk.Stock.SAVE, Gtk.ResponseType.ACCEPT, null); + AppWindow.get_instance(), Gtk.FileChooserAction.SAVE, Resources.CANCEL_LABEL, + Gtk.ResponseType.CANCEL, Resources.SAVE_LABEL, Gtk.ResponseType.ACCEPT, null); chooser.set_do_overwrite_confirmation(true); chooser.set_current_folder(current_export_dir.get_path()); chooser.set_current_name(current_file_basename); @@ -87,8 +87,8 @@ public File? choose_dir(string? user_title = null) { user_title = _("Export Photos"); Gtk.FileChooserDialog chooser = new Gtk.FileChooserDialog(user_title, - AppWindow.get_instance(), Gtk.FileChooserAction.SELECT_FOLDER, Gtk.Stock.CANCEL, - Gtk.ResponseType.CANCEL, Gtk.Stock.OK, Gtk.ResponseType.ACCEPT, null); + AppWindow.get_instance(), Gtk.FileChooserAction.SELECT_FOLDER, Resources.CANCEL_LABEL, + Gtk.ResponseType.CANCEL, Resources.OK_LABEL, Gtk.ResponseType.ACCEPT, null); chooser.set_current_folder(current_export_dir.get_path()); chooser.set_local_only(false); @@ -168,6 +168,8 @@ public class ExportDialog : Gtk.Dialog { private bool in_insert = false; public ExportDialog(string title) { + Object (use_header_bar: 1); + this.title = title; resizable = false; @@ -198,7 +200,6 @@ public class ExportDialog : Gtk.Dialog { pixels_entry = new Gtk.Entry(); pixels_entry.set_max_length(6); - pixels_entry.set_size_request(60, -1); pixels_entry.set_text("%d".printf(current_scale)); // register after preparation to avoid signals during init @@ -218,30 +219,23 @@ public class ExportDialog : Gtk.Dialog { add_label(_("_Scaling constraint:"), 0, 2, constraint_combo); add_control(constraint_combo, 1, 2); - Gtk.Label pixels_label = new Gtk.Label.with_mnemonic(_(" _pixels")); - pixels_label.set_mnemonic_widget(pixels_entry); - - Gtk.Box pixels_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); - pixels_box.pack_start(pixels_entry, false, false, 0); - pixels_box.pack_end(pixels_label, false, false, 0); - add_control(pixels_box, 1, 3); + add_label(_("_Pixels:"), 0, 3, pixels_entry); + add_control(pixels_entry, 1, 3); export_metadata = new Gtk.CheckButton.with_label(_("Export metadata")); add_control(export_metadata, 1, 4); export_metadata.active = true; - table.set_row_spacing(4); - table.set_column_spacing(4); - table.set_margin_top(4); - table.set_margin_bottom(4); - table.set_margin_left(4); - table.set_margin_right(4); + table.set_row_spacing(5); + table.set_column_spacing(5); + table.set_border_width(3); ((Gtk.Box) get_content_area()).add(table); // add buttons to action area - add_button(Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL); - ok_button = add_button(Gtk.Stock.OK, Gtk.ResponseType.OK); + 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; @@ -357,7 +351,7 @@ public class ExportDialog : Gtk.Dialog { } private void add_label(string text, int x, int y, Gtk.Widget? widget = null) { - Gtk.Alignment left_aligned = new Gtk.Alignment(0.0f, 0.5f, 0, 0); + Gtk.Alignment left_aligned = new Gtk.Alignment(1, 0.5f, 0, 0); Gtk.Label new_label = new Gtk.Label.with_mnemonic(text); new_label.set_use_underline(true); @@ -371,7 +365,7 @@ public class ExportDialog : Gtk.Dialog { } private void add_control(Gtk.Widget widget, int x, int y) { - Gtk.Alignment left_aligned = new Gtk.Alignment(0, 0.5f, 0, 0); + Gtk.Alignment left_aligned = new Gtk.Alignment(0, 0.5f, 1, 0); left_aligned.add(widget); table.attach(left_aligned, x, y, 1, 1); @@ -857,7 +851,7 @@ public bool report_manifest(ImportManifest manifest, bool show_dest_id, Gtk.Widget save_results_button = dialog.add_button(ImportUI.SAVE_RESULTS_BUTTON_NAME, ImportUI.SAVE_RESULTS_RESPONSE_ID); save_results_button.set_visible(manifest.success.size < manifest.all.size); - Gtk.Widget ok_button = dialog.add_button(Gtk.Stock.OK, Gtk.ResponseType.OK); + Gtk.Widget ok_button = dialog.add_button(Resources.OK_LABEL, Gtk.ResponseType.OK); dialog.set_default(ok_button); Gtk.Window dialog_parent = (Gtk.Window) dialog.get_parent(); @@ -896,7 +890,7 @@ public bool report_manifest(ImportManifest manifest, bool show_dest_id, internal void save_import_results(Gtk.Window? chooser_dialog_parent, string results_log) { Gtk.FileChooserDialog chooser_dialog = new Gtk.FileChooserDialog( ImportUI.SAVE_RESULTS_FILE_CHOOSER_TITLE, chooser_dialog_parent, Gtk.FileChooserAction.SAVE, - Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, Gtk.Stock.SAVE, Gtk.ResponseType.ACCEPT, null); + Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL, Resources.SAVE_AS_LABEL, Gtk.ResponseType.ACCEPT, null); chooser_dialog.set_do_overwrite_confirmation(true); chooser_dialog.set_current_folder(Environment.get_home_dir()); chooser_dialog.set_current_name("Shotwell Import Log.txt"); @@ -1196,6 +1190,10 @@ public class TextEntryDialog : Gtk.Dialog { private Gtk.Button button2; private Gtk.ButtonBox action_area_box; + public TextEntryDialog() { + Object (use_header_bar: 1); + } + public void set_builder(Gtk.Builder builder) { this.builder = builder; } @@ -1204,7 +1202,6 @@ public class TextEntryDialog : Gtk.Dialog { string? initial_text, Gee.Collection<string>? completion_list, string? completion_delimiter) { set_title(title); set_resizable(true); - set_default_size (350, 104); set_parent_window(AppWindow.get_instance().get_parent_window()); set_transient_for(AppWindow.get_instance()); on_modify_validate = modify_validate; @@ -1220,8 +1217,8 @@ public class TextEntryDialog : Gtk.Dialog { action_area_box = (Gtk.ButtonBox) get_action_area(); action_area_box.set_layout(Gtk.ButtonBoxStyle.END); - button1 = (Gtk.Button) add_button(Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL); - button2 = (Gtk.Button) add_button(Gtk.Stock.SAVE, Gtk.ResponseType.OK); + button1 = (Gtk.Button) add_button(Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL); + button2 = (Gtk.Button) add_button(Resources.SAVE_LABEL, Gtk.ResponseType.OK); set_default_response(Gtk.ResponseType.OK); if (completion_list != null) { // Textfield with autocompletion @@ -1266,6 +1263,10 @@ public class MultiTextEntryDialog : Gtk.Dialog { private Gtk.Button button2; private Gtk.ButtonBox action_area_box; + public MultiTextEntryDialog() { + Object (use_header_bar: 1); + } + public void set_builder(Gtk.Builder builder) { this.builder = builder; } @@ -1278,12 +1279,6 @@ public class MultiTextEntryDialog : Gtk.Dialog { set_transient_for(AppWindow.get_instance()); on_modify_validate = modify_validate; - Gtk.Label name_label = builder.get_object("label9") as Gtk.Label; - name_label.set_text(label); - - Gtk.ScrolledWindow scrolled = builder.get_object("scrolledwindow1") as Gtk.ScrolledWindow; - scrolled.set_shadow_type (Gtk.ShadowType.ETCHED_IN); - entry = builder.get_object("textview1") as Gtk.TextView; entry.set_wrap_mode (Gtk.WrapMode.WORD); entry.buffer = new Gtk.TextBuffer(null); @@ -1294,8 +1289,9 @@ public class MultiTextEntryDialog : Gtk.Dialog { action_area_box = (Gtk.ButtonBox) get_action_area(); action_area_box.set_layout(Gtk.ButtonBoxStyle.END); - button1 = (Gtk.Button) add_button(Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL); - button2 = (Gtk.Button) add_button(Gtk.Stock.SAVE, Gtk.ResponseType.OK); + button1 = (Gtk.Button) add_button(Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL); + button2 = (Gtk.Button) add_button(Resources.SAVE_LABEL, Gtk.ResponseType.OK); + set_default_response(Gtk.ResponseType.OK); set_has_resize_grip(true); } @@ -1326,7 +1322,9 @@ public class EventRenameDialog : TextEntryDialogMediator { public class EditTitleDialog : TextEntryDialogMediator { public EditTitleDialog(string? photo_title) { - base (_("Edit Title"), _("Title:"), photo_title); + // Dialog title + base (_("Edit Title"), + _("Title:"), photo_title); } public virtual string? execute() { @@ -1340,7 +1338,10 @@ public class EditTitleDialog : TextEntryDialogMediator { public class EditCommentDialog : MultiTextEntryDialogMediator { public EditCommentDialog(string? comment, bool is_event = false) { - string title_tmp = (is_event) ? _("Edit Event Comment") : _("Edit Photo/Video Comment"); + string title_tmp = (is_event) + // Dialog title + ? _("Edit Event Comment") + : _("Edit Photo/Video Comment"); base(title_tmp, _("Comment:"), comment); } @@ -1477,7 +1478,7 @@ public class ProgressDialog : Gtk.Window { vbox_bar.pack_start(progress_bar, true, false, 0); if (cancellable != null) { - cancel_button = new Gtk.Button.from_stock(Gtk.Stock.CANCEL); + cancel_button = new Gtk.Button.with_mnemonic(Resources.CANCEL_LABEL); cancel_button.clicked.connect(on_cancel); delete_event.connect(on_window_closed); } @@ -1648,12 +1649,14 @@ public class AdjustDateTimeDialog : Gtk.Dialog { bool contains_video = false, bool only_video = false) { assert(source != null); + Object(use_header_bar: 1); + set_modal(true); set_resizable(false); set_transient_for(AppWindow.get_instance()); - add_buttons(Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, - Gtk.Stock.OK, Gtk.ResponseType.OK); + add_buttons(Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL, + Resources.OK_LABEL, Gtk.ResponseType.OK); set_title(Resources.ADJUST_DATE_TIME_LABEL); calendar = new Gtk.Calendar(); @@ -1669,13 +1672,16 @@ public class AdjustDateTimeDialog : Gtk.Dialog { hour.output.connect(on_spin_button_output); hour.set_width_chars(2); + hour.set_max_width_chars(2); minute = new Gtk.SpinButton.with_range(0, 59, 1); minute.set_width_chars(2); + minute.set_max_width_chars(2); minute.output.connect(on_spin_button_output); second = new Gtk.SpinButton.with_range(0, 59, 1); second.set_width_chars(2); + second.set_max_width_chars(2); second.output.connect(on_spin_button_output); system = new Gtk.ComboBoxText(); @@ -1684,14 +1690,14 @@ public class AdjustDateTimeDialog : Gtk.Dialog { system.append_text(_("24 Hr")); system.changed.connect(on_time_system_changed); - Gtk.Box clock = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); + Gtk.Box clock = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 3); - clock.pack_start(hour, false, false, 3); - clock.pack_start(new Gtk.Label(":"), false, false, 3); // internationalize? - clock.pack_start(minute, false, false, 3); - clock.pack_start(new Gtk.Label(":"), false, false, 3); - clock.pack_start(second, false, false, 3); - clock.pack_start(system, false, false, 3); + clock.pack_start(hour, false, false, 0); + clock.pack_start(new Gtk.Label(":"), false, false, 0); // internationalize? + clock.pack_start(minute, false, false, 0); + clock.pack_start(new Gtk.Label(":"), false, false, 0); + clock.pack_start(second, false, false, 0); + clock.pack_start(system, false, false, 0); set_default_response(Gtk.ResponseType.OK); @@ -1719,15 +1725,15 @@ public class AdjustDateTimeDialog : Gtk.Dialog { modify_originals_check_button.sensitive = (!only_video) && (!Config.Facade.get_instance().get_commit_metadata_to_masters() && display_options); - Gtk.Box time_content = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); + Gtk.Box time_content = new Gtk.Box(Gtk.Orientation.VERTICAL, 5); - time_content.pack_start(calendar, true, false, 3); - time_content.pack_start(clock, true, false, 3); + time_content.pack_start(calendar, true, false, 0); + time_content.pack_start(clock, true, false, 0); if (display_options) { - time_content.pack_start(relativity_radio_button, true, false, 3); - time_content.pack_start(batch_radio_button, true, false, 3); - time_content.pack_start(modify_originals_check_button, true, false, 3); + time_content.pack_start(relativity_radio_button, true, false, 0); + time_content.pack_start(batch_radio_button, true, false, 0); + time_content.pack_start(modify_originals_check_button, true, false, 0); } Gdk.Pixbuf preview = null; @@ -1740,26 +1746,26 @@ public class AdjustDateTimeDialog : Gtk.Dialog { } Gtk.Box image_content = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); + image_content.set_valign(Gtk.Align.START); + image_content.set_homogeneous(true); Gtk.Image image = (preview != null) ? new Gtk.Image.from_pixbuf(preview) : new Gtk.Image(); original_time_label = new Gtk.Label(null); - image_content.pack_start(image, true, false, 3); - image_content.pack_start(original_time_label, true, false, 3); + image_content.pack_start(image, true, false, 0); + image_content.pack_start(original_time_label, true, false, 0); - Gtk.Box hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); - hbox.pack_start(image_content, true, false, 6); - hbox.pack_start(time_content, true, false, 6); + Gtk.Box hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 10); + hbox.set_border_width(3); + hbox.pack_start(image_content, true, false, 0); + hbox.pack_start(time_content, true, false, 0); Gtk.Alignment hbox_alignment = new Gtk.Alignment(0.5f, 0.5f, 0, 0); - hbox_alignment.set_padding(6, 3, 6, 6); hbox_alignment.add(hbox); - ((Gtk.Box) get_content_area()).pack_start(hbox_alignment, true, false, 6); + ((Gtk.Box) get_content_area()).pack_start(hbox_alignment, true, false, 0); notification = new Gtk.Label(""); notification.set_line_wrap(true); notification.set_justify(Gtk.Justification.CENTER); - notification.set_size_request(-1, -1); - notification.set_padding(12, 6); ((Gtk.Box) get_content_area()).pack_start(notification, true, true, 0); @@ -1779,8 +1785,8 @@ public class AdjustDateTimeDialog : Gtk.Dialog { calendar.select_day(time.day); if (Config.Facade.get_instance().get_use_24_hour_time()) { - hour.set_value(time.hour); system.set_active(TimeSystem.24HR); + hour.set_value(time.hour); } else { int AMPM_hour = time.hour % 12; hour.set_value((AMPM_hour == 0) ? 12 : AMPM_hour); @@ -2066,7 +2072,7 @@ public class WelcomeDialog : Gtk.Dialog { public WelcomeDialog(Gtk.Window owner) { import_meta_host = new Spit.DataImports.WelcomeImportMetaHost(this); bool show_system_pictures_import = is_system_pictures_import_possible(); - Gtk.Widget ok_button = add_button(Gtk.Stock.OK, Gtk.ResponseType.OK); + Gtk.Widget ok_button = add_button(Resources.OK_LABEL, Gtk.ResponseType.OK); set_title(_("Welcome!")); set_resizable(false); set_type_hint(Gdk.WindowTypeHint.DIALOG); @@ -2265,7 +2271,6 @@ public class PreferencesDialog { 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); private Gtk.CheckButton lowercase; - private Gtk.Button close_button; private Plugins.ManifestWidgetMediator plugins_mediator = new Plugins.ManifestWidgetMediator(); private Gtk.ComboBoxText default_raw_developer_combo; @@ -2289,8 +2294,6 @@ public class PreferencesDialog { library_dir_button = builder.get_object("library_dir_button") as Gtk.FileChooserButton; - close_button = builder.get_object("close_button") as Gtk.Button; - photo_editor_combo = builder.get_object("external_photo_editor_combo") as Gtk.ComboBox; raw_editor_combo = builder.get_object("external_raw_editor_combo") as Gtk.ComboBox; @@ -2563,20 +2566,19 @@ public class PreferencesDialog { 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_stock(Gtk.EntryIconPosition.SECONDARY, Gtk.Stock.DIALOG_ERROR); + 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_stock(Gtk.EntryIconPosition.SECONDARY, null); + dir_pattern_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, null); set_allow_closing(true); } } private void set_allow_closing(bool allow) { dialog.set_deletable(allow); - close_button.set_sensitive(allow); allow_closing = allow; } diff --git a/src/Dimensions.vala b/src/Dimensions.vala index f689aca..42188d3 100644 --- a/src/Dimensions.vala +++ b/src/Dimensions.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/DirectoryMonitor.vala b/src/DirectoryMonitor.vala index 1778fe4..468425f 100644 --- a/src/DirectoryMonitor.vala +++ b/src/DirectoryMonitor.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Event.vala b/src/Event.vala index ed0af76..cbc3485 100644 --- a/src/Event.vala +++ b/src/Event.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Exporter.vala b/src/Exporter.vala index a930c4c..6a1b377 100644 --- a/src/Exporter.vala +++ b/src/Exporter.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/International.vala b/src/International.vala index 1bf242b..a51d0a2 100644 --- a/src/International.vala +++ b/src/International.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/LibraryFiles.vala b/src/LibraryFiles.vala index 4cffe94..918ed1e 100644 --- a/src/LibraryFiles.vala +++ b/src/LibraryFiles.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/LibraryMonitor.vala b/src/LibraryMonitor.vala index 363213b..4793f7d 100644 --- a/src/LibraryMonitor.vala +++ b/src/LibraryMonitor.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/MediaDataRepresentation.vala b/src/MediaDataRepresentation.vala index 6a54718..31b9cc8 100644 --- a/src/MediaDataRepresentation.vala +++ b/src/MediaDataRepresentation.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/MediaInterfaces.vala b/src/MediaInterfaces.vala index 96c5d49..e5f078c 100644 --- a/src/MediaInterfaces.vala +++ b/src/MediaInterfaces.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/MediaMetadata.vala b/src/MediaMetadata.vala index ad0d719..22ee96b 100644 --- a/src/MediaMetadata.vala +++ b/src/MediaMetadata.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/MediaMonitor.vala b/src/MediaMonitor.vala index aeb2952..5d9c488 100644 --- a/src/MediaMonitor.vala +++ b/src/MediaMonitor.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/MediaPage.vala b/src/MediaPage.vala index 9f98466..6496503 100644 --- a/src/MediaPage.vala +++ b/src/MediaPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -9,6 +9,7 @@ public class MediaSourceItem : CheckerboardItem { private static Gdk.Pixbuf current_sprocket_pixbuf = null; private bool enable_sprockets = false; + private string? natural_collation_key = null; // preserve the same constructor arguments and semantics as CheckerboardItem so that we're // a drop-in replacement @@ -93,6 +94,19 @@ public class MediaSourceItem : CheckerboardItem { public void set_enable_sprockets(bool enable_sprockets) { this.enable_sprockets = enable_sprockets; } + + public new void set_title(string text, bool marked_up = false, + Pango.Alignment alignment = Pango.Alignment.LEFT) { + base.set_title(text, marked_up, alignment); + this.natural_collation_key = null; + } + + public string get_natural_collation_key() { + if (this.natural_collation_key == null) { + this.natural_collation_key = NaturalCollate.collate_key(this.get_title()); + } + return this.natural_collation_key; + } } public abstract class MediaPage : CheckerboardPage { @@ -108,7 +122,8 @@ public abstract class MediaPage : CheckerboardPage { TITLE = 1, EXPOSURE_DATE = 2, RATING = 3, - MAX = 3 + FILENAME = 4, + MAX = 4 } protected class ZoomSliderAssembly : Gtk.ToolItem { @@ -271,7 +286,7 @@ public abstract class MediaPage : CheckerboardPage { protected override Gtk.ActionEntry[] init_collect_action_entries() { Gtk.ActionEntry[] actions = base.init_collect_action_entries(); - Gtk.ActionEntry export = { "Export", Gtk.Stock.SAVE_AS, TRANSLATABLE, "<Ctrl><Shift>E", + Gtk.ActionEntry export = { "Export", Resources.SAVE_AS_LABEL, TRANSLATABLE, "<Ctrl><Shift>E", TRANSLATABLE, on_export }; export.label = Resources.EXPORT_MENU; actions += export; @@ -288,7 +303,7 @@ public abstract class MediaPage : CheckerboardPage { send_to_context_menu.label = Resources.SEND_TO_CONTEXT_MENU; actions += send_to_context_menu; - Gtk.ActionEntry remove_from_library = { "RemoveFromLibrary", Gtk.Stock.REMOVE, TRANSLATABLE, + Gtk.ActionEntry remove_from_library = { "RemoveFromLibrary", Resources.REMOVE_LABEL, TRANSLATABLE, "<Shift>Delete", TRANSLATABLE, on_remove_from_library }; remove_from_library.label = Resources.REMOVE_FROM_LIBRARY_MENU; actions += remove_from_library; @@ -298,7 +313,7 @@ public abstract class MediaPage : CheckerboardPage { move_to_trash.label = Resources.MOVE_TO_TRASH_MENU; actions += move_to_trash; - Gtk.ActionEntry new_event = { "NewEvent", Gtk.Stock.NEW, TRANSLATABLE, "<Ctrl>N", + Gtk.ActionEntry new_event = { "NewEvent", Resources.NEW_LABEL, TRANSLATABLE, "<Ctrl>N", TRANSLATABLE, on_new_event }; new_event.label = Resources.NEW_EVENT_MENU; actions += new_event; @@ -320,13 +335,13 @@ public abstract class MediaPage : CheckerboardPage { modify_tags.label = Resources.MODIFY_TAGS_MENU; actions += modify_tags; - Gtk.ActionEntry increase_size = { "IncreaseSize", Gtk.Stock.ZOOM_IN, TRANSLATABLE, + Gtk.ActionEntry increase_size = { "IncreaseSize", Resources.ZOOM_IN_LABEL, TRANSLATABLE, "<Ctrl>plus", TRANSLATABLE, on_increase_size }; increase_size.label = _("Zoom _In"); increase_size.tooltip = _("Increase the magnification of the thumbnails"); actions += increase_size; - Gtk.ActionEntry decrease_size = { "DecreaseSize", Gtk.Stock.ZOOM_OUT, TRANSLATABLE, + Gtk.ActionEntry decrease_size = { "DecreaseSize", Resources.ZOOM_OUT_LABEL, TRANSLATABLE, "<Ctrl>minus", TRANSLATABLE, on_decrease_size }; decrease_size.label = _("Zoom _Out"); decrease_size.tooltip = _("Decrease the magnification of the thumbnails"); @@ -403,7 +418,7 @@ public abstract class MediaPage : CheckerboardPage { filter_photos.label = Resources.FILTER_PHOTOS_MENU; actions += filter_photos; - Gtk.ActionEntry play = { "PlayVideo", Gtk.Stock.MEDIA_PLAY, TRANSLATABLE, "<Ctrl>Y", + Gtk.ActionEntry play = { "PlayVideo", Resources.PLAY_LABEL, TRANSLATABLE, "<Ctrl>Y", TRANSLATABLE, on_play_video }; play.label = _("_Play Video"); play.tooltip = _("Open the selected videos in the system video player"); @@ -484,18 +499,24 @@ public abstract class MediaPage : CheckerboardPage { by_rating.tooltip = _("Sort photos by rating"); sort_crit_actions += by_rating; + Gtk.RadioActionEntry by_filename = { "SortByFilename", null, TRANSLATABLE, null, + TRANSLATABLE, SortBy.FILENAME }; + by_filename.label = _("By _Filename"); + by_filename.tooltip = _("Sort photos by filename"); + sort_crit_actions += by_filename; + action_group.add_radio_actions(sort_crit_actions, sort_by, on_sort_changed); // Sort order. Gtk.RadioActionEntry[] sort_order_actions = new Gtk.RadioActionEntry[0]; - Gtk.RadioActionEntry ascending = { "SortAscending", Gtk.Stock.SORT_ASCENDING, + Gtk.RadioActionEntry ascending = { "SortAscending", Resources.SORT_ASCENDING_LABEL, TRANSLATABLE, null, TRANSLATABLE, SORT_ORDER_ASCENDING }; ascending.label = _("_Ascending"); ascending.tooltip = _("Sort photos in an ascending order"); sort_order_actions += ascending; - Gtk.RadioActionEntry descending = { "SortDescending", Gtk.Stock.SORT_DESCENDING, + Gtk.RadioActionEntry descending = { "SortDescending", Resources.SORT_DESCENDING_LABEL, TRANSLATABLE, null, TRANSLATABLE, SORT_ORDER_DESCENDING }; descending.label = _("D_escending"); descending.tooltip = _("Sort photos in a descending order"); @@ -1206,6 +1227,13 @@ public abstract class MediaPage : CheckerboardPage { predicate = Thumbnail.rating_comparator_predicate; break; + case SortBy.FILENAME: + if (ascending) + comparator = Thumbnail.filename_ascending_comparator; + else comparator = Thumbnail.filename_descending_comparator; + predicate = Thumbnail.filename_comparator_predicate; + break; + default: debug("Unknown sort criteria: %s", get_menu_sort_by().to_string()); comparator = Thumbnail.title_descending_comparator; @@ -1226,6 +1254,9 @@ public abstract class MediaPage : CheckerboardPage { case SortBy.RATING: return "/MenuBar/ViewMenu/SortPhotos/SortByRating"; + + case SortBy.FILENAME: + return "/MenuBar/ViewMenu/SortPhotos/SortByFilename"; default: debug("Unknown sort criteria: %d", sort_by); diff --git a/src/MediaViewTracker.vala b/src/MediaViewTracker.vala index 879dc84..0c48f2d 100644 --- a/src/MediaViewTracker.vala +++ b/src/MediaViewTracker.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/MetadataWriter.vala b/src/MetadataWriter.vala index aee5855..969506e 100644 --- a/src/MetadataWriter.vala +++ b/src/MetadataWriter.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -23,6 +23,8 @@ public class MetadataWriter : Object { public Photo.ReimportMasterState reimport_master_state = null; public Photo.ReimportEditableState reimport_editable_state = null; public Error? err = null; + public bool wrote_master = false; + public bool wrote_editable = false; public CommitJob(MetadataWriter owner, LibraryPhoto photo, Gee.Set<string>? keywords) { base (owner, owner.on_update_completed, new Cancellable(), owner.on_update_cancelled); @@ -58,6 +60,8 @@ public class MetadataWriter : Object { LibraryMonitor.unblacklist_file(photo.get_master_file()); } } + + wrote_master = true; } private void commit_editable() throws Error { @@ -75,6 +79,8 @@ public class MetadataWriter : Object { LibraryMonitor.unblacklist_file(photo.get_editable_file()); } } + + wrote_editable = true; } private bool update_metadata(PhotoMetadata metadata, bool skip_orientation = false) { @@ -617,10 +623,21 @@ public class MetadataWriter : Object { private void on_update_completed(BackgroundJob j) { CommitJob job = (CommitJob) j; - if (job.err != null) - warning("Unable to update metadata for %s: %s", job.photo.to_string(), job.err.message); - else - message("Completed writing metadata for %s", job.photo.to_string()); + if (job.err != null) { + warning("Unable to write metadata to %s: %s", job.photo.to_string(), job.err.message); + } else { + if (job.wrote_master) + message("Completed writing metadata to %s", job.photo.get_master_file().get_path()); + else + message("Unable to write metadata to %s", job.photo.get_master_file().get_path()); + + if (job.photo.get_editable_file() != null) { + if (job.wrote_editable) + message("Completed writing metadata to %s", job.photo.get_editable_file().get_path()); + else + message("Unable to write metadata to %s", job.photo.get_editable_file().get_path()); + } + } bool removed = pending.unset(job.photo); assert(removed); diff --git a/src/NaturalCollate.vala b/src/NaturalCollate.vala new file mode 100644 index 0000000..4adb027 --- /dev/null +++ b/src/NaturalCollate.vala @@ -0,0 +1,98 @@ +/** + * NaturalCollate + * Simple helper class for natural sorting in Vala. + * + * (c) Tobia Tesan <tobia.tesan@gmail.com>, 2014 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the Lesser GNU General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; see the file COPYING. If not, + * see <http://www.gnu.org/licenses/>. + */ + +namespace NaturalCollate { + +private const unichar SUPERDIGIT = ':'; +private const unichar NUM_SENTINEL = 0x2; // glib uses these, so do we +private const string COLLATION_SENTINEL = "\x01\x01\x01"; + +private static int read_number(owned string s, ref int byte_index) { + /* + * Given a string in the form [numerals]*[everythingelse]* + * returns the int value of the first block and increments index + * by its length as a side effect. + * Notice that "numerals" is not just 0-9 but everything else + * Unicode considers a numeral (see: string::isdigit()) + */ + int number = 0; + + while (s.length != 0 && s.get_char(0).isdigit()) { + number = number*10; + number += s.get_char(0).digit_value(); + int second_char = s.index_of_nth_char(1); + s = s.substring(second_char); + byte_index += second_char; + } + return number; +} + +public static int compare(string str1, string str2) { + return strcmp(collate_key(str1), collate_key(str2)); +} + +public static string collate_key(owned string str) { + /* + * Computes a collate key. + * Has roughly the same effect as g_utf8_collate_key_for_file, except that it doesn't + * handle the dot as a special char. + */ + assert (str.validate()); + string result = ""; + bool eos = (str.length == 0); + + while (!eos) { + assert(str.validate()); + int position = 0; + while (!(str.get_char(position).to_string() in "0123456789")) { + // We only care about plain old 0123456789, aping what g_utf8_collate_key_for_filename does + position++; + } + + // (0... position( is a bunch of non-numerical chars, so we compute and append the collate key... + result = result + (str.substring(0, position).collate_key()); + + // ...then throw them away + str = str.substring(position); + + eos = (str.length == 0); + position = 0; + + if (!eos) { + // We have some numbers to handle in front of us + int number = read_number(str, ref position); + str = str.substring(position); + int number_of_superdigits = number.to_string().length; + string to_append = ""; + for (int i = 1; i < number_of_superdigits; i++) { + // We append n - 1 superdigits where n is the number of digits + to_append = to_append + SUPERDIGIT.to_string(); + } + to_append = to_append + (number.to_string()); // We append the actual number + result = result + + COLLATION_SENTINEL + + NUM_SENTINEL.to_string() + + to_append; + } + eos = (str.length == 0); + } + + result = result + NUM_SENTINEL.to_string(); + // No specific reason except that glib does it + + return result; +} +} diff --git a/src/Orientation.vala b/src/Orientation.vala index b31c22d..e9f0cd0 100644 --- a/src/Orientation.vala +++ b/src/Orientation.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Page.vala b/src/Page.vala index 807a926..72613e0 100644 --- a/src/Page.vala +++ b/src/Page.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -95,8 +95,6 @@ public abstract class Page : Gtk.ScrolledWindow { init_ui(); realize.connect(attach_view_signals); - - Resources.style_widget(this, Resources.SCROLL_FRAME_STYLESHEET); } ~Page() { @@ -218,6 +216,7 @@ public abstract class Page : Gtk.ScrolledWindow { toolbar = toolbar_path == null ? new Gtk.Toolbar() : ui.get_widget(toolbar_path) as Gtk.Toolbar; toolbar.get_style_context().add_class("bottom-toolbar"); // for elementary theme + toolbar.set_icon_size(Gtk.IconSize.SMALL_TOOLBAR); } return toolbar; } @@ -1210,8 +1209,6 @@ public abstract class CheckerboardPage : Page { viewport.set_border_width(0); viewport.set_shadow_type(Gtk.ShadowType.NONE); - Resources.style_widget(viewport, Resources.VIEWPORT_STYLESHEET); - viewport.add(layout); // want to set_adjustments before adding to ScrolledWindow to let our signal handlers @@ -1228,8 +1225,6 @@ public abstract class CheckerboardPage : Page { // scrollbar policy set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC); - - Resources.style_widget(this, Resources.PAGE_STYLESHEET); } public void init_item_context_menu(string path) { @@ -1952,9 +1947,6 @@ public abstract class SinglePhotoPage : Page { canvas.draw.connect(on_canvas_exposed); set_event_source(canvas); - - // style the viewport - Resources.style_widget(viewport, Resources.VIEWPORT_STYLESHEET); } public bool is_transition_in_progress() { diff --git a/src/Photo.vala b/src/Photo.vala index 98a3175..2f2b7a5 100644 --- a/src/Photo.vala +++ b/src/Photo.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/PhotoMonitor.vala b/src/PhotoMonitor.vala index d7f2929..58725a4 100644 --- a/src/PhotoMonitor.vala +++ b/src/PhotoMonitor.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/PhotoPage.vala b/src/PhotoPage.vala index 8db84a1..c4175a3 100644 --- a/src/PhotoPage.vala +++ b/src/PhotoPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -398,8 +398,8 @@ public abstract class EditingHostPage : SinglePhotoPage { private Gtk.ToggleToolButton straighten_button = null; private Gtk.ToolButton enhance_button = null; private Gtk.Scale zoom_slider = null; - private Gtk.ToolButton prev_button = new Gtk.ToolButton.from_stock(Gtk.Stock.GO_BACK); - private Gtk.ToolButton next_button = new Gtk.ToolButton.from_stock(Gtk.Stock.GO_FORWARD); + private Gtk.ToolButton prev_button = new Gtk.ToolButton(null, Resources.PREVIOUS_LABEL); + private Gtk.ToolButton next_button = new Gtk.ToolButton(null, Resources.NEXT_LABEL); private EditingTools.EditingTool current_tool = null; private Gtk.ToggleToolButton current_editing_toggle = null; private Gdk.Pixbuf cancel_editing_pixbuf = null; @@ -467,7 +467,8 @@ public abstract class EditingHostPage : SinglePhotoPage { toolbar.insert(redeye_button, -1); // adjust tool - adjust_button = new Gtk.ToggleToolButton.from_stock(Resources.ADJUST); + adjust_button = new Gtk.ToggleToolButton(); + adjust_button.set_icon_name(Resources.ADJUST); adjust_button.set_label(Resources.ADJUST_LABEL); adjust_button.set_tooltip_text(Resources.ADJUST_TOOLTIP); adjust_button.toggled.connect(on_adjust_toggled); @@ -475,8 +476,8 @@ public abstract class EditingHostPage : SinglePhotoPage { toolbar.insert(adjust_button, -1); // enhance tool - enhance_button = new Gtk.ToolButton.from_stock(Resources.ENHANCE); - enhance_button.set_label(Resources.ENHANCE_LABEL); + enhance_button = new Gtk.ToolButton(null, Resources.ENHANCE_LABEL); + enhance_button.set_icon_name(Resources.ENHANCE); enhance_button.set_tooltip_text(Resources.ENHANCE_TOOLTIP); enhance_button.clicked.connect(on_enhance); enhance_button.is_important = true; @@ -530,11 +531,13 @@ public abstract class EditingHostPage : SinglePhotoPage { // previous button prev_button.set_tooltip_text(_("Previous photo")); + prev_button.set_icon_name("go-previous"); prev_button.clicked.connect(on_previous_photo); toolbar.insert(prev_button, -1); // next button next_button.set_tooltip_text(_("Next photo")); + next_button.set_icon_name("go-next"); next_button.clicked.connect(on_next_photo); toolbar.insert(next_button, -1); } @@ -1157,7 +1160,7 @@ public abstract class EditingHostPage : SinglePhotoPage { } if (pixbuf == null) { // Create empty pixbuf. - pixbuf = AppWindow.get_instance().render_icon(Gtk.Stock.MISSING_IMAGE, + pixbuf = AppWindow.get_instance().render_icon("image-missing", Gtk.IconSize.DIALOG, null); get_canvas_scaling().perform_on_pixbuf(pixbuf, Gdk.InterpType.NEAREST, true); @@ -2381,12 +2384,12 @@ public class LibraryPhotoPage : EditingHostPage { protected override Gtk.ActionEntry[] init_collect_action_entries() { Gtk.ActionEntry[] actions = base.init_collect_action_entries(); - Gtk.ActionEntry export = { "Export", Gtk.Stock.SAVE_AS, TRANSLATABLE, "<Ctrl><Shift>E", + Gtk.ActionEntry export = { "Export", Resources.SAVE_AS_LABEL, TRANSLATABLE, "<Ctrl><Shift>E", TRANSLATABLE, on_export }; export.label = Resources.EXPORT_MENU; actions += export; - Gtk.ActionEntry print = { "Print", Gtk.Stock.PRINT, TRANSLATABLE, "<Ctrl>P", + Gtk.ActionEntry print = { "Print", Resources.PRINT_LABEL, TRANSLATABLE, "<Ctrl>P", TRANSLATABLE, on_print }; print.label = Resources.PRINT_MENU; actions += print; @@ -2397,7 +2400,7 @@ public class LibraryPhotoPage : EditingHostPage { publish.tooltip = Resources.PUBLISH_TOOLTIP; actions += publish; - Gtk.ActionEntry remove_from_library = { "RemoveFromLibrary", Gtk.Stock.REMOVE, TRANSLATABLE, + Gtk.ActionEntry remove_from_library = { "RemoveFromLibrary", Resources.REMOVE_LABEL, TRANSLATABLE, "<Shift>Delete", TRANSLATABLE, on_remove_from_library }; remove_from_library.label = Resources.REMOVE_FROM_LIBRARY_MENU; actions += remove_from_library; @@ -2415,13 +2418,13 @@ public class LibraryPhotoPage : EditingHostPage { tools.label = _("T_ools"); actions += tools; - Gtk.ActionEntry prev = { "PrevPhoto", Gtk.Stock.GO_BACK, TRANSLATABLE, null, + Gtk.ActionEntry prev = { "PrevPhoto", Resources.PREVIOUS_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_previous_photo }; prev.label = _("_Previous Photo"); prev.tooltip = _("Previous Photo"); actions += prev; - Gtk.ActionEntry next = { "NextPhoto", Gtk.Stock.GO_FORWARD, TRANSLATABLE, null, + Gtk.ActionEntry next = { "NextPhoto", Resources.NEXT_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_next_photo }; next.label = _("_Next Photo"); next.tooltip = _("Next Photo"); @@ -2473,7 +2476,7 @@ public class LibraryPhotoPage : EditingHostPage { crop.tooltip = Resources.CROP_TOOLTIP; actions += crop; - Gtk.ActionEntry straighten = { "Straighten", Gtk.Stock.REFRESH, TRANSLATABLE, "<Ctrl>A", + Gtk.ActionEntry straighten = { "Straighten", Resources.REFRESH_LABEL, TRANSLATABLE, "<Ctrl>A", TRANSLATABLE, toggle_straighten }; straighten.label = Resources.STRAIGHTEN_MENU; straighten.tooltip = Resources.STRAIGHTEN_TOOLTIP; @@ -2491,7 +2494,7 @@ public class LibraryPhotoPage : EditingHostPage { adjust.tooltip = Resources.ADJUST_TOOLTIP; actions += adjust; - Gtk.ActionEntry revert = { "Revert", Gtk.Stock.REVERT_TO_SAVED, TRANSLATABLE, + Gtk.ActionEntry revert = { "Revert", Resources.REVERT_TO_SAVED_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_revert }; revert.label = Resources.REVERT_MENU; actions += revert; @@ -2511,7 +2514,7 @@ public class LibraryPhotoPage : EditingHostPage { adjust_date_time.label = Resources.ADJUST_DATE_TIME_MENU; actions += adjust_date_time; - Gtk.ActionEntry external_edit = { "ExternalEdit", Gtk.Stock.EDIT, TRANSLATABLE, + Gtk.ActionEntry external_edit = { "ExternalEdit", Resources.EDIT_LABEL, TRANSLATABLE, "<Ctrl>Return", TRANSLATABLE, on_external_edit }; external_edit.label = Resources.EXTERNAL_EDIT_MENU; actions += external_edit; @@ -2585,25 +2588,25 @@ public class LibraryPhotoPage : EditingHostPage { rate_five.label = Resources.rating_menu(Rating.FIVE); actions += rate_five; - Gtk.ActionEntry increase_size = { "IncreaseSize", Gtk.Stock.ZOOM_IN, TRANSLATABLE, + Gtk.ActionEntry increase_size = { "IncreaseSize", Resources.ZOOM_IN_LABEL, TRANSLATABLE, "<Ctrl>plus", TRANSLATABLE, on_increase_size }; increase_size.label = _("Zoom _In"); increase_size.tooltip = _("Increase the magnification of the photo"); actions += increase_size; - Gtk.ActionEntry decrease_size = { "DecreaseSize", Gtk.Stock.ZOOM_OUT, TRANSLATABLE, + Gtk.ActionEntry decrease_size = { "DecreaseSize", Resources.ZOOM_OUT_LABEL, TRANSLATABLE, "<Ctrl>minus", TRANSLATABLE, on_decrease_size }; decrease_size.label = _("Zoom _Out"); decrease_size.tooltip = _("Decrease the magnification of the photo"); actions += decrease_size; - Gtk.ActionEntry best_fit = { "ZoomFit", Gtk.Stock.ZOOM_FIT, TRANSLATABLE, + Gtk.ActionEntry best_fit = { "ZoomFit", Resources.ZOOM_FIT_LABEL, TRANSLATABLE, "<Ctrl>0", TRANSLATABLE, snap_zoom_to_min }; best_fit.label = _("Fit to _Page"); best_fit.tooltip = _("Zoom the photo to fit on the screen"); actions += best_fit; - Gtk.ActionEntry actual_size = { "Zoom100", Gtk.Stock.ZOOM_100, TRANSLATABLE, + Gtk.ActionEntry actual_size = { "Zoom100", Resources.ZOOM_100_LABEL, TRANSLATABLE, "<Ctrl>1", TRANSLATABLE, snap_zoom_to_isomorphic }; /// xgettext:no-c-format actual_size.label = _("Zoom _100%"); @@ -3029,15 +3032,13 @@ public class LibraryPhotoPage : EditingHostPage { } protected override bool on_double_click(Gdk.EventButton event) { - if (!(get_container() is FullscreenWindow)) { + FullscreenWindow? fs = get_container() as FullscreenWindow; + if (fs == null) return_to_collection_on_release = true; - - return true; - } - - AppWindow.get_instance().end_fullscreen(); + else + fs.close(); - return base.on_double_click(event); + return true; } protected override bool on_left_released(Gdk.EventButton event) { diff --git a/src/PixbufCache.vala b/src/PixbufCache.vala index 0708f5e..e3723ae 100644 --- a/src/PixbufCache.vala +++ b/src/PixbufCache.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Printing.vala b/src/Printing.vala index 8e37997..b0a2cf0 100644 --- a/src/Printing.vala +++ b/src/Printing.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Properties.vala b/src/Properties.vala index 9edb4fb..88e0e1d 100644 --- a/src/Properties.vala +++ b/src/Properties.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -453,8 +453,6 @@ private class BasicProperties : Properties { private class ExtendedPropertiesWindow : Gtk.Dialog { private ExtendedProperties properties = null; - private const int FRAME_BORDER = 6; - private Gtk.Button close_button; private class ExtendedProperties : Properties { private const string NO_VALUE = ""; @@ -632,13 +630,13 @@ private class ExtendedPropertiesWindow : Gtk.Dialog { } public ExtendedPropertiesWindow(Gtk.Window owner) { + Object(use_header_bar: 1); + add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.KEY_PRESS_MASK); focus_on_map = true; set_accept_focus(true); set_can_focus(true); set_title(_("Extended Information")); - set_size_request(300,-1); - set_default_size(520, -1); set_position(Gtk.WindowPosition.CENTER); set_transient_for(owner); set_type_hint(Gdk.WindowTypeHint.DIALOG); @@ -648,20 +646,8 @@ private class ExtendedPropertiesWindow : Gtk.Dialog { properties = new ExtendedProperties(); Gtk.Alignment alignment = new Gtk.Alignment(0.5f,0.5f,1,1); alignment.add(properties); - alignment.set_padding(4, 4, 4, 4); + alignment.set_border_width(3); ((Gtk.Box) get_content_area()).add(alignment); - close_button = new Gtk.Button.from_stock(Gtk.Stock.CLOSE); - close_button.clicked.connect(on_close_clicked); - - Gtk.Alignment action_alignment = new Gtk.Alignment(1, 0.5f, 1, 1); - action_alignment.add(close_button); - ((Gtk.Container) get_action_area()).add(action_alignment); - - set_has_resize_grip(false); - } - - ~ExtendedPropertiesWindow() { - close_button.clicked.disconnect(on_close_clicked); } public override bool button_press_event(Gdk.EventButton event) { @@ -674,10 +660,6 @@ private class ExtendedPropertiesWindow : Gtk.Dialog { return true; } - private void on_close_clicked() { - hide(); - } - public override bool key_press_event(Gdk.EventKey event) { // hide properties if (Gdk.keyval_name(event.keyval) == "Escape") { diff --git a/src/Resources.vala b/src/Resources.vala index c8f02c4..54118f8 100644 --- a/src/Resources.vala +++ b/src/Resources.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -24,7 +24,7 @@ namespace Resources { public const string? GIT_VERSION = null; #endif - public const string COPYRIGHT = _("Copyright 2009-2014 Yorba Foundation"); + public const string COPYRIGHT = _("Copyright 2009-2015 Yorba Foundation"); public const string APP_GETTEXT_PACKAGE = GETTEXT_PACKAGE; public const string HOME_URL = "https://wiki.gnome.org/Apps/Shotwell"; @@ -73,7 +73,7 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., public const string CROP = "shotwell-crop"; public const string STRAIGHTEN = "shotwell-straighten"; public const string REDEYE = "shotwell-redeye"; - public const string ADJUST = "shotwell-adjust"; + public const string ADJUST = "image-adjust"; public const string PIN_TOOLBAR = "shotwell-pin-toolbar"; public const string MAKE_PRIMARY = "shotwell-make-primary"; public const string IMPORT = "shotwell-import"; @@ -82,6 +82,9 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., public const string CROP_PIVOT_RETICLE = "shotwell-crop-pivot-reticle"; public const string PUBLISH = "applications-internet"; public const string MERGE = "shotwell-merge-events"; + + public const string GO_NEXT = "go-next"; + public const string GO_PREVIOUS = "go-previous"; public const string ICON_APP = "shotwell.svg"; public const string ICON_APP16 = "shotwell-16.svg"; @@ -117,8 +120,7 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., public const string ICON_NO_EVENT = "no-event"; public const string ICON_ONE_TAG = "one-tag"; public const string ICON_TAGS = "multiple-tags"; - public const string ICON_FOLDER_CLOSED = "folder"; - public const string ICON_FOLDER_OPEN = "folder-open"; + public const string ICON_FOLDER = "folder"; public const string ICON_FOLDER_DOCUMENTS = "folder-documents"; public const string ICON_IMPORTING = "go-down"; public const string ICON_LAST_IMPORT = "document-open-recent"; @@ -155,6 +157,37 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., public const string VFLIP_MENU = _("Flip Verti_cally"); public const string VFLIP_LABEL = _("Flip Vertically"); + public const string ABOUT_LABEL = _("_About"); + public const string APPLY_LABEL = _("_Apply"); + public const string CANCEL_LABEL = _("_Cancel"); + public const string DELETE_LABEL = _("_Delete"); + public const string EDIT_LABEL = _("_Edit"); + public const string FORWARD_LABEL = _("_Forward"); + public const string FULLSCREEN_LABEL = _("Fulls_creen"); + public const string HELP_LABEL = _("_Help"); + public const string LEAVE_FULLSCREEN_LABEL = _("Leave _Fullscreen"); + public const string NEW_LABEL = _("_New"); + public const string NEXT_LABEL = _("_Next"); + public const string OK_LABEL = _("_OK"); + public const string PLAY_LABEL = _("_Play"); + public const string PREFERENCES_LABEL = _("_Preferences"); + public const string PREVIOUS_LABEL = _("_Previous"); + public const string PRINT_LABEL = _("_Print"); + public const string QUIT_LABEL = _("_Quit"); + public const string REFRESH_LABEL = _("_Refresh"); + public const string REMOVE_LABEL = _("_Remove"); + public const string REVERT_TO_SAVED_LABEL = _("_Revert"); + public const string SAVE_LABEL = _("_Save"); + public const string SAVE_AS_LABEL = _("Save _As"); + public const string SORT_ASCENDING_LABEL = _("Sort _Ascending"); + public const string SORT_DESCENDING_LABEL = _("Sort _Descending"); + public const string STOP_LABEL = _("_Stop"); + public const string UNDELETE_LABEL = _("_Undelete"); + public const string ZOOM_100_LABEL = _("_Normal Size"); + public const string ZOOM_FIT_LABEL = _("Best _Fit"); + public const string ZOOM_IN_LABEL = _("Zoom _In"); + public const string ZOOM_OUT_LABEL = _("Zoom _Out"); + public const string ENHANCE_MENU = _("_Enhance"); public const string ENHANCE_LABEL = _("Enhance"); public const string ENHANCE_TOOLTIP = _("Automatically improve the photo's appearance"); @@ -246,7 +279,9 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., public const string DISPLAY_REJECTED_OR_HIGHER_TOOLTIP = _("Show all photos, including rejected"); public const string DISPLAY_UNRATED_OR_HIGHER_MENU = _("_All Photos"); + // Button label public const string DISPLAY_UNRATED_OR_HIGHER_LABEL = _("Show all photos"); + // Button tooltip public const string DISPLAY_UNRATED_OR_HIGHER_TOOLTIP = _("Show all photos"); public const string VIEW_RATINGS_MENU = _("_Ratings"); @@ -269,9 +304,11 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., public const string PUBLISH_TOOLTIP = _("Publish to various websites"); public const string EDIT_TITLE_MENU = _("Edit _Title..."); + // Button label public const string EDIT_TITLE_LABEL = _("Edit Title"); public const string EDIT_COMMENT_MENU = _("Edit _Comment..."); + // Button label public const string EDIT_COMMENT_LABEL = _("Edit Comment"); public const string EDIT_EVENT_COMMENT_MENU = _("Edit Event _Comment..."); @@ -282,6 +319,7 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., public const string ADD_TAGS_MENU = _("Add _Tags..."); public const string ADD_TAGS_CONTEXT_MENU = _("_Add Tags..."); + // Dialog title public const string ADD_TAGS_TITLE = _("Add Tags"); public const string PREFERENCES_MENU = _("_Preferences"); @@ -306,14 +344,17 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., } public string add_tags_label(string[] names) { - if (names.length == 1) + if (names.length == 1) { return _("Add Tag \"%s\"").printf(HierarchicalTagUtilities.get_basename(names[0])); - else if (names.length == 2) + } else if (names.length == 2) { + // Used when adding two tags to photo(s) return _("Add Tags \"%s\" and \"%s\"").printf( - HierarchicalTagUtilities.get_basename(names[0]), - HierarchicalTagUtilities.get_basename(names[1])); - else + HierarchicalTagUtilities.get_basename(names[0]), + HierarchicalTagUtilities.get_basename(names[1])); + } else { + // Undo/Redo command name (in Edit menu) return _("Add Tags"); + } } public string delete_tag_menu(string name) { @@ -677,13 +718,11 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., File icons_dir = AppDirs.get_resources_dir().get_child("icons"); add_stock_icon(icons_dir.get_child("crop.svg"), CROP); add_stock_icon(icons_dir.get_child("redeye.png"), REDEYE); - add_stock_icon(icons_dir.get_child("image-adjust.svg"), ADJUST); - add_stock_icon(icons_dir.get_child("pin-toolbar.svg"), PIN_TOOLBAR); add_stock_icon(icons_dir.get_child("make-primary.svg"), MAKE_PRIMARY); add_stock_icon(icons_dir.get_child("import.svg"), IMPORT); add_stock_icon(icons_dir.get_child("straighten.svg"), STRAIGHTEN); add_stock_icon(icons_dir.get_child("import-all.png"), IMPORT_ALL); - add_stock_icon(icons_dir.get_child("enhance.png"), ENHANCE); + add_stock_icon(icons_dir.get_child("shotwell-auto-enhance.png"), ENHANCE); add_stock_icon(icons_dir.get_child("crop-pivot-reticle.png"), CROP_PIVOT_RETICLE); add_stock_icon(icons_dir.get_child("merge.svg"), MERGE); add_stock_icon_from_themed_icon(new GLib.ThemedIcon(ICON_FLAGGED_PAGE), ICON_FLAGGED_PAGE); @@ -1046,97 +1085,20 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc., providers.set(widget, styler); } - - public const string INSET_FRAME_STYLESHEET = - """ .frame { - border-style: inset; - border-width: 1px; - }"""; - - public const string SCROLL_FRAME_STYLESHEET = - """ GtkScrolledWindow { - border-width: 0; - border-style: none; - border-radius: 0; - padding: 0; - } - - .frame { - border-width: 1px; - border-style: inset; - }"""; - public const string PAGE_STYLESHEET = - """ .frame { - border-width: 1px; - border-style: inset; - border-radius: 0; - - padding: 0; - }"""; - - public const string VIEWPORT_STYLESHEET = - """ GtkViewport { - border-width: 1px; - border-style: inset; - border-radius: 0; - padding: 0; - }"""; - - public const string TOOLBAR_STYLESHEET_TEMPLATE = - """ - @define-color primary-bg %s; - - .toolbar { - background-color: @primary-bg; - border-width: 1px; - border-color: shade (@primary-bg, 0.75); - border-style: solid; - }"""; - - public const string SEARCH_BUTTON_STYLESHEET_TEMPLATE = - """ - @define-color primary-bg %s; - - .button { - background-image: none; - background-color: @primary-bg; - border-image: none; - border-color: shade (@primary-bg, 0.75) @primary-bg shade (@primary-bg, 0.75) @primary-bg; - border-style: solid; - margin: 5px; - - -unico-border-gradient: none; - -unico-outer-stroke-width: 0; - -unico-outer-stroke-gradient: none; - -unico-glow-radius: 0; - -unico-inner-stroke-width: 0; - -unico-inner-stroke-color: shade (@primary-bg, 1.1); + public const string CUSTOM_CSS = + """LibraryWindow { + -GtkPaned-handle-size: 1; } - - .button:prelight { - border-style: solid; - border-width: 1px; - border-color: shade (@primary-bg, 1.1); - - -unico-inner-stroke-color: shade (@primary-bg, 1.1); - -unico-inner-stroke-width: 0; - - -unico-outer-stroke-width: 1px; - -unico-outer-stroke-color: shade (@primary-bg, 0.8); + LibraryWindow .pane-separator { + background-color: @borders; } - - .button:active { - background-image: none; - background-color: shade (@primary-bg, 0.75); - border-style: solid; - border-width: 1px; - border-color: shade (@primary-bg, 0.6); - - -unico-outer-stroke-width: 1px; - -unico-outer-stroke-color: shade (@primary-bg, 1.1); + SearchFilterToolbar { + border-width: 0 0 1px 0; + border-style: solid; + border-color: @borders; }"""; - + public const string ONIMAGE_FONT_COLOR = "#000000"; public const string ONIMAGE_FONT_BACKGROUND = "rgba(255,255,255,0.5)"; } diff --git a/src/Screensaver.vala b/src/Screensaver.vala index d00af21..836df5b 100644 --- a/src/Screensaver.vala +++ b/src/Screensaver.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/SearchFilter.vala b/src/SearchFilter.vala index e8f0986..3fc5d8b 100644 --- a/src/SearchFilter.vala +++ b/src/SearchFilter.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -646,7 +646,8 @@ public class SearchFilterActions { } } -public class SearchFilterToolbar : Gtk.Toolbar { +public class SearchFilterToolbar : Gtk.Revealer { + private Gtk.Toolbar toolbar; private const int FILTER_BUTTON_MARGIN = 12; // the distance between icon and edge of button private const float FILTER_ICON_STAR_SCALE = 0.65f; // changes the size of the filter icon private const float FILTER_ICON_SCALE = 0.75f; // changes the size of the all photos icon @@ -671,10 +672,6 @@ public class SearchFilterToolbar : Gtk.Toolbar { add(label); } } - - public void set_color(Gdk.RGBA color) { - label.override_color(Gtk.StateFlags.NORMAL, color); - } } private class ToggleActionToolButton : Gtk.ToolItem { @@ -688,8 +685,8 @@ public class SearchFilterToolbar : Gtk.Toolbar { button.set_active(action.active); button.clicked.connect(on_button_activate); button.set_has_tooltip(true); - - restyle(); + button.set_relief(Gtk.ReliefStyle.NONE); + button.set_margin_start(2); this.add(button); } @@ -711,21 +708,13 @@ public class SearchFilterToolbar : Gtk.Toolbar { button.set_image(image); } - - public void restyle() { - string bgcolorname = - Resources.to_css_color(Config.Facade.get_instance().get_bg_color()); - string stylesheet = Resources.SEARCH_BUTTON_STYLESHEET_TEMPLATE.printf(bgcolorname); - - Resources.style_widget(button, stylesheet); - } } // Ticket #3260 - Add a 'close' context menu to // the searchbar. // The close menu. Populated below in the constructor. private Gtk.Menu close_menu = new Gtk.Menu(); - private Gtk.ImageMenuItem close_item = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.CLOSE, null); + private Gtk.MenuItem close_item = new Gtk.MenuItem(); // Text search box. protected class SearchBox : Gtk.ToolItem { @@ -812,10 +801,10 @@ public class SearchFilterToolbar : Gtk.Toolbar { button = new Gtk.Button(); button.set_image(get_filter_icon(RatingFilter.UNRATED_OR_HIGHER)); button.set_can_focus(false); + button.set_relief(Gtk.ReliefStyle.NONE); + button.set_margin_start(2); button.clicked.connect(on_clicked); - - restyle(); set_homogeneous(false); @@ -911,14 +900,6 @@ public class SearchFilterToolbar : Gtk.Toolbar { private int get_filter_button_size(RatingFilter filter) { return get_filter_icon_size(filter) + 2 * FILTER_BUTTON_MARGIN; } - - public void restyle() { - string bgcolorname = - Resources.to_css_color(Config.Facade.get_instance().get_bg_color()); - string stylesheet = Resources.SEARCH_BUTTON_STYLESHEET_TEMPLATE.printf(bgcolorname); - - Resources.style_widget(button, stylesheet); - } } public Gtk.UIManager ui = new Gtk.UIManager(); @@ -939,11 +920,12 @@ public class SearchFilterToolbar : Gtk.Toolbar { public SearchFilterToolbar(SearchFilterActions actions) { this.actions = actions; + toolbar = new Gtk.Toolbar(); actions.media_context_changed.connect(on_media_context_changed); search_box = new SearchBox(actions.text); - set_name("search-filter-toolbar"); - set_icon_size(Gtk.IconSize.SMALL_TOOLBAR); + toolbar.set_name("search-filter-toolbar"); + toolbar.set_icon_size(Gtk.IconSize.SMALL_TOOLBAR); File ui_file = Resources.get_ui("search_bar.ui"); try { @@ -960,14 +942,14 @@ public class SearchFilterToolbar : Gtk.Toolbar { // Prepare the close menu for use, but don't // display it yet; we'll connect it to secondary // click later on. - ((Gtk.MenuItem) close_item).show(); - close_item.always_show_image = true; + close_item.set_label(_("Close")); + close_item.show(); close_item.activate.connect(on_context_menu_close_chosen); close_menu.append(close_item); // Type label and toggles label_type = new LabelToolItem(_("Type"), 10, 5); - insert(label_type, -1); + toolbar.insert(label_type, -1); toolbtn_photos = new ToggleActionToolButton(actions.photos); toolbtn_photos.set_tooltip_text(actions.get_action_group().get_action("CommonDisplayPhotos").tooltip); @@ -978,47 +960,45 @@ public class SearchFilterToolbar : Gtk.Toolbar { toolbtn_raw = new ToggleActionToolButton(actions.raw); toolbtn_raw.set_tooltip_text(actions.get_action_group().get_action("CommonDisplayRaw").tooltip); - insert(toolbtn_photos, -1); - insert(toolbtn_videos, -1); - insert(toolbtn_raw, -1); + toolbar.insert(toolbtn_photos, -1); + toolbar.insert(toolbtn_videos, -1); + toolbar.insert(toolbtn_raw, -1); // separator sepr_mediatype_flagged = new Gtk.SeparatorToolItem(); - insert(sepr_mediatype_flagged, -1); + toolbar.insert(sepr_mediatype_flagged, -1); // Flagged label and toggle label_flagged = new LabelToolItem(_("Flagged")); - insert(label_flagged, -1); + toolbar.insert(label_flagged, -1); toolbtn_flag = new ToggleActionToolButton(actions.flagged); toolbtn_flag.set_tooltip_text(actions.get_action_group().get_action("CommonDisplayFlagged").tooltip); - insert(toolbtn_flag, -1); + toolbar.insert(toolbtn_flag, -1); // separator sepr_flagged_rating = new Gtk.SeparatorToolItem(); - insert(sepr_flagged_rating, -1); + toolbar.insert(sepr_flagged_rating, -1); // Rating label and button label_rating = new LabelToolItem(_("Rating")); - insert(label_rating, -1); + toolbar.insert(label_rating, -1); rating_button.filter_popup = (Gtk.Menu) ui.get_widget("/FilterPopupMenu"); rating_button.set_expand(false); rating_button.clicked.connect(on_filter_button_clicked); - insert(rating_button, -1); + toolbar.insert(rating_button, -1); // Separator to right-align the text box Gtk.SeparatorToolItem separator_align = new Gtk.SeparatorToolItem(); separator_align.set_expand(true); separator_align.set_draw(false); - insert(separator_align, -1); + toolbar.insert(separator_align, -1); // Search box. - insert(search_box, -1); - - // Set background color of toolbar and update them when the configuration is updated - Config.Facade.get_instance().bg_color_name_changed.connect(on_bg_color_name_changed); - on_bg_color_name_changed(); + toolbar.insert(search_box, -1); + + add(toolbar); // hook up signals to actions to be notified when they change actions.flagged_toggled.connect(on_flagged_toggled); @@ -1030,14 +1010,13 @@ public class SearchFilterToolbar : Gtk.Toolbar { actions.criteria_changed.connect(on_criteria_changed); // #3260 part II Hook up close menu. - popup_context_menu.connect(on_context_menu_requested); + toolbar.popup_context_menu.connect(on_context_menu_requested); on_media_context_changed(actions.get_has_photos(), actions.get_has_videos(), actions.get_has_raw(), actions.get_has_flagged()); } ~SearchFilterToolbar() { - Config.Facade.get_instance().bg_color_name_changed.disconnect(on_bg_color_name_changed); actions.media_context_changed.disconnect(on_media_context_changed); @@ -1049,7 +1028,7 @@ public class SearchFilterToolbar : Gtk.Toolbar { actions.text_changed.disconnect(on_search_text_changed); actions.criteria_changed.disconnect(on_criteria_changed); - popup_context_menu.disconnect(on_context_menu_requested); + toolbar.popup_context_menu.disconnect(on_context_menu_requested); } private void on_media_context_changed(bool has_photos, bool has_videos, bool has_raw, @@ -1075,24 +1054,6 @@ public class SearchFilterToolbar : Gtk.Toolbar { toolbtn_flag.set_icon_name(Resources.ICON_FILTER_FLAGGED_DISABLED); } - private void on_bg_color_name_changed() { - string bgcolorname = - Resources.to_css_color(Config.Facade.get_instance().get_bg_color()); - string toolbar_stylesheet = Resources.TOOLBAR_STYLESHEET_TEMPLATE.printf(bgcolorname); - Resources.style_widget(this, toolbar_stylesheet); - - label_type.set_color(Config.Facade.get_instance().get_unselected_color()); - label_flagged.set_color(Config.Facade.get_instance().get_unselected_color()); - label_rating.set_color(Config.Facade.get_instance().get_unselected_color()); - - toolbtn_photos.restyle(); - toolbtn_videos.restyle(); - toolbtn_raw.restyle(); - toolbtn_flag.restyle(); - rating_button.restyle(); - - } - // Ticket #3260 part IV - display the context menu on secondary click private bool on_context_menu_requested(int x, int y, int button) { close_menu.popup(null, null, null, button, Gtk.get_current_event_time()); diff --git a/src/SlideshowPage.vala b/src/SlideshowPage.vala index f22fd53..654576d 100644 --- a/src/SlideshowPage.vala +++ b/src/SlideshowPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -44,8 +44,8 @@ class SlideshowPage : SinglePhotoPage { set_modal(true); set_transient_for(AppWindow.get_fullscreen()); - add_buttons(Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, - Gtk.Stock.OK, Gtk.ResponseType.OK); + add_buttons(Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL, + Resources.OK_LABEL, Gtk.ResponseType.OK); set_title(_("Settings")); Gtk.Adjustment adjustment = new Gtk.Adjustment(delay, Config.Facade.SLIDESHOW_DELAY_MIN, Config.Facade.SLIDESHOW_DELAY_MAX, 0.1, 1, 0); @@ -157,28 +157,29 @@ class SlideshowPage : SinglePhotoPage { Gtk.Toolbar toolbar = get_toolbar(); // add toolbar buttons - Gtk.ToolButton previous_button = new Gtk.ToolButton.from_stock(Gtk.Stock.GO_BACK); - previous_button.set_label(_("Back")); + Gtk.ToolButton previous_button = new Gtk.ToolButton(null, _("Back")); + previous_button.set_icon_name("go-previous"); previous_button.set_tooltip_text(_("Go to the previous photo")); previous_button.clicked.connect(on_previous_photo); toolbar.insert(previous_button, -1); - play_pause_button = new Gtk.ToolButton.from_stock(Gtk.Stock.MEDIA_PAUSE); - play_pause_button.set_label(_("Pause")); + play_pause_button = new Gtk.ToolButton(null, _("Pause")); + play_pause_button.set_icon_name("media-playback-pause"); play_pause_button.set_tooltip_text(_("Pause the slideshow")); play_pause_button.clicked.connect(on_play_pause); toolbar.insert(play_pause_button, -1); - Gtk.ToolButton next_button = new Gtk.ToolButton.from_stock(Gtk.Stock.GO_FORWARD); - next_button.set_label(_("Next")); + Gtk.ToolButton next_button = new Gtk.ToolButton(null, _("Next")); + next_button.set_icon_name("go-next"); next_button.set_tooltip_text(_("Go to the next photo")); next_button.clicked.connect(on_next_photo); toolbar.insert(next_button, -1); - settings_button = new Gtk.ToolButton.from_stock(Gtk.Stock.PREFERENCES); + settings_button = new Gtk.ToolButton(null, null); + settings_button.set_icon_name("preferences-system"); settings_button.set_label(_("Settings")); settings_button.set_tooltip_text(_("Change slideshow settings")); settings_button.clicked.connect(on_change_settings); @@ -265,11 +266,11 @@ class SlideshowPage : SinglePhotoPage { private void on_play_pause() { if (playing) { - play_pause_button.set_stock_id(Gtk.Stock.MEDIA_PLAY); + play_pause_button.set_icon_name("media-playback-start"); play_pause_button.set_label(_("Play")); play_pause_button.set_tooltip_text(_("Continue the slideshow")); } else { - play_pause_button.set_stock_id(Gtk.Stock.MEDIA_PAUSE); + play_pause_button.set_icon_name("media-playback-pause"); play_pause_button.set_label(_("Pause")); play_pause_button.set_tooltip_text(_("Pause the slideshow")); } diff --git a/src/SortedList.vala b/src/SortedList.vala index 791f9e0..ed8313f 100644 --- a/src/SortedList.vala +++ b/src/SortedList.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/Tag.vala b/src/Tag.vala index 450af20..8218a88 100644 --- a/src/Tag.vala +++ b/src/Tag.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/Thumbnail.vala b/src/Thumbnail.vala index c33d43b..4ce9e81 100644 --- a/src/Thumbnail.vala +++ b/src/Thumbnail.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -161,8 +161,7 @@ public class Thumbnail : MediaSourceItem { } public static int64 title_ascending_comparator(void *a, void *b) { - int64 result = strcmp(((Thumbnail *) a)->media.get_name(), ((Thumbnail *) b)->media.get_name()); - + int64 result = strcmp(((Thumbnail *) a)->get_natural_collation_key(), ((Thumbnail *) b)->get_natural_collation_key()); return (result != 0) ? result : photo_id_ascending_comparator(a, b); } @@ -194,6 +193,10 @@ public class Thumbnail : MediaSourceItem { return alteration.has_detail("metadata", "exposure-time"); } + public static bool filename_comparator_predicate(DataObject object, Alteration alteration) { + return alteration.has_detail("metadata", "filename"); + } + public static int64 filename_ascending_comparator(void *a, void *b) { string path_a = ((Thumbnail *) a)->media.get_file().get_basename().down(); string path_b = ((Thumbnail *) b)->media.get_file().get_basename().down(); diff --git a/src/ThumbnailCache.vala b/src/ThumbnailCache.vala index c24087c..6408a1a 100644 --- a/src/ThumbnailCache.vala +++ b/src/ThumbnailCache.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -86,6 +86,7 @@ public class ThumbnailCache : Object { public Gdk.Pixbuf scaled = null; public Error err = null; public bool fetched = false; + public bool replace = false; public AsyncFetchJob(ThumbnailCache cache, string thumbnail_name, ThumbnailSource source, Gdk.Pixbuf? prefetched, Dimensions dim, @@ -131,38 +132,33 @@ public class ThumbnailCache : Object { // scale if specified scaled = dim.has_area() ? resize_pixbuf(unscaled, dim, interp) : unscaled; } catch (Error err) { - // Is the problem that the thumbnail couldn't be read? If so, it's recoverable; - // we'll just create it and leave this.err as null if creation works. if (err is FileError) { try { - Photo photo = source as Photo; - Video video = source as Video; - - if (photo != null) { - unscaled = photo.get_pixbuf(Scaling.for_best_fit(dim.width, true)); - photo.notify_altered(new Alteration("image","thumbnail")); - return; - } - - if (video != null) { - unscaled = video.create_thumbnail(dim.width); - scaled = resize_pixbuf(unscaled, dim, interp); - cache.save_thumbnail(cache.get_source_cached_file(source), - unscaled, source); - replace(source, cache.size, unscaled); - return; - } - - } catch (Error e) { - // Creating the thumbnail failed; tell the rest of the app. - this.err = e; - return; + generate_thumbnail(); + } catch (Error generr) { + // save thumbnail generation error, not original, for processing in callback + err = generr; } + } else { + // save error for processing in callback + this.err = err; } - - // ...the original error wasn't from reading the file, but something else; - // tell the rest of the app. - this.err = err; + } + } + + private void generate_thumbnail() throws Error { + Photo? photo = source as Photo; + if (photo != null) { + unscaled = photo.get_pixbuf(Scaling.for_best_fit(dim.width, true)); + } else { + Video? video = source as Video; + if (video != null) + unscaled = video.create_thumbnail(dim.width); + } + + if (unscaled != null) { + scaled = resize_pixbuf(unscaled, dim, interp); + replace = true; } } } @@ -420,6 +416,16 @@ public class ThumbnailCache : Object { private static void async_fetch_completion_callback(BackgroundJob background_job) { AsyncFetchJob job = (AsyncFetchJob) background_job; + // Is the problem that the thumbnail couldn't be read? If so, it's recoverable; + // we'll just create it and leave this.err as null if creation works. + if (job.replace && job.unscaled != null) { + try { + replace(job.source, job.cache.size, job.unscaled); + } catch (Error err) { + job.err = err; + } + } + if (job.unscaled != null) { if (job.fetched) { // only store in cache if fetched, not pre-fetched diff --git a/src/TimedQueue.vala b/src/TimedQueue.vala index 7001421..d175c8d 100644 --- a/src/TimedQueue.vala +++ b/src/TimedQueue.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/Tombstone.vala b/src/Tombstone.vala index d25b979..6a95881 100644 --- a/src/Tombstone.vala +++ b/src/Tombstone.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/UnityProgressBar.vala b/src/UnityProgressBar.vala index fcf36bc..d28428e 100644 --- a/src/UnityProgressBar.vala +++ b/src/UnityProgressBar.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/Upgrades.vala b/src/Upgrades.vala index 7fef59a..d7ccf6f 100644 --- a/src/Upgrades.vala +++ b/src/Upgrades.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/VideoMetadata.vala b/src/VideoMetadata.vala index 100a040..5dfa812 100644 --- a/src/VideoMetadata.vala +++ b/src/VideoMetadata.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/VideoMonitor.vala b/src/VideoMonitor.vala index f062999..7f2fd3b 100644 --- a/src/VideoMonitor.vala +++ b/src/VideoMonitor.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/VideoSupport.vala b/src/VideoSupport.vala index e23ba37..4e6f3ed 100644 --- a/src/VideoSupport.vala +++ b/src/VideoSupport.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -197,8 +197,11 @@ public class VideoReader { // (and the corresponding output struct) in order to implement #2836. Date? video_date = null; if (info.get_tags() != null && info.get_tags().get_date(Gst.Tags.DATE, out video_date)) { - timestamp = new DateTime.local(video_date.get_year(), video_date.get_month(), - video_date.get_day(), 0, 0, 0); + // possible for get_date() to return true and a null Date + if (video_date != null) { + timestamp = new DateTime.local(video_date.get_year(), video_date.get_month(), + video_date.get_day(), 0, 0, 0); + } } } catch (Error e) { debug("Video read error: %s", e.message); diff --git a/src/camera/Branch.vala b/src/camera/Branch.vala index 63a5443..83f3f56 100644 --- a/src/camera/Branch.vala +++ b/src/camera/Branch.vala @@ -1,17 +1,17 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ public class Camera.Branch : Sidebar.Branch { - internal static Icon? cameras_icon = null; + internal static string? cameras_icon = Resources.ICON_CAMERAS; private Gee.HashMap<DiscoveredCamera, Camera.SidebarEntry> camera_map = new Gee.HashMap< DiscoveredCamera, Camera.SidebarEntry>(); public Branch() { - base (new Camera.Grouping(), + base (new Camera.Header(), Sidebar.Branch.Options.HIDE_IF_EMPTY | Sidebar.Branch.Options.AUTO_OPEN_ON_NEW_CHILD, camera_comparator); @@ -23,11 +23,9 @@ public class Camera.Branch : Sidebar.Branch { } internal static void init() { - cameras_icon = new GLib.ThemedIcon(Resources.ICON_CAMERAS); } internal static void terminate() { - cameras_icon = null; } private static int camera_comparator(Sidebar.Entry a, Sidebar.Entry b) { @@ -82,9 +80,9 @@ public class Camera.Branch : Sidebar.Branch { } } -public class Camera.Grouping : Sidebar.Grouping { - public Grouping() { - base (_("Cameras"), Camera.Branch.cameras_icon); +public class Camera.Header : Sidebar.Header { + public Header() { + base (_("Cameras")); } } @@ -101,7 +99,7 @@ public class Camera.SidebarEntry : Sidebar.SimplePageEntry { return camera.display_name ?? _("Camera"); } - public override Icon? get_sidebar_icon() { + public override string? get_sidebar_icon() { return camera.icon ?? Camera.Branch.cameras_icon; } diff --git a/src/camera/Camera.vala b/src/camera/Camera.vala index f6d1f4b..84fff8e 100644 --- a/src/camera/Camera.vala +++ b/src/camera/Camera.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/camera/CameraTable.vala b/src/camera/CameraTable.vala index 8466388..bdeac54 100644 --- a/src/camera/CameraTable.vala +++ b/src/camera/CameraTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -8,9 +8,9 @@ public class DiscoveredCamera { public GPhoto.Camera gcamera; public string uri; public string display_name; - public GLib.Icon? icon; + public string? icon; - public DiscoveredCamera(GPhoto.Camera gcamera, string uri, string display_name, GLib.Icon? icon) { + public DiscoveredCamera(GPhoto.Camera gcamera, string uri, string display_name, string? icon) { this.gcamera = gcamera; this.uri = uri; this.display_name = display_name; @@ -221,10 +221,10 @@ public class CameraTable { return null; } - private GLib.Icon? get_icon_for_uuid(string uuid) { + private string? get_icon_for_uuid(string uuid) { foreach (Volume volume in volume_monitor.get_volumes()) { if (volume.get_identifier(VolumeIdentifier.UUID) == uuid) { - return volume.get_icon(); + return volume.get_icon().to_string(); } } return null; @@ -323,7 +323,7 @@ public class CameraTable { foreach (string port in detected_map.keys) { string name = detected_map.get(port); string display_name = null; - GLib.Icon? icon = null; + string? icon = null; string uri = get_port_uri(port); if (camera_map.has_key(uri)) { diff --git a/src/camera/GPhoto.vala b/src/camera/GPhoto.vala index a1a46cb..41af0b2 100644 --- a/src/camera/GPhoto.vala +++ b/src/camera/GPhoto.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/camera/ImportPage.vala b/src/camera/ImportPage.vala index 823a458..ba66990 100644 --- a/src/camera/ImportPage.vala +++ b/src/camera/ImportPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -289,7 +289,7 @@ class ImportPreview : MediaSourceItem { bool using_placeholder = (pixbuf == null); if (pixbuf == null) { if (placeholder_preview == null) { - placeholder_preview = AppWindow.get_instance().render_icon(Gtk.Stock.MISSING_IMAGE, + placeholder_preview = AppWindow.get_instance().render_icon("image-missing", Gtk.IconSize.DIALOG, null); placeholder_preview = scale_pixbuf(placeholder_preview, MAX_SCALE, Gdk.InterpType.BILINEAR, true); @@ -691,7 +691,7 @@ public class ImportPage : CheckerboardPage { private string camera_name; private VolumeMonitor volume_monitor = null; private ImportPage? local_ref = null; - private GLib.Icon? icon; + private string? icon; private ImportPageSearchViewFilter search_filter = new ImportPageSearchViewFilter(); private HideImportedViewFilter hide_imported_filter = new HideImportedViewFilter(); private CameraViewTracker tracker; @@ -707,7 +707,7 @@ public class ImportPage : CheckerboardPage { LIBRARY_ERROR } - public ImportPage(GPhoto.Camera camera, string uri, string? display_name = null, GLib.Icon? icon = null) { + public ImportPage(GPhoto.Camera camera, string uri, string? display_name = null, string? icon = null) { base(_("Camera")); this.camera = camera; this.uri = uri; @@ -810,13 +810,15 @@ public class ImportPage : CheckerboardPage { toolbar.insert(new Gtk.SeparatorToolItem(), -1); // Import selected - Gtk.ToolButton import_selected_button = new Gtk.ToolButton.from_stock(Resources.IMPORT); + Gtk.ToolButton import_selected_button = new Gtk.ToolButton(null, null); + import_selected_button.set_icon_name(Resources.IMPORT); import_selected_button.set_related_action(get_action("ImportSelected")); toolbar.insert(import_selected_button, -1); // Import all - Gtk.ToolButton import_all_button = new Gtk.ToolButton.from_stock(Resources.IMPORT_ALL); + Gtk.ToolButton import_all_button = new Gtk.ToolButton(null, null); + import_all_button.set_icon_name(Resources.IMPORT_ALL); import_all_button.set_related_action(get_action("ImportAll")); toolbar.insert(import_all_button, -1); @@ -1736,7 +1738,7 @@ public class ImportPage : CheckerboardPage { photos_string, videos_string, both_string, neither_string); ImportUI.QuestionParams question = new ImportUI.QuestionParams( - question_string, Gtk.Stock.DELETE, _("_Keep")); + question_string, Resources.DELETE_LABEL, _("_Keep")); if (!ImportUI.report_manifest(manifest, false, question)) return; diff --git a/src/config/Config.vala b/src/config/Config.vala index 2095107..588c466 100644 --- a/src/config/Config.vala +++ b/src/config/Config.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/config/ConfigurationInterfaces.vala b/src/config/ConfigurationInterfaces.vala index 42a591a..41ae188 100644 --- a/src/config/ConfigurationInterfaces.vala +++ b/src/config/ConfigurationInterfaces.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/config/GSettingsEngine.vala b/src/config/GSettingsEngine.vala index 0b2e691..1586684 100644 --- a/src/config/GSettingsEngine.vala +++ b/src/config/GSettingsEngine.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/core/Alteration.vala b/src/core/Alteration.vala index 865be84..ecb8142 100644 --- a/src/core/Alteration.vala +++ b/src/core/Alteration.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/ContainerSourceCollection.vala b/src/core/ContainerSourceCollection.vala index 655cfa0..24e2d89 100644 --- a/src/core/ContainerSourceCollection.vala +++ b/src/core/ContainerSourceCollection.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/Core.vala b/src/core/Core.vala index 1b9958e..b646f02 100644 --- a/src/core/Core.vala +++ b/src/core/Core.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/DataCollection.vala b/src/core/DataCollection.vala index 615c6ac..0e8041d 100644 --- a/src/core/DataCollection.vala +++ b/src/core/DataCollection.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/core/DataObject.vala b/src/core/DataObject.vala index 1fe133d..85ec63f 100644 --- a/src/core/DataObject.vala +++ b/src/core/DataObject.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/core/DataSet.vala b/src/core/DataSet.vala index ebb5500..dc11422 100644 --- a/src/core/DataSet.vala +++ b/src/core/DataSet.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/DataSource.vala b/src/core/DataSource.vala index e4d2d34..514ef9b 100644 --- a/src/core/DataSource.vala +++ b/src/core/DataSource.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/DataSourceTypes.vala b/src/core/DataSourceTypes.vala index 9f23ac6..f7ebec1 100644 --- a/src/core/DataSourceTypes.vala +++ b/src/core/DataSourceTypes.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/DataView.vala b/src/core/DataView.vala index 07cd4fc..c70b9b4 100644 --- a/src/core/DataView.vala +++ b/src/core/DataView.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/DataViewTypes.vala b/src/core/DataViewTypes.vala index fac7602..fe7bffd 100644 --- a/src/core/DataViewTypes.vala +++ b/src/core/DataViewTypes.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/DatabaseSourceCollection.vala b/src/core/DatabaseSourceCollection.vala index 0c704bb..917c50d 100644 --- a/src/core/DatabaseSourceCollection.vala +++ b/src/core/DatabaseSourceCollection.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/SourceCollection.vala b/src/core/SourceCollection.vala index 020df0e..9e2af57 100644 --- a/src/core/SourceCollection.vala +++ b/src/core/SourceCollection.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/SourceHoldingTank.vala b/src/core/SourceHoldingTank.vala index adfec8b..a3fb1c6 100644 --- a/src/core/SourceHoldingTank.vala +++ b/src/core/SourceHoldingTank.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/SourceInterfaces.vala b/src/core/SourceInterfaces.vala index 59956d3..958e4b3 100644 --- a/src/core/SourceInterfaces.vala +++ b/src/core/SourceInterfaces.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/Tracker.vala b/src/core/Tracker.vala index e72992b..3f5d39a 100644 --- a/src/core/Tracker.vala +++ b/src/core/Tracker.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/ViewCollection.vala b/src/core/ViewCollection.vala index a34e23e..5577681 100644 --- a/src/core/ViewCollection.vala +++ b/src/core/ViewCollection.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/core/util.vala b/src/core/util.vala index 1846380..0460454 100644 --- a/src/core/util.vala +++ b/src/core/util.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/data_imports/DataImportJob.vala b/src/data_imports/DataImportJob.vala index b27997c..df5aebe 100644 --- a/src/data_imports/DataImportJob.vala +++ b/src/data_imports/DataImportJob.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -157,6 +157,10 @@ public class DataImportJob : BatchImportJob { string? title = src_photo.get_title(); if (title != null) photo.set_title(title); + // exposure time + time_t? date_time = src_photo.get_exposure_time(); + if (date_time != null) + photo.set_exposure_time(date_time); // import ID photo.set_import_id(import_roll.import_id); diff --git a/src/data_imports/DataImportSource.vala b/src/data_imports/DataImportSource.vala index d7e8ec8..f60c06d 100644 --- a/src/data_imports/DataImportSource.vala +++ b/src/data_imports/DataImportSource.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -48,9 +48,16 @@ public class DataImportSource { warning("Could not get file metadata for %s: %s", get_filename(), e.message); metadata = null; } - - title = (metadata != null) ? metadata.get_title() : null; - exposure_time = (metadata != null) ? metadata.get_exposure_date_time() : null; + title = db_photo.get_title(); + if (title == null) { + title = (metadata != null) ? metadata.get_title() : null; + } + time_t? date_time = db_photo.get_exposure_time(); + if (date_time != null) { + exposure_time = new MetadataDateTime(date_time); + } else { + exposure_time = (metadata != null) ? metadata.get_exposure_date_time() : null; + } PhotoPreview? preview = metadata != null ? metadata.get_preview(0) : null; if (preview != null) { try { diff --git a/src/data_imports/DataImports.vala b/src/data_imports/DataImports.vala index 72c8b4d..1406d71 100644 --- a/src/data_imports/DataImports.vala +++ b/src/data_imports/DataImports.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/data_imports/DataImportsPluginHost.vala b/src/data_imports/DataImportsPluginHost.vala index f92bc53..f783e1f 100644 --- a/src/data_imports/DataImportsPluginHost.vala +++ b/src/data_imports/DataImportsPluginHost.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/data_imports/DataImportsUI.vala b/src/data_imports/DataImportsUI.vala index 9b171b1..7b975a7 100644 --- a/src/data_imports/DataImportsUI.vala +++ b/src/data_imports/DataImportsUI.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -202,19 +202,19 @@ public class DataImportsDialog : Gtk.Dialog { public const int STANDARD_ACTION_BUTTON_WIDTH = 128; private Gtk.ComboBoxText service_selector_box; - private Gtk.Label service_selector_box_label; private Gtk.Box central_area_layouter; private Gtk.Button close_cancel_button; private Spit.DataImports.DialogPane active_pane; private Spit.DataImports.ConcreteDataImportsHost host; protected DataImportsDialog() { + Object(use_header_bar: 1); + ((Gtk.HeaderBar) get_header_bar()).set_show_close_button(false); resizable = false; delete_event.connect(on_window_close); string title = _("Import From Application"); - string label = _("Import media _from:"); set_title(title); @@ -225,9 +225,6 @@ public class DataImportsDialog : Gtk.Dialog { // service to select from service_selector_box = new Gtk.ComboBoxText(); service_selector_box.set_active(0); - service_selector_box_label = new Gtk.Label.with_mnemonic(label); - service_selector_box_label.set_mnemonic_widget(service_selector_box); - service_selector_box_label.set_alignment(0.0f, 0.5f); // get the name of the service the user last used string? last_used_service = Config.Facade.get_instance().get_last_used_dataimports_service(); @@ -248,30 +245,6 @@ public class DataImportsDialog : Gtk.Dialog { service_selector_box.set_active(0); service_selector_box.changed.connect(on_service_changed); - - /* the wrapper is not an extraneous widget -- it's necessary to prevent the service - selection box from growing and shrinking whenever its parent's size changes. - When wrapped inside a Gtk.Alignment, the Alignment grows and shrinks instead of - the service selection box. */ - Gtk.Alignment service_selector_box_wrapper = new Gtk.Alignment(1.0f, 0.5f, 0.0f, 0.0f); - service_selector_box_wrapper.add(service_selector_box); - - Gtk.Box service_selector_layouter = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); - service_selector_layouter.set_border_width(12); - service_selector_layouter.add(service_selector_box_label); - service_selector_layouter.pack_start(service_selector_box_wrapper, true, true, 0); - - /* 'service area' is the selector assembly plus the horizontal rule dividing it from the - rest of the dialog */ - Gtk.Box service_area_layouter = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); - service_area_layouter.pack_start(service_selector_layouter, true, true, 0); - Gtk.Separator service_central_separator = new Gtk.Separator(Gtk.Orientation.HORIZONTAL); - service_area_layouter.add(service_central_separator); - - Gtk.Alignment service_area_wrapper = new Gtk.Alignment(0.0f, 0.0f, 1.0f, 0.0f); - service_area_wrapper.add(service_area_layouter); - - ((Gtk.Box) get_content_area()).pack_start(service_area_wrapper, false, false, 0); } // Intall the central area in all cases @@ -281,7 +254,9 @@ public class DataImportsDialog : Gtk.Dialog { close_cancel_button = new Gtk.Button.with_mnemonic("_Cancel"); close_cancel_button.set_can_default(true); close_cancel_button.clicked.connect(on_close_cancel_clicked); - ((Gtk.Box) get_action_area()).add(close_cancel_button); + + ((Gtk.HeaderBar) get_header_bar()).pack_start(close_cancel_button); + ((Gtk.HeaderBar) get_header_bar()).pack_end(service_selector_box); set_standard_window_mode(); diff --git a/src/db/DatabaseTable.vala b/src/db/DatabaseTable.vala index 55d440d..235ac06 100644 --- a/src/db/DatabaseTable.vala +++ b/src/db/DatabaseTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/db/Db.vala b/src/db/Db.vala index ced530a..c6b69d9 100644 --- a/src/db/Db.vala +++ b/src/db/Db.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/db/EventTable.vala b/src/db/EventTable.vala index 016fa00..04310b8 100644 --- a/src/db/EventTable.vala +++ b/src/db/EventTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/db/PhotoTable.vala b/src/db/PhotoTable.vala index 9891fe6..21a8d5e 100644 --- a/src/db/PhotoTable.vala +++ b/src/db/PhotoTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/db/SavedSearchDBTable.vala b/src/db/SavedSearchDBTable.vala index d986038..9baab4e 100644 --- a/src/db/SavedSearchDBTable.vala +++ b/src/db/SavedSearchDBTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/db/TagTable.vala b/src/db/TagTable.vala index a0fade8..05b2daa 100644 --- a/src/db/TagTable.vala +++ b/src/db/TagTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/db/TombstoneTable.vala b/src/db/TombstoneTable.vala index 9e108bd..861cba4 100644 --- a/src/db/TombstoneTable.vala +++ b/src/db/TombstoneTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/db/VersionTable.vala b/src/db/VersionTable.vala index 9003b1b..3711b83 100644 --- a/src/db/VersionTable.vala +++ b/src/db/VersionTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/db/VideoTable.vala b/src/db/VideoTable.vala index c681dc2..bd45750 100644 --- a/src/db/VideoTable.vala +++ b/src/db/VideoTable.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/direct/Direct.vala b/src/direct/Direct.vala index dd2a847..59680b1 100644 --- a/src/direct/Direct.vala +++ b/src/direct/Direct.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/direct/DirectPhoto.vala b/src/direct/DirectPhoto.vala index f7271ba..9cd86f9 100644 --- a/src/direct/DirectPhoto.vala +++ b/src/direct/DirectPhoto.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/direct/DirectPhotoPage.vala b/src/direct/DirectPhotoPage.vala index 4dfd520..58d82fc 100644 --- a/src/direct/DirectPhotoPage.vala +++ b/src/direct/DirectPhotoPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -46,13 +46,13 @@ public class DirectPhotoPage : EditingHostPage { file.label = _("_File"); actions += file; - Gtk.ActionEntry save = { "Save", Gtk.Stock.SAVE, TRANSLATABLE, "<Ctrl>S", TRANSLATABLE, + Gtk.ActionEntry save = { "Save", Resources.SAVE_LABEL, TRANSLATABLE, "<Ctrl>S", TRANSLATABLE, on_save }; save.label = _("_Save"); save.tooltip = _("Save photo"); actions += save; - Gtk.ActionEntry save_as = { "SaveAs", Gtk.Stock.SAVE_AS, TRANSLATABLE, + Gtk.ActionEntry save_as = { "SaveAs", Resources.SAVE_AS_LABEL, TRANSLATABLE, "<Ctrl><Shift>S", TRANSLATABLE, on_save_as }; save_as.label = _("Save _As..."); save_as.tooltip = _("Save photo with a different name"); @@ -63,7 +63,7 @@ public class DirectPhotoPage : EditingHostPage { send_to.label = Resources.SEND_TO_MENU; actions += send_to; - Gtk.ActionEntry print = { "Print", Gtk.Stock.PRINT, TRANSLATABLE, "<Ctrl>P", + Gtk.ActionEntry print = { "Print", Resources.PRINT_LABEL, TRANSLATABLE, "<Ctrl>P", TRANSLATABLE, on_print }; print.label = Resources.PRINT_MENU; print.tooltip = _("Print the photo to a printer connected to your computer"); @@ -81,13 +81,13 @@ public class DirectPhotoPage : EditingHostPage { tools.label = _("T_ools"); actions += tools; - Gtk.ActionEntry prev = { "PrevPhoto", Gtk.Stock.GO_BACK, TRANSLATABLE, null, + Gtk.ActionEntry prev = { "PrevPhoto", Resources.PREVIOUS_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_previous_photo }; prev.label = _("_Previous Photo"); prev.tooltip = _("Previous Photo"); actions += prev; - Gtk.ActionEntry next = { "NextPhoto", Gtk.Stock.GO_FORWARD, TRANSLATABLE, null, + Gtk.ActionEntry next = { "NextPhoto", Resources.NEXT_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_next_photo }; next.label = _("_Next Photo"); next.tooltip = _("Next Photo"); @@ -127,7 +127,7 @@ public class DirectPhotoPage : EditingHostPage { crop.tooltip = Resources.CROP_TOOLTIP; actions += crop; - Gtk.ActionEntry straighten = { "Straighten", Gtk.Stock.REFRESH, TRANSLATABLE, "<Ctrl>A", + Gtk.ActionEntry straighten = { "Straighten", Resources.REFRESH_LABEL, TRANSLATABLE, "<Ctrl>A", TRANSLATABLE, toggle_straighten }; straighten.label = Resources.STRAIGHTEN_MENU; straighten.tooltip = Resources.STRAIGHTEN_TOOLTIP; @@ -145,7 +145,7 @@ public class DirectPhotoPage : EditingHostPage { adjust.tooltip = Resources.ADJUST_TOOLTIP; actions += adjust; - Gtk.ActionEntry revert = { "Revert", Gtk.Stock.REVERT_TO_SAVED, TRANSLATABLE, + Gtk.ActionEntry revert = { "Revert", Resources.REVERT_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_revert }; revert.label = Resources.REVERT_MENU; actions += revert; @@ -169,25 +169,25 @@ public class DirectPhotoPage : EditingHostPage { help.label = _("_Help"); actions += help; - Gtk.ActionEntry increase_size = { "IncreaseSize", Gtk.Stock.ZOOM_IN, TRANSLATABLE, + Gtk.ActionEntry increase_size = { "IncreaseSize", Resources.ZOOM_IN_LABEL, TRANSLATABLE, "<Ctrl>plus", TRANSLATABLE, on_increase_size }; increase_size.label = _("Zoom _In"); increase_size.tooltip = _("Increase the magnification of the photo"); actions += increase_size; - Gtk.ActionEntry decrease_size = { "DecreaseSize", Gtk.Stock.ZOOM_OUT, TRANSLATABLE, + Gtk.ActionEntry decrease_size = { "DecreaseSize", Resources.ZOOM_OUT_LABEL, TRANSLATABLE, "<Ctrl>minus", TRANSLATABLE, on_decrease_size }; decrease_size.label = _("Zoom _Out"); decrease_size.tooltip = _("Decrease the magnification of the photo"); actions += decrease_size; - Gtk.ActionEntry best_fit = { "ZoomFit", Gtk.Stock.ZOOM_FIT, TRANSLATABLE, + Gtk.ActionEntry best_fit = { "ZoomFit", Resources.ZOOM_FIT_LABEL, TRANSLATABLE, "<Ctrl>0", TRANSLATABLE, snap_zoom_to_min }; best_fit.label = _("Fit to _Page"); best_fit.tooltip = _("Zoom the photo to fit on the screen"); actions += best_fit; - Gtk.ActionEntry actual_size = { "Zoom100", Gtk.Stock.ZOOM_100, TRANSLATABLE, + Gtk.ActionEntry actual_size = { "Zoom100", Resources.ZOOM_100_LABEL, TRANSLATABLE, "<Ctrl>1", TRANSLATABLE, snap_zoom_to_isomorphic }; /// xgettext:no-c-format actual_size.label = _("Zoom _100%"); @@ -324,10 +324,15 @@ public class DirectPhotoPage : EditingHostPage { } protected override bool on_double_click(Gdk.EventButton event) { - AppWindow.get_instance().end_fullscreen(); + FullscreenWindow? fs = get_container() as FullscreenWindow; + if (fs != null) { + fs.close(); + + return true; + } return base.on_double_click(event); - } + } protected override void update_ui(bool missing) { bool sensitivity = !missing; @@ -501,8 +506,8 @@ public class DirectPhotoPage : EditingHostPage { } Gtk.FileChooserDialog save_as_dialog = new Gtk.FileChooserDialog(_("Save As"), - AppWindow.get_instance(), Gtk.FileChooserAction.SAVE, Gtk.Stock.CANCEL, - Gtk.ResponseType.CANCEL, Gtk.Stock.OK, Gtk.ResponseType.OK); + AppWindow.get_instance(), Gtk.FileChooserAction.SAVE, Resources.CANCEL_LABEL, + Gtk.ResponseType.CANCEL, Resources.OK_LABEL, Gtk.ResponseType.OK); save_as_dialog.set_select_multiple(false); save_as_dialog.set_current_name(filename); save_as_dialog.set_current_folder(current_save_dir.get_path()); diff --git a/src/direct/DirectView.vala b/src/direct/DirectView.vala index a36ec68..6f37850 100644 --- a/src/direct/DirectView.vala +++ b/src/direct/DirectView.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/direct/DirectWindow.vala b/src/direct/DirectWindow.vala index b339ac4..35729b7 100644 --- a/src/direct/DirectWindow.vala +++ b/src/direct/DirectWindow.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/editing_tools/EditingTools.vala b/src/editing_tools/EditingTools.vala index f5fb144..6c91011 100644 --- a/src/editing_tools/EditingTools.vala +++ b/src/editing_tools/EditingTools.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -647,7 +647,7 @@ public class CropTool : EditingTool { private const int CONTROL_SPACING = 8; public Gtk.Button ok_button = new Gtk.Button.with_label(Resources.CROP_LABEL); - public Gtk.Button cancel_button = new Gtk.Button.from_stock(Gtk.Stock.CANCEL); + public Gtk.Button cancel_button = new Gtk.Button.with_mnemonic(Resources.CANCEL_LABEL); public Gtk.ComboBox constraint_combo; public Gtk.Button pivot_reticle_button = new Gtk.Button(); public Gtk.Entry custom_width_entry = new Gtk.Entry(); @@ -1890,9 +1890,9 @@ public class RedeyeTool : EditingTool { private Gtk.Label slider_label = new Gtk.Label.with_mnemonic(_("Size:")); public Gtk.Button apply_button = - new Gtk.Button.from_stock(Gtk.Stock.APPLY); + new Gtk.Button.with_mnemonic(Resources.APPLY_LABEL); public Gtk.Button close_button = - new Gtk.Button.from_stock(Gtk.Stock.CLOSE); + new Gtk.Button.with_mnemonic(Resources.CANCEL_LABEL); public Gtk.Scale slider = new Gtk.Scale.with_range(Gtk.Orientation.HORIZONTAL, RedeyeInstance.MIN_RADIUS, RedeyeInstance.MAX_RADIUS, 1.0); @@ -2240,9 +2240,9 @@ public class AdjustTool : EditingTool { HighlightDetailTransformation.MIN_PARAMETER, HighlightDetailTransformation.MAX_PARAMETER, 1.0); - public Gtk.Button ok_button = new Gtk.Button.from_stock(Gtk.Stock.OK); + public Gtk.Button ok_button = new Gtk.Button.with_mnemonic(Resources.OK_LABEL); public Gtk.Button reset_button = new Gtk.Button.with_mnemonic(_("_Reset")); - public Gtk.Button cancel_button = new Gtk.Button.from_stock(Gtk.Stock.CANCEL); + public Gtk.Button cancel_button = new Gtk.Button.with_mnemonic(Resources.CANCEL_LABEL); public RGBHistogramManipulator histogram_manipulator = new RGBHistogramManipulator(); public AdjustToolWindow(Gtk.Window container) { diff --git a/src/editing_tools/StraightenTool.vala b/src/editing_tools/StraightenTool.vala index 8a778ec..e2b117e 100644 --- a/src/editing_tools/StraightenTool.vala +++ b/src/editing_tools/StraightenTool.vala @@ -1,5 +1,5 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -98,7 +98,7 @@ public class StraightenTool : EditingTool { public Gtk.Label angle_label = new Gtk.Label(""); public Gtk.Label description_label = new Gtk.Label(_("Angle:")); public Gtk.Button ok_button = new Gtk.Button.with_mnemonic(_("_Straighten")); - public Gtk.Button cancel_button = new Gtk.Button.from_stock(Gtk.Stock.CANCEL); + public Gtk.Button cancel_button = new Gtk.Button.with_mnemonic(Resources.CANCEL_LABEL); public Gtk.Button reset_button = new Gtk.Button.with_mnemonic(_("_Reset")); /** diff --git a/src/events/Branch.vala b/src/events/Branch.vala index e1b5221..1093411 100644 --- a/src/events/Branch.vala +++ b/src/events/Branch.vala @@ -1,15 +1,14 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ public class Events.Branch : Sidebar.Branch { - internal static Icon open_icon; - internal static Icon closed_icon; - internal static Icon events_icon; - internal static Icon single_event_icon; - internal static Icon no_event_icon; + internal static string icon = Resources.ICON_FOLDER; + internal static string events_icon = Resources.ICON_EVENTS; + internal static string single_event_icon = Resources.ICON_ONE_EVENT; + internal static string no_event_icon = Resources.ICON_NO_EVENT; // NOTE: Because the comparators must be static methods (due to CompareFunc's stupid impl.) // and there's an assumption that only one Events.Branch is ever created, this is a static @@ -20,11 +19,14 @@ public class Events.Branch : Sidebar.Branch { Event, Events.EventEntry>(); private Events.UndatedDirectoryEntry undated_entry = new Events.UndatedDirectoryEntry(); private Events.NoEventEntry no_event_entry = new Events.NoEventEntry(); + private Events.MasterDirectoryEntry all_events_entry = new Events.MasterDirectoryEntry(); public Branch() { - base (new Events.MasterDirectoryEntry(), Sidebar.Branch.Options.STARTUP_EXPAND_TO_FIRST_CHILD, + base (new Sidebar.Header(_("Events")), Sidebar.Branch.Options.STARTUP_EXPAND_TO_FIRST_CHILD, event_year_comparator); + graft(get_root(), all_events_entry); + // seed the branch foreach (DataObject object in Event.global.get_all()) add_event((Event) object); @@ -49,25 +51,18 @@ public class Events.Branch : Sidebar.Branch { } internal static void init() { - open_icon = new ThemedIcon(Resources.ICON_FOLDER_OPEN); - closed_icon = new ThemedIcon(Resources.ICON_FOLDER_CLOSED); - events_icon = new ThemedIcon(Resources.ICON_EVENTS); - single_event_icon = new ThemedIcon(Resources.ICON_ONE_EVENT); - no_event_icon = new ThemedIcon(Resources.ICON_NO_EVENT); - sort_ascending = Config.Facade.get_instance().get_events_sort_ascending(); } internal static void terminate() { - open_icon = null; - closed_icon = null; - events_icon = null; - single_event_icon = null; - no_event_icon = null; + } + + public bool is_user_renameable() { + return true; } public Events.MasterDirectoryEntry get_master_entry() { - return (Events.MasterDirectoryEntry) get_root(); + return all_events_entry; } private static int event_year_comparator(Sidebar.Entry a, Sidebar.Entry b) { @@ -91,6 +86,12 @@ public class Events.Branch : Sidebar.Branch { else if (b is Events.NoEventEntry) return -1; + // The All events entry should always appear on top + if (a is Events.MasterDirectoryEntry) + return -1; + else if (b is Events.MasterDirectoryEntry) + return 1; + if (!sort_ascending) { Sidebar.Entry swap = a; a = b; @@ -312,7 +313,8 @@ public class Events.Branch : Sidebar.Branch { int event_year = event_tm.year + 1900; return find_first_child(get_root(), (entry) => { - if ((entry is Events.UndatedDirectoryEntry) || (entry is Events.NoEventEntry)) + if ((entry is Events.UndatedDirectoryEntry) || (entry is Events.NoEventEntry) || + entry is Events.MasterDirectoryEntry) return false; else return ((Events.YearDirectoryEntry) entry).get_year() == event_year; @@ -334,11 +336,11 @@ public class Events.Branch : Sidebar.Branch { } private void graft_event(Sidebar.Entry parent, Event event, - owned CompareDataFunc<Sidebar.Entry>? comparator = null) { + owned CompareFunc<Sidebar.Entry>? comparator = null) { Events.EventEntry entry = new Events.EventEntry(event); entry_map.set(event, entry); - graft(parent, entry, (owned) comparator); + graft(parent, entry, comparator); } private void reparent_event(Event event, Sidebar.Entry new_parent) { @@ -372,16 +374,8 @@ public abstract class Events.DirectoryEntry : Sidebar.SimplePageEntry, Sidebar.E public DirectoryEntry() { } - public override Icon? get_sidebar_icon() { - return null; - } - - public virtual Icon? get_sidebar_open_icon() { - return Events.Branch.open_icon; - } - - public virtual Icon? get_sidebar_closed_icon() { - return Events.Branch.closed_icon; + public override string? get_sidebar_icon() { + return Events.Branch.icon; } public bool expand_on_select() { @@ -397,15 +391,7 @@ public class Events.MasterDirectoryEntry : Events.DirectoryEntry { return MasterEventsDirectoryPage.NAME; } - public override Icon? get_sidebar_icon() { - return Events.Branch.events_icon; - } - - public override Icon? get_sidebar_open_icon() { - return Events.Branch.events_icon; - } - - public override Icon? get_sidebar_closed_icon() { + public override string? get_sidebar_icon() { return Events.Branch.events_icon; } @@ -492,7 +478,7 @@ public class Events.EventEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr return event.get_name(); } - public override Icon? get_sidebar_icon() { + public override string? get_sidebar_icon() { return Events.Branch.single_event_icon; } @@ -500,6 +486,10 @@ public class Events.EventEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr return new EventPage(event); } + public bool is_user_renameable() { + return true; + } + public void rename(string new_name) { string? prepped = Event.prep_event_name(new_name); if (prepped != null) @@ -523,6 +513,7 @@ public class Events.EventEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr } } + public class Events.NoEventEntry : Sidebar.SimplePageEntry { public NoEventEntry() { } @@ -531,7 +522,7 @@ public class Events.NoEventEntry : Sidebar.SimplePageEntry { return NoEventPage.NAME; } - public override Icon? get_sidebar_icon() { + public override string? get_sidebar_icon() { return Events.Branch.no_event_icon; } diff --git a/src/events/EventDirectoryItem.vala b/src/events/EventDirectoryItem.vala index 5b2026b..d3434c2 100644 --- a/src/events/EventDirectoryItem.vala +++ b/src/events/EventDirectoryItem.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/events/EventPage.vala b/src/events/EventPage.vala index 3d23f25..ed103a8 100644 --- a/src/events/EventPage.vala +++ b/src/events/EventPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/events/Events.vala b/src/events/Events.vala index dc2b662..f93e33c 100644 --- a/src/events/Events.vala +++ b/src/events/Events.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/events/EventsDirectoryPage.vala b/src/events/EventsDirectoryPage.vala index 41a1ac6..99601a0 100644 --- a/src/events/EventsDirectoryPage.vala +++ b/src/events/EventsDirectoryPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -227,7 +227,7 @@ public abstract class EventsDirectoryPage : CheckerboardPage { } public class MasterEventsDirectoryPage : EventsDirectoryPage { - public const string NAME = _("Events"); + public const string NAME = _("All Events"); public MasterEventsDirectoryPage() { base (NAME, new EventDirectoryManager(), (Gee.Collection<Event>) Event.global.get_all()); diff --git a/src/folders/Branch.vala b/src/folders/Branch.vala index bc5b578..0904e5c 100644 --- a/src/folders/Branch.vala +++ b/src/folders/Branch.vala @@ -1,4 +1,4 @@ -/* Copyright 2012-2014 Yorba Foundation +/* Copyright 2012-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -136,9 +136,9 @@ public class Folders.Branch : Sidebar.Branch { } } -private class Folders.Root : Sidebar.Grouping { +private class Folders.Root : Sidebar.Header { public Root() { - base (_("Folders"), Folders.opened_icon, Folders.closed_icon); + base (_("Folders")); } } @@ -172,22 +172,14 @@ public class Folders.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.ExpandableE return dir.get_basename(); } - public override Icon? get_sidebar_icon() { - return count == 0 ? closed_icon : have_photos_icon; + public override string? get_sidebar_icon() { + return count == 0 ? icon : have_photos_icon; } public override string to_string() { return dir.get_path(); } - public Icon? get_sidebar_open_icon() { - return count == 0 ? opened_icon : have_photos_icon; - } - - public Icon? get_sidebar_closed_icon() { - return count == 0 ? closed_icon : have_photos_icon; - } - public bool expand_on_select() { return true; } diff --git a/src/folders/Folders.vala b/src/folders/Folders.vala index 1cc14b1..da6f817 100644 --- a/src/folders/Folders.vala +++ b/src/folders/Folders.vala @@ -1,4 +1,4 @@ -/* Copyright 2012-2014 Yorba Foundation +/* Copyright 2012-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -15,19 +15,16 @@ namespace Folders { -static Icon? opened_icon = null; -static Icon? closed_icon = null; -static Icon? have_photos_icon = null; +static string? icon = null; +static string? have_photos_icon = null; public void init() throws Error { - opened_icon = new ThemedIcon(Resources.ICON_FOLDER_OPEN); - closed_icon = new ThemedIcon(Resources.ICON_FOLDER_CLOSED); - have_photos_icon = new ThemedIcon(Resources.ICON_FOLDER_DOCUMENTS); + icon = Resources.ICON_FOLDER; + have_photos_icon = Resources.ICON_FOLDER_DOCUMENTS; } public void terminate() { - opened_icon = null; - closed_icon = null; + icon = null; have_photos_icon = null; } diff --git a/src/folders/Page.vala b/src/folders/Page.vala index d101e88..eb3a84f 100644 --- a/src/folders/Page.vala +++ b/src/folders/Page.vala @@ -1,4 +1,4 @@ -/* Copyright 2012-2014 Yorba Foundation +/* Copyright 2012-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/library/Branch.vala b/src/library/Branch.vala index dc05d60..0e875d2 100644 --- a/src/library/Branch.vala +++ b/src/library/Branch.vala @@ -1,31 +1,104 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ -public class Library.Branch : Sidebar.RootOnlyBranch { +public class Library.Branch : Sidebar.Branch { + private const string POSITION_DATA = "x-photos-entry-position"; + + public Library.PhotosEntry photos_entry { get; private set; } + public Library.FlaggedSidebarEntry flagged_entry { get; private set; } + public Library.LastImportSidebarEntry last_imported_entry { get; private set; } + public Library.ImportQueueSidebarEntry import_queue_entry { get; private set; } + public Library.OfflineSidebarEntry offline_entry { get; private set; } + public Library.TrashSidebarEntry trash_entry { get; private set; } + + // This lists the order of the library items in the sidebar. To re-order, simply move + // the item in this list to a new position. These numbers should *not* persist anywhere + // outside the app. + private enum EntryPosition { + PHOTOS, + FLAGGED, + LAST_IMPORTED, + IMPORT_QUEUE, + OFFLINE, + TRASH + } + public Branch() { - base (new Library.SidebarEntry()); + base(new Sidebar.Header(_("Library")), + Sidebar.Branch.Options.STARTUP_OPEN_GROUPING, comparator); + + photos_entry = new Library.PhotosEntry(); + trash_entry = new Library.TrashSidebarEntry(); + last_imported_entry = new Library.LastImportSidebarEntry(); + flagged_entry = new Library.FlaggedSidebarEntry(); + offline_entry = new Library.OfflineSidebarEntry(); + import_queue_entry = new Library.ImportQueueSidebarEntry(); + + insert(photos_entry, EntryPosition.PHOTOS); + insert(trash_entry, EntryPosition.TRASH); + + flagged_entry.visibility_changed.connect(on_flagged_visibility_changed); + on_flagged_visibility_changed(); + + last_imported_entry.visibility_changed.connect(on_last_imported_visibility_changed); + on_last_imported_visibility_changed(); + + import_queue_entry.visibility_changed.connect(on_import_queue_visibility_changed); + on_import_queue_visibility_changed(); + + offline_entry.visibility_changed.connect(on_offline_visibility_changed); + on_offline_visibility_changed(); } - public Library.MainPage get_main_page() { - return (Library.MainPage) ((Library.SidebarEntry) get_root()).get_page(); + private void insert(Sidebar.Entry entry, int position) { + entry.set_data<int>(POSITION_DATA, position); + graft(get_root(), entry); + } + + private void on_flagged_visibility_changed() { + update_entry_visibility(flagged_entry, EntryPosition.FLAGGED); + } + + private void on_last_imported_visibility_changed() { + update_entry_visibility(last_imported_entry, EntryPosition.LAST_IMPORTED); + } + + private void on_import_queue_visibility_changed() { + update_entry_visibility(import_queue_entry, EntryPosition.IMPORT_QUEUE); + } + + private void on_offline_visibility_changed() { + update_entry_visibility(offline_entry, EntryPosition.OFFLINE); + } + + private void update_entry_visibility(Library.HideablePageEntry entry, int position) { + if (entry.visible) { + if (!has_entry(entry)) + insert(entry, position); + } else if (has_entry(entry)) { + prune(entry); + } + } + + private static int comparator(Sidebar.Entry a, Sidebar.Entry b) { + return a.get_data<int>(POSITION_DATA) - b.get_data<int>(POSITION_DATA); } } -public class Library.SidebarEntry : Sidebar.SimplePageEntry { - private Icon icon = new ThemedIcon(Resources.ICON_PHOTOS); +public class Library.PhotosEntry : Sidebar.SimplePageEntry { - public SidebarEntry() { + public PhotosEntry() { } public override string get_sidebar_name() { - return Library.MainPage.NAME; + return _("Photos"); } - public override Icon? get_sidebar_icon() { - return icon; + public override string? get_sidebar_icon() { + return Resources.ICON_PHOTOS; } protected override Page create_page() { @@ -33,6 +106,26 @@ public class Library.SidebarEntry : Sidebar.SimplePageEntry { } } +public abstract class Library.HideablePageEntry : Sidebar.SimplePageEntry { + // container branch should listen to this signal + public signal void visibility_changed(bool visible); + + private bool show_entry = false; + public bool visible { + get { return show_entry; } + set { + if (value == show_entry) + return; + + show_entry = value; + visibility_changed(value); + } + } + + public HideablePageEntry() { + } +} + public class Library.MainPage : CollectionPage { public const string NAME = _("Library"); diff --git a/src/library/FlaggedPage.vala b/src/library/FlaggedPage.vala index 28bc57b..b45cc54 100644 --- a/src/library/FlaggedPage.vala +++ b/src/library/FlaggedPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/library/FlaggedBranch.vala b/src/library/FlaggedSidebarEntry.vala index 472d999..240aaf3 100644 --- a/src/library/FlaggedBranch.vala +++ b/src/library/FlaggedSidebarEntry.vala @@ -1,47 +1,28 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ -public class Library.FlaggedBranch : Sidebar.RootOnlyBranch { - public FlaggedBranch() { - base (new Library.FlaggedSidebarEntry()); - +public class Library.FlaggedSidebarEntry : Library.HideablePageEntry, Sidebar.InternalDropTargetEntry { + public FlaggedSidebarEntry() { foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) media_sources.flagged_contents_altered.connect(on_flagged_contents_altered); - set_show_branch(get_total_flagged() != 0); + visible = (get_total_flagged() != 0); } - ~FlaggedBranch() { + ~FlaggedSidebarEntry() { foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) media_sources.flagged_contents_altered.disconnect(on_flagged_contents_altered); - } - - private void on_flagged_contents_altered() { - set_show_branch(get_total_flagged() != 0); - } - - private int get_total_flagged() { - int total = 0; - foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) - total += media_sources.get_flagged().size; - - return total; - } -} - -public class Library.FlaggedSidebarEntry : Sidebar.SimplePageEntry, Sidebar.InternalDropTargetEntry { - public FlaggedSidebarEntry() { - } - + } + public override string get_sidebar_name() { return FlaggedPage.NAME; } - public override Icon? get_sidebar_icon() { - return new ThemedIcon(Resources.ICON_FLAGGED_PAGE); + public override string? get_sidebar_icon() { + return Resources.ICON_FLAGGED_PAGE; } protected override Page create_page() { @@ -57,5 +38,17 @@ public class Library.FlaggedSidebarEntry : Sidebar.SimplePageEntry, Sidebar.Inte public bool internal_drop_received_arbitrary(Gtk.SelectionData data) { return false; } + + private void on_flagged_contents_altered() { + visible = (get_total_flagged() != 0); + } + + private int get_total_flagged() { + int total = 0; + foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) + total += media_sources.get_flagged().size; + + return total; + } } diff --git a/src/library/ImportQueuePage.vala b/src/library/ImportQueuePage.vala index 5ace1d8..9886f5a 100644 --- a/src/library/ImportQueuePage.vala +++ b/src/library/ImportQueuePage.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -28,7 +28,8 @@ public class ImportQueuePage : SinglePhotoPage { Gtk.Toolbar toolbar = get_toolbar(); // Stop button - Gtk.ToolButton stop_button = new Gtk.ToolButton.from_stock(Gtk.Stock.STOP); + Gtk.ToolButton stop_button = new Gtk.ToolButton(null, null); + stop_button.set_icon_name("stop"); stop_button.set_related_action(get_action("Stop")); toolbar.insert(stop_button, -1); @@ -61,7 +62,7 @@ public class ImportQueuePage : SinglePhotoPage { protected override Gtk.ActionEntry[] init_collect_action_entries() { Gtk.ActionEntry[] actions = base.init_collect_action_entries(); - Gtk.ActionEntry stop = { "Stop", Gtk.Stock.STOP, TRANSLATABLE, null, TRANSLATABLE, + Gtk.ActionEntry stop = { "Stop", Resources.STOP_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_stop }; stop.label = _("_Stop Import"); stop.tooltip = _("Stop importing photos"); diff --git a/src/library/ImportQueueBranch.vala b/src/library/ImportQueueSidebarEntry.vala index 32a3e0d..5d34ce2 100644 --- a/src/library/ImportQueueBranch.vala +++ b/src/library/ImportQueueSidebarEntry.vala @@ -1,38 +1,37 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ -public class Library.ImportQueueBranch : Sidebar.RootOnlyBranch { - private Library.ImportQueueSidebarEntry entry; - - public ImportQueueBranch() { - // can't pass to base() an object that was allocated in declaration; see - // https://bugzilla.gnome.org/show_bug.cgi?id=646286 - base (new Library.ImportQueueSidebarEntry()); - - entry = (Library.ImportQueueSidebarEntry) get_root(); - +public class Library.ImportQueueSidebarEntry : Library.HideablePageEntry { + public ImportQueueSidebarEntry() { // only attach signals to the page when it's created - entry.page_created.connect(on_page_created); - entry.destroying_page.connect(on_destroying_page); + page_created.connect(on_page_created); + destroying_page.connect(on_destroying_page); // don't use entry.get_page() or get_queue_page() because (a) we don't want to // create the page during initialization, and (b) we know there's no import activity // at this moment - set_show_branch(false); + visible = false; } - ~ImportQueueBranch() { - entry.page_created.disconnect(on_page_created); - entry.destroying_page.disconnect(on_destroying_page); + public override string get_sidebar_name() { + return ImportQueuePage.NAME; } - public ImportQueuePage get_queue_page() { - return (ImportQueuePage) entry.get_page(); + public override string? get_sidebar_icon() { + return Resources.ICON_IMPORTING; } + protected override Page create_page() { + return new ImportQueuePage(); + } + + private ImportQueuePage get_queue_page() { + return get_page() as ImportQueuePage; + } + private void on_page_created() { get_queue_page().batch_added.connect(on_batch_added_or_removed); get_queue_page().batch_removed.connect(on_batch_added_or_removed); @@ -44,31 +43,14 @@ public class Library.ImportQueueBranch : Sidebar.RootOnlyBranch { } private void on_batch_added_or_removed() { - set_show_branch(get_queue_page().get_batch_count() > 0); + visible = (get_queue_page().get_batch_count() > 0); } public void enqueue_and_schedule(BatchImport batch_import, bool allow_user_cancel) { // want to display the branch before passing to the page because this might result in the // page being created, and want it all hooked up in the tree prior to creating the page - set_show_branch(true); + visible = true; get_queue_page().enqueue_and_schedule(batch_import, allow_user_cancel); } } -public class Library.ImportQueueSidebarEntry : Sidebar.SimplePageEntry { - public ImportQueueSidebarEntry() { - } - - public override string get_sidebar_name() { - return ImportQueuePage.NAME; - } - - public override Icon? get_sidebar_icon() { - return new ThemedIcon(Resources.ICON_IMPORTING); - } - - protected override Page create_page() { - return new ImportQueuePage(); - } -} - diff --git a/src/library/LastImportPage.vala b/src/library/LastImportPage.vala index 877faa5..ea9045c 100644 --- a/src/library/LastImportPage.vala +++ b/src/library/LastImportPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/library/LastImportBranch.vala b/src/library/LastImportSidebarEntry.vala index bc03ee5..3414130 100644 --- a/src/library/LastImportBranch.vala +++ b/src/library/LastImportSidebarEntry.vala @@ -1,47 +1,36 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ -public class Library.LastImportBranch : Sidebar.RootOnlyBranch { - public LastImportBranch() { - base (new Library.LastImportSidebarEntry()); - +public class Library.LastImportSidebarEntry : Library.HideablePageEntry { + public LastImportSidebarEntry() { foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) media_sources.import_roll_altered.connect(on_import_rolls_altered); - set_show_branch(MediaCollectionRegistry.get_instance().get_last_import_id() != null); + visible = (MediaCollectionRegistry.get_instance().get_last_import_id() != null); } - ~LastImportBranch() { + ~LastImportSidebarEntry() { foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) media_sources.import_roll_altered.disconnect(on_import_rolls_altered); } - public Library.LastImportSidebarEntry get_main_entry() { - return (Library.LastImportSidebarEntry) get_root(); - } - - private void on_import_rolls_altered() { - set_show_branch(MediaCollectionRegistry.get_instance().get_last_import_id() != null); - } -} - -public class Library.LastImportSidebarEntry : Sidebar.SimplePageEntry { - public LastImportSidebarEntry() { - } - public override string get_sidebar_name() { return LastImportPage.NAME; } - public override Icon? get_sidebar_icon() { - return new ThemedIcon(Resources.ICON_LAST_IMPORT); + public override string? get_sidebar_icon() { + return Resources.ICON_LAST_IMPORT; } protected override Page create_page() { return new LastImportPage(); } + + private void on_import_rolls_altered() { + visible = (MediaCollectionRegistry.get_instance().get_last_import_id() != null); + } } diff --git a/src/library/Library.vala b/src/library/Library.vala index 79a4880..272f3d2 100644 --- a/src/library/Library.vala +++ b/src/library/Library.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/library/LibraryWindow.vala b/src/library/LibraryWindow.vala index dab1f6f..a756436 100644 --- a/src/library/LibraryWindow.vala +++ b/src/library/LibraryWindow.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -42,16 +42,11 @@ public class LibraryWindow : AppWindow { // outside the app. private enum SidebarRootPosition { LIBRARY, - FLAGGED, - LAST_IMPORTED, CAMERAS, - IMPORT_QUEUE, SAVED_SEARCH, EVENTS, FOLDERS, - TAGS, - TRASH, - OFFLINE + TAGS } public enum TargetType { @@ -114,12 +109,7 @@ public class LibraryWindow : AppWindow { private Library.Branch library_branch = new Library.Branch(); private Tags.Branch tags_branch = new Tags.Branch(); private Folders.Branch folders_branch = new Folders.Branch(); - private Library.TrashBranch trash_branch = new Library.TrashBranch(); private Events.Branch events_branch = new Events.Branch(); - private Library.OfflineBranch offline_branch = new Library.OfflineBranch(); - private Library.FlaggedBranch flagged_branch = new Library.FlaggedBranch(); - private Library.LastImportBranch last_import_branch = new Library.LastImportBranch(); - private Library.ImportQueueBranch import_queue_branch = new Library.ImportQueueBranch(); private Camera.Branch camera_branch = new Camera.Branch(); private Searches.Branch saved_search_branch = new Searches.Branch(); private bool page_switching_enabled = true; @@ -172,12 +162,7 @@ public class LibraryWindow : AppWindow { sidebar_tree.graft(library_branch, SidebarRootPosition.LIBRARY); sidebar_tree.graft(tags_branch, SidebarRootPosition.TAGS); sidebar_tree.graft(folders_branch, SidebarRootPosition.FOLDERS); - sidebar_tree.graft(trash_branch, SidebarRootPosition.TRASH); sidebar_tree.graft(events_branch, SidebarRootPosition.EVENTS); - sidebar_tree.graft(offline_branch, SidebarRootPosition.OFFLINE); - sidebar_tree.graft(flagged_branch, SidebarRootPosition.FLAGGED); - sidebar_tree.graft(last_import_branch, SidebarRootPosition.LAST_IMPORTED); - sidebar_tree.graft(import_queue_branch, SidebarRootPosition.IMPORT_QUEUE); sidebar_tree.graft(camera_branch, SidebarRootPosition.CAMERAS); sidebar_tree.graft(saved_search_branch, SidebarRootPosition.SAVED_SEARCH); @@ -207,7 +192,7 @@ public class LibraryWindow : AppWindow { menubar.no_show_all = true; // create the main layout & start at the Library page - create_layout(library_branch.get_main_page()); + create_layout(library_branch.photos_entry.get_page()); // settings that should persist between sessions load_configuration(); @@ -313,12 +298,12 @@ public class LibraryWindow : AppWindow { sort.label = _("Sort _Events"); actions += sort; - Gtk.ActionEntry preferences = { "CommonPreferences", Gtk.Stock.PREFERENCES, TRANSLATABLE, + Gtk.ActionEntry preferences = { "CommonPreferences", Resources.PREFERENCES_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_preferences }; preferences.label = Resources.PREFERENCES_MENU; actions += preferences; - Gtk.ActionEntry empty = { "CommonEmptyTrash", Gtk.Stock.CLEAR, TRANSLATABLE, null, null, + Gtk.ActionEntry empty = { "CommonEmptyTrash", null, TRANSLATABLE, null, null, on_empty_trash }; empty.label = _("Empty T_rash"); empty.tooltip = _("Delete all photos in the trash"); @@ -329,8 +314,7 @@ public class LibraryWindow : AppWindow { jump_to_event.label = _("View Eve_nt for Photo"); actions += jump_to_event; - Gtk.ActionEntry find = { "CommonFind", Gtk.Stock.FIND, TRANSLATABLE, null, null, - on_find }; + Gtk.ActionEntry find = { "CommonFind", null, TRANSLATABLE, null, null, on_find }; find.label = _("_Find"); find.tooltip = _("Find photos and videos by search criteria"); actions += find; @@ -398,7 +382,7 @@ public class LibraryWindow : AppWindow { extended_props.tooltip = _("Display extended information for the selection"); actions += extended_props; - Gtk.ToggleActionEntry searchbar = { "CommonDisplaySearchbar", Gtk.Stock.FIND, TRANSLATABLE, + Gtk.ToggleActionEntry searchbar = { "CommonDisplaySearchbar", "edit-find", TRANSLATABLE, "F8", TRANSLATABLE, on_display_searchbar, is_search_toolbar_visible }; searchbar.label = _("_Search Bar"); searchbar.tooltip = _("Display the search bar"); @@ -417,14 +401,14 @@ public class LibraryWindow : AppWindow { Gtk.RadioActionEntry[] actions = new Gtk.RadioActionEntry[0]; Gtk.RadioActionEntry ascending = { "CommonSortEventsAscending", - Gtk.Stock.SORT_ASCENDING, TRANSLATABLE, null, TRANSLATABLE, + Resources.SORT_ASCENDING_LABEL, TRANSLATABLE, null, TRANSLATABLE, SORT_EVENTS_ORDER_ASCENDING }; ascending.label = _("_Ascending"); ascending.tooltip = _("Sort photos in an ascending order"); actions += ascending; Gtk.RadioActionEntry descending = { "CommonSortEventsDescending", - Gtk.Stock.SORT_DESCENDING, TRANSLATABLE, null, TRANSLATABLE, + Resources.SORT_DESCENDING_LABEL, TRANSLATABLE, null, TRANSLATABLE, SORT_EVENTS_ORDER_DESCENDING }; descending.label = _("D_escending"); descending.tooltip = _("Sort photos in a descending order"); @@ -666,8 +650,8 @@ public class LibraryWindow : AppWindow { private void on_file_import() { Gtk.FileChooserDialog import_dialog = new Gtk.FileChooserDialog(_("Import From Folder"), null, - Gtk.FileChooserAction.SELECT_FOLDER, Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, - Gtk.Stock.OK, Gtk.ResponseType.OK); + Gtk.FileChooserAction.SELECT_FOLDER, Resources.CANCEL_LABEL, Gtk.ResponseType.CANCEL, + Resources.OK_LABEL, Gtk.ResponseType.OK); import_dialog.set_local_only(false); import_dialog.set_select_multiple(true); import_dialog.set_current_folder(import_dir); @@ -883,7 +867,7 @@ public class LibraryWindow : AppWindow { } public void enqueue_batch_import(BatchImport batch_import, bool allow_user_cancel) { - import_queue_branch.enqueue_and_schedule(batch_import, allow_user_cancel); + library_branch.import_queue_entry.enqueue_and_schedule(batch_import, allow_user_cancel); } private void import_reporter(ImportManifest manifest) { @@ -1029,7 +1013,7 @@ public class LibraryWindow : AppWindow { } public void switch_to_library_page() { - switch_to_page(library_branch.get_main_page()); + switch_to_page(library_branch.photos_entry.get_page()); } public void switch_to_event(Event event) { @@ -1066,7 +1050,7 @@ public class LibraryWindow : AppWindow { } public void switch_to_import_queue_page() { - switch_to_page(import_queue_branch.get_queue_page()); + switch_to_page(library_branch.import_queue_entry.get_page()); } private void on_camera_added(DiscoveredCamera camera) { @@ -1285,52 +1269,36 @@ public class LibraryWindow : AppWindow { Gtk.ScrolledWindow scrolled_sidebar = new Gtk.ScrolledWindow(null, null); scrolled_sidebar.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); scrolled_sidebar.add(sidebar_tree); - scrolled_sidebar.get_style_context().add_class(Gtk.STYLE_CLASS_SIDEBAR); - scrolled_sidebar.set_shadow_type(Gtk.ShadowType.IN); - get_style_context().add_class("sidebar-pane-separator"); - - // divy the sidebar up into selection tree list, background progress bar, and properties - Gtk.Frame top_frame = new Gtk.Frame(null); - top_frame.add(scrolled_sidebar); - top_frame.set_shadow_type(Gtk.ShadowType.IN); + background_progress_frame.set_border_width(2); background_progress_frame.add(background_progress_bar); - background_progress_frame.set_shadow_type(Gtk.ShadowType.IN); + background_progress_frame.get_style_context().remove_class("frame"); // pad the bottom frame (properties) Gtk.Alignment bottom_alignment = new Gtk.Alignment(0, 0.5f, 1, 0); - - Resources.style_widget(scrolled_sidebar, Resources.SCROLL_FRAME_STYLESHEET); - Resources.style_widget(bottom_frame, Resources.INSET_FRAME_STYLESHEET); bottom_alignment.set_padding(10, 10, 6, 0); bottom_alignment.add(basic_properties); bottom_frame.add(bottom_alignment); - bottom_frame.set_shadow_type(Gtk.ShadowType.IN); + bottom_frame.get_style_context().remove_class("frame"); // "attach" the progress bar to the sidebar tree, so the movable ridge is to resize the // top two and the basic information pane - top_section.pack_start(top_frame, true, true, 0); + top_section.pack_start(scrolled_sidebar, true, true, 0); sidebar_paned.pack1(top_section, true, false); sidebar_paned.pack2(bottom_frame, false, false); sidebar_paned.set_position(1000); - - // layout the selection tree to the left of the collection/toolbar box with an adjustable - // gutter between them, framed for presentation - Gtk.Frame right_frame = new Gtk.Frame(null); - right_frame.set_shadow_type(Gtk.ShadowType.IN); right_vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); - right_frame.add(right_vbox); right_vbox.pack_start(search_toolbar, false, false, 0); right_vbox.pack_start(notebook, true, true, 0); client_paned = new Gtk.Paned(Gtk.Orientation.HORIZONTAL); client_paned.pack1(sidebar_paned, false, false); sidebar_tree.set_size_request(SIDEBAR_MIN_WIDTH, -1); - client_paned.pack2(right_frame, true, false); + client_paned.pack2(right_vbox, true, false); client_paned.set_position(Config.Facade.get_instance().get_sidebar_position()); // TODO: Calc according to layout's size, to give sidebar a maximum width notebook.set_size_request(PAGE_MIN_WIDTH, -1); @@ -1436,7 +1404,7 @@ public class LibraryWindow : AppWindow { // Turns the search bar on or off. Note that if show is true, page must not be null. private void toggle_search_bar(bool show, CheckerboardPage? page = null) { - search_toolbar.visible = show; + search_toolbar.set_reveal_child(show); if (show) { assert(null != page); search_toolbar.set_view_filter(page.get_search_view_filter()); @@ -1457,7 +1425,7 @@ public class LibraryWindow : AppWindow { private void on_destroying_page(Sidebar.PageRepresentative entry, Page page) { // if page is the current page, switch to fallback before destroying if (page == get_current_page()) - switch_to_page(library_branch.get_main_page()); + switch_to_page(library_branch.photos_entry.get_page()); remove_from_notebook(page); @@ -1475,9 +1443,11 @@ public class LibraryWindow : AppWindow { // if the currently selected item is removed, want to jump to fallback page (which // depends on the item that was selected) + Library.LastImportSidebarEntry last_import_entry = library_branch.last_imported_entry; + // Importing... -> Last Import (if available) - if (selectable is Library.ImportQueueSidebarEntry && last_import_branch.get_show_branch()) { - switch_to_page(last_import_branch.get_main_entry().get_page()); + if (selectable is Library.ImportQueueSidebarEntry && last_import_entry.visible) { + switch_to_page(last_import_entry.get_page()); return; } @@ -1497,7 +1467,7 @@ public class LibraryWindow : AppWindow { } // basic all-around default: jump to the Library page - switch_to_page(library_branch.get_main_page()); + switch_to_page(library_branch.photos_entry.get_page()); } private void subscribe_for_basic_information(Page page) { diff --git a/src/library/OfflinePage.vala b/src/library/OfflinePage.vala index cb6af2d..eecd71b 100644 --- a/src/library/OfflinePage.vala +++ b/src/library/OfflinePage.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -55,7 +55,7 @@ public class OfflinePage : CheckerboardPage { protected override Gtk.ActionEntry[] init_collect_action_entries() { Gtk.ActionEntry[] actions = base.init_collect_action_entries(); - Gtk.ActionEntry remove = { "RemoveFromLibrary", Gtk.Stock.REMOVE, TRANSLATABLE, "Delete", + Gtk.ActionEntry remove = { "RemoveFromLibrary", Resources.REMOVE_LABEL, TRANSLATABLE, "Delete", TRANSLATABLE, on_remove_from_library }; remove.label = Resources.REMOVE_FROM_LIBRARY_MENU; remove.tooltip = Resources.DELETE_FROM_LIBRARY_TOOLTIP; diff --git a/src/library/OfflineBranch.vala b/src/library/OfflineSidebarEntry.vala index 4ed2e49..34c09a0 100644 --- a/src/library/OfflineBranch.vala +++ b/src/library/OfflineSidebarEntry.vala @@ -1,26 +1,25 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ -public class Library.OfflineBranch : Sidebar.RootOnlyBranch { - public OfflineBranch() { - base (new Library.OfflineSidebarEntry()); +public class Library.OfflineSidebarEntry : Library.HideablePageEntry { + public OfflineSidebarEntry() { foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) media_sources.offline_contents_altered.connect(on_offline_contents_altered); - set_show_branch(get_total_offline() != 0); + visible = (get_total_offline() != 0); } - - ~OfflineBranch() { + + ~OfflineSidebarEntry() { foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) media_sources.trashcan_contents_altered.disconnect(on_offline_contents_altered); } private void on_offline_contents_altered() { - set_show_branch(get_total_offline() != 0); + visible = (get_total_offline() != 0); } private int get_total_offline() { @@ -30,18 +29,13 @@ public class Library.OfflineBranch : Sidebar.RootOnlyBranch { return total; } -} - -public class Library.OfflineSidebarEntry : Sidebar.SimplePageEntry { - public OfflineSidebarEntry() { - } public override string get_sidebar_name() { return OfflinePage.NAME; } - public override Icon? get_sidebar_icon() { - return new ThemedIcon(Resources.ICON_MISSING_FILES); + public override string? get_sidebar_icon() { + return Resources.ICON_MISSING_FILES; } protected override Page create_page() { diff --git a/src/library/TrashPage.vala b/src/library/TrashPage.vala index 2991727..ae80a7b 100644 --- a/src/library/TrashPage.vala +++ b/src/library/TrashPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -50,13 +50,13 @@ public class TrashPage : CheckerboardPage { protected override Gtk.ActionEntry[] init_collect_action_entries() { Gtk.ActionEntry[] actions = base.init_collect_action_entries(); - Gtk.ActionEntry delete_action = { "Delete", Gtk.Stock.DELETE, TRANSLATABLE, "Delete", + Gtk.ActionEntry delete_action = { "Delete", Resources.DELETE_LABEL, TRANSLATABLE, "Delete", TRANSLATABLE, on_delete }; delete_action.label = Resources.DELETE_PHOTOS_MENU; delete_action.tooltip = Resources.DELETE_FROM_TRASH_TOOLTIP; actions += delete_action; - Gtk.ActionEntry restore = { "Restore", Gtk.Stock.UNDELETE, TRANSLATABLE, null, TRANSLATABLE, + Gtk.ActionEntry restore = { "Restore", Resources.UNDELETE_LABEL, TRANSLATABLE, null, TRANSLATABLE, on_restore }; restore.label = Resources.RESTORE_PHOTOS_MENU; restore.tooltip = Resources.RESTORE_PHOTOS_TOOLTIP; diff --git a/src/library/TrashBranch.vala b/src/library/TrashSidebarEntry.vala index 5ef8b3c..69412b7 100644 --- a/src/library/TrashBranch.vala +++ b/src/library/TrashSidebarEntry.vala @@ -1,18 +1,10 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ -public class Library.TrashBranch : Sidebar.RootOnlyBranch { - public TrashBranch() { - base (new Library.TrashSidebarEntry()); - } -} - public class Library.TrashSidebarEntry : Sidebar.SimplePageEntry, Sidebar.InternalDropTargetEntry { - private static Icon? full_icon = null; - private static Icon? empty_icon = null; public TrashSidebarEntry() { foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) @@ -25,30 +17,26 @@ public class Library.TrashSidebarEntry : Sidebar.SimplePageEntry, Sidebar.Intern } internal static void init() { - full_icon = new ThemedIcon(Resources.ICON_TRASH_FULL); - empty_icon = new ThemedIcon(Resources.ICON_TRASH_EMPTY); } internal static void terminate() { - full_icon = null; - empty_icon = null; } public override string get_sidebar_name() { return TrashPage.NAME; } - public override Icon? get_sidebar_icon() { + public override string? get_sidebar_icon() { return get_current_icon(); } - private static Icon get_current_icon() { + private static string get_current_icon() { foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) { if (media_sources.get_trashcan_count() > 0) - return full_icon; + return Resources.ICON_TRASH_FULL; } - return empty_icon; + return Resources.ICON_TRASH_EMPTY; } public bool internal_drop_received(Gee.List<MediaSource> media) { diff --git a/src/library/mk/library.mk b/src/library/mk/library.mk index b4ab790..dc6201f 100644 --- a/src/library/mk/library.mk +++ b/src/library/mk/library.mk @@ -13,11 +13,11 @@ UNIT_DIR := library UNIT_FILES := \ LibraryWindow.vala \ Branch.vala \ - TrashBranch.vala \ - OfflineBranch.vala \ - FlaggedBranch.vala \ - LastImportBranch.vala \ - ImportQueueBranch.vala \ + TrashSidebarEntry.vala \ + OfflineSidebarEntry.vala \ + FlaggedSidebarEntry.vala \ + LastImportSidebarEntry.vala \ + ImportQueueSidebarEntry.vala \ FlaggedPage.vala \ ImportQueuePage.vala \ LastImportPage.vala \ diff --git a/src/main.vala b/src/main.vala index 8c045fd..6a705a7 100644 --- a/src/main.vala +++ b/src/main.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/photos/BmpSupport.vala b/src/photos/BmpSupport.vala index dbeb64c..677eac3 100644 --- a/src/photos/BmpSupport.vala +++ b/src/photos/BmpSupport.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/photos/GRaw.vala b/src/photos/GRaw.vala index 915a861..1aa7ca5 100644 --- a/src/photos/GRaw.vala +++ b/src/photos/GRaw.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/photos/GdkSupport.vala b/src/photos/GdkSupport.vala index ed2ff63..05e6854 100644 --- a/src/photos/GdkSupport.vala +++ b/src/photos/GdkSupport.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/photos/JfifSupport.vala b/src/photos/JfifSupport.vala index d721441..6ac5e4b 100644 --- a/src/photos/JfifSupport.vala +++ b/src/photos/JfifSupport.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/photos/PhotoFileAdapter.vala b/src/photos/PhotoFileAdapter.vala index 38b00ea..735e153 100644 --- a/src/photos/PhotoFileAdapter.vala +++ b/src/photos/PhotoFileAdapter.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/photos/PhotoFileFormat.vala b/src/photos/PhotoFileFormat.vala index 2ab2f00..b9d3f63 100644 --- a/src/photos/PhotoFileFormat.vala +++ b/src/photos/PhotoFileFormat.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/photos/PhotoFileSniffer.vala b/src/photos/PhotoFileSniffer.vala index 3f65ac2..cdbdad2 100644 --- a/src/photos/PhotoFileSniffer.vala +++ b/src/photos/PhotoFileSniffer.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/photos/PhotoMetadata.vala b/src/photos/PhotoMetadata.vala index 37804bf..be781b6 100644 --- a/src/photos/PhotoMetadata.vala +++ b/src/photos/PhotoMetadata.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/photos/Photos.vala b/src/photos/Photos.vala index 3033b92..c9eb357 100644 --- a/src/photos/Photos.vala +++ b/src/photos/Photos.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/photos/PngSupport.vala b/src/photos/PngSupport.vala index 2cde6a2..feb409d 100644 --- a/src/photos/PngSupport.vala +++ b/src/photos/PngSupport.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/photos/RawSupport.vala b/src/photos/RawSupport.vala index 98bc982..fb5f864 100644 --- a/src/photos/RawSupport.vala +++ b/src/photos/RawSupport.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/photos/TiffSupport.vala b/src/photos/TiffSupport.vala index ee8b087..ac1eb6d 100644 --- a/src/photos/TiffSupport.vala +++ b/src/photos/TiffSupport.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/plugins/DataImportsInterfaces.vala b/src/plugins/DataImportsInterfaces.vala index 154503b..2f519bd 100644 --- a/src/plugins/DataImportsInterfaces.vala +++ b/src/plugins/DataImportsInterfaces.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -119,6 +119,8 @@ public interface ImportableMediaItem : GLib.Object { public abstract string get_folder_path(); public abstract string get_filename(); + + public abstract time_t? get_exposure_time(); } /** diff --git a/src/plugins/ManifestWidget.vala b/src/plugins/ManifestWidget.vala index 54f2e56..fe32b91 100644 --- a/src/plugins/ManifestWidget.vala +++ b/src/plugins/ManifestWidget.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/plugins/Plugins.vala b/src/plugins/Plugins.vala index d0f9185..9a8860b 100644 --- a/src/plugins/Plugins.vala +++ b/src/plugins/Plugins.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/plugins/PublishingInterfaces.vala b/src/plugins/PublishingInterfaces.vala index ca74597..7c0a901 100644 --- a/src/plugins/PublishingInterfaces.vala +++ b/src/plugins/PublishingInterfaces.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/plugins/SpitInterfaces.vala b/src/plugins/SpitInterfaces.vala index f2fce6f..0a432c2 100644 --- a/src/plugins/SpitInterfaces.vala +++ b/src/plugins/SpitInterfaces.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/plugins/StandardHostInterface.vala b/src/plugins/StandardHostInterface.vala index 9bfc0aa..c14d688 100644 --- a/src/plugins/StandardHostInterface.vala +++ b/src/plugins/StandardHostInterface.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/plugins/TransitionsInterfaces.vala b/src/plugins/TransitionsInterfaces.vala index eae76cf..917f88d 100644 --- a/src/plugins/TransitionsInterfaces.vala +++ b/src/plugins/TransitionsInterfaces.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/publishing/APIGlue.vala b/src/publishing/APIGlue.vala index f282c1f..24e10cc 100644 --- a/src/publishing/APIGlue.vala +++ b/src/publishing/APIGlue.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/publishing/Publishing.vala b/src/publishing/Publishing.vala index fb04eab..c245385 100644 --- a/src/publishing/Publishing.vala +++ b/src/publishing/Publishing.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/publishing/PublishingPluginHost.vala b/src/publishing/PublishingPluginHost.vala index 1a5ed86..1a95ef3 100644 --- a/src/publishing/PublishingPluginHost.vala +++ b/src/publishing/PublishingPluginHost.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/publishing/PublishingUI.vala b/src/publishing/PublishingUI.vala index 4f63f55..a74bfaf 100644 --- a/src/publishing/PublishingUI.vala +++ b/src/publishing/PublishingUI.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -146,7 +146,6 @@ public class PublishingDialog : Gtk.Dialog { private Gtk.ListStore service_selector_box_model; private Gtk.ComboBox service_selector_box; - private Gtk.Label service_selector_box_label; private Gtk.Box central_area_layouter; private Gtk.Button close_cancel_button; private Spit.Publishing.DialogPane active_pane; @@ -157,6 +156,9 @@ public class PublishingDialog : Gtk.Dialog { protected PublishingDialog(Gee.Collection<MediaSource> to_publish) { assert(to_publish.size > 0); + Object(use_header_bar: 1); + ((Gtk.HeaderBar) get_header_bar()).set_show_close_button(false); + resizable = false; delete_event.connect(on_window_close); @@ -180,7 +182,7 @@ public class PublishingDialog : Gtk.Dialog { string label = null; if (has_photos && !has_videos) { - title = null;_("Publish Photos"); + title = _("Publish Photos"); label = _("Publish photos _to:"); } else if (!has_photos && has_videos) { title = _("Publish Videos"); @@ -203,10 +205,6 @@ public class PublishingDialog : Gtk.Dialog { service_selector_box.add_attribute(renderer_text, "text", 1); service_selector_box.set_active(0); - - service_selector_box_label = new Gtk.Label.with_mnemonic(label); - service_selector_box_label.set_mnemonic_widget(service_selector_box); - service_selector_box_label.set_alignment(0.0f, 0.5f); // get the name of the service the user last used string? last_used_service = Config.Facade.get_instance().get_last_used_service(); @@ -244,37 +242,16 @@ public class PublishingDialog : Gtk.Dialog { } service_selector_box.changed.connect(on_service_changed); - - /* the wrapper is not an extraneous widget -- it's necessary to prevent the service - selection box from growing and shrinking whenever its parent's size changes. - When wrapped inside a Gtk.Alignment, the Alignment grows and shrinks instead of - the service selection box. */ - Gtk.Alignment service_selector_box_wrapper = new Gtk.Alignment(1.0f, 0.5f, 0.0f, 0.0f); - service_selector_box_wrapper.add(service_selector_box); - - Gtk.Box service_selector_layouter = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); - service_selector_layouter.set_border_width(12); - service_selector_layouter.add(service_selector_box_label); - service_selector_layouter.pack_start(service_selector_box_wrapper, true, true, 0); - - /* 'service area' is the selector assembly plus the horizontal rule dividing it from the - rest of the dialog */ - Gtk.Box service_area_layouter = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); - service_area_layouter.add(service_selector_layouter); - service_area_layouter.add(new Gtk.Separator(Gtk.Orientation.HORIZONTAL)); - - Gtk.Alignment service_area_wrapper = new Gtk.Alignment(0.0f, 0.0f, 1.0f, 0.0f); - service_area_wrapper.add(service_area_layouter); central_area_layouter = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); - get_content_area().pack_start(service_area_wrapper, false, false, 0); get_content_area().pack_start(central_area_layouter, true, true, 0); close_cancel_button = new Gtk.Button.with_mnemonic("_Cancel"); close_cancel_button.set_can_default(true); close_cancel_button.clicked.connect(on_close_cancel_clicked); - ((Gtk.Container) get_action_area()).add(close_cancel_button); + ((Gtk.HeaderBar) get_header_bar()).pack_start(close_cancel_button); + ((Gtk.HeaderBar) get_header_bar()).pack_end(service_selector_box); set_standard_window_mode(); diff --git a/src/searches/Branch.vala b/src/searches/Branch.vala index 229c710..00a9ea7 100644 --- a/src/searches/Branch.vala +++ b/src/searches/Branch.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -9,7 +9,7 @@ public class Searches.Branch : Sidebar.Branch { new Gee.HashMap<SavedSearch, Searches.SidebarEntry>(); public Branch() { - base (new Searches.Grouping(), + base (new Searches.Header(), Sidebar.Branch.Options.HIDE_IF_EMPTY | Sidebar.Branch.Options.AUTO_OPEN_ON_NEW_CHILD | Sidebar.Branch.Options.STARTUP_EXPAND_TO_FIRST_CHILD, @@ -60,12 +60,12 @@ public class Searches.Branch : Sidebar.Branch { } } -public class Searches.Grouping : Sidebar.Grouping, Sidebar.Contextable { +public class Searches.Header : Sidebar.Header, Sidebar.Contextable { private Gtk.UIManager ui = new Gtk.UIManager(); private Gtk.Menu? context_menu = null; - public Grouping() { - base (_("Saved Searches"), new ThemedIcon(Gtk.Stock.FIND)); + public Header() { + base (_("Saved Searches")); setup_context_menu(); } @@ -104,7 +104,7 @@ public class Searches.Grouping : Sidebar.Grouping, Sidebar.Contextable { public class Searches.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntry, Sidebar.DestroyableEntry { - private static Icon single_search_icon; + private static string single_search_icon = "find"; private SavedSearch search; @@ -113,11 +113,9 @@ public class Searches.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.Renameable } internal static void init() { - single_search_icon = new ThemedIcon(Gtk.Stock.FIND); } internal static void terminate() { - single_search_icon = null; } public SavedSearch for_saved_search() { @@ -128,7 +126,7 @@ public class Searches.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.Renameable return search.get_name(); } - public override Icon? get_sidebar_icon() { + public override string? get_sidebar_icon() { return single_search_icon; } @@ -136,6 +134,10 @@ public class Searches.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.Renameable return new SavedSearchPage(search); } + public bool is_user_renameable() { + return true; + } + public void rename(string new_name) { if (!SavedSearchTable.get_instance().exists(new_name)) AppWindow.get_command_manager().execute(new RenameSavedSearchCommand(search, new_name)); diff --git a/src/searches/SavedSearchDialog.vala b/src/searches/SavedSearchDialog.vala index da7f7db..eb016d3 100644 --- a/src/searches/SavedSearchDialog.vala +++ b/src/searches/SavedSearchDialog.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -48,13 +48,12 @@ public class SavedSearchDialog { set_type_combo_box(SearchCondition.SearchType.ANY_TEXT); // Sets default. type_combo.changed.connect(on_type_changed); - remove_button = new Gtk.Button(); - remove_button.set_label(" – "); + remove_button = new Gtk.Button.from_icon_name("list-remove-symbolic", Gtk.IconSize.BUTTON); remove_button.button_press_event.connect(on_removed); align = new Gtk.Alignment(0,0,0,0); - box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); + box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 3); box.pack_start(type_combo, false, false, 0); box.pack_start(align, false, false, 0); box.pack_start(new Gtk.Alignment(0,0,0,0), true, true, 0); // Fill space. @@ -172,6 +171,7 @@ public class SavedSearchDialog { text_context.append_text(_("ends with")); text_context.append_text(_("does not contain")); text_context.append_text(_("is not set")); + text_context.append_text(_("is set")); text_context.set_active(0); text_context.changed.connect(on_changed); @@ -180,7 +180,7 @@ public class SavedSearchDialog { entry.set_activates_default(true); entry.changed.connect(on_changed); - box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); + box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 3); box.pack_start(text_context, false, false, 0); box.pack_start(entry, false, false, 0); box.show_all(); @@ -212,7 +212,9 @@ public class SavedSearchDialog { } public override bool is_complete() { - return entry.text.chomp() != "" || get_text_context() == SearchConditionText.Context.IS_NOT_SET; + return entry.text.chomp() != "" || + get_text_context() == SearchConditionText.Context.IS_NOT_SET || + get_text_context() == SearchConditionText.Context.IS_SET; } private SearchConditionText.Context get_text_context() { @@ -220,7 +222,8 @@ public class SavedSearchDialog { } private void on_changed() { - if (get_text_context() == SearchConditionText.Context.IS_NOT_SET) { + if (get_text_context() == SearchConditionText.Context.IS_NOT_SET + || get_text_context() == SearchConditionText.Context.IS_SET) { entry.hide(); } else { entry.show(); @@ -255,7 +258,7 @@ public class SavedSearchDialog { media_type.set_active(0); media_type.changed.connect(on_changed); - box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); + box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 3); box.pack_start(media_context, false, false, 0); box.pack_start(media_type, false, false, 0); box.show_all(); @@ -317,7 +320,7 @@ public class SavedSearchDialog { modified_state.set_active(0); modified_state.changed.connect(on_changed); - box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); + box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 3); box.pack_start(modified_context, false, false, 0); box.pack_start(modified_state, false, false, 0); box.show_all(); @@ -372,7 +375,7 @@ public class SavedSearchDialog { flagged_state.set_active(0); flagged_state.changed.connect(on_changed); - box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); + box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 3); box.pack_start(new Gtk.Label(_("is")), false, false, 0); box.pack_start(flagged_state, false, false, 0); box.show_all(); @@ -437,7 +440,7 @@ public class SavedSearchDialog { context.set_active(0); context.changed.connect(on_changed); - box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); + box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 3); box.pack_start(new Gtk.Label(_("is")), false, false, 0); box.pack_start(rating, false, false, 0); box.pack_start(context, false, false, 0); @@ -512,7 +515,7 @@ public class SavedSearchDialog { and = new Gtk.Label(_("and")); - box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 8); + box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 3); box.pack_start(context, false, false, 0); box.pack_start(label_one, false, false, 0); box.pack_start(and, false, false, 0); @@ -604,14 +607,16 @@ public class SavedSearchDialog { int orig_month = cal.month; int orig_year = cal.year; Gtk.Dialog d = new Gtk.Dialog.with_buttons(null, null, - Gtk.DialogFlags.MODAL, Gtk.Stock.CANCEL, Gtk.ResponseType.REJECT, - Gtk.Stock.OK, Gtk.ResponseType.ACCEPT); + Gtk.DialogFlags.MODAL, Resources.CANCEL_LABEL, Gtk.ResponseType.REJECT, + Resources.OK_LABEL, Gtk.ResponseType.ACCEPT); d.set_modal(true); d.set_resizable(false); d.set_decorated(false); ((Gtk.Box) d.get_content_area()).add(cal); ulong id_1 = cal.day_selected.connect(()=>{update_date_labels();}); - ulong id_2 = cal.day_selected_double_click.connect(()=>{d.close();}); + ulong id_2 = cal.day_selected_double_click.connect(()=> { + d.response(Gtk.ResponseType.ACCEPT); + }); d.show_all(); int res = d.run(); if (res != Gtk.ResponseType.ACCEPT) { @@ -656,14 +661,7 @@ public class SavedSearchDialog { // Default is text search. add_text_search(); row_list.get(0).allow_removal(false); - - // Add buttons for new search. - dialog.add_action_widget(new Gtk.Button.from_stock(Gtk.Stock.CANCEL), Gtk.ResponseType.CANCEL); - Gtk.Button ok_button = new Gtk.Button.from_stock(Gtk.Stock.OK); - ok_button.can_default = true; - dialog.add_action_widget(ok_button, Gtk.ResponseType.OK); - dialog.set_default_response(Gtk.ResponseType.OK); - + dialog.show_all(); set_valid(false); } @@ -673,12 +671,6 @@ public class SavedSearchDialog { edit_mode = true; setup_dialog(); - // Add close button. - Gtk.Button close_button = new Gtk.Button.from_stock(Gtk.Stock.CLOSE); - close_button.can_default = true; - dialog.add_action_widget(close_button, Gtk.ResponseType.OK); - dialog.set_default_response(Gtk.ResponseType.OK); - dialog.show_all(); // Load existing search into dialog. @@ -701,12 +693,21 @@ public class SavedSearchDialog { // Builds the dialog UI. Doesn't add buttons to the dialog or call dialog.show(). private void setup_dialog() { builder = AppWindow.create_builder(); - - dialog = builder.get_object("Search criteria") as Gtk.Dialog; - dialog.set_parent_window(AppWindow.get_instance().get_parent_window()); + + dialog = new Gtk.Dialog.with_buttons(_("Search"), + (Gtk.Window) AppWindow.get_instance().get_parent_window(), + Gtk.DialogFlags.MODAL | + Gtk.DialogFlags.DESTROY_WITH_PARENT | + Gtk.DialogFlags.USE_HEADER_BAR, + _("Cancel"), Gtk.ResponseType.CANCEL, + _("OK"), Gtk.ResponseType.OK, + null); + dialog.set_resizable(false); dialog.set_transient_for(AppWindow.get_instance()); + dialog.set_default_response(Gtk.ResponseType.OK); dialog.response.connect(on_response); - + dialog.get_content_area().add(builder.get_object("criteria") as Gtk.Widget); + add_criteria = builder.get_object("Add search button") as Gtk.Button; add_criteria.button_press_event.connect(on_add_criteria); diff --git a/src/searches/SavedSearchPage.vala b/src/searches/SavedSearchPage.vala index 8e6672e..99473fb 100644 --- a/src/searches/SavedSearchPage.vala +++ b/src/searches/SavedSearchPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/searches/SearchBoolean.vala b/src/searches/SearchBoolean.vala index 431e398..8031814 100644 --- a/src/searches/SearchBoolean.vala +++ b/src/searches/SearchBoolean.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. @@ -206,7 +206,8 @@ public class SearchConditionText : SearchCondition { STARTS_WITH, ENDS_WITH, DOES_NOT_CONTAIN, - IS_NOT_SET; + IS_NOT_SET, + IS_SET; public string to_string() { switch (this) { @@ -228,6 +229,9 @@ public class SearchConditionText : SearchCondition { case Context.IS_NOT_SET: return "IS_NOT_SET"; + case Context.IS_SET: + return "IS_SET"; + default: error("unrecognized text search context enumeration value"); } @@ -252,6 +256,9 @@ public class SearchConditionText : SearchCondition { else if (str == "IS_NOT_SET") return Context.IS_NOT_SET; + else if (str == "IS_SET") + return Context.IS_SET; + else error("unrecognized text search context name: %s", str); } @@ -287,6 +294,9 @@ public class SearchConditionText : SearchCondition { case Context.IS_NOT_SET: return (is_string_empty(haystack)); + + case Context.IS_SET: + return (!is_string_empty(haystack)); } return false; @@ -298,10 +308,9 @@ public class SearchConditionText : SearchCondition { // title if (SearchType.ANY_TEXT == search_type || SearchType.TITLE == search_type) { - string title = source.get_title(); - if(title != null){ - ret |= string_match(text, String.remove_diacritics(title.down())); - } + string? title = (null != source.get_title()) ? + String.remove_diacritics(source.get_title().down()) : null; + ret |= string_match(text, title); } // tags diff --git a/src/searches/Searches.vala b/src/searches/Searches.vala index 478de86..691bcf0 100644 --- a/src/searches/Searches.vala +++ b/src/searches/Searches.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/sidebar/Branch.vala b/src/sidebar/Branch.vala index 23badda..a6c3ee8 100644 --- a/src/sidebar/Branch.vala +++ b/src/sidebar/Branch.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -39,23 +39,22 @@ public class Sidebar.Branch : Object { public Sidebar.Entry entry; public weak Node? parent; - public CompareDataFunc<Sidebar.Entry> comparator; + public CompareFunc<Sidebar.Entry> comparator; public Gee.SortedSet<Node>? children = null; - public Node(Sidebar.Entry entry, Node? parent, - owned CompareDataFunc<Sidebar.Entry> comparator) { + public Node(Sidebar.Entry entry, Node? parent, CompareFunc<Sidebar.Entry> comparator) { this.entry = entry; this.parent = parent; - this.comparator = (owned) comparator; + this.comparator = comparator; } - private static int comparator_wrapper(Node? a, Node? b) { - if (a == b) + private static int comparator_wrapper(Node anode, Node bnode) { + if (anode == bnode) return 0; - assert(a.parent == b.parent); + assert(anode.parent == bnode.parent); - return a.parent.comparator(a.entry, b.entry); + return anode.parent.comparator(anode.entry, bnode.entry); } public bool has_children() { @@ -172,16 +171,16 @@ public class Sidebar.Branch : Object { cb(this); } - public void change_comparator(owned CompareDataFunc<Sidebar.Entry> comparator, bool recursive, + public void change_comparator(CompareFunc<Sidebar.Entry> comparator, bool recursive, ChildrenReorderedCallback cb) { - this.comparator = (owned) comparator; + this.comparator = comparator; // reorder children, but need to do manual recursion to set comparator reorder_children(false, cb); if (recursive) { foreach (Node child in children) - child.change_comparator((owned) comparator, true, cb); + child.change_comparator(comparator, true, cb); } } } @@ -189,7 +188,7 @@ public class Sidebar.Branch : Object { private Node root; private Options options; private bool shown = true; - private CompareDataFunc<Sidebar.Entry> default_comparator; + private CompareFunc<Sidebar.Entry> default_comparator; private Gee.HashMap<Sidebar.Entry, Node> map = new Gee.HashMap<Sidebar.Entry, Node>(); public signal void entry_added(Sidebar.Entry entry); @@ -204,19 +203,11 @@ public class Sidebar.Branch : Object { public signal void show_branch(bool show); - public Branch(Sidebar.Entry root, Options options, - owned CompareDataFunc<Sidebar.Entry> default_comparator, - owned CompareDataFunc<Sidebar.Entry>? root_comparator = null) { - this.default_comparator = (owned) default_comparator; - - CompareDataFunc<Sidebar.Entry>? broken_ternary_workaround; - - if (root_comparator != null) - broken_ternary_workaround = (owned) root_comparator; - else - broken_ternary_workaround = (owned) default_comparator; - - this.root = new Node(root, null, (owned) broken_ternary_workaround); + public Branch(Sidebar.Entry root, Options options, CompareFunc<Sidebar.Entry> default_comparator, + CompareFunc<Sidebar.Entry>? root_comparator = null) { + this.default_comparator = default_comparator; + this.root = new Node(root, null, + (root_comparator != null) ? root_comparator : default_comparator); this.options = options; map.set(root, this.root); @@ -254,7 +245,7 @@ public class Sidebar.Branch : Object { } public void graft(Sidebar.Entry parent, Sidebar.Entry entry, - owned CompareDataFunc<Sidebar.Entry>? comparator = null) { + CompareFunc<Sidebar.Entry>? comparator = null) { assert(map.has_key(parent)); assert(!map.has_key(entry)); @@ -262,15 +253,8 @@ public class Sidebar.Branch : Object { set_show_branch(true); Node parent_node = map.get(parent); - - CompareDataFunc<Sidebar.Entry>? broken_ternary_workaround; - - if (comparator != null) - broken_ternary_workaround = (owned) comparator; - else - broken_ternary_workaround = (owned) default_comparator; - - Node entry_node = new Node(entry, parent_node, (owned) broken_ternary_workaround); + Node entry_node = new Node(entry, parent_node, + (comparator != null) ? comparator : default_comparator); parent_node.add_child(entry_node); map.set(entry, entry_node); @@ -347,16 +331,16 @@ public class Sidebar.Branch : Object { entry_node.reorder_children(recursive, children_reordered_callback); } - public void change_all_comparators(owned CompareDataFunc<Sidebar.Entry>? comparator) { - root.change_comparator((owned) comparator, true, children_reordered_callback); + public void change_all_comparators(CompareFunc<Sidebar.Entry>? comparator) { + root.change_comparator(comparator, true, children_reordered_callback); } public void change_comparator(Sidebar.Entry entry, bool recursive, - owned CompareDataFunc<Sidebar.Entry>? comparator) { + CompareFunc<Sidebar.Entry>? comparator) { Node? entry_node = map.get(entry); assert(entry_node != null); - entry_node.change_comparator((owned) comparator, recursive, children_reordered_callback); + entry_node.change_comparator(comparator, recursive, children_reordered_callback); } public int get_child_count(Sidebar.Entry parent) { diff --git a/src/sidebar/Entry.vala b/src/sidebar/Entry.vala index 4162f21..5a84f74 100644 --- a/src/sidebar/Entry.vala +++ b/src/sidebar/Entry.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -7,13 +7,13 @@ public interface Sidebar.Entry : Object { public signal void sidebar_tooltip_changed(string? tooltip); - public signal void sidebar_icon_changed(Icon? icon); + public signal void sidebar_icon_changed(string? icon); public abstract string get_sidebar_name(); public abstract string? get_sidebar_tooltip(); - public abstract Icon? get_sidebar_icon(); + public abstract string? get_sidebar_icon(); public abstract string to_string(); @@ -25,12 +25,6 @@ public interface Sidebar.Entry : Object { } public interface Sidebar.ExpandableEntry : Sidebar.Entry { - public signal void sidebar_open_closed_icons_changed(Icon? open, Icon? closed); - - public abstract Icon? get_sidebar_open_icon(); - - public abstract Icon? get_sidebar_closed_icon(); - public abstract bool expand_on_select(); } @@ -53,6 +47,15 @@ public interface Sidebar.RenameableEntry : Sidebar.Entry { public signal void sidebar_name_changed(string name); public abstract void rename(string new_name); + + // Return true to allow the user to rename the sidebar entry in the UI. + public abstract bool is_user_renameable(); +} + +public interface Sidebar.EmphasizableEntry : Sidebar.Entry { + public signal void is_emphasized_changed(bool emphasized); + + public abstract bool is_emphasized(); } public interface Sidebar.DestroyableEntry : Sidebar.Entry { diff --git a/src/sidebar/Sidebar.vala b/src/sidebar/Sidebar.vala index 8f6904b..0b4c0da 100644 --- a/src/sidebar/Sidebar.vala +++ b/src/sidebar/Sidebar.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/sidebar/Tree.vala b/src/sidebar/Tree.vala index 37da7e0..a020b18 100644 --- a/src/sidebar/Tree.vala +++ b/src/sidebar/Tree.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -37,8 +37,7 @@ public class Sidebar.Tree : Gtk.TreeView { private class RootWrapper : EntryWrapper { public int root_position; - public RootWrapper(Gtk.TreeModel model, Sidebar.Entry entry, Gtk.TreePath path, int root_position) - requires (root_position >= 0) { + public RootWrapper(Gtk.TreeModel model, Sidebar.Entry entry, Gtk.TreePath path, int root_position) { base (model, entry, path); this.root_position = root_position; @@ -49,9 +48,7 @@ public class Sidebar.Tree : Gtk.TreeView { NAME, TOOLTIP, WRAPPER, - PIXBUF, - CLOSED_PIXBUF, - OPEN_PIXBUF, + ICON, N_COLUMNS } @@ -59,17 +56,13 @@ public class Sidebar.Tree : Gtk.TreeView { typeof (string), // NAME typeof (string?), // TOOLTIP typeof (EntryWrapper), // WRAPPER - typeof (Gdk.Pixbuf?), // PIXBUF - typeof (Gdk.Pixbuf?), // CLOSED_PIXBUF - typeof (Gdk.Pixbuf?) // OPEN_PIXBUF + typeof (string?) // ICON ); private Gtk.UIManager ui = new Gtk.UIManager(); - private Gtk.IconTheme icon_theme; private Gtk.CellRendererText text_renderer; private unowned ExternalDropHandler drop_handler; private Gtk.Entry? text_entry = null; - private Gee.HashMap<string, Gdk.Pixbuf> icon_cache = new Gee.HashMap<string, Gdk.Pixbuf>(); private Gee.HashMap<Sidebar.Entry, EntryWrapper> entry_map = new Gee.HashMap<Sidebar.Entry, EntryWrapper>(); private Gee.HashMap<Sidebar.Branch, int> branches = new Gee.HashMap<Sidebar.Branch, int>(); @@ -77,8 +70,11 @@ public class Sidebar.Tree : Gtk.TreeView { private bool mask_entry_selected_signal = false; private weak EntryWrapper? selected_wrapper = null; private Gtk.Menu? default_context_menu = null; + private bool expander_called_manually = false; + private int expander_special_count = 0; private bool is_internal_drag_in_progress = false; private Sidebar.Entry? internal_drag_source_entry = null; + private Gtk.TreeRowReference? old_path_ref = null; public signal void entry_selected(Sidebar.SelectableEntry selectable); @@ -97,15 +93,17 @@ public class Sidebar.Tree : Gtk.TreeView { public Tree(Gtk.TargetEntry[] target_entries, Gdk.DragAction actions, ExternalDropHandler drop_handler) { set_model(store); + get_style_context().add_class("sidebar"); Gtk.TreeViewColumn text_column = new Gtk.TreeViewColumn(); - text_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED); + text_column.set_expand(true); Gtk.CellRendererPixbuf icon_renderer = new Gtk.CellRendererPixbuf(); + icon_renderer.follow_state = true; text_column.pack_start(icon_renderer, false); - text_column.add_attribute(icon_renderer, "pixbuf", Columns.PIXBUF); - text_column.add_attribute(icon_renderer, "pixbuf_expander_closed", Columns.CLOSED_PIXBUF); - text_column.add_attribute(icon_renderer, "pixbuf_expander_open", Columns.OPEN_PIXBUF); + text_column.add_attribute(icon_renderer, "icon_name", Columns.ICON); + text_column.set_cell_data_func(icon_renderer, icon_renderer_function); text_renderer = new Gtk.CellRendererText(); + text_renderer.ellipsize = Pango.EllipsizeMode.END; text_renderer.editing_canceled.connect(on_editing_canceled); text_renderer.editing_started.connect(on_editing_started); text_column.pack_start(text_renderer, true); @@ -131,6 +129,9 @@ public class Sidebar.Tree : Gtk.TreeView { selection.set_mode(Gtk.SelectionMode.BROWSE); selection.set_select_function(on_selection); + test_expand_row.connect(on_toggle_row); + test_collapse_row.connect(on_toggle_row); + // It Would Be Nice if the target entries and actions were gleaned by querying each // Sidebar.Entry as it was added, but that's a tad too complicated for our needs // currently @@ -145,9 +146,6 @@ public class Sidebar.Tree : Gtk.TreeView { popup_menu.connect(on_context_menu_keypress); - icon_theme = Resources.get_icon_theme_engine(); - icon_theme.changed.connect(on_theme_change); - setup_default_context_menu(); drag_begin.connect(on_drag_begin); @@ -158,7 +156,14 @@ public class Sidebar.Tree : Gtk.TreeView { ~Tree() { text_renderer.editing_canceled.disconnect(on_editing_canceled); text_renderer.editing_started.disconnect(on_editing_started); - icon_theme.changed.disconnect(on_theme_change); + } + + public void icon_renderer_function(Gtk.CellLayout layout, Gtk.CellRenderer renderer, Gtk.TreeModel model, Gtk.TreeIter iter) { + EntryWrapper? wrapper = get_wrapper_at_iter(iter); + if (wrapper == null) { + return; + } + renderer.visible = !(wrapper.entry is Sidebar.Header); } private void on_drag_begin(Gdk.DragContext ctx) { @@ -270,41 +275,72 @@ public class Sidebar.Tree : Gtk.TreeView { public bool is_selected(Sidebar.Entry entry) { EntryWrapper? wrapper = get_wrapper(entry); - return (wrapper != null) ? get_selection().path_is_selected(wrapper.get_path()) : false; + // Even though get_selection() does not report its return type as nullable, it can be null + // if the window has been destroyed. + Gtk.TreeSelection selection = get_selection(); + if (selection == null) + return false; + + return (wrapper != null) ? selection.path_is_selected(wrapper.get_path()) : false; } public bool is_any_selected() { return get_selection().count_selected_rows() != 0; } - + private Gtk.TreePath? get_selected_path() { Gtk.TreeModel model; - GLib.List<Gtk.TreePath> rows = get_selection().get_selected_rows(out model); + Gtk.TreeSelection? selection = get_selection(); + if (selection == null){ + return null; + } + GLib.List<Gtk.TreePath> rows = selection.get_selected_rows(out model); assert(rows.length() == 0 || rows.length() == 1); - + return rows.length() != 0 ? rows.nth_data(0) : null; } + + private string get_name_for_entry(Sidebar.Entry entry) { + string name = guarded_markup_escape_text(entry.get_sidebar_name()); + + Sidebar.EmphasizableEntry? emphasizable_entry = entry as Sidebar.EmphasizableEntry; + if (emphasizable_entry != null && emphasizable_entry.is_emphasized()) + name = "<b>%s</b>".printf(name); + + return name; + } + + public virtual bool accept_cursor_changed() { + return true; + } public override void cursor_changed() { Gtk.TreePath? path = get_selected_path(); if (path == null) { if (base.cursor_changed != null) base.cursor_changed(); - return; } EntryWrapper? wrapper = get_wrapper_at_path(path); - - selected_wrapper = wrapper; - - if (editing_disabled == 0 && wrapper != null) - text_renderer.editable = wrapper.entry is Sidebar.RenameableEntry; - if (wrapper != null && !mask_entry_selected_signal) { - Sidebar.SelectableEntry? selectable = wrapper.entry as Sidebar.SelectableEntry; - if (selectable != null) - entry_selected(selectable); + if (selected_wrapper != wrapper) { + EntryWrapper old_wrapper = selected_wrapper; + selected_wrapper = wrapper; + + if (editing_disabled == 0 && wrapper != null && wrapper.entry is Sidebar.RenameableEntry) + text_renderer.editable = ((Sidebar.RenameableEntry) wrapper.entry).is_user_renameable(); + + if (wrapper != null && !mask_entry_selected_signal) { + Sidebar.SelectableEntry? selectable = wrapper.entry as Sidebar.SelectableEntry; + if (selectable != null) { + if (accept_cursor_changed()) { + entry_selected(selectable); + } else { + place_cursor(old_wrapper.entry, true); + } + } + } } if (base.cursor_changed != null) @@ -320,11 +356,14 @@ public class Sidebar.Tree : Gtk.TreeView { Gtk.TreePath? path = get_selected_path(); if (path != null && editing_disabled > 0 && --editing_disabled == 0) { EntryWrapper? wrapper = get_wrapper_at_path(path); - text_renderer.editable = (wrapper != null && (wrapper.entry is Sidebar.RenameableEntry)); + if (wrapper != null && (wrapper.entry is Sidebar.RenameableEntry)) + text_renderer.editable = ((Sidebar.RenameableEntry) wrapper.entry). + is_user_renameable(); } } public void toggle_branch_expansion(Gtk.TreePath path, bool expand_all) { + expander_called_manually = true; if (is_row_expanded(path)) collapse_row(path); else @@ -332,6 +371,7 @@ public class Sidebar.Tree : Gtk.TreeView { } public bool expand_to_entry(Sidebar.Entry entry) { + expander_called_manually = true; EntryWrapper? wrapper = get_wrapper(entry); if (wrapper == null) return false; @@ -342,6 +382,7 @@ public class Sidebar.Tree : Gtk.TreeView { } public void expand_to_first_child(Sidebar.Entry entry) { + expander_called_manually = true; EntryWrapper? wrapper = get_wrapper(entry); if (wrapper == null) return; @@ -445,7 +486,7 @@ public class Sidebar.Tree : Gtk.TreeView { assert(!entry_map.has_key(entry)); entry_map.set(entry, wrapper); - store.set(assoc_iter, Columns.NAME, guarded_markup_escape_text(entry.get_sidebar_name())); + store.set(assoc_iter, Columns.NAME, get_name_for_entry(entry)); store.set(assoc_iter, Columns.TOOLTIP, guarded_markup_escape_text(entry.get_sidebar_tooltip())); store.set(assoc_iter, Columns.WRAPPER, wrapper); load_entry_icons(assoc_iter); @@ -458,15 +499,15 @@ public class Sidebar.Tree : Gtk.TreeView { pageable.page_created.connect(on_sidebar_page_created); pageable.destroying_page.connect(on_sidebar_destroying_page); } + + Sidebar.EmphasizableEntry? emphasizable = entry as Sidebar.EmphasizableEntry; + if (emphasizable != null) + emphasizable.is_emphasized_changed.connect(on_is_emphasized_changed); Sidebar.RenameableEntry? renameable = entry as Sidebar.RenameableEntry; if (renameable != null) renameable.sidebar_name_changed.connect(on_sidebar_name_changed); - - Sidebar.ExpandableEntry? expandable = entry as Sidebar.ExpandableEntry; - if (expandable != null) - expandable.sidebar_open_closed_icons_changed.connect(on_sidebar_open_closed_icons_changed); - + entry.grafted(this); } @@ -479,7 +520,7 @@ public class Sidebar.Tree : Gtk.TreeView { EntryWrapper new_wrapper = new EntryWrapper(store, entry, store.get_path(new_iter)); entry_map.set(entry, new_wrapper); - store.set(new_iter, Columns.NAME, guarded_markup_escape_text(entry.get_sidebar_name())); + store.set(new_iter, Columns.NAME, get_name_for_entry(entry)); store.set(new_iter, Columns.TOOLTIP, guarded_markup_escape_text(entry.get_sidebar_tooltip())); store.set(new_iter, Columns.WRAPPER, new_wrapper); load_entry_icons(new_iter); @@ -571,9 +612,9 @@ public class Sidebar.Tree : Gtk.TreeView { if (renameable != null) renameable.sidebar_name_changed.disconnect(on_sidebar_name_changed); - Sidebar.ExpandableEntry? expandable = entry as Sidebar.ExpandableEntry; - if (expandable != null) - expandable.sidebar_open_closed_icons_changed.disconnect(on_sidebar_open_closed_icons_changed); + Sidebar.EmphasizableEntry? emphasizable = entry as Sidebar.EmphasizableEntry; + if (emphasizable != null) + emphasizable.is_emphasized_changed.disconnect(on_is_emphasized_changed); bool removed = entry_map.unset(entry); assert(removed); @@ -703,88 +744,42 @@ public class Sidebar.Tree : Gtk.TreeView { store.set(wrapper.get_iter(), Columns.TOOLTIP, guarded_markup_escape_text(tooltip)); } - private void on_sidebar_icon_changed(Sidebar.Entry entry, Icon? icon) { + private void on_sidebar_icon_changed(Sidebar.Entry entry, string? icon) { EntryWrapper? wrapper = get_wrapper(entry); assert(wrapper != null); - store.set(wrapper.get_iter(), Columns.PIXBUF, fetch_icon_pixbuf(icon)); + store.set(wrapper.get_iter(), Columns.ICON, icon); } - - private void on_sidebar_page_created(Sidebar.PageRepresentative entry, Page page) { - page_created(entry, page); + + private void rename_entry(Sidebar.Entry entry) { + EntryWrapper? wrapper = get_wrapper(entry); + assert(wrapper != null); + + store.set(wrapper.get_iter(), Columns.NAME, get_name_for_entry(entry)); } - private void on_sidebar_destroying_page(Sidebar.PageRepresentative entry, Page page) { - destroying_page(entry, page); + private void on_sidebar_name_changed(Sidebar.Entry entry, string name) { + rename_entry(entry); } - private void on_sidebar_open_closed_icons_changed(Sidebar.ExpandableEntry entry, Icon? open, - Icon? closed) { - EntryWrapper? wrapper = get_wrapper(entry); - assert(wrapper != null); - - store.set(wrapper.get_iter(), Columns.OPEN_PIXBUF, fetch_icon_pixbuf(open)); - store.set(wrapper.get_iter(), Columns.CLOSED_PIXBUF, fetch_icon_pixbuf(closed)); + private void on_sidebar_page_created(Sidebar.PageRepresentative entry, Page page) { + page_created(entry, page); } - private void on_sidebar_name_changed(Sidebar.RenameableEntry entry, string name) { - EntryWrapper? wrapper = get_wrapper(entry); - assert(wrapper != null); - - store.set(wrapper.get_iter(), Columns.NAME, guarded_markup_escape_text(name)); + private void on_is_emphasized_changed(Sidebar.EmphasizableEntry entry, bool is_emphasized) { + rename_entry(entry); } - private Gdk.Pixbuf? fetch_icon_pixbuf(GLib.Icon? gicon) { - if (gicon == null) - return null; - - try { - Gdk.Pixbuf? icon = icon_cache.get(gicon.to_string()); - if (icon != null) - return icon; - - Gtk.IconInfo? info = icon_theme.lookup_by_gicon(gicon, ICON_SIZE, 0); - if (info == null) - return null; - - icon = info.load_icon(); - if (icon == null) - return null; - - icon_cache.set(gicon.to_string(), icon); - - return icon; - } catch (Error err) { - warning("Unable to load icon %s: %s", gicon.to_string(), err.message); - - return null; - } + private void on_sidebar_destroying_page(Sidebar.PageRepresentative entry, Page page) { + destroying_page(entry, page); } private void load_entry_icons(Gtk.TreeIter iter) { EntryWrapper? wrapper = get_wrapper_at_iter(iter); if (wrapper == null) return; - - Icon? icon = wrapper.entry.get_sidebar_icon(); - Icon? open = null; - Icon? closed = null; - - Sidebar.ExpandableEntry? expandable = wrapper.entry as Sidebar.ExpandableEntry; - if (expandable != null) { - open = expandable.get_sidebar_open_icon(); - closed = expandable.get_sidebar_closed_icon(); - } - - if (open == null) - open = icon; - - if (closed == null) - closed = icon; - - store.set(iter, Columns.PIXBUF, fetch_icon_pixbuf(icon)); - store.set(iter, Columns.OPEN_PIXBUF, fetch_icon_pixbuf(open)); - store.set(iter, Columns.CLOSED_PIXBUF, fetch_icon_pixbuf(closed)); + string? icon = wrapper.entry.get_sidebar_icon(); + store.set(iter, Columns.ICON, icon); } private void load_branch_icons(Gtk.TreeIter iter) { @@ -798,15 +793,6 @@ public class Sidebar.Tree : Gtk.TreeView { } } - private void on_theme_change() { - Gtk.TreeIter iter; - if (store.get_iter_first(out iter)) { - do { - load_branch_icons(iter); - } while (store.iter_next(ref iter)); - } - } - private bool on_selection(Gtk.TreeSelection selection, Gtk.TreeModel model, Gtk.TreePath path, bool path_currently_selected) { // only allow selection if a page is selectable @@ -879,6 +865,42 @@ public class Sidebar.Tree : Gtk.TreeView { return true; } + public bool on_toggle_row(Gtk.TreeIter iter, Gtk.TreePath path) { + // Determine whether to allow the row to toggle + EntryWrapper? wrapper = get_wrapper_at_iter(iter); + if (wrapper == null) { + return false; // don't affect things + } + + // Most of the time, only allow manual toggles + bool should_allow_toggle = expander_called_manually; + + // Cancel out the manual flag + expander_called_manually = false; + + // If we are an expanded parent entry with content + if (is_row_expanded(path) && store.iter_has_child(iter) && wrapper.entry is Sidebar.SelectableEntry) { + // We are taking a special action + expander_special_count++; + if (expander_special_count == 1) { + // Workaround that prevents arrows from double-toggling + return true; + } else { + // Toggle only if non-manual, as opposed to the usual behavior + should_allow_toggle = !should_allow_toggle; + } + } else { + // Reset the special behavior count + expander_special_count = 0; + } + + if (should_allow_toggle) { + return false; + } + // Prevent branch expansion toggle + return true; + } + public override bool button_press_event(Gdk.EventButton event) { Gtk.TreePath? path = get_path_from_event(event); @@ -893,19 +915,29 @@ public class Sidebar.Tree : Gtk.TreeView { popup_context_menu(path, event); else popup_default_context_menu(event); - } else if (event.button == 1 && event.type == Gdk.EventType.2BUTTON_PRESS) { - // double left click - if (path != null) { + } else if (event.button == 1 && event.type == Gdk.EventType.BUTTON_PRESS) { + if (path == null) { + old_path_ref = null; + return base.button_press_event(event); + } + + EntryWrapper? wrapper = get_wrapper_at_path(path); + + if (wrapper == null) { + old_path_ref = null; + return base.button_press_event(event); + } + + // Enable single click to toggle tree entries (bug 4985) + if (wrapper.entry is Sidebar.ExpandableEntry + || wrapper.entry is Sidebar.InternalDropTargetEntry) { + // all labels are InternalDropTargetEntries toggle_branch_expansion(path, false); - - if (can_rename_path(path)) - return false; } - } else if (event.button == 1 && event.type == Gdk.EventType.BUTTON_PRESS) { + // Is this a click on an already-highlighted tree item? - Gtk.TreePath? cursor_path = null; - get_cursor(out cursor_path, null); - if ((cursor_path != null) && (cursor_path.compare(path) == 0)) { + if ((old_path_ref != null) && (old_path_ref.get_path() != null) + && (old_path_ref.get_path().compare(path) == 0)) { // yes, don't allow single-click editing, but // pass the event on for dragging. text_renderer.editable = false; @@ -914,9 +946,13 @@ public class Sidebar.Tree : Gtk.TreeView { // Got click on different tree item, make sure it is editable // if it needs to be. - if (path != null && get_wrapper_at_path(path).entry is Sidebar.RenameableEntry) { + if (wrapper.entry is Sidebar.RenameableEntry && + ((Sidebar.RenameableEntry) wrapper.entry).is_user_renameable()) { text_renderer.editable = true; } + + // Remember what tree item is highlighted for next time. + old_path_ref = new Gtk.TreeRowReference(store, path); } return base.button_press_event(event); @@ -1106,6 +1142,9 @@ public class Sidebar.Tree : Gtk.TreeView { if (renameable == null) return false; + if (wrapper.entry is Sidebar.Header) + return false; + get_selection().select_path(path); return true; diff --git a/src/sidebar/common.vala b/src/sidebar/common.vala index 36adfff..0f1bc05 100644 --- a/src/sidebar/common.vala +++ b/src/sidebar/common.vala @@ -1,39 +1,42 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ // A simple grouping Entry that is only expandable -public class Sidebar.Grouping : Object, Sidebar.Entry, Sidebar.ExpandableEntry { +public class Sidebar.Grouping : Object, Sidebar.Entry, Sidebar.ExpandableEntry, + Sidebar.RenameableEntry { + private string name; - private Icon? open_icon; - private Icon? closed_icon; + private string? tooltip; + private string? icon; - public Grouping(string name, Icon? open_icon, Icon? closed_icon = null) { + public Grouping(string name, string? icon, string? tooltip = null) { this.name = name; - this.open_icon = open_icon; - this.closed_icon = closed_icon ?? open_icon; + this.icon = icon; + this.tooltip = tooltip; } - public string get_sidebar_name() { - return name; + public void rename(string name) { + this.name = name; + sidebar_name_changed(name); } - public string? get_sidebar_tooltip() { - return name; + public bool is_user_renameable() { + return false; } - public Icon? get_sidebar_icon() { - return null; + public string get_sidebar_name() { + return name; } - public Icon? get_sidebar_open_icon() { - return open_icon; + public string? get_sidebar_tooltip() { + return tooltip; } - public Icon? get_sidebar_closed_icon() { - return closed_icon; + public string? get_sidebar_icon() { + return icon; } public string to_string() { @@ -61,7 +64,7 @@ public abstract class Sidebar.SimplePageEntry : Object, Sidebar.Entry, Sidebar.S return get_sidebar_name(); } - public abstract Icon? get_sidebar_icon(); + public abstract string? get_sidebar_icon(); public virtual string to_string() { return get_sidebar_name(); @@ -107,6 +110,26 @@ public class Sidebar.RootOnlyBranch : Sidebar.Branch { } } +/** + * A header is an entry that is visually distinguished from its children. Bug 6397 recommends + * headers to appear bolded and without any icons. To prevent the icons from rendering, we set the + * icons to null in the base class @see Sidebar.Grouping. But we also go a step further by + * using a custom cell_data_function (@see Sidebar.Tree::icon_renderer_function) which ensures that + * header icons won't be rendered. This approach avoids the blank icon spacing issues. + */ +public class Sidebar.Header : Sidebar.Grouping, Sidebar.EmphasizableEntry { + private bool emphasized; + + public Header(string name, bool emphasized = true) { + base(name, null); + this.emphasized = emphasized; + } + + public bool is_emphasized() { + return emphasized; + } +} + public interface Sidebar.Contextable : Object { // Return null if the context menu should not be invoked for this event public abstract Gtk.Menu? get_sidebar_context_menu(Gdk.EventButton? event); diff --git a/src/slideshow/Slideshow.vala b/src/slideshow/Slideshow.vala index d55e3d6..7d20f91 100644 --- a/src/slideshow/Slideshow.vala +++ b/src/slideshow/Slideshow.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/slideshow/TransitionEffects.vala b/src/slideshow/TransitionEffects.vala index 7b10543..5acc36d 100644 --- a/src/slideshow/TransitionEffects.vala +++ b/src/slideshow/TransitionEffects.vala @@ -1,5 +1,5 @@ /* Copyright 2010 Maxim Kartashev - * Copyright 2011-2014 Yorba Foundation + * Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/tags/Branch.vala b/src/tags/Branch.vala index 71bf424..e68b2b1 100644 --- a/src/tags/Branch.vala +++ b/src/tags/Branch.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. @@ -8,7 +8,7 @@ public class Tags.Branch : Sidebar.Branch { private Gee.HashMap<Tag, Tags.SidebarEntry> entry_map = new Gee.HashMap<Tag, Tags.SidebarEntry>(); public Branch() { - base (new Tags.Grouping(), + base (new Tags.Header(), Sidebar.Branch.Options.HIDE_IF_EMPTY | Sidebar.Branch.Options.AUTO_OPEN_ON_NEW_CHILD | Sidebar.Branch.Options.STARTUP_OPEN_GROUPING, @@ -31,6 +31,10 @@ public class Tags.Branch : Sidebar.Branch { return entry_map.get(tag); } + public bool is_user_renameable() { + return true; + } + private static int comparator(Sidebar.Entry a, Sidebar.Entry b) { if (a == b) return 0; @@ -118,13 +122,13 @@ public class Tags.Branch : Sidebar.Branch { } } -public class Tags.Grouping : Sidebar.Grouping, Sidebar.InternalDropTargetEntry, +public class Tags.Header : Sidebar.Header, Sidebar.InternalDropTargetEntry, Sidebar.InternalDragSourceEntry, Sidebar.Contextable { private Gtk.UIManager ui = new Gtk.UIManager(); private Gtk.Menu? context_menu = null; - public Grouping() { - base (_("Tags"), new ThemedIcon(Resources.ICON_TAGS)); + public Header() { + base (_("Tags")); setup_context_menu(); } @@ -199,7 +203,7 @@ public class Tags.Grouping : Sidebar.Grouping, Sidebar.InternalDropTargetEntry, public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntry, Sidebar.DestroyableEntry, Sidebar.InternalDropTargetEntry, Sidebar.ExpandableEntry, Sidebar.InternalDragSourceEntry { - private static Icon single_tag_icon; + private string single_tag_icon = Resources.ICON_ONE_TAG; private Tag tag; @@ -208,11 +212,9 @@ public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr } internal static void init() { - single_tag_icon = new ThemedIcon(Resources.ICON_ONE_TAG); } internal static void terminate() { - single_tag_icon = null; } public Tag for_tag() { @@ -223,7 +225,7 @@ public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr return tag.get_user_visible_name(); } - public override Icon? get_sidebar_icon() { + public override string? get_sidebar_icon() { return single_tag_icon; } @@ -231,6 +233,10 @@ public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr return new TagPage(tag); } + public bool is_user_renameable() { + return true; + } + public void rename(string new_name) { string? prepped = Tag.prep_tag_name(new_name); if (prepped == null) @@ -290,14 +296,6 @@ public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr return false; } - public Icon? get_sidebar_open_icon() { - return single_tag_icon; - } - - public Icon? get_sidebar_closed_icon() { - return single_tag_icon; - } - public bool expand_on_select() { return false; } diff --git a/src/tags/HierarchicalTagIndex.vala b/src/tags/HierarchicalTagIndex.vala index 58b5f89..abc1f20 100644 --- a/src/tags/HierarchicalTagIndex.vala +++ b/src/tags/HierarchicalTagIndex.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/tags/HierarchicalTagUtilities.vala b/src/tags/HierarchicalTagUtilities.vala index dbb7165..a455bbf 100644 --- a/src/tags/HierarchicalTagUtilities.vala +++ b/src/tags/HierarchicalTagUtilities.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/tags/TagPage.vala b/src/tags/TagPage.vala index f3ef237..2eebc42 100644 --- a/src/tags/TagPage.vala +++ b/src/tags/TagPage.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/tags/Tags.vala b/src/tags/Tags.vala index 7d02a2f..0639cdc 100644 --- a/src/tags/Tags.vala +++ b/src/tags/Tags.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/threads/BackgroundJob.vala b/src/threads/BackgroundJob.vala index 178211e..8203307 100644 --- a/src/threads/BackgroundJob.vala +++ b/src/threads/BackgroundJob.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/threads/Semaphore.vala b/src/threads/Semaphore.vala index dfb0a2f..31d2b2d 100644 --- a/src/threads/Semaphore.vala +++ b/src/threads/Semaphore.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/threads/Threads.vala b/src/threads/Threads.vala index 0e1b1ec..b9bcd55 100644 --- a/src/threads/Threads.vala +++ b/src/threads/Threads.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/threads/Workers.vala b/src/threads/Workers.vala index 756eb01..a97b557 100644 --- a/src/threads/Workers.vala +++ b/src/threads/Workers.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/unit/Unit.vala b/src/unit/Unit.vala index f297974..e6c7228 100644 --- a/src/unit/Unit.vala +++ b/src/unit/Unit.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/unit/rc/template.vala b/src/unit/rc/template.vala index 4869700..8199c01 100644 --- a/src/unit/rc/template.vala +++ b/src/unit/rc/template.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/util/KeyValueMap.vala b/src/util/KeyValueMap.vala index c1f5a55..cf52719 100644 --- a/src/util/KeyValueMap.vala +++ b/src/util/KeyValueMap.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/util/Util.vala b/src/util/Util.vala index c754ff8..701ca04 100644 --- a/src/util/Util.vala +++ b/src/util/Util.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/util/file.vala b/src/util/file.vala index 1b6bb6c..8af5ca1 100644 --- a/src/util/file.vala +++ b/src/util/file.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/util/image.vala b/src/util/image.vala index e8f93ba..4485fc7 100644 --- a/src/util/image.vala +++ b/src/util/image.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/util/misc.vala b/src/util/misc.vala index 73ce428..1507e02 100644 --- a/src/util/misc.vala +++ b/src/util/misc.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/util/string.vala b/src/util/string.vala index 9fda007..3574249 100644 --- a/src/util/string.vala +++ b/src/util/string.vala @@ -1,4 +1,4 @@ -/* Copyright 2010-2014 Yorba Foundation +/* Copyright 2010-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. diff --git a/src/util/system.vala b/src/util/system.vala index 9407405..8e5a07f 100644 --- a/src/util/system.vala +++ b/src/util/system.vala @@ -1,4 +1,4 @@ -/* Copyright 2009-2014 Yorba Foundation +/* Copyright 2009-2015 Yorba Foundation * * This software is licensed under the GNU LGPL (version 2.1 or later). * See the COPYING file in this distribution. diff --git a/src/util/ui.vala b/src/util/ui.vala index 9f66de8..b846f22 100644 --- a/src/util/ui.vala +++ b/src/util/ui.vala @@ -1,4 +1,4 @@ -/* Copyright 2011-2014 Yorba Foundation +/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. |