Commit 807ccf1f authored by Jim Nelson's avatar Jim Nelson

#3100: Search bar, from Eric.

parent d1242150
......@@ -90,7 +90,6 @@ UNUNITIZED_SRC_FILES = \
OfflinePage.vala \
LastImportPage.vala \
VideoSupport.vala \
VideosPage.vala \
Tombstone.vala \
MetadataWriter.vala \
Application.vala \
......@@ -104,7 +103,8 @@ UNUNITIZED_SRC_FILES = \
VideoMetadata.vala \
MediaMonitor.vala \
PhotoMonitor.vala \
VideoMonitor.vala
VideoMonitor.vala \
SearchFilter.vala
VAPI_FILES = \
libexif.vapi \
......
......@@ -886,7 +886,7 @@ public class CheckerboardLayout : Gtk.DrawingArea {
queue_draw();
}
public void set_message(string text) {
public void set_message(string? text) {
message = text;
// set the layout's size to be exactly the same as the parent's
......@@ -894,6 +894,10 @@ public class CheckerboardLayout : Gtk.DrawingArea {
set_size_request(parent.allocation.width, parent.allocation.height);
}
public void unset_message() {
set_message(null);
}
private void update_visible_page() {
if (hadjustment != null && vadjustment != null)
visible_page = get_adjustment_page(hadjustment, vadjustment);
......@@ -912,7 +916,7 @@ public class CheckerboardLayout : Gtk.DrawingArea {
}
public CheckerboardItem? get_item_at_pixel(double xd, double yd) {
if (null == item_rows)
if (message != null || item_rows == null)
return null;
int x = (int) xd;
......
......@@ -19,8 +19,16 @@ public class CollectionViewManager : ViewManager {
public abstract class CollectionPage : MediaPage {
private const double DESKTOP_SLIDESHOW_TRANSITION_SEC = 2.0;
protected class CollectionSearchViewFilter : DefaultSearchViewFilter {
public override uint get_criteria() {
return SearchFilterCriteria.TEXT | SearchFilterCriteria.FLAG |
SearchFilterCriteria.MEDIA | SearchFilterCriteria.RATING;
}
}
private Gtk.ToolButton rotate_button = null;
private ExporterUI exporter = null;
private CollectionSearchViewFilter search_filter = new CollectionSearchViewFilter();
public CollectionPage(string page_name) {
base (page_name);
......@@ -60,18 +68,7 @@ public abstract class CollectionPage : MediaPage {
Gtk.SeparatorToolItem separator = new Gtk.SeparatorToolItem();
separator.set_expand(true);
separator.set_draw(false);
toolbar.insert(separator, -1);
// Search box.
MediaPage.SearchBox search_box = create_search_box();
connect_search_box(search_box);
toolbar.insert(search_box, -1);
// ratings filter button
MediaPage.FilterButton filter_button = create_filter_button();
connect_filter_button(filter_button);
toolbar.insert(filter_button, -1);
Gtk.SeparatorToolItem drawn_separator = new Gtk.SeparatorToolItem();
drawn_separator.set_expand(false);
......@@ -722,16 +719,18 @@ public abstract class CollectionPage : MediaPage {
return base.on_ctrl_released(event);
}
public override SearchViewFilter get_search_view_filter() {
return search_filter;
}
}
public class LibraryPage : CollectionPage {
public LibraryPage(ProgressMonitor? monitor = null) {
base(_("Photos"));
base(_("Media"));
get_view().freeze_notifications();
get_view().monitor_source_collection(LibraryPhoto.global, new CollectionViewManager(this),
null, (Gee.Collection<DataSource>) LibraryPhoto.global.get_all(), monitor);
get_view().thaw_notifications();
foreach (MediaSourceCollection sources in MediaCollectionRegistry.get_instance().get_all())
get_view().monitor_source_collection(sources, new CollectionViewManager(this), null, null, monitor);
}
protected override void get_config_photos_sort(out bool sort_order, out int sort_by) {
......
......@@ -481,14 +481,45 @@ public class Config {
return set_int("/apps/shotwell/preferences/ui/photo_rating_filter", filter);
}
public string? get_search_filter() {
return (get_string("/apps/shotwell/preferences/ui/search_filter",
null));
public string? get_search_text() {
return get_string("/apps/shotwell/preferences/ui/search_filter", null);
}
public bool set_search_filter(string search) {
public bool set_search_text(string search) {
return set_string("/apps/shotwell/preferences/ui/search_filter", search);
}
public bool get_search_flagged() {
return get_bool("/apps/shotwell/preferences/ui/search_flagged", false);
}
public bool set_search_flagged(bool flagged) {
return set_bool("/apps/shotwell/preferences/ui/search_flagged", flagged);
}
public bool get_show_media_video() {
return get_bool("/apps/shotwell/preferences/ui/show_media_video", false);
}
public bool set_show_media_video(bool b) {
return set_bool("/apps/shotwell/preferences/ui/show_media_video", b);
}
public bool get_show_media_photos() {
return get_bool("/apps/shotwell/preferences/ui/show_media_photos", false);
}
public bool set_show_media_photos(bool b) {
return set_bool("/apps/shotwell/preferences/ui/show_media_photos", b);
}
public bool get_show_media_raw() {
return get_bool("/apps/shotwell/preferences/ui/show_media_raw", false);
}
public bool set_show_media_raw(bool b) {
return set_bool("/apps/shotwell/preferences/ui/show_media_raw", b);
}
public void get_library_window_state(out bool maximize, out Dimensions dimensions) {
maximize = get_bool("/apps/shotwell/preferences/window/library_maximize", false);
......
......@@ -2811,5 +2811,9 @@ public class ViewCollection : DataCollection {
base.notify_thawed();
}
public bool are_items_filtered_out() {
return base.get_count() != get_count();
}
}
......@@ -150,10 +150,29 @@ public class EventsDirectoryPage : CheckerboardPage {
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();
string title = source.get_raw_name() != null ? source.get_raw_name().down() : "";
if (!title.contains(get_search_filter()))
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) {
......@@ -318,6 +337,10 @@ public class EventsDirectoryPage : CheckerboardPage {
MergeEventsCommand command = new MergeEventsCommand(get_view().get_selected());
get_command_manager().execute(command);
}
public override SearchViewFilter get_search_view_filter() {
return search_filter;
}
}
public class NoEventPage : CollectionPage {
......
......@@ -34,8 +34,16 @@ public class FlaggedPage : CollectionPage {
}
}
private class FlaggedSearchViewFilter : CollectionPage.CollectionSearchViewFilter {
public override uint get_criteria() {
return SearchFilterCriteria.TEXT | SearchFilterCriteria.MEDIA |
SearchFilterCriteria.RATING;
}
}
private ViewManager view_manager;
private Alteration prereq = new Alteration("metadata", "flagged");
private FlaggedSearchViewFilter search_filter = new FlaggedSearchViewFilter();
private FlaggedPage(string name) {
base (name);
......@@ -57,5 +65,9 @@ public class FlaggedPage : CollectionPage {
protected override void set_config_photos_sort(bool sort_order, int sort_by) {
Config.get_instance().set_library_photos_sort(sort_order, sort_by);
}
public override SearchViewFilter get_search_view_filter() {
return search_filter;
}
}
......@@ -339,12 +339,6 @@ public class ImportPage : CheckerboardPage {
}
}
private class UnimportedViewFilter : ViewFilter {
public override bool predicate(DataView view) {
return !((ImportPreview) view).is_already_imported();
}
}
private class CameraImportJob : BatchImportJob {
private GPhoto.ContextWrapper context;
private ImportSource import_file;
......@@ -434,6 +428,45 @@ public class ImportPage : CheckerboardPage {
}
}
private class ImportPageSearchViewFilter : SearchViewFilter {
// Set to true if you want to hide duplicates.
public bool hide_duplicates { get; set; default = false; }
public override uint get_criteria() {
return SearchFilterCriteria.TEXT | SearchFilterCriteria.MEDIA;
}
public override bool predicate(DataView view) {
// Duplicate check.
if (hide_duplicates && ((ImportPreview) view).is_already_imported())
return false;
ImportSource source = ((ImportPreview) view).get_import_source();
// Media type.
if ((bool) (SearchFilterCriteria.MEDIA & get_criteria()) && filter_by_media_type()) {
if (source is VideoImportSource) {
if (!show_media_video)
return false;
} else if (source is PhotoImportSource) {
if (((PhotoImportSource) source).get_file_format() == PhotoFileFormat.RAW) {
if (!show_media_photos && !show_media_raw)
return false;
} else if (!show_media_photos)
return false;
}
}
// Text filter.
if ((bool) (SearchFilterCriteria.TEXT & get_criteria())) {
if (!source.get_filename().down().contains(get_search_filter()))
return false;
}
return true;
}
}
public static GPhoto.ContextWrapper null_context = null;
public static GPhoto.SpinIdleWrapper spin_idle_context = null;
......@@ -451,7 +484,7 @@ public class ImportPage : CheckerboardPage {
private VolumeMonitor volume_monitor = null;
private ImportPage? local_ref = null;
private GLib.Icon? icon;
private UnimportedViewFilter show_unimported_filter = new UnimportedViewFilter();
private ImportPageSearchViewFilter search_filter = new ImportPageSearchViewFilter();
public enum RefreshResult {
OK,
......@@ -684,7 +717,7 @@ public class ImportPage : CheckerboardPage {
}
private void on_media_added_removed() {
show_unimported_filter.refresh();
search_filter.refresh();
}
private void on_display_titles(Gtk.Action action) {
......@@ -1169,10 +1202,8 @@ public class ImportPage : CheckerboardPage {
}
private void on_hide_imported() {
if (hide_imported.get_active())
get_view().install_view_filter(show_unimported_filter);
else
get_view().reset_view_filter();
search_filter.hide_duplicates = hide_imported.get_active();
search_filter.refresh();
}
private void on_import_selected() {
......@@ -1328,6 +1359,11 @@ public class ImportPage : CheckerboardPage {
if (action != null)
action.set_active(display);
}
// Gets the search view filter for this page.
public override SearchViewFilter get_search_view_filter() {
return search_filter;
}
}
public class ImportQueuePage : SinglePhotoPage {
......
......@@ -35,7 +35,6 @@ public class LibraryWindow : AppWindow {
// outside the app.
private enum ToplevelPosition {
LIBRARY_PAGE,
VIDEOS_PAGE,
FLAGGED_PAGE,
LAST_IMPORT_PAGE,
CAMERAS_GROUPING,
......@@ -132,7 +131,6 @@ public class LibraryWindow : AppWindow {
private OfflinePage.Stub offline_page = null;
private LastImportPage.Stub last_import_page = null;
private FlaggedPage.Stub flagged_page = null;
private VideosPage.Stub videos_page = null;
private ImportQueuePage import_queue_page = null;
private bool displaying_import_queue_page = false;
private OneShotScheduler properties_scheduler = null;
......@@ -154,6 +152,8 @@ public class LibraryWindow : AppWindow {
private SidebarMarker cameras_marker = null;
private SidebarMarker tags_marker = null;
private SearchFilterToolbar search_toolbar = new SearchFilterToolbar();
private Gtk.VBox top_section = new Gtk.VBox(false, 0);
private Gtk.Frame background_progress_frame = new Gtk.Frame(null);
private Gtk.ProgressBar background_progress_bar = new Gtk.ProgressBar();
......@@ -178,7 +178,6 @@ public class LibraryWindow : AppWindow {
import_queue_page = new ImportQueuePage();
import_queue_page.batch_removed.connect(import_queue_batch_finished);
trash_page = TrashPage.create_stub();
videos_page = VideosPage.create_stub();
// create and connect extended properties window
extended_properties = new ExtendedPropertiesWindow(this);
......@@ -187,7 +186,6 @@ public class LibraryWindow : AppWindow {
// add the default parents and orphans to the notebook
add_toplevel_page(library_page, ToplevelPosition.LIBRARY_PAGE);
sidebar.add_toplevel(videos_page, ToplevelPosition.VIDEOS_PAGE);
sidebar.add_toplevel(last_import_page, ToplevelPosition.LAST_IMPORT_PAGE);
sidebar.add_toplevel(events_directory_page, ToplevelPosition.EVENTS_DIRECTORY_PAGE);
sidebar.add_toplevel(trash_page, ToplevelPosition.TRASH_PAGE);
......@@ -267,9 +265,6 @@ public class LibraryWindow : AppWindow {
sync_last_import_visibility();
sync_flagged_visibility();
Video.global.contents_altered.connect(sync_videos_visibility);
sync_videos_visibility();
MetadataWriter.get_instance().progress.connect(on_metadata_writer_progress);
LibraryPhoto.mimic_manager.progress.connect(on_mimic_manager_progress);
......@@ -793,10 +788,6 @@ public class LibraryWindow : AppWindow {
enable_disable_flagged_page(has_flagged);
}
private void sync_videos_visibility() {
enable_disable_videos_page(Video.global.get_count() > 0);
}
private void import_queue_batch_finished() {
if (displaying_import_queue_page && import_queue_page.get_batch_count() == 0) {
// only hide the import queue page, as it might be used later
......@@ -1280,16 +1271,6 @@ public class LibraryWindow : AppWindow {
}
}
private void enable_disable_videos_page(bool enable) {
if (enable && videos_page == null) {
videos_page = VideosPage.create_stub();
sidebar.add_toplevel(videos_page, ToplevelPosition.VIDEOS_PAGE);
} else if (!enable && videos_page != null) {
remove_stub(videos_page, library_page, null);
videos_page = null;
}
}
private void add_event_page(Event event) {
EventPage.Stub event_stub = EventPage.create_stub(event);
......@@ -1725,9 +1706,13 @@ public class LibraryWindow : AppWindow {
// 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.add(notebook);
right_frame.set_shadow_type(Gtk.ShadowType.IN);
Gtk.VBox right_vbox = new Gtk.VBox(false, 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.HPaned();
client_paned.pack1(sidebar_paned, false, false);
sidebar.set_size_request(SIDEBAR_MIN_WIDTH, -1);
......@@ -1823,6 +1808,15 @@ public class LibraryWindow : AppWindow {
// which will then call this function again
base.set_current_page(page);
// Update search filter to new page.
if (page is CheckerboardPage) {
search_toolbar.set_view_filter(((CheckerboardPage) page).get_search_view_filter());
page.get_view().install_view_filter(((CheckerboardPage) page).get_search_view_filter());
} else {
// Disables the search view filter for non CheckerboardPages.
search_toolbar.unset_view_filter();
}
sidebar.cursor_changed.disconnect(on_sidebar_cursor_changed);
sidebar.place_cursor(page);
sidebar.cursor_changed.connect(on_sidebar_cursor_changed);
......@@ -1916,8 +1910,6 @@ public class LibraryWindow : AppWindow {
switch_to_page(last_import_page.get_page());
} else if (flagged_page != null && is_page_selected(flagged_page, path)) {
switch_to_page(flagged_page.get_page());
} else if (videos_page != null && is_page_selected(videos_page, path)) {
switch_to_page(videos_page.get_page());
} else {
// nothing recognized selected
}
......@@ -2029,5 +2021,9 @@ public class LibraryWindow : AppWindow {
return false;
}
public void set_search_box_focus() {
search_toolbar.set_search_box_focus();
}
}
This diff is collapsed.
......@@ -30,6 +30,15 @@ public class OfflinePage : CheckerboardPage {
}
}
private class OfflineSearchViewFilter : DefaultSearchViewFilter {
public override uint get_criteria() {
return SearchFilterCriteria.TEXT | SearchFilterCriteria.FLAG |
SearchFilterCriteria.MEDIA | SearchFilterCriteria.RATING;
}
}
private OfflineSearchViewFilter search_filter = new OfflineSearchViewFilter();
private OfflinePage(string name) {
base (name);
......@@ -156,5 +165,9 @@ public class OfflinePage : CheckerboardPage {
public override CheckerboardItem? get_fullscreen_photo() {
return null;
}
public override SearchViewFilter get_search_view_filter() {
return search_filter;
}
}
......@@ -1266,8 +1266,12 @@ public abstract class CheckerboardPage : Page {
return layout;
}
// Gets the search view filter for this page.
public abstract SearchViewFilter get_search_view_filter();
public override void switching_from() {
layout.set_in_view(false);
get_search_view_filter().refresh.disconnect(on_view_filter_refresh);
// unselect everything so selection won't persist after page loses focus
get_view().unselect_all();
......@@ -1277,10 +1281,22 @@ public abstract class CheckerboardPage : Page {
public override void switched_to() {
layout.set_in_view(true);
get_search_view_filter().refresh.connect(on_view_filter_refresh);
on_view_filter_refresh();
base.switched_to();
}
private void on_view_filter_refresh() {
if (get_view().are_items_filtered_out() && get_view().get_count() == 0) {
set_page_message(_("No items visible in your current filter"));
} else if (get_view().get_count() == 0) {
set_page_message(_("There are currently no items on this page"));
} else {
unset_page_message();
}
}
public abstract CheckerboardItem? get_fullscreen_photo();
public void set_page_message(string message) {
......@@ -1289,6 +1305,12 @@ public abstract class CheckerboardPage : Page {
layout.queue_draw();
}
public void unset_page_message() {
layout.unset_message();
if (is_in_view())
layout.queue_draw();
}
public override void set_page_name(string name) {
base.set_page_name(name);
......
......@@ -82,9 +82,9 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc.,
public const string ICON_RATING_FOUR = "four-stars.svg";
public const string ICON_RATING_FIVE = "five-stars.svg";
public const string ICON_FILTER_REJECTED_OR_BETTER = "all-rejected.png";
public const int ICON_FILTER_REJECTED_OR_BETTER_FIXED_SIZE = 44;
public const string ICON_FILTER_UNRATED_OR_BETTER = "shotwell-24.svg";
public const int ICON_FILTER_UNRATED_OR_BETTER_FIXED_SIZE = 24;
public const int ICON_FILTER_REJECTED_OR_BETTER_FIXED_SIZE = 32;
public const string ICON_FILTER_UNRATED_OR_BETTER = "shotwell-16.svg";
public const int ICON_FILTER_UNRATED_OR_BETTER_FIXED_SIZE = 16;
public const string ICON_FILTER_ONE_OR_BETTER = "one-star-filter-plus.svg";
public const string ICON_FILTER_TWO_OR_BETTER = "two-star-filter-plus.svg";
public const string ICON_FILTER_THREE_OR_BETTER = "three-star-filter-plus.svg";
......@@ -640,6 +640,10 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc.,
add_stock_icon(icons_dir.get_child("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);
add_stock_icon_from_themed_icon(new GLib.ThemedIcon(ICON_VIDEOS_PAGE), ICON_VIDEOS_PAGE);
add_stock_icon_from_themed_icon(new GLib.ThemedIcon(ICON_SINGLE_PHOTO), ICON_SINGLE_PHOTO);
add_stock_icon_from_themed_icon(new GLib.ThemedIcon(ICON_CAMERAS), ICON_CAMERAS);
factory.add_default();
......@@ -733,6 +737,25 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc.,
Gtk.IconSet icon_set = new Gtk.IconSet.from_pixbuf(pixbuf);
factory.add(stock_id, icon_set);
}
private void add_stock_icon_from_themed_icon(GLib.ThemedIcon gicon, string stock_id) {
Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default();
icon_theme.append_search_path(AppDirs.get_resources_dir().get_child("icons").get_path());
Gtk.IconInfo? info = icon_theme.lookup_by_gicon(gicon,
Resources.DEFAULT_ICON_SCALE, Gtk.IconLookupFlags.FORCE_SIZE);
if (info == null) {
debug("unable to load icon for: %s", stock_id);
return;
}
try {
Gtk.IconSet icon_set = new Gtk.IconSet.from_pixbuf(info.load_icon());
factory.add(stock_id, icon_set);
} catch (Error err) {
debug("%s", err.message);
}
}
public static void launch_help(Gdk.Screen screen) throws Error {
// if running from the build directory, launch the help from there ... don't just search for
......
This diff is collapsed.
......@@ -36,6 +36,15 @@ public class TrashPage : CheckerboardPage {
}
}
private class TrashSearchViewFilter : DefaultSearchViewFilter {
public override uint get_criteria() {
return SearchFilterCriteria.TEXT | SearchFilterCriteria.FLAG |
SearchFilterCriteria.MEDIA | SearchFilterCriteria.RATING;
}
}
private TrashSearchViewFilter search_filter = new TrashSearchViewFilter();
private TrashPage(string name) {
base (name);
......@@ -161,5 +170,9 @@ public class TrashPage : CheckerboardPage {
remove_from_app((Gee.Collection<MediaSource>) get_view().get_selected_sources(), _("Delete"),
ngettext("Deleting a Photo", "Deleting Photos", get_view().get_selected_count()));
}
public override SearchViewFilter get_search_view_filter() {
return search_filter;
}
}
/* Copyright 2010-2011 Yorba Foundation
*
* This software is licensed under the GNU LGPL (version 2.1 or later).
* See the COPYING file in this distribution.
*/
public class VideosPage : MediaPage {
public class Stub : PageStub {
public Stub() {
}
protected override Page construct_page() {
return new VideosPage();
}
public override string get_name() {
return _("Videos");
}
public override GLib.Icon? get_icon() {
return new GLib.ThemedIcon(Resources.ICON_VIDEOS_PAGE);
}
}
private class VideoView : Thumbnail {
public VideoView(Video video) {
base(video);
}
}
private ExporterUI exporter = null;
public VideosPage() {
base (_("Videos"));
init_item_context_menu("/VideoContextMenu");
// Update "Photo" labels to "Video"
action_group.get_action("PhotosMenu").set_label(_("Vi_deos"));
action_group.get_action("FilterPhotos").set_label(_("_Filter Videos"));
action_group.get_action("SortPhotos").set_label(_("Sort _Videos"));
action_group.get_action("DisplayUnratedOrHigher").set_label(_("_All Videos"));
set_common_action_label("CommonJumpToEvent", _("View Eve_nt for Video"));
Gtk.Toolbar toolbar = get_toolbar();
// play button
Gtk.ToolButton play_button = new Gtk.ToolButton.from_stock(Gtk.STOCK_MEDIA_PLAY);
play_button.set_related_action(get_action("PlayVideo"));
play_button.set_label(_("Play"));
toolbar.insert(play_button, -1);
// publish button
Gtk.ToolButton publish_button = new Gtk.ToolButton.from_stock("");
publish_button.set_related_action(action_group.get_action("Publish"));
publish_button.set_icon_name(Resources.PUBLISH);
publish_button.set_label(Resources.PUBLISH_LABEL);
toolbar.insert(publish_button, -1);
// separator to force slider to right side of toolbar
Gtk.SeparatorToolItem separator = new Gtk.SeparatorToolItem();
separator.set_expand(true);
separator.set_draw(false);
toolbar.insert(separator, -1);
// Search box.
MediaPage.SearchBox search_box = create_search_box();
connect_search_box(search_box);
toolbar.insert(search_box, -1);
// ratings filter button
MediaPage.FilterButton filter_button = create_filter_button();
connect_filter_button(filter_button);
toolbar.insert(filter_button, -1);
Gtk.SeparatorToolItem drawn_separator = new Gtk.SeparatorToolItem();
drawn_separator.set_expand(false);
drawn_separator.set_draw(true);
toolbar.insert(drawn_separator, -1);
// zoom slider assembly
MediaPage.ZoomSliderAssembly zoom_slider_assembly = create_zoom_slider_assembly();
connect_slider(zoom_slider_assembly);
toolbar.insert(zoom_slider_assembly, -1);
get_view().monitor_source_collection(Video.global, new VideoViewManager(this), null);
}
protected override void init_collect_ui_filenames(Gee.List<string> ui_filenames) {
base.init_collect_ui_filenames(ui_filenames);
ui_filenames.add("video.ui");
}
private static InjectionGroup create_file_menu_injectables() {
InjectionGroup group = new InjectionGroup("/MenuBar/FileMenu/FileExtrasPlaceholder");
group.add_separator();
group.add_menu_item("Publish");
group.add_menu_item("SendTo");
return group;
}
private static InjectionGroup create_videos_menu_injectables() {
InjectionGroup group = new InjectionGroup("/MenuBar/PhotosMenu/PhotosExtrasExternalsPlaceholder");
group.add_menu_item("PlayVideo");
return group;
}
protected override Gtk.ActionEntry[] init_collect_action_entries() {
Gtk.ActionEntry[] actions = base.init_collect_action_entries();
Gtk.ActionEntry publish = { "Publish", Resources.PUBLISH, TRANSLATABLE, "<Ctrl><Shift>P",
TRANSLATABLE, on_publish };
publish.label = Resources.PUBLISH_MENU;
publish.tooltip = Resources.PUBLISH_TOOLTIP;
actions += publish;
return actions;