[f-spot/rubenv-gsoc-2009: 66/86] Add proper image deletion.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/rubenv-gsoc-2009: 66/86] Add proper image deletion.
- Date: Sun, 23 May 2010 12:37:30 +0000 (UTC)
commit 8bfece78c4f64cadbddc3e47a4d7faf968d9e93a
Author: Ruben Vermeersch <ruben savanne be>
Date: Tue Aug 11 23:27:23 2009 +0200
Add proper image deletion.
extensions/Tools/RawPlusJpeg/RawPlusJpeg.cs | 4 +-
src/Core/Photo.cs | 133 ++++++++++++++++++++-------
src/Core/PhotoChanges.cs | 26 +++++
src/Db.cs | 1 +
src/Jobs/CleanHiddenVersionsJob.cs | 31 ++++++
src/MainWindow.cs | 13 +++-
src/Makefile.am | 1 +
src/PhotoImageView.cs | 2 +-
src/PhotoStore.cs | 52 +++++++++--
src/PhotoVersionCommands.cs | 5 +-
10 files changed, 222 insertions(+), 46 deletions(-)
---
diff --git a/extensions/Tools/RawPlusJpeg/RawPlusJpeg.cs b/extensions/Tools/RawPlusJpeg/RawPlusJpeg.cs
index 7673e00..4461d7f 100644
--- a/extensions/Tools/RawPlusJpeg/RawPlusJpeg.cs
+++ b/extensions/Tools/RawPlusJpeg/RawPlusJpeg.cs
@@ -96,7 +96,7 @@ namespace RawPlusJpegExtension
foreach (uint version_id in jpeg.VersionIds) {
string name = jpeg.GetVersion (version_id).Name;
try {
- raw.DefaultVersionId = raw.CreateReparentedVersion (jpeg.GetVersion (version_id) as PhotoVersion, version_id == Photo.OriginalVersionId);
+ raw.DefaultVersionId = raw.CreateReparentedVersion (jpeg.GetVersion (version_id));
if (version_id == Photo.OriginalVersionId)
raw.RenameVersion (raw.DefaultVersionId, "Jpeg");
else
@@ -110,7 +110,7 @@ namespace RawPlusJpegExtension
Array.Reverse (version_ids);
foreach (uint version_id in version_ids) {
try {
- jpeg.DeleteVersion (version_id, true, true);
+ jpeg.DeleteVersion (version_id, true);
} catch (Exception e) {
Console.WriteLine (e);
}
diff --git a/src/Core/Photo.cs b/src/Core/Photo.cs
index 125d1f2..f0345f3 100644
--- a/src/Core/Photo.cs
+++ b/src/Core/Photo.cs
@@ -18,6 +18,7 @@ using System.Collections.Generic;
using Mono.Unix;
using FSpot.Utils;
+using FSpot.Jobs;
using FSpot.Imaging;
using FSpot.Platform;
@@ -131,7 +132,26 @@ namespace FSpot
// Version management
public const int OriginalVersionId = 1;
- private uint highest_version_id;
+
+ public uint HighestVersionId {
+ get {
+ uint highest = 0;
+ foreach (uint key in HiddenVersions.Keys)
+ highest = Math.Max (highest, key);
+ foreach (uint key in Versions.Keys)
+ highest = Math.Max (highest, key);
+ return highest;
+ }
+ }
+
+ private Dictionary<uint, PhotoVersion> hidden_versions;
+ private Dictionary<uint, PhotoVersion> HiddenVersions {
+ get {
+ if (hidden_versions == null)
+ hidden_versions = new Dictionary<uint, PhotoVersion> ();
+ return hidden_versions;
+ }
+ }
private Dictionary<uint, PhotoVersion> versions = new Dictionary<uint, PhotoVersion> ();
public IEnumerable<IBrowsableItemVersion> Versions {
@@ -155,10 +175,18 @@ namespace FSpot
public PhotoVersion GetVersion (uint version_id)
{
- if (versions == null)
- return null;
+ return GetVersion (version_id, false);
+ }
+
+ public PhotoVersion GetVersion (uint version_id, bool include_hidden)
+ {
+ if (versions.ContainsKey (version_id))
+ return versions [version_id];
+
+ if (include_hidden && HiddenVersions.ContainsKey (version_id))
+ return HiddenVersions [version_id];
- return versions [version_id];
+ return null;
}
private uint default_version_id = OriginalVersionId;
@@ -171,6 +199,11 @@ namespace FSpot
changes.DefaultVersionIdChanged = true;
}
}
+
+ internal void AddHiddenVersion (uint version_id, System.Uri uri, string md5_sum, string name, bool is_protected, PhotoVersionType type, uint parent_version_id)
+ {
+ HiddenVersions [version_id] = new PhotoVersion (this, version_id, uri, md5_sum, name, is_protected, type, parent_version_id);
+ }
// This doesn't check if a version of that name already exists,
// it's supposed to be used only within the Photo and PhotoStore classes.
@@ -178,7 +211,6 @@ namespace FSpot
{
versions [version_id] = new PhotoVersion (this, version_id, uri, md5_sum, name, is_protected, type, parent_version_id);
- highest_version_id = Math.Max (version_id, highest_version_id);
changes.AddVersion (version_id);
}
@@ -191,13 +223,13 @@ namespace FSpot
{
if (VersionNameExists (name))
throw new ApplicationException ("A version with that name already exists");
- highest_version_id ++;
+ uint version_id = HighestVersionId + 1;
string md5_sum = GenerateMD5 (uri);
- versions [highest_version_id] = new PhotoVersion (this, highest_version_id, uri, md5_sum, name, is_protected, PhotoVersionType.Simple, 0);
+ versions [version_id] = new PhotoVersion (this, version_id, uri, md5_sum, name, is_protected, PhotoVersionType.Simple, 0);
- changes.AddVersion (highest_version_id);
- return highest_version_id;
+ changes.AddVersion (version_id);
+ return version_id;
}
//FIXME: store versions next to originals. will crash on ro locations.
@@ -280,22 +312,37 @@ namespace FSpot
return version;
}
+ uint clean_hidden_versions_timeout = 0;
+
public void DeleteVersion (uint version_id)
{
- DeleteVersion (version_id, false, false);
+ DeleteVersion (version_id, false);
}
-
+
public void DeleteVersion (uint version_id, bool remove_original)
{
- DeleteVersion (version_id, remove_original, false);
- }
-
- public void DeleteVersion (uint version_id, bool remove_original, bool keep_file)
- {
if (version_id == OriginalVersionId && !remove_original)
throw new Exception ("Cannot delete original version");
- System.Uri uri = VersionUri (version_id);
+ changes.HideVersion (version_id);
+ Versions.Remove (version_id);
+ ResetDefaultVersion (version_id);
+
+ if (clean_hidden_versions_timeout == 0) {
+ clean_hidden_versions_timeout = GLib.Timeout.Add (5000, delegate () {
+ clean_hidden_versions_timeout = 0;
+
+ Core.Database.Jobs.Create (typeof (CleanHiddenVersionsJob), "");
+ return true;
+ });
+ }
+ }
+
+ // Deletes a version without checking for refs. Use with care!
+ public void FullyDeleteVersion (uint version_id, bool keep_file)
+ {
+ PhotoVersion version = GetVersion (version_id, true) as PhotoVersion;
+ System.Uri uri = version.Uri;
if (!keep_file) {
GLib.File file = GLib.FileFactory.NewForUri (uri);
@@ -312,10 +359,27 @@ namespace FSpot
//ignore an error here we don't really care.
}
}
- versions.Remove (version_id);
- changes.RemoveVersion (version_id);
+ if (versions.ContainsKey (version_id)) {
+ versions.Remove (version_id);
+ changes.RemoveVersion (version_id);
+ } else if (HiddenVersions.ContainsKey (version_id)) {
+ HiddenVersions.Remove (version_id);
+ }
+
+ ResetDefaultVersion (version_id);
+ }
+
+ public void DeleteHiddenVersions ()
+ {
+ foreach (uint version_id in HiddenVersions.Keys)
+ {
+ FullyDeleteVersion (version_id, false);
+ }
+ }
+ void ResetDefaultVersion (uint version_id)
+ {
do {
version_id --;
if (versions.ContainsKey (version_id)) {
@@ -356,22 +420,18 @@ namespace FSpot
FSpot.ThumbnailGenerator.Create (new_uri).Dispose ();
}
- highest_version_id ++;
- versions [highest_version_id] = new PhotoVersion (this, highest_version_id, new_uri, md5_sum, name, is_protected, PhotoVersionType.Simple, 0);
+ uint version_id = HighestVersionId + 1;
+
+ versions [version_id] = new PhotoVersion (this, version_id, new_uri, md5_sum, name, is_protected, PhotoVersionType.Simple, 0);
- changes.AddVersion (highest_version_id);
+ changes.AddVersion (version_id);
- return highest_version_id;
+ return version_id;
}
public uint CreateReparentedVersion (PhotoVersion version)
{
- return CreateReparentedVersion (version, false);
- }
-
- public uint CreateReparentedVersion (PhotoVersion version, bool is_protected)
- {
int num = 0;
while (true) {
num++;
@@ -381,12 +441,21 @@ namespace FSpot
if (VersionNameExists (name))
continue;
- highest_version_id ++;
- versions [highest_version_id] = new PhotoVersion (this, highest_version_id, version.Uri, version.MD5Sum, name, is_protected, PhotoVersionType.Simple, 0);
+ Uri uri = GetUriForVersionName (name, System.IO.Path.GetExtension (version.Uri.AbsolutePath));
+ uint version_id = HighestVersionId + 1;
+ bool is_protected = version_id == OriginalVersionId;
+ versions [version_id] = new PhotoVersion (this, version_id, uri, version.MD5Sum, name, is_protected, PhotoVersionType.Simple, 0);
+
+ changes.AddVersion (version_id);
+
+ Uri source_uri = version.Uri;
+ Uri dest_uri = VersionUri (version_id);
- changes.AddVersion (highest_version_id);
+ GLib.File source = GLib.FileFactory.NewForUri (source_uri);
+ GLib.File dest = GLib.FileFactory.NewForUri (dest_uri);
+ source.Copy (dest, GLib.FileCopyFlags.None, null, null);
- return highest_version_id;
+ return version_id;
}
}
diff --git a/src/Core/PhotoChanges.cs b/src/Core/PhotoChanges.cs
index 708fe49..07e2dd1 100644
--- a/src/Core/PhotoChanges.cs
+++ b/src/Core/PhotoChanges.cs
@@ -146,9 +146,35 @@ namespace FSpot
return;
if (versions_removed != null && versions_removed.Contains (v))
return;
+ if (versions_hidden != null && versions_hidden.Contains (v))
+ return;
versions_modified.Add (v);
}
+ List<uint> versions_hidden = null;
+ public uint [] VersionsHidden {
+ get {
+ if (versions_hidden == null)
+ return null;
+ if (versions_hidden.Count == 0)
+ return null;
+ return versions_hidden.ToArray ();
+ }
+ set {
+ foreach (uint u in value)
+ HideVersion (u);
+ }
+ }
+
+ public void HideVersion (uint v)
+ {
+ if (versions_hidden == null)
+ versions_hidden = new List<uint> ();
+ if (versions_modified != null)
+ versions_modified.Remove (v);
+ versions_hidden.Add (v);
+ }
+
public PhotoChanges ()
{
}
diff --git a/src/Db.cs b/src/Db.cs
index 3ddb09b..fd7b211 100644
--- a/src/Db.cs
+++ b/src/Db.cs
@@ -248,6 +248,7 @@ public class Db : IDisposable {
void HandleDbException (Exception e)
{
+ Log.Debug ("DatabaseException: {0}", e.ToString ());
if (ExceptionThrown != null)
ExceptionThrown (e);
else
diff --git a/src/Jobs/CleanHiddenVersionsJob.cs b/src/Jobs/CleanHiddenVersionsJob.cs
new file mode 100644
index 0000000..f594765
--- /dev/null
+++ b/src/Jobs/CleanHiddenVersionsJob.cs
@@ -0,0 +1,31 @@
+//
+// Fspot.Jobs.CleanHiddenVersionsJob.cs
+//
+// Author(s)
+// Ruben Vermeersch <ruben savanne be>
+//
+// This is free software. See COPYING for details
+//
+
+using Banshee.Kernel;
+using FSpot.Utils;
+using System;
+
+namespace FSpot.Jobs {
+ public class CleanHiddenVersionsJob : Job
+ {
+ public CleanHiddenVersionsJob (uint id, string job_options, int run_at, JobPriority job_priority, bool persistent) : this (id, job_options, DbUtils.DateTimeFromUnixTime (run_at), job_priority, persistent)
+ {
+ }
+
+ public CleanHiddenVersionsJob (uint id, string job_options, DateTime run_at, JobPriority job_priority, bool persistent) : base (id, job_options, job_priority, run_at, persistent)
+ {
+ }
+
+ protected override bool Execute ()
+ {
+ Core.Database.Photos.CleanHiddenVersions ();
+ return true;
+ }
+ }
+}
diff --git a/src/MainWindow.cs b/src/MainWindow.cs
index 3e30e8b..abe1a87 100644
--- a/src/MainWindow.cs
+++ b/src/MainWindow.cs
@@ -2204,12 +2204,13 @@ namespace FSpot
foreach (Photo photo in photos) {
foreach (uint id in photo.VersionIds) {
try {
- photo.DeleteVersion (id, true);
+ photo.FullyDeleteVersion (id, false);
} catch (Exception e) {
DeleteException (e, photo.VersionUri (id).ToString ());
}
}
}
+ photo.DeleteHiddenVersions ();
Database.Photos.Remove (photos);
UpdateQuery ();
@@ -2238,6 +2239,16 @@ namespace FSpot
string ok_caption = Catalog.GetString("_Remove from Catalog");
if (ResponseType.Ok == HigMessageDialog.RunHigConfirmation(GetToplevel (sender), DialogFlags.DestroyWithParent,
MessageType.Warning, header, msg, ok_caption)) {
+ foreach (Photo photo in photos) {
+ foreach (uint id in photo.VersionIds) {
+ try {
+ photo.FullyDeleteVersion (id, true);
+ } catch (Exception e) {
+ DeleteException (e, photo.VersionUri (id).ToString ());
+ }
+ }
+ photo.DeleteHiddenVersions ();
+ }
Database.Photos.Remove (photos);
UpdateQuery ();
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 9f3dbcb..35d6e09 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -244,6 +244,7 @@ F_SPOT_CSDISTFILES = \
$(srcdir)/JobStore.cs \
$(srcdir)/Jobs/SyncMetadataJob.cs \
$(srcdir)/Jobs/CalculateHashJob.cs \
+ $(srcdir)/Jobs/CleanHiddenVersionsJob.cs \
$(srcdir)/Loupe.cs \
$(srcdir)/MainWindow.cs \
$(srcdir)/MemorySurface.cs \
diff --git a/src/PhotoImageView.cs b/src/PhotoImageView.cs
index ade9fe7..fb0dae9 100644
--- a/src/PhotoImageView.cs
+++ b/src/PhotoImageView.cs
@@ -156,7 +156,7 @@ namespace FSpot.Widgets {
if (Loader != null) {
Loader.AreaUpdated -= HandlePixbufAreaUpdated;
Loader.AreaPrepared -= HandlePixbufPrepared;
- Loader.Dispose ();
+ DisposeLoader (Loader);
}
base.OnDestroyed ();
}
diff --git a/src/PhotoStore.cs b/src/PhotoStore.cs
index 345249f..ff89ed3 100644
--- a/src/PhotoStore.cs
+++ b/src/PhotoStore.cs
@@ -190,7 +190,11 @@ public class PhotoStore : DbStore<Photo> {
PhotoVersionType type = (PhotoVersionType) Enum.ToObject (typeof (PhotoVersionType), reader["type"]);
uint parent_version_id = Convert.ToUInt32 (reader ["parent_version_id"]);
- photo.AddVersionUnsafely (version_id, uri, md5_sum, name, is_protected, type, parent_version_id);
+ if (type == PhotoVersionType.Hidden) {
+ photo.AddHiddenVersion (version_id, uri, md5_sum, name, is_protected, type, parent_version_id);
+ } else {
+ photo.AddVersionUnsafely (version_id, uri, md5_sum, name, is_protected, type, parent_version_id);
+ }
}
reader.Close();
}
@@ -233,7 +237,11 @@ public class PhotoStore : DbStore<Photo> {
PhotoVersionType type = (PhotoVersionType) Enum.ToObject (typeof (PhotoVersionType), reader["type"]);
uint parent_version_id = Convert.ToUInt32 (reader ["parent_version_id"]);
- photo.AddVersionUnsafely (version_id, uri, md5_sum, name, is_protected, type, parent_version_id);
+ if (type == PhotoVersionType.Hidden) {
+ photo.AddHiddenVersion (version_id, uri, md5_sum, name, is_protected, type, parent_version_id);
+ } else {
+ photo.AddVersionUnsafely (version_id, uri, md5_sum, name, is_protected, type, parent_version_id);
+ }
}
/*
@@ -246,14 +254,33 @@ public class PhotoStore : DbStore<Photo> {
reader.Close();
}
+ public void CleanHiddenVersions ()
+ {
+ bool deleted;
+ do {
+ deleted = false;
+ SqliteDataReader reader = Database.Query(new DbCommand ("SELECT photo_id, version_id FROM photo_versions WHERE type = :type", "type", (uint) PhotoVersionType.Hidden));
+
+ while (reader.Read ()) {
+ uint photo_id = Convert.ToUInt32 (reader ["photo_id"]);
+ uint version_id = Convert.ToUInt32 (reader ["version_id"]);
+
+ Photo photo = Get (photo_id);
+ PhotoVersion version = photo.GetVersion (version_id, true);
+
+ if (VersionRefCount (version) == 0) {
+ photo.FullyDeleteVersion (version_id, false);
+ Database.ExecuteNonQuery (new DbCommand ("DELETE FROM photo_versions WHERE photo_id = :photo_id AND version_id = :version_id", "photo_id", photo_id, "version_id", version_id));
+ deleted = true;
+ }
+ }
+ } while (deleted);
+ }
+
public uint VersionRefCount (PhotoVersion version)
{
- SqliteDataReader reader = Database.Query (
- new DbCommand ("SELECT COUNT (*) as ref_count FROM photo_versions WHERE parent_version_id = :version_id AND photo_id = :photo_id",
- "version_id", version.VersionId,
- "photo_id", version.Photo));
- uint ref_count = Convert.ToUInt32 (reader ["ref_count"]);
- reader.Close ();
+ string query = String.Format ("SELECT COUNT(*) AS ref_count FROM photo_versions WHERE photo_id = {0} AND parent_version_id = {1}", version.Photo.Id, version.VersionId);
+ uint ref_count = Convert.ToUInt32 (Database.QuerySingle (query));
return ref_count;
}
@@ -562,6 +589,15 @@ public class PhotoStore : DbStore<Photo> {
"photo_id", photo.Id,
"version_id", version_id));
}
+ if (changes.VersionsHidden != null)
+ foreach (uint version_id in changes.VersionsHidden) {
+ Database.ExecuteNonQuery (new DbCommand (
+ "UPDATE photo_versions SET type = :type " +
+ "WHERE photo_id = :photo_id AND version_id = :version_id",
+ "type", (uint) PhotoVersionType.Hidden,
+ "photo_id", photo.Id,
+ "version_id", version_id));
+ }
photo.Changes = null;
return changes;
}
diff --git a/src/PhotoVersionCommands.cs b/src/PhotoVersionCommands.cs
index ef1d27f..ddd26d1 100644
--- a/src/PhotoVersionCommands.cs
+++ b/src/PhotoVersionCommands.cs
@@ -218,7 +218,8 @@ public class PhotoVersionCommands
new_parent.AddTag (photo.Tags);
foreach (uint version_id in photo.VersionIds) {
try {
- new_parent.DefaultVersionId = new_parent.CreateReparentedVersion (photo.GetVersion (version_id) as PhotoVersion);
+ uint new_version = new_parent.CreateReparentedVersion (photo.GetVersion (version_id) as PhotoVersion);
+ new_parent.DefaultVersionId = new_version;
store.Commit (new_parent);
} catch (Exception e) {
Log.DebugException (e);
@@ -228,7 +229,7 @@ public class PhotoVersionCommands
Array.Reverse (version_ids);
foreach (uint version_id in version_ids) {
try {
- photo.DeleteVersion (version_id, true, true);
+ photo.DeleteVersion (version_id, true);
} catch (Exception e) {
Log.DebugException (e);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]