diff options
author | Jörg Frings-Fürst <debian@jff.email> | 2018-10-01 07:17:16 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff.email> | 2018-10-01 07:17:16 +0200 |
commit | 71137cc5832110d91599d68790402cf196762ed3 (patch) | |
tree | e7985bbfb6ca50ea738b38a9f852ee51431d48a7 /src/Commands.vala | |
parent | 8ae550d463720d5d1c0e253af29843ff15de1a54 (diff) | |
parent | 1e92964463e564bb3359a7110342182fcfdc67f2 (diff) |
Merge branch 'release/debian/0.30.1-1'debian/0.30.1-1
Diffstat (limited to 'src/Commands.vala')
-rw-r--r-- | src/Commands.vala | 218 |
1 files changed, 217 insertions, 1 deletions
diff --git a/src/Commands.vala b/src/Commands.vala index 7441a50..6924f82 100644 --- a/src/Commands.vala +++ b/src/Commands.vala @@ -920,7 +920,6 @@ public abstract class MovePhotosCommand : Command { } public override void execute() { - // create the new event base.execute(); @@ -2507,3 +2506,220 @@ public class FlagUnflagCommand : MultipleDataSourceAtOnceCommand { } } } + +#if ENABLE_FACES +public class RemoveFacesFromPhotosCommand : SimpleProxyableCommand { + private Gee.Map<MediaSource, string> map_source_geometry = new Gee.HashMap<MediaSource, string>(); + + public RemoveFacesFromPhotosCommand(Face face, Gee.Collection<MediaSource> sources) { + base (face, + Resources.remove_face_from_photos_label(face.get_name(), sources.size), + face.get_name()); + + foreach (MediaSource source in sources) { + FaceLocation? face_location = + FaceLocation.get_face_location(face.get_face_id(), ((Photo) source).get_photo_id()); + assert(face_location != null); + + this.map_source_geometry.set(source, face_location.get_serialized_geometry()); + } + + LibraryPhoto.global.item_destroyed.connect(on_source_destroyed); + Video.global.item_destroyed.connect(on_source_destroyed); + } + + ~RemoveFacesFromPhotosCommand() { + LibraryPhoto.global.item_destroyed.disconnect(on_source_destroyed); + Video.global.item_destroyed.disconnect(on_source_destroyed); + } + + public override void execute_on_source(DataSource source) { + ((Face) source).detach_many(map_source_geometry.keys); + } + + public override void undo_on_source(DataSource source) { + Face face = (Face) source; + + face.attach_many(map_source_geometry.keys); + foreach (Gee.Map.Entry<MediaSource, string> entry in map_source_geometry.entries) + FaceLocation.create(face.get_face_id(), ((Photo) entry.key).get_photo_id(), entry.value); + } + + private void on_source_destroyed(DataSource source) { + if (map_source_geometry.keys.contains((MediaSource) source)) + get_command_manager().reset(); + } +} + +public class RenameFaceCommand : SimpleProxyableCommand { + private string old_name; + private string new_name; + + public RenameFaceCommand(Face face, string new_name) { + base (face, Resources.rename_face_label(face.get_name(), new_name), face.get_name()); + + old_name = face.get_name(); + this.new_name = new_name; + } + + protected override void execute_on_source(DataSource source) { + if (!((Face) source).rename(new_name)) + AppWindow.error_message(Resources.rename_face_exists_message(new_name)); + } + + protected override void undo_on_source(DataSource source) { + if (!((Face) source).rename(old_name)) + AppWindow.error_message(Resources.rename_face_exists_message(old_name)); + } +} + +public class DeleteFaceCommand : SimpleProxyableCommand { + private Gee.Map<PhotoID?, string> photo_geometry_map = new Gee.HashMap<PhotoID?, string> + ((Gee.HashDataFunc)FaceLocation.photo_id_hash, (Gee.EqualDataFunc)FaceLocation.photo_ids_equal); + + public DeleteFaceCommand(Face face) { + base (face, Resources.delete_face_label(face.get_name()), face.get_name()); + + // we can't use the Gee.Map returned by FaceLocation.get_locations_by_face + // because it will be modified in execute_on_source + Gee.Map<PhotoID?, FaceLocation>? temp = FaceLocation.get_locations_by_face(face); + assert(temp != null); + foreach (Gee.Map.Entry<PhotoID?, FaceLocation> entry in temp.entries) + photo_geometry_map.set(entry.key, entry.value.get_serialized_geometry()); + } + + protected override void execute_on_source(DataSource source) { + FaceID face_id = ((Face) source).get_face_id(); + foreach (PhotoID photo_id in photo_geometry_map.keys) + FaceLocation.destroy(face_id, photo_id); + + Face.global.destroy_marked(Face.global.mark(source), false); + } + + protected override void undo_on_source(DataSource source) { + // merely instantiating the Face will rehydrate it ... should always work, because the + // undo stack is cleared if the proxy ever breaks + assert(source is Face); + + foreach (Gee.Map.Entry<PhotoID?, string> entry in photo_geometry_map.entries) { + Photo? photo = LibraryPhoto.global.fetch(entry.key); + + if (photo != null) { + Face face = (Face) source; + + face.attach(photo); + FaceLocation.create(face.get_face_id(), entry.key, entry.value); + } + } + } +} + +public class ModifyFacesCommand : SingleDataSourceCommand { + private MediaSource media; + private Gee.ArrayList<SourceProxy> to_add = new Gee.ArrayList<SourceProxy>(); + private Gee.ArrayList<SourceProxy> to_remove = new Gee.ArrayList<SourceProxy>(); + private Gee.Map<SourceProxy, string> to_update = new Gee.HashMap<SourceProxy, string>(); + private Gee.Map<SourceProxy, string> geometries = new Gee.HashMap<SourceProxy, string>(); + + public ModifyFacesCommand(MediaSource media, Gee.Map<Face, string> new_face_list) { + base (media, Resources.MODIFY_FACES_LABEL, ""); + + this.media = media; + + // Remove any face that's in the original list but not the new one + Gee.Collection<Face>? original_faces = Face.global.fetch_for_source(media); + if (original_faces != null) { + foreach (Face face in original_faces) { + if (!new_face_list.keys.contains(face)) { + SourceProxy proxy = face.get_proxy(); + + to_remove.add(proxy); + proxy.broken.connect(on_proxy_broken); + + FaceLocation? face_location = + FaceLocation.get_face_location(face.get_face_id(), ((Photo) media).get_photo_id()); + assert(face_location != null); + + geometries.set(proxy, face_location.get_serialized_geometry()); + } + } + } + + // Add any face that's in the new list but not the original + foreach (Gee.Map.Entry<Face, string> entry in new_face_list.entries) { + if (original_faces == null || !original_faces.contains(entry.key)) { + SourceProxy proxy = entry.key.get_proxy(); + + to_add.add(proxy); + proxy.broken.connect(on_proxy_broken); + + geometries.set(proxy, entry.value); + } else { + // If it is already in the original list we need to check if it's + // geometry has changed. + FaceLocation? face_location = + FaceLocation.get_face_location(entry.key.get_face_id(), ((Photo) media).get_photo_id()); + assert(face_location != null); + + string old_geometry = face_location.get_serialized_geometry(); + if (old_geometry != entry.value) { + SourceProxy proxy = entry.key.get_proxy(); + + to_update.set(proxy, entry.value); + proxy.broken.connect(on_proxy_broken); + + geometries.set(proxy, old_geometry); + } + } + } + } + + ~ModifyFacesCommand() { + foreach (SourceProxy proxy in to_add) + proxy.broken.disconnect(on_proxy_broken); + + foreach (SourceProxy proxy in to_remove) + proxy.broken.disconnect(on_proxy_broken); + + foreach (SourceProxy proxy in to_update.keys) + proxy.broken.disconnect(on_proxy_broken); + } + + public override void execute() { + foreach (SourceProxy proxy in to_add) { + Face face = (Face) proxy.get_source(); + face.attach(media); + FaceLocation.create(face.get_face_id(), ((Photo) media).get_photo_id(), geometries.get(proxy)); + } + + foreach (SourceProxy proxy in to_remove) + ((Face) proxy.get_source()).detach(media); + + foreach (Gee.Map.Entry<SourceProxy, string> entry in to_update.entries) { + Face face = (Face) entry.key.get_source(); + FaceLocation.create(face.get_face_id(), ((Photo) media).get_photo_id(), entry.value); + } + } + + public override void undo() { + foreach (SourceProxy proxy in to_add) + ((Face) proxy.get_source()).detach(media); + + foreach (SourceProxy proxy in to_remove) { + Face face = (Face) proxy.get_source(); + face.attach(media); + FaceLocation.create(face.get_face_id(), ((Photo) media).get_photo_id(), geometries.get(proxy)); + } + + foreach (SourceProxy proxy in to_update.keys) { + Face face = (Face) proxy.get_source(); + FaceLocation.create(face.get_face_id(), ((Photo) media).get_photo_id(), geometries.get(proxy)); + } + } + + private void on_proxy_broken() { + get_command_manager().reset(); + } +} + +#endif |