diff options
Diffstat (limited to 'src/events/EventsDirectoryPage.vala')
-rw-r--r-- | src/events/EventsDirectoryPage.vala | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/src/events/EventsDirectoryPage.vala b/src/events/EventsDirectoryPage.vala new file mode 100644 index 0000000..41a1ac6 --- /dev/null +++ b/src/events/EventsDirectoryPage.vala @@ -0,0 +1,313 @@ +/* Copyright 2009-2014 Yorba Foundation + * + * This software is licensed under the GNU LGPL (version 2.1 or later). + * See the COPYING file in this distribution. + */ + +public abstract class EventsDirectoryPage : CheckerboardPage { + public class EventDirectoryManager : ViewManager { + public override DataView create_view(DataSource source) { + return new EventDirectoryItem((Event) source); + } + } + + private class EventsDirectorySearchViewFilter : SearchViewFilter { + public override uint get_criteria() { + return SearchFilterCriteria.TEXT; + } + + public override bool predicate(DataView view) { + assert(view.get_source() is Event); + if (is_string_empty(get_search_filter())) + return true; + + Event source = (Event) view.get_source(); + unowned string? event_keywords = source.get_indexable_keywords(); + if (is_string_empty(event_keywords)) + return false; + + // Return false if the word isn't found, true otherwise. + foreach (unowned string word in get_search_filter_words()) { + if (!event_keywords.contains(word)) + return false; + } + + return true; + } + } + + private const int MIN_PHOTOS_FOR_PROGRESS_WINDOW = 50; + + protected ViewManager view_manager; + + private EventsDirectorySearchViewFilter search_filter = new EventsDirectorySearchViewFilter(); + + public EventsDirectoryPage(string page_name, ViewManager view_manager, + Gee.Collection<Event>? initial_events) { + base (page_name); + + // set comparator before monitoring source collection, to prevent a re-sort + get_view().set_comparator(get_event_comparator(Config.Facade.get_instance().get_events_sort_ascending()), + event_comparator_predicate); + get_view().monitor_source_collection(Event.global, view_manager, null, initial_events); + + get_view().set_property(Event.PROP_SHOW_COMMENTS, + Config.Facade.get_instance().get_display_event_comments()); + + init_item_context_menu("/EventsDirectoryContextMenu"); + + this.view_manager = view_manager; + + // set up page's toolbar (used by AppWindow for layout and FullscreenWindow as a popup) + Gtk.Toolbar toolbar = get_toolbar(); + + // merge tool + Gtk.ToolButton merge_button = new Gtk.ToolButton.from_stock(Resources.MERGE); + merge_button.set_related_action(get_action("Merge")); + + toolbar.insert(merge_button, -1); + } + + ~EventsDirectoryPage() { + Gtk.RadioAction? action = get_action("CommonSortEventsAscending") as Gtk.RadioAction; + assert(action != null); + action.changed.disconnect(on_sort_changed); + } + + protected override void init_collect_ui_filenames(Gee.List<string> ui_filenames) { + ui_filenames.add("events_directory.ui"); + + base.init_collect_ui_filenames(ui_filenames); + } + + protected static bool event_comparator_predicate(DataObject object, Alteration alteration) { + return alteration.has_detail("metadata", "time"); + } + + private static int64 event_ascending_comparator(void *a, void *b) { + time_t start_a = ((EventDirectoryItem *) a)->event.get_start_time(); + time_t start_b = ((EventDirectoryItem *) b)->event.get_start_time(); + + return start_a - start_b; + } + + private static int64 event_descending_comparator(void *a, void *b) { + return event_ascending_comparator(b, a); + } + + private static Comparator get_event_comparator(bool ascending) { + if (ascending) + return event_ascending_comparator; + else + return event_descending_comparator; + } + + protected override Gtk.ActionEntry[] init_collect_action_entries() { + Gtk.ActionEntry[] actions = base.init_collect_action_entries(); + + Gtk.ActionEntry rename = { "Rename", null, TRANSLATABLE, "F2", TRANSLATABLE, on_rename }; + rename.label = Resources.RENAME_EVENT_MENU; + actions += rename; + + Gtk.ActionEntry merge = { "Merge", Resources.MERGE, TRANSLATABLE, null, Resources.MERGE_TOOLTIP, + on_merge }; + merge.label = Resources.MERGE_MENU; + actions += merge; + + Gtk.ActionEntry comment = { "EditComment", null, TRANSLATABLE, null, Resources.EDIT_COMMENT_MENU, + on_edit_comment }; + comment.label = Resources.EDIT_COMMENT_MENU; + actions += comment; + + return actions; + } + + protected override Gtk.ToggleActionEntry[] init_collect_toggle_action_entries() { + Gtk.ToggleActionEntry[] toggle_actions = base.init_collect_toggle_action_entries(); + + Gtk.ToggleActionEntry comments = { "ViewComment", null, TRANSLATABLE, "<Ctrl><Shift>C", + TRANSLATABLE, on_display_comments, Config.Facade.get_instance().get_display_event_comments() }; + comments.label = _("_Comments"); + comments.tooltip = _("Display the comment of each event"); + toggle_actions += comments; + + return toggle_actions; + } + + protected override void init_actions(int selected_count, int count) { + base.init_actions(selected_count, count); + + Gtk.RadioAction? action = get_action("CommonSortEventsAscending") as Gtk.RadioAction; + assert(action != null); + action.changed.connect(on_sort_changed); + } + + protected override void update_actions(int selected_count, int count) { + set_action_sensitive("Merge", selected_count > 1); + set_action_important("Merge", true); + set_action_sensitive("Rename", selected_count == 1); + set_action_sensitive("EditComment", selected_count == 1); + + base.update_actions(selected_count, count); + } + + protected override string get_view_empty_message() { + return _("No events"); + } + + protected override string get_filter_no_match_message() { + return _("No events found"); + } + + public override void on_item_activated(CheckerboardItem item, CheckerboardPage.Activator + activator, CheckerboardPage.KeyboardModifiers modifiers) { + EventDirectoryItem event = (EventDirectoryItem) item; + LibraryWindow.get_app().switch_to_event(event.event); + } + + private void on_sort_changed(Gtk.Action action, Gtk.Action c) { + Gtk.RadioAction current = (Gtk.RadioAction) c; + + get_view().set_comparator( + get_event_comparator(current.current_value == LibraryWindow.SORT_EVENTS_ORDER_ASCENDING), + event_comparator_predicate); + } + + private void on_rename() { + // only rename one at a time + if (get_view().get_selected_count() != 1) + return; + + EventDirectoryItem item = (EventDirectoryItem) get_view().get_selected_at(0); + + EventRenameDialog rename_dialog = new EventRenameDialog(item.event.get_raw_name()); + string? new_name = rename_dialog.execute(); + if (new_name == null) + return; + + RenameEventCommand command = new RenameEventCommand(item.event, new_name); + get_command_manager().execute(command); + } + + protected void on_edit_comment() { + // only edit one at a time + if (get_view().get_selected_count() != 1) + return; + + EventDirectoryItem item = (EventDirectoryItem) get_view().get_selected_at(0); + + EditCommentDialog edit_comment_dialog = new EditCommentDialog(item.event.get_comment()); + string? new_comment = edit_comment_dialog.execute(); + if (new_comment == null) + return; + + EditEventCommentCommand command = new EditEventCommentCommand(item.event, new_comment); + get_command_manager().execute(command); + } + + private void on_merge() { + if (get_view().get_selected_count() <= 1) + return; + + MergeEventsCommand command = new MergeEventsCommand(get_view().get_selected()); + get_command_manager().execute(command); + } + + private void on_display_comments(Gtk.Action action) { + bool display = ((Gtk.ToggleAction) action).get_active(); + + set_display_comments(display); + + Config.Facade.get_instance().set_display_event_comments(display); + } + + public override SearchViewFilter get_search_view_filter() { + return search_filter; + } +} + +public class MasterEventsDirectoryPage : EventsDirectoryPage { + public const string NAME = _("Events"); + + public MasterEventsDirectoryPage() { + base (NAME, new EventDirectoryManager(), (Gee.Collection<Event>) Event.global.get_all()); + } +} + +public class SubEventsDirectoryPage : EventsDirectoryPage { + public enum DirectoryType { + YEAR, + MONTH, + UNDATED; + } + + public const string UNDATED_PAGE_NAME = _("Undated"); + public const string YEAR_FORMAT = _("%Y"); + public const string MONTH_FORMAT = _("%B"); + + private class SubEventDirectoryManager : EventsDirectoryPage.EventDirectoryManager { + private int month = 0; + private int year = 0; + DirectoryType type; + + public SubEventDirectoryManager(DirectoryType type, Time time) { + base(); + + if (type == DirectoryType.MONTH) + month = time.month; + this.type = type; + year = time.year; + } + + public override bool include_in_view(DataSource source) { + if (!base.include_in_view(source)) + return false; + + EventSource event = (EventSource) source; + Time event_time = Time.local(event.get_start_time()); + if (event_time.year == year) { + if (type == DirectoryType.MONTH) { + return (event_time.month == month); + } + return true; + } + return false; + } + + public int get_month() { + return month; + } + + public int get_year() { + return year; + } + + public DirectoryType get_event_directory_type() { + return type; + } + } + + public SubEventsDirectoryPage(DirectoryType type, Time time) { + string page_name; + if (type == SubEventsDirectoryPage.DirectoryType.UNDATED) { + page_name = UNDATED_PAGE_NAME; + } else { + page_name = time.format((type == DirectoryType.YEAR) ? YEAR_FORMAT : MONTH_FORMAT); + } + + base(page_name, new SubEventDirectoryManager(type, time), null); + } + + public int get_month() { + return ((SubEventDirectoryManager) view_manager).get_month(); + } + + public int get_year() { + return ((SubEventDirectoryManager) view_manager).get_year(); + } + + public DirectoryType get_event_directory_type() { + return ((SubEventDirectoryManager) view_manager).get_event_directory_type(); + } +} + |