Commit 2f9856b2 authored by Lucas Beeler's avatar Lucas Beeler

Closes #2695, #2736, #2762 and fixes a previously unreported critical GLib cast warning.

parent 2a238485
......@@ -672,9 +672,9 @@ public abstract class AppWindow : PageWindow {
if (get_current_page().get_view().get_selected_count() != 1)
return;
Photo photo = (Photo) get_current_page().get_view().get_selected_at(0).get_source();
MediaSource media = (MediaSource) get_current_page().get_view().get_selected_at(0).get_source();
try {
AppWindow.get_instance().show_file_uri(photo.get_master_file().get_parent());
AppWindow.get_instance().show_file_uri(media.get_master_file().get_parent());
} catch (Error err) {
AppWindow.error_message(Resources.jump_to_file_failed(err));
}
......
......@@ -20,7 +20,6 @@ public abstract class CollectionPage : MediaPage {
private const double DESKTOP_SLIDESHOW_TRANSITION_SEC = 2.0;
private Gtk.ToolButton rotate_button = null;
private PhotoDragAndDropHandler dnd_handler = null;
private ExporterUI exporter = null;
public CollectionPage(string page_name) {
......@@ -89,9 +88,6 @@ public abstract class CollectionPage : MediaPage {
toolbar.insert(zoom_slider_assembly, -1);
show_all();
// enable photo drag-and-drop on our ViewCollection
dnd_handler = new PhotoDragAndDropHandler(this);
// watch for updates to the external app settings
Config.get_instance().external_app_changed.connect(on_external_app_changed);
......@@ -124,14 +120,6 @@ public abstract class CollectionPage : MediaPage {
return group;
}
private static InjectionGroup create_view_menu_tags_injectables() {
InjectionGroup group = new InjectionGroup("/MediaMenuBar/ViewMenu/ViewExtrasTagsPlaceholder");
group.add_menu_item("ViewTags");
return group;
}
private static InjectionGroup create_view_menu_fullscreen_injectables() {
InjectionGroup group = new InjectionGroup("/MediaMenuBar/ViewMenu/ViewExtrasFullscreenSlideshowPlaceholder");
......@@ -198,11 +186,7 @@ public abstract class CollectionPage : MediaPage {
publish.tooltip = Resources.PUBLISH_TOOLTIP;
actions += publish;
#endif
Gtk.ActionEntry event = { "EventsMenu", null, TRANSLATABLE, null, null, null };
event.label = _("Even_ts");
actions += event;
Gtk.ActionEntry rotate_right = { "RotateClockwise", Resources.CLOCKWISE,
TRANSLATABLE, "<Ctrl>R", TRANSLATABLE, on_rotate_clockwise };
rotate_right.label = Resources.ROTATE_CW_MENU;
......@@ -276,50 +260,15 @@ public abstract class CollectionPage : MediaPage {
slideshow.label = _("_Slideshow");
slideshow.tooltip = _("Play a slideshow");
actions += slideshow;
Gtk.ActionEntry new_event = { "NewEvent", Gtk.STOCK_NEW, TRANSLATABLE, "<Ctrl>N",
TRANSLATABLE, on_new_event };
new_event.label = Resources.NEW_EVENT_MENU;
new_event.tooltip = Resources.NEW_EVENT_TOOLTIP;
actions += new_event;
Gtk.ActionEntry tags = { "TagsMenu", null, TRANSLATABLE, null, null, null };
tags.label = _("Ta_gs");
actions += tags;
Gtk.ActionEntry add_tags = { "AddTags", null, TRANSLATABLE, "<Ctrl>T", TRANSLATABLE,
on_add_tags };
add_tags.label = Resources.ADD_TAGS_MENU;
add_tags.tooltip = Resources.ADD_TAGS_TOOLTIP;
actions += add_tags;
Gtk.ActionEntry modify_tags = { "ModifyTags", null, TRANSLATABLE, "<Ctrl>M", TRANSLATABLE,
on_modify_tags };
modify_tags.label = Resources.MODIFY_TAGS_MENU;
modify_tags.tooltip = Resources.MODIFY_TAGS_TOOLTIP;
actions += modify_tags;
return actions;
}
protected override Gtk.ToggleActionEntry[] init_collect_toggle_action_entries() {
Gtk.ToggleActionEntry[] toggle_actions = base.init_collect_toggle_action_entries();
Gtk.ToggleActionEntry tags = { "ViewTags", null, TRANSLATABLE, "<Ctrl><Shift>G",
TRANSLATABLE, on_display_tags, Config.get_instance().get_display_photo_tags() };
tags.label = _("Ta_gs");
tags.tooltip = _("Display each photo's tags");
toggle_actions += tags;
return toggle_actions;
}
protected override InjectionGroup[] init_collect_injection_groups() {
InjectionGroup[] groups = base.init_collect_injection_groups();
groups += create_file_menu_injectables();
groups += create_edit_menu_injectables();
groups += create_view_menu_tags_injectables();
groups += create_view_menu_fullscreen_injectables();
groups += create_photos_menu_edits_injectables();
groups += create_photos_menu_date_injectables();
......@@ -358,16 +307,6 @@ public abstract class CollectionPage : MediaPage {
return false;
}
public override void switched_to() {
// set display options to match Configuration toggles (which can change while switched away)
get_view().freeze_notifications();
set_display_tags(Config.get_instance().get_display_photo_tags());
get_view().thaw_notifications();
// perform these operations before calling base method to prevent flicker
base.switched_to();
}
protected override void update_actions(int selected_count, int count) {
base.update_actions(selected_count, count);
......@@ -708,21 +647,6 @@ public abstract class CollectionPage : MediaPage {
get_command_manager().execute(command);
}
private void on_modify_tags() {
if (get_view().get_selected_count() != 1)
return;
MediaSource media = (MediaSource) get_view().get_selected_at(0).get_source();
ModifyTagsDialog dialog = new ModifyTagsDialog(media);
Gee.ArrayList<Tag>? new_tags = dialog.execute();
if (new_tags == null)
return;
get_command_manager().execute(new ModifyTagsCommand(media, new_tags));
}
private void on_duplicate_photo() {
if (get_view().get_selected_count() == 0)
return;
......@@ -823,15 +747,7 @@ public abstract class CollectionPage : MediaPage {
AppWindow.get_instance().go_fullscreen(new SlideshowPage(LibraryPhoto.global, get_view(),
photo));
}
private void on_display_tags(Gtk.Action action) {
bool display = ((Gtk.ToggleAction) action).get_active();
set_display_tags(display);
Config.get_instance().set_display_photo_tags(display);
}
protected override bool on_ctrl_pressed(Gdk.EventKey? event) {
rotate_button.set_related_action(get_action("RotateCounterclockwise"));
rotate_button.set_label(Resources.ROTATE_CCW_LABEL);
......@@ -845,33 +761,6 @@ public abstract class CollectionPage : MediaPage {
return base.on_ctrl_released(event);
}
private void set_display_tags(bool display) {
get_view().freeze_notifications();
get_view().set_property(Thumbnail.PROP_SHOW_TAGS, display);
get_view().thaw_notifications();
Gtk.ToggleAction action = (Gtk.ToggleAction) action_group.get_action("ViewTags");
if (action != null)
action.set_active(display);
}
private void on_new_event() {
if (get_view().get_selected_count() > 0)
get_command_manager().execute(new NewEventCommand(get_view().get_selected()));
}
private void on_add_tags() {
if (get_view().get_selected_count() == 0)
return;
AddTagsDialog dialog = new AddTagsDialog();
string[]? names = dialog.execute();
if (names != null) {
get_command_manager().execute(new AddTagsCommand(names,
(Gee.Collection<MediaSource>) get_view().get_selected_sources()));
}
}
}
public class LibraryPage : CollectionPage {
......
......@@ -316,6 +316,7 @@ public abstract class MediaPage : CheckerboardPage {
private ZoomSliderAssembly? connected_slider = null;
private FilterButton? connected_filter_button = null;
private DragAndDropHandler dnd_handler = null;
public MediaPage(string page_name) {
base (page_name);
......@@ -337,6 +338,9 @@ public abstract class MediaPage : CheckerboardPage {
get_view().set_property(Thumbnail.PROP_SHOW_RATINGS,
Config.get_instance().get_display_photo_ratings());
get_view().thaw_notifications();
// enable drag-and-drop export of media
dnd_handler = new DragAndDropHandler(this);
}
private static void set_global_thumbnail_scale(int new_scale) {
......@@ -406,7 +410,33 @@ public abstract class MediaPage : CheckerboardPage {
Gtk.ActionEntry photos = { "PhotosMenu", null, TRANSLATABLE, null, null, null };
photos.label = _("_Photos");
actions += photos;
Gtk.ActionEntry event = { "EventsMenu", null, TRANSLATABLE, null, null, null };
event.label = _("Even_ts");
actions += event;
Gtk.ActionEntry tags = { "TagsMenu", null, TRANSLATABLE, null, null, null };
tags.label = _("Ta_gs");
actions += tags;
Gtk.ActionEntry new_event = { "NewEvent", Gtk.STOCK_NEW, TRANSLATABLE, "<Ctrl>N",
TRANSLATABLE, on_new_event };
new_event.label = Resources.NEW_EVENT_MENU;
new_event.tooltip = Resources.NEW_EVENT_TOOLTIP;
actions += new_event;
Gtk.ActionEntry add_tags = { "AddTags", null, TRANSLATABLE, "<Ctrl>T", TRANSLATABLE,
on_add_tags };
add_tags.label = Resources.ADD_TAGS_MENU;
add_tags.tooltip = Resources.ADD_TAGS_TOOLTIP;
actions += add_tags;
Gtk.ActionEntry modify_tags = { "ModifyTags", null, TRANSLATABLE, "<Ctrl>M", TRANSLATABLE,
on_modify_tags };
modify_tags.label = Resources.MODIFY_TAGS_MENU;
modify_tags.tooltip = Resources.MODIFY_TAGS_TOOLTIP;
actions += modify_tags;
Gtk.ActionEntry increase_size = { "IncreaseSize", Gtk.STOCK_ZOOM_IN, TRANSLATABLE,
"<Ctrl>plus", TRANSLATABLE, on_increase_size };
increase_size.label = _("Zoom _In");
......@@ -527,7 +557,13 @@ public abstract class MediaPage : CheckerboardPage {
ratings.label = Resources.VIEW_RATINGS_MENU;
ratings.tooltip = Resources.VIEW_RATINGS_TOOLTIP;
toggle_actions += ratings;
Gtk.ToggleActionEntry tags = { "ViewTags", null, TRANSLATABLE, "<Ctrl><Shift>G",
TRANSLATABLE, on_display_tags, Config.get_instance().get_display_photo_tags() };
tags.label = _("Ta_gs");
tags.tooltip = _("Display each photo's tags");
toggle_actions += tags;
return toggle_actions;
}
......@@ -955,6 +991,7 @@ public abstract class MediaPage : CheckerboardPage {
get_view().freeze_notifications();
set_display_titles(Config.get_instance().get_display_photo_titles());
set_display_ratings(Config.get_instance().get_display_photo_ratings());
set_display_tags(Config.get_instance().get_display_photo_tags());
get_view().thaw_notifications();
restore_saved_rating_view_filter(); // Set filter to current level and set menu selection
......@@ -1001,6 +1038,48 @@ public abstract class MediaPage : CheckerboardPage {
protected virtual void on_decrease_size() {
decrease_zoom_level();
}
private void on_add_tags() {
if (get_view().get_selected_count() == 0)
return;
AddTagsDialog dialog = new AddTagsDialog();
string[]? names = dialog.execute();
if (names != null) {
get_command_manager().execute(new AddTagsCommand(names,
(Gee.Collection<MediaSource>) get_view().get_selected_sources()));
}
}
private void on_modify_tags() {
if (get_view().get_selected_count() != 1)
return;
MediaSource media = (MediaSource) get_view().get_selected_at(0).get_source();
ModifyTagsDialog dialog = new ModifyTagsDialog(media);
Gee.ArrayList<Tag>? new_tags = dialog.execute();
if (new_tags == null)
return;
get_command_manager().execute(new ModifyTagsCommand(media, new_tags));
}
private void set_display_tags(bool display) {
get_view().freeze_notifications();
get_view().set_property(Thumbnail.PROP_SHOW_TAGS, display);
get_view().thaw_notifications();
Gtk.ToggleAction action = (Gtk.ToggleAction) action_group.get_action("ViewTags");
if (action != null)
action.set_active(display);
}
private void on_new_event() {
if (get_view().get_selected_count() > 0)
get_command_manager().execute(new NewEventCommand(get_view().get_selected()));
}
private void on_flag_unflag() {
if (get_view().get_selected_count() == 0)
......@@ -1123,6 +1202,14 @@ public abstract class MediaPage : CheckerboardPage {
Config.get_instance().set_display_photo_ratings(display);
}
protected virtual void on_display_tags(Gtk.Action action) {
bool display = ((Gtk.ToggleAction) action).get_active();
set_display_tags(display);
Config.get_instance().set_display_photo_tags(display);
}
protected abstract void get_config_photos_sort(out bool sort_order, out int sort_by);
protected abstract void set_config_photos_sort(bool sort_order, int sort_by);
......
......@@ -2166,13 +2166,11 @@ public abstract class SinglePhotoPage : Page {
}
//
// DragPhotoHandler attaches signals to a Page so properly handle drag-and-drop requests for the
// DragAndDropHandler attaches signals to a Page to properly handle drag-and-drop requests for the
// Page as a DnD Source. (DnD Destination handling is handled by the appropriate AppWindow, i.e.
// LibraryWindow and DirectWindow).
// LibraryWindow and DirectWindow). Assumes the Page's ViewCollection holds MediaSources.
//
// The Page's ViewCollection *must* be holding TransformablePhotos or the show is off.
//
public class PhotoDragAndDropHandler {
public class DragAndDropHandler {
private enum TargetType {
XDS,
MEDIA_LIST
......@@ -2192,7 +2190,7 @@ public class PhotoDragAndDropHandler {
private File? drag_destination = null;
private ExporterUI exporter = null;
public PhotoDragAndDropHandler(Page page) {
public DragAndDropHandler(Page page) {
this.page = page;
this.event_source = page.get_event_source();
assert(event_source != null);
......@@ -2220,7 +2218,7 @@ public class PhotoDragAndDropHandler {
event_source.drag_failed.connect(on_drag_failed);
}
~PhotoDragAndDropHandler() {
~DragAndDropHandler() {
if (event_source != null) {
event_source.drag_begin.disconnect(on_drag_begin);
event_source.drag_data_get.disconnect(on_drag_data_get);
......
......@@ -393,7 +393,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
private bool photo_missing = false;
private PixbufCache cache = null;
private PixbufCache master_cache = null;
private PhotoDragAndDropHandler dnd_handler = null;
private DragAndDropHandler dnd_handler = null;
private bool enable_interactive_zoom_refresh = false;
private Gdk.Point zoom_pan_start_point;
private bool is_pan_in_progress = false;
......@@ -738,7 +738,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
// DnD not available in fullscreen mode
if (!(container is FullscreenWindow))
dnd_handler = new PhotoDragAndDropHandler(this);
dnd_handler = new DragAndDropHandler(this);
}
public override ViewCollection get_controller() {
......
......@@ -410,14 +410,19 @@ private class ExtendedPropertiesWindow : Gtk.Window {
protected override void get_single_properties(DataView view) {
base.get_single_properties(view);
PhotoSource photo = view.get_source() as PhotoSource;
if (photo == null)
MediaSource media = view.get_source() as MediaSource;
if (media == null)
return;
if (photo is Photo)
file_path = ((Photo) photo).get_file().get_path();
filesize = photo.get_filesize();
file_path = media.get_file().get_path();
filesize = media.get_filesize();
// as of right now, all extended properties other than filesize & filepath aren't
// applicable to non-photo media types, so if the current media source isn't a photo,
// just do a short-circuit return
Photo photo = media as Photo;
if (photo == null)
return;
PhotoMetadata? metadata = photo.get_metadata();
if (metadata == null)
......
<ui>
<menubar name="MediaMenuBar">
<placeholder name="MenubarExtrasPlaceholder">
<menu name="EventsMenu" action="EventsMenu">
<menuitem name="NewEvent" action="NewEvent" />
<menuitem name="CommonJumpToEvent" action="CommonJumpToEvent" />
</menu>
<menu name="TagsMenu" action="TagsMenu">
<menuitem name="AddTags" action="AddTags" />
<menuitem name="ModifyTags" action="ModifyTags" />
</menu>
</placeholder>
</menubar>
<popup name="CollectionContextMenu">
<menuitem name="ContextEnhance" action="Enhance" />
<menuitem name="ContextRevert" action="Revert" />
......
......@@ -34,7 +34,7 @@
<menuitem name="DisplayExtendedProperties" action="CommonDisplayExtendedProperties" />
<separator />
<menuitem name="ViewTitle" action="ViewTitle" />
<placeholder name="ViewExtrasTagsPlaceholder" />
<menuitem name="ViewTags" action="ViewTags" />
<menuitem name="ViewRatings" action="ViewRatings" />
<separator />
<menu name="FilterPhotos" action="FilterPhotos">
......@@ -90,7 +90,15 @@
<placeholder name="PhotosExtrasExternalsPlaceholder" />
</menu>
<placeholder name="MenubarExtrasPlaceholder" />
<menu name="EventsMenu" action="EventsMenu">
<menuitem name="NewEvent" action="NewEvent" />
<menuitem name="CommonJumpToEvent" action="CommonJumpToEvent" />
</menu>
<menu name="TagsMenu" action="TagsMenu">
<menuitem name="AddTags" action="AddTags" />
<menuitem name="ModifyTags" action="ModifyTags" />
</menu>
<menu name="HelpMenu" action="HelpMenu">
<menuitem name="Contents" action="CommonHelpContents" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment