f-spot r4289 - in trunk: . src src/Query src/Widgets
- From: sdelcroix svn gnome org
- To: svn-commits-list gnome org
- Subject: f-spot r4289 - in trunk: . src src/Query src/Widgets
- Date: Mon, 25 Aug 2008 12:17:43 +0000 (UTC)
Author: sdelcroix
Date: Mon Aug 25 12:17:42 2008
New Revision: 4289
URL: http://svn.gnome.org/viewvc/f-spot?rev=4289&view=rev
Log:
Merge branch '02'
Added:
trunk/src/Query/IOrderCondition.cs
trunk/src/Query/OrderByTime.cs
Modified:
trunk/ChangeLog
trunk/src/DirectoryAdaptor.cs
trunk/src/GroupAdaptor.cs
trunk/src/MainWindow.cs
trunk/src/Makefile.am
trunk/src/PhotoQuery.cs
trunk/src/PhotoStore.cs
trunk/src/Query/DateRange.cs
trunk/src/SendEmail.cs
trunk/src/TagCommands.cs
trunk/src/TimeAdaptor.cs
trunk/src/Widgets/PreviewPopup.cs
trunk/src/Widgets/TrayView.cs
Modified: trunk/src/DirectoryAdaptor.cs
==============================================================================
--- trunk/src/DirectoryAdaptor.cs (original)
+++ trunk/src/DirectoryAdaptor.cs Mon Aug 25 12:17:42 2008
@@ -109,7 +109,7 @@
public override FSpot.IBrowsableItem PhotoFromIndex (int item)
{
- return query.Items [LookupItem (item)];
+ return query [LookupItem (item)];
}
private int LookupItem (int group)
Modified: trunk/src/GroupAdaptor.cs
==============================================================================
--- trunk/src/GroupAdaptor.cs (original)
+++ trunk/src/GroupAdaptor.cs Mon Aug 25 12:17:42 2008
@@ -45,20 +45,19 @@
protected void HandleQueryChanged (IBrowsableCollection sender)
{
- Log.Debug ("GroupAdaptor::Reloading" );
Reload ();
}
public void Dispose ()
{
- this.query.PreChanged -= HandleQueryChanged;
+ this.query.Changed -= HandleQueryChanged;
}
protected GroupAdaptor (PhotoQuery query, bool order_ascending)
{
this.order_ascending = order_ascending;
this.query = query;
- this.query.PreChanged += HandleQueryChanged;
+ this.query.Changed += HandleQueryChanged;
Reload ();
}
Modified: trunk/src/MainWindow.cs
==============================================================================
--- trunk/src/MainWindow.cs (original)
+++ trunk/src/MainWindow.cs Mon Aug 25 12:17:42 2008
@@ -546,7 +546,7 @@
get {
int active = ActiveIndex ();
if (active >= 0)
- return query.Photos [active];
+ return query [active] as Photo;
else
return null;
}
@@ -866,7 +866,7 @@
int i = 0;
foreach (int num in selected_ids)
- photo_list [i ++] = query.Photos [num];
+ photo_list [i ++] = query [num] as Photo;
return photo_list;
}
@@ -876,6 +876,7 @@
return SelectedPhotos (SelectedIds ());
}
+ [Obsolete ("MARKED FOR REMOVAL")]
public Photo [] ActivePhotos ()
{
return query.Photos;
@@ -930,7 +931,7 @@
public void AddTagExtended (int [] nums, Tag [] tags)
{
foreach (int num in nums)
- query.Photos [num].AddTag (tags);
+ (query[num] as Photo).AddTag (tags);
query.Commit (nums);
foreach (Tag t in tags) {
@@ -939,7 +940,7 @@
// FIXME this needs a lot more work.
Pixbuf icon = null;
try {
- Pixbuf tmp = FSpot.PhotoLoader.LoadAtMaxSize (query.Items [nums[0]], 128, 128);
+ Pixbuf tmp = FSpot.PhotoLoader.LoadAtMaxSize (query [nums[0]], 128, 128);
icon = PixbufUtils.TagIconFromPixbuf (tmp);
tmp.Dispose ();
} catch {
@@ -954,7 +955,7 @@
public void RemoveTags (int [] nums, Tag [] tags)
{
foreach (int num in nums)
- query.Photos [num].RemoveTag (tags);
+ (query[num] as Photo).RemoveTag (tags);
query.Commit (nums);
}
@@ -1150,7 +1151,7 @@
FSpot.TimeAdaptor time_adaptor = group_selector.Adaptor as FSpot.TimeAdaptor;
if (time_adaptor != null)
- JumpTo (time_adaptor.LookupItem (time));
+ JumpTo (query.LookupItem (time));
}
private void JumpTo (int index)
@@ -1189,7 +1190,7 @@
if (cell_num == -1 /*|| cell_num == lastTopLeftCell*/)
return;
- FSpot.IBrowsableItem photo = icon_view.Collection.Items [cell_num];
+ FSpot.IBrowsableItem photo = icon_view.Collection [cell_num];
#if false
group_selector.Adaptor.GlassSet -= HandleAdaptorGlassSet;
group_selector.Adaptor.SetGlass (group_selector.Adaptor.IndexFromPhoto (photo));
@@ -1586,7 +1587,7 @@
db.BeginTransaction ();
int [] selected_photos = SelectedIds ();
foreach (int num in selected_photos) {
- p = query.Photos [num];
+ p = query [num] as Photo;
p.Rating = (uint) r;
}
query.Commit (selected_photos);
@@ -1872,7 +1873,7 @@
return;
group_selector.Adaptor.OrderAscending = item.Active;
- query.RequestReload ();
+ query.TimeOrderAsc = item.Active;
// FIXME this is blah...we need UIManager love here
if (item != reverse_order)
@@ -2256,12 +2257,14 @@
clear_date_range.Sensitive = (query.Range != null);
clear_rating_filter.Sensitive = (query.RatingRange != null);
- UpdateStatusLabel ();
+ update_status_label = true;
+ GLib.Idle.Add (UpdateStatusLabel);
}
- private void UpdateStatusLabel ()
+ bool update_status_label;
+ private bool UpdateStatusLabel ()
{
- //uint timer = Log.DebugTimerStart ();
+ update_status_label = false;
int total_photos = Database.Photos.TotalPhotos;
if (total_photos != query.Count)
status_label.Text = String.Format (Catalog.GetPluralString ("{0} Photo out of {1}", "{0} Photos out of {1}", query.Count), query.Count, total_photos);
@@ -2271,7 +2274,7 @@
if ((selection != null) && (selection.Count > 0))
status_label.Text += String.Format (Catalog.GetPluralString (" ({0} selected)", " ({0} selected)", selection.Count), selection.Count);
status_label.UseMarkup = true;
- //Log.DebugTimerPrint (timer, "UpdateStatusLabel took {0}");
+ return update_status_label;
}
void HandleZoomChanged (object sender, System.EventArgs args)
@@ -2402,9 +2405,9 @@
MessageType.Warning,
header, msg, ok_caption)) {
+ uint timer = Log.DebugTimerStart ();
foreach (Photo photo in photos) {
foreach (uint id in photo.VersionIds) {
- Console.WriteLine (" path == {0}", photo.VersionUri (id).LocalPath);
try {
photo.DeleteVersion (id, true);
} catch (Exception e) {
@@ -2415,6 +2418,7 @@
db.Photos.Remove (photos);
UpdateQuery ();
+ Log.DebugTimerPrint (timer, "HandleDeleteCommand took {0}");
}
}
@@ -2489,7 +2493,7 @@
Db db = MainWindow.Toplevel.Database;
FSpot.PhotoQuery count_query = new FSpot.PhotoQuery(db.Photos);
count_query.Terms = FSpot.OrTerm.FromTags(tags);
- int associated_photos = count_query.Photos.Length;
+ int associated_photos = count_query.Count;
string header;
if (tags.Length == 1)
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Mon Aug 25 12:17:42 2008
@@ -37,8 +37,10 @@
QUERY_CSDISTFILES = \
$(srcdir)/Query/DateRange.cs \
+ $(srcdir)/Query/IOrderCondition.cs \
$(srcdir)/Query/IQueryCondition.cs \
$(srcdir)/Query/LogicalTerm.cs \
+ $(srcdir)/Query/OrderByTime.cs \
$(srcdir)/Query/RatingRange.cs \
$(srcdir)/Query/RollSet.cs \
$(srcdir)/Query/UntaggedCondition.cs
Modified: trunk/src/PhotoQuery.cs
==============================================================================
--- trunk/src/PhotoQuery.cs (original)
+++ trunk/src/PhotoQuery.cs Mon Aug 25 12:17:42 2008
@@ -12,17 +12,70 @@
using System.Collections;
using System.Collections.Generic;
using FSpot.Query;
+using FSpot.Utils;
namespace FSpot {
public class PhotoQuery : FSpot.IBrowsableCollection {
- private Photo [] photos;
+ class PhotoCache
+ {
+ static int SIZE = 100;
+ public int Size {
+ get { return SIZE; }
+ }
+
+ Dictionary <int, Photo []> cache;
+ string temp_table;
+ PhotoStore store;
+
+ public PhotoCache (PhotoStore store, string temp_table)
+ {
+ this.temp_table = temp_table;
+ this.store = store;
+ cache = new Dictionary<int, Photo[]> ();
+ }
+
+ public bool TryGetPhoto (int index, out Photo photo)
+ {
+ photo = null;
+ Photo [] val;
+ int offset = index - index % SIZE;
+ if (!cache.TryGetValue (offset, out val))
+ return false;
+ photo = val [index - offset];
+ return true;
+ }
+
+ public Photo Get (int index)
+ {
+ Photo [] val;
+ int offset = index - index % SIZE;
+ if (!cache.TryGetValue (offset, out val)) {
+ val = store.QueryFromTemp (temp_table, offset, SIZE);
+ cache [offset] = val;
+ }
+ return val [index - offset];
+ }
+ }
+
+ PhotoCache cache;
private PhotoStore store;
private Term terms;
private Tag [] tags;
private string extra_condition;
+
+ static int query_count = 0;
+ static int QueryCount {
+ get {return query_count ++;}
+ }
+
+ Dictionary<uint, int> reverse_lookup;
+
+ int count = -1;
+ string temp_table = String.Format ("photoquery_temp_{0}", QueryCount);
+
// Constructor
- public PhotoQuery (PhotoStore store)
+ public PhotoQuery (PhotoStore store, params IQueryCondition [] conditions)
{
this.store = store;
// Note: this is to let the query pick up
@@ -30,12 +83,22 @@
this.store.ItemsAddedOverDBus += delegate { RequestReload(); };
this.store.ItemsRemovedOverDBus += delegate { RequestReload(); };
this.store.ItemsChanged += MarkChanged;
+ cache = new PhotoCache (store, temp_table);
+ reverse_lookup = new Dictionary<uint, int> ();
+ SetCondition (OrderByTime.OrderByTimeDesc);
+
+ foreach (IQueryCondition condition in conditions)
+ SetCondition (condition);
- photos = store.Query ((Tag [])null, null, Range, RollSet, RatingRange);
+ store.QueryToTemp (temp_table, (Tag [])null, null, Range, RollSet, RatingRange, OrderByTime);
}
public int Count {
- get { return photos.Length;}
+ get {
+ if (count < 0)
+ count = store.Count (temp_table);
+ return count;
+ }
}
public bool Contains (IBrowsableItem item) {
@@ -44,26 +107,26 @@
// IPhotoCollection Interface
public event FSpot.IBrowsableCollectionChangedHandler Changed;
- public event FSpot.IBrowsableCollectionChangedHandler PreChanged;
public event FSpot.IBrowsableCollectionItemsChangedHandler ItemsChanged;
public IBrowsableItem this [int index] {
- get { return photos [index]; }
+ get { return cache.Get (index); }
}
+ [Obsolete ("DO NOT USE THIS, IT'S TOO SLOW")]
public Photo [] Photos {
- get { return photos; }
+ get { return store.QueryFromTemp (temp_table); }
}
+ [Obsolete ("DO NOT USE Items on PhotoQuery")]
public IBrowsableItem [] Items {
- get { return (IBrowsableItem [])photos; }
+ get { throw new NotImplementedException (); }
}
-
+
public PhotoStore Store {
get { return store; }
}
-
//Query Conditions
private Dictionary<Type, IQueryCondition> conditions;
private Dictionary<Type, IQueryCondition> Conditions {
@@ -84,11 +147,11 @@
return true;
}
- internal IQueryCondition GetCondition<T> ()
+ internal T GetCondition<T> () where T : IQueryCondition
{
- if (Conditions.ContainsKey (typeof (T)))
- return Conditions [typeof (T)];
- return null;
+ IQueryCondition val;
+ Conditions.TryGetValue (typeof (T), out val);
+ return (T)val;
}
internal bool UnSetCondition<T> ()
@@ -129,7 +192,7 @@
}
public DateRange Range {
- get { return GetCondition<DateRange> () as DateRange; }
+ get { return GetCondition<DateRange> (); }
set {
if (value == null && UnSetCondition<DateRange> () || value != null && SetCondition (value))
RequestReload ();
@@ -150,7 +213,7 @@
}
public RollSet RollSet {
- get { return GetCondition<RollSet> () as RollSet; }
+ get { return GetCondition<RollSet> (); }
set {
if (value == null && UnSetCondition<RollSet> () || value != null && SetCondition (value))
RequestReload ();
@@ -158,33 +221,107 @@
}
public RatingRange RatingRange {
- get { return GetCondition<RatingRange> () as RatingRange; }
+ get { return GetCondition<RatingRange> (); }
set {
if (value == null && UnSetCondition<RatingRange>() || value != null && SetCondition (value))
RequestReload ();
}
}
+ public OrderByTime OrderByTime {
+ get { return GetCondition<OrderByTime> (); }
+ set {
+ if (value != null && SetCondition (value))
+ RequestReload ();
+ }
+ }
+
+ public bool TimeOrderAsc {
+ get { return OrderByTime.Asc; }
+ set {
+ if (value != OrderByTime.Asc)
+ OrderByTime = new OrderByTime (value);
+ }
+ }
+
public void RequestReload ()
{
+ uint timer = Log.DebugTimerStart ();
if (untagged)
- photos = store.Query (new UntaggedCondition (), Range, RollSet, RatingRange);
+ store.QueryToTemp (temp_table, new UntaggedCondition (), Range, RollSet, RatingRange, OrderByTime);
else
- photos = store.Query (terms, extra_condition, Range, RollSet, RatingRange);
+ store.QueryToTemp (temp_table, terms, extra_condition, Range, RollSet, RatingRange, OrderByTime);
- //this event will allow resorting the query content
- if (PreChanged != null)
- PreChanged (this);
+ count = -1;
+ cache = new PhotoCache (store, temp_table);
+ reverse_lookup = new Dictionary<uint,int> ();
if (Changed != null)
Changed (this);
+ Log.DebugTimerPrint (timer, "Reloading the query took {0}");
}
public int IndexOf (IBrowsableItem photo)
{
- return System.Array.IndexOf (photos, photo);
+ if (photo == null || !(photo is Photo))
+ return -1;
+ return store.IndexOf (temp_table, photo as Photo);
+ }
+
+ private int [] IndicesOf (DbItem [] dbitems)
+ {
+ uint timer = Log.DebugTimerStart ();
+ List<int> indices = new List<int> ();
+ List<uint> items_to_search = new List<uint> ();
+ int cur;
+ foreach (DbItem dbitem in dbitems) {
+ if (reverse_lookup.TryGetValue (dbitem.Id, out cur))
+ indices.Add (cur);
+ else
+ items_to_search.Add (dbitem.Id);
+ }
+
+ if (items_to_search.Count > 0)
+ indices.AddRange (store.IndicesOf (temp_table, items_to_search.ToArray ()));
+ Log.DebugTimerPrint (timer, "IndicesOf took {0}");
+ return indices.ToArray ();
+ }
+
+ public int LookupItem (System.DateTime date)
+ {
+ return LookupItem (date, TimeOrderAsc);
+ }
+
+ private int LookupItem (System.DateTime date, bool asc)
+ {
+ uint timer = Log.DebugTimerStart ();
+ int low = 0;
+ int high = Count - 1;
+ int mid = (low + high) / 2;
+ Photo current;
+ while (low <= high) {
+ mid = (low + high) / 2;
+ if (!cache.TryGetPhoto (mid, out current))
+ //the item we're looking for is not in the cache
+ //a binary search could take up to ln2 (N/cache.SIZE) request
+ //lets reduce that number to 1
+ return store.IndexOf (temp_table, date, asc);
+
+ int comp = this [mid].Time.CompareTo (date);
+ if (!asc && comp < 0 || asc && comp > 0)
+ high = mid - 1;
+ else if (!asc && comp > 0 || asc && comp < 0)
+ low = mid + 1;
+ else
+ return mid;
+ }
+ Log.DebugTimerPrint (timer, "LookupItem took {0}");
+ if (asc)
+ return this[mid].Time < date ? mid + 1 : mid;
+ return this[mid].Time > date ? mid + 1 : mid;
+
}
-
+
public void Commit (int index)
{
Commit (new int [] {index});
@@ -193,25 +330,21 @@
public void Commit (int [] indexes)
{
List<Photo> to_commit = new List<Photo>();
- foreach (int index in indexes)
- to_commit.Add (photos [index]);
+ foreach (int index in indexes) {
+ to_commit.Add (this [index] as Photo);
+ reverse_lookup [(this [index] as Photo).Id] = index;
+ }
store.Commit (to_commit.ToArray ());
}
private void MarkChanged (object sender, DbItemEventArgs args)
{
- List<int> indexes = new List<int>();
- foreach (DbItem item in args.Items) {
- Photo photo = item as Photo;
- int index = IndexOf (photo);
-
- // Ignore photos that are not in the query
- if (index > -1)
- indexes.Add (index);
- }
+ int [] indexes = IndicesOf (args.Items);
+
+ PhotoEventArgs photo_args = args as PhotoEventArgs;
- if (indexes.Count > 0 && ItemsChanged != null)
- ItemsChanged (this, new BrowsableEventArgs(indexes.ToArray (), (args as PhotoEventArgs).Changes));
+ if (indexes.Length > 0 && ItemsChanged != null)
+ ItemsChanged (this, new BrowsableEventArgs(indexes, (args as PhotoEventArgs).Changes));
}
public void MarkChanged (int index, IBrowsableItemChanges changes)
Modified: trunk/src/PhotoStore.cs
==============================================================================
--- trunk/src/PhotoStore.cs (original)
+++ trunk/src/PhotoStore.cs Mon Aug 25 12:17:42 2008
@@ -529,6 +529,123 @@
ItemsRemovedOverDBus (this, new DbItemEventArgs (photos));
}
+ public int Count (string table_name, params IQueryCondition [] conditions)
+ {
+ StringBuilder query_builder = new StringBuilder ("SELECT COUNT(*) FROM " + table_name + " ");
+ bool where_added = false;
+ foreach (IQueryCondition condition in conditions) {
+ if (condition == null)
+ continue;
+ if (condition is IOrderCondition)
+ continue;
+ query_builder.Append (where_added ? " AND " : " WHERE ");
+ query_builder.Append (condition.SqlClause ());
+ where_added = true;
+ }
+
+ SqliteDataReader reader = Database.Query (query_builder.ToString());
+ reader.Read ();
+ int count = Convert.ToInt32 (reader [0]);
+ reader.Close();
+ return count;
+ }
+
+ public int [] IndicesOf (string table_name, uint [] items)
+ {
+ StringBuilder query_builder = new StringBuilder ("SELECT ROWID FROM ");
+ query_builder.Append (table_name);
+ query_builder.Append (" WHERE \"photos.id\" IN (");
+ for (int i = 0; i < items.Length; i++) {
+ query_builder.Append (items [i]);
+ query_builder.Append ((i != items.Length - 1) ? ", " : ")" );
+ }
+ return IndicesOf (query_builder.ToString ());
+ }
+
+ public int IndexOf (string table_name, Photo photo)
+ {
+ string query = String.Format ("SELECT ROWID FROM {0} WHERE \"photos.id\" = {1}", table_name, photo.Id);
+ return IndexOf (query);
+ }
+
+ public int IndexOf (string table_name, DateTime time, bool asc)
+ {
+ string query = String.Format ("SELECT ROWID FROM {0} WHERE \"photos.time\" {2} {1} ORDER BY \"photos.time\" {3} LIMIT 1",
+ table_name,
+ DbUtils.UnixTimeFromDateTime (time),
+ asc ? ">=" : "<=",
+ asc ? "ASC" : "DESC");
+ return IndexOf (query);
+ }
+
+ private int IndexOf (string query)
+ {
+ uint timer = Log.DebugTimerStart ();
+ SqliteDataReader reader = Database.Query (query);
+ int index = - 1;
+ if (reader.Read ())
+ index = Convert.ToInt32 (reader [0]);
+ reader.Close();
+ Log.DebugTimerPrint (timer, "IndexOf took {0} : " + query);
+ return index - 1; //ROWID starts counting at 1
+ }
+
+ private int [] IndicesOf (string query)
+ {
+ uint timer = Log.DebugTimerStart ();
+ List<int> list = new List<int> ();
+ SqliteDataReader reader = Database.Query (query);
+ while (reader.Read ())
+ list.Add (Convert.ToInt32 (reader [0]) - 1);
+ Log.DebugTimerPrint (timer, "IndicesOf took {0} : " + query);
+ return list.ToArray ();
+ }
+
+ public Dictionary<int,int[]> PhotosPerMonth (params IQueryCondition [] conditions)
+ {
+ uint timer = Log.DebugTimerStart ();
+ Dictionary<int, int[]> val = new Dictionary<int, int[]> ();
+
+ //Sqlite is way more efficient querying to a temp then grouping than grouping at once
+ Database.ExecuteNonQuery ("DROP TABLE IF EXISTS POPULATION");
+ StringBuilder query_builder = new StringBuilder ("CREATE TEMP TABLE population AS SELECT strftime('%Y%m', datetime(time, 'unixepoch')) AS month FROM photos");
+ bool where_added = false;
+ foreach (IQueryCondition condition in conditions) {
+ if (condition == null)
+ continue;
+ if (condition is IOrderCondition)
+ continue;
+ query_builder.Append (where_added ? " AND " : " WHERE ");
+ query_builder.Append (condition.SqlClause ());
+ where_added = true;
+ }
+ Database.ExecuteNonQuery (query_builder.ToString ());
+
+ int minyear = Int32.MaxValue;
+ int maxyear = Int32.MinValue;
+
+ SqliteDataReader reader = Database.Query ("SELECT COUNT (*), month from population GROUP BY month");
+ while (reader.Read ()) {
+ string yyyymm = reader [1].ToString ();
+ int count = Convert.ToInt32 (reader [0]);
+ int year = Convert.ToInt32 (yyyymm.Substring (0,4));
+ maxyear = Math.Max (year, maxyear);
+ minyear = Math.Min (year, minyear);
+ int month = Convert.ToInt32 (yyyymm.Substring (4));
+ if (!val.ContainsKey (year))
+ val.Add (year, new int[12]);
+ val[year][month-1] = count;
+ }
+ reader.Close ();
+
+ //Fill the blank
+ for (int i = minyear; i <= maxyear; i++)
+ if (!val.ContainsKey (i))
+ val.Add (i, new int[12]);
+
+ Log.DebugTimerPrint (timer, "PhotosPerMonth took {0}");
+ return val;
+ }
// Queries.
[Obsolete ("drop this, use IQueryCondition correctly instead")]
@@ -541,16 +658,78 @@
StringBuilder query_builder = new StringBuilder ("SELECT * FROM photos ");
bool where_added = false;
- foreach (IQueryCondition condition in conditions)
- if (condition != null) {
- query_builder.Append (where_added ? " AND " : " WHERE ");
- query_builder.Append (condition.SqlClause ());
- where_added = true;
- }
- query_builder.Append(" ORDER BY time ");
+ foreach (IQueryCondition condition in conditions) {
+ if (condition == null)
+ continue;
+ if (condition is IOrderCondition)
+ continue;
+ query_builder.Append (where_added ? " AND " : " WHERE ");
+ query_builder.Append (condition.SqlClause ());
+ where_added = true;
+ }
+
+ bool order_added = false;
+ foreach (IQueryCondition condition in conditions) {
+ if (condition == null)
+ continue;
+ if (!(condition is IOrderCondition))
+ continue;
+ query_builder.Append (order_added ? " , " : "ORDER BY ");
+ query_builder.Append (condition.SqlClause ());
+ order_added = true;
+ }
return Query (query_builder.ToString ());
}
+ public void QueryToTemp (string temp_table, params IQueryCondition [] conditions)
+ {
+ StringBuilder query_builder = new StringBuilder ("SELECT * FROM photos ");
+
+ bool where_added = false;
+ foreach (IQueryCondition condition in conditions) {
+ if (condition == null)
+ continue;
+ if (condition is IOrderCondition)
+ continue;
+ query_builder.Append (where_added ? " AND " : " WHERE ");
+ query_builder.Append (condition.SqlClause ());
+ where_added = true;
+ }
+
+ bool order_added = false;
+ foreach (IQueryCondition condition in conditions) {
+ if (condition == null)
+ continue;
+ if (!(condition is IOrderCondition))
+ continue;
+ query_builder.Append (order_added ? " , " : "ORDER BY ");
+ query_builder.Append (condition.SqlClause ());
+ order_added = true;
+ }
+ QueryToTemp (temp_table, query_builder.ToString ());
+ }
+
+ public void QueryToTemp(string temp_table, string query)
+ {
+ uint timer = Log.DebugTimerStart ();
+ Database.BeginTransaction ();
+ Database.ExecuteNonQuery (String.Format ("DROP TABLE IF EXISTS {0}", temp_table));
+ //Database.ExecuteNonQuery (String.Format ("CREATE TEMPORARY TABLE {0} AS {1}", temp_table, query));
+ Database.Query (String.Format ("CREATE TEMPORARY TABLE {0} AS {1}", temp_table, query)).Close ();
+ Database.CommitTransaction ();
+ Log.DebugTimerPrint (timer, "QueryToTemp took {0} : " + query);
+ }
+
+ public Photo [] QueryFromTemp (string temp_table)
+ {
+ return QueryFromTemp (temp_table, 0, -1);
+ }
+
+ public Photo [] QueryFromTemp (string temp_table, int offset, int limit)
+ {
+ return Query (String.Format ("SELECT * FROM {0} LIMIT {1} OFFSET {2}", temp_table, limit, offset));
+ }
+
public Photo [] Query (string query)
{
return Query (new DbCommand (query));
@@ -558,7 +737,7 @@
public Photo [] Query (DbCommand query)
{
- uint timer = Log.DebugTimerStart ("Query: " + query.CommandText);
+ uint timer = Log.DebugTimerStart ();
SqliteDataReader reader = Database.Query(query);
List<Photo> new_photos = new List<Photo> ();
@@ -604,7 +783,7 @@
foreach (Photo photo in new_photos)
photo.Changes = null;
- Log.DebugTimerPrint (timer, "Query took {0}");
+ Log.DebugTimerPrint (timer, "Query took {0} : " + query.CommandText);
return query_result.ToArray ();
}
@@ -650,12 +829,88 @@
}
[Obsolete ("drop this, use IQueryCondition correctly instead")]
+ public void QueryToTemp (string temp_table, Tag [] tags, string extra_condition, DateRange range, RollSet importidrange, RatingRange ratingrange, OrderByTime orderbytime)
+ {
+ QueryToTemp (temp_table, FSpot.OrTerm.FromTags(tags), extra_condition, range, importidrange, ratingrange, orderbytime);
+ }
+
+ [Obsolete ("drop this, use IQueryCondition correctly instead")]
public Photo [] Query (Tag [] tags, string extra_condition, DateRange range, RollSet importidrange, RatingRange ratingrange)
{
return Query (FSpot.OrTerm.FromTags(tags), extra_condition, range, importidrange, ratingrange);
}
[Obsolete ("drop this, use IQueryCondition correctly instead")]
+ public void QueryToTemp (string temp_table, Term searchexpression, string extra_condition, DateRange range, RollSet importidrange, RatingRange ratingrange, OrderByTime orderbytime)
+ {
+ bool hide = (extra_condition == null);
+
+ // The SQL query that we want to construct is:
+ //
+ // SELECT photos.id
+ // photos.time
+ // photos.uri,
+ // photos.description,
+ // photos.roll_id,
+ // photos.default_version_id
+ // photos.rating
+ // FROM photos, photo_tags
+ // WHERE photos.time >= time1 AND photos.time <= time2
+ // AND photos.rating >= rat1 AND photos.rating <= rat2
+ // AND photos.id NOT IN (select photo_id FROM photo_tags WHERE tag_id = HIDDEN)
+ // AND photos.id IN (select photo_id FROM photo_tags where tag_id IN (tag1, tag2..)
+ // AND extra_condition_string
+ // GROUP BY photos.id
+
+ StringBuilder query_builder = new StringBuilder ();
+ ArrayList where_clauses = new ArrayList ();
+ query_builder.Append ("SELECT photos.id, " +
+ "photos.time, " +
+ "photos.uri, " +
+ "photos.description, " +
+ "photos.roll_id, " +
+ "photos.default_version_id, " +
+ "photos.rating " +
+ "FROM photos ");
+
+ if (range != null) {
+ where_clauses.Add (String.Format ("photos.time >= {0} AND photos.time <= {1}",
+ DbUtils.UnixTimeFromDateTime (range.Start),
+ DbUtils.UnixTimeFromDateTime (range.End)));
+
+ }
+
+ if (ratingrange != null) {
+ where_clauses.Add (ratingrange.SqlClause ());
+ }
+
+ if (importidrange != null) {
+ where_clauses.Add (importidrange.SqlClause ());
+ }
+
+ if (hide && Core.Database.Tags.Hidden != null) {
+ where_clauses.Add (String.Format ("photos.id NOT IN (SELECT photo_id FROM photo_tags WHERE tag_id = {0})",
+ FSpot.Core.Database.Tags.Hidden.Id));
+ }
+
+ if (searchexpression != null) {
+ where_clauses.Add (searchexpression.SqlCondition ());
+ }
+
+ if (extra_condition != null && extra_condition.Trim () != String.Empty) {
+ where_clauses.Add (extra_condition);
+ }
+
+ if (where_clauses.Count > 0) {
+ query_builder.Append (" WHERE ");
+ query_builder.Append (String.Join (" AND ", ((String []) where_clauses.ToArray (typeof(String)))));
+ }
+ query_builder.Append (" ORDER BY ");
+ query_builder.Append (orderbytime.SqlClause ());
+ QueryToTemp (temp_table, query_builder.ToString ());
+ }
+
+ [Obsolete ("drop this, use IQueryCondition correctly instead")]
public Photo [] Query (Term searchexpression, string extra_condition, DateRange range, RollSet importidrange, RatingRange ratingrange)
{
bool hide = (extra_condition == null);
Modified: trunk/src/Query/DateRange.cs
==============================================================================
--- trunk/src/Query/DateRange.cs (original)
+++ trunk/src/Query/DateRange.cs Mon Aug 25 12:17:42 2008
@@ -30,6 +30,12 @@
this.end = end;
}
+ public DateRange (int year, int month)
+ {
+ start = new DateTime (year, month, 1);
+ end = new DateTime (month < 12 ? year : year + 1, month < 12 ? month + 1 : 1, 1);
+ }
+
public string SqlClause ()
{
return String.Format (" photos.time >= {0} AND photos.time <= {1} ",
Added: trunk/src/Query/IOrderCondition.cs
==============================================================================
--- (empty file)
+++ trunk/src/Query/IOrderCondition.cs Mon Aug 25 12:17:42 2008
@@ -0,0 +1,16 @@
+/*
+ * IOrderCondition.cs
+ *
+ * Author(s)
+ * Stephane Delcroix <stephane delcroix org>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+namespace FSpot.Query
+{
+ public interface IOrderCondition
+ {
+ string SqlClause ();
+ }
+}
Added: trunk/src/Query/OrderByTime.cs
==============================================================================
--- (empty file)
+++ trunk/src/Query/OrderByTime.cs Mon Aug 25 12:17:42 2008
@@ -0,0 +1,35 @@
+/*
+ * FSpot.Query.OrderByTime.cs
+ *
+ * Author(s):
+ * Stephane Delcroix <stephane delcroix org>
+ *
+ * This is free software. See COPYING for details.
+ *
+ */
+
+using System;
+using FSpot.Utils;
+
+namespace FSpot.Query {
+ public class OrderByTime : IQueryCondition, IOrderCondition
+ {
+ public static OrderByTime OrderByTimeAsc = new OrderByTime (true);
+ public static OrderByTime OrderByTimeDesc = new OrderByTime (false);
+
+ bool asc;
+ public bool Asc {
+ get { return asc; }
+ }
+
+ public OrderByTime (bool asc)
+ {
+ this.asc = asc;
+ }
+
+ public string SqlClause ()
+ {
+ return String.Format (" time {0}", asc ? "ASC" : "DESC");
+ }
+ }
+}
Modified: trunk/src/SendEmail.cs
==============================================================================
--- trunk/src/SendEmail.cs (original)
+++ trunk/src/SendEmail.cs Mon Aug 25 12:17:42 2008
@@ -56,9 +56,11 @@
{
this.selection = selection;
- foreach (Photo p in selection.Items)
+ for (int i = 0; i < selection.Count; i++) {
+ Photo p = selection[i] as Photo;
if (Gnome.Vfs.MimeType.GetMimeTypeForUri (p.DefaultVersionUri.ToString ()) != "image/jpeg")
force_original = true;
+ }
if (force_original) {
original_size.Active = true;
@@ -86,7 +88,8 @@
Dialog.Modal = false;
// Calculate total original filesize
- foreach (Photo photo in selection.Items) {
+ for (int i = 0; i < selection.Count; i++) {
+ Photo photo = selection[i] as Photo;
try {
Orig_Photo_Size += (new Gnome.Vfs.FileInfo (photo.DefaultVersionUri.ToString ())).Size;
} catch {
@@ -98,7 +101,7 @@
// Calculate approximate size shrinking, use first photo, and shrink to medium size as base.
- Photo scalephoto = selection.Items [0] as Photo;
+ Photo scalephoto = selection [0] as Photo;
if (scalephoto != null && !force_original) {
// Get first photos file size
@@ -236,7 +239,7 @@
progress_dialog = new ProgressDialog (Catalog.GetString ("Preparing email"),
ProgressDialog.CancelButtonType.Stop,
- selection.Items.Length,
+ selection.Count,
parent_window);
size = GetScaleSize(); // Which size should we scale to. 0 --> Original
@@ -280,8 +283,8 @@
filters.Add (new UniqueNameFilter (tmp_mail_dir));
- foreach (Photo photo in selection.Items) {
-
+ for (int i = 0; i < selection.Count; i++) {
+ Photo photo = selection [i] as Photo;
if ( (photo != null) && (!UserCancelled) ) {
if (progress_dialog != null)
Modified: trunk/src/TagCommands.cs
==============================================================================
--- trunk/src/TagCommands.cs (original)
+++ trunk/src/TagCommands.cs Mon Aug 25 12:17:42 2008
@@ -482,10 +482,10 @@
photo_scrolled_window.Add (image_view);
- if (query.Photos.Length > 0) {
+ if (query.Count > 0) {
photo_spin_button.Wrap = true;
photo_spin_button.Adjustment.Lower = 1.0;
- photo_spin_button.Adjustment.Upper = (double)query.Photos.Length;
+ photo_spin_button.Adjustment.Upper = (double) query.Count;
photo_spin_button.Adjustment.StepIncrement = 1.0;
photo_spin_button.ValueChanged += HandleSpinButtonChanged;
Modified: trunk/src/TimeAdaptor.cs
==============================================================================
--- trunk/src/TimeAdaptor.cs (original)
+++ trunk/src/TimeAdaptor.cs Mon Aug 25 12:17:42 2008
@@ -1,56 +1,34 @@
+/*
+ * FSpot.TimeAdaptor.cs
+ *
+ * Author(s):
+ * Larry Ewing <lewing novell com>
+ * Stephane Delcroix <stephnae delcroix org>
+ *
+ * This is free software. See COPYING for details.
+ */
+
using System;
-using System.Collections;
+using System.Threading;
+using System.Collections.Generic;
using FSpot.Query;
using FSpot.Utils;
namespace FSpot {
public class TimeAdaptor : GroupAdaptor, FSpot.ILimitable {
- ArrayList years = new ArrayList ();
- struct YearData {
- public int Year;
- public int [] Months;
- }
+ Dictionary <int, int[]> years = new Dictionary<int, int[]> ();
public override event GlassSetHandler GlassSet;
public override void SetGlass (int min)
{
DateTime date = DateFromIndex (min);
-
- if (GlassSet != null)
- GlassSet (this, LookupItem (date));
- }
-
- public int LookupItem (System.DateTime date)
- {
- if (order_ascending)
- return LookUpItemAscending (date);
-
- return LookUpItemDescending (date);
- }
- private int LookUpItemAscending (System.DateTime date)
- {
- int i = 0;
-
- while (i < query.Count && query [i].Time < date)
- i++;
-
- return i;
+ if (GlassSet != null)
+ GlassSet (this, query.LookupItem (date));
}
- private int LookUpItemDescending (System.DateTime date)
- {
- int i = 0;
-
- while (i < query.Count && query [i].Time > date)
- i++;
-
- return i;
- }
-
public void SetLimits (int min, int max)
{
- //Console.WriteLine ("min {0} max {1}", min, max);
DateTime start = DateFromIndex (min);
DateTime end = DateFromIndex(max);
@@ -65,11 +43,7 @@
public void SetLimits (DateTime start, DateTime end)
{
- //Console.WriteLine ("{0} {1}", start, end);
- if (start > end)
- query.Range = new DateRange (end, start);
- else
- query.Range = new DateRange (start, end);
+ query.Range = (start > end) ? new DateRange (end, start) : new DateRange (start, end);
}
public override int Count ()
@@ -79,9 +53,7 @@
public override string GlassLabel (int item)
{
- DateTime start = DateFromIndex (item);
-
- return String.Format ("{0} ({1})", start.ToString ("MMMM yyyy"), Value (item));
+ return String.Format ("{0} ({1})", DateFromIndex (item).ToString ("MMMM yyyy"), Value (item));
}
public override string TickLabel (int item)
@@ -96,9 +68,10 @@
public override int Value (int item)
{
- YearData data = (YearData)years [item/12];
-
- return data.Months [item % 12];
+ if (order_ascending)
+ return years [startyear + item/12][item % 12];
+ else
+ return years [endyear - item/12][11 - item % 12];
}
public DateTime DateFromIndex (int item)
@@ -114,7 +87,7 @@
private DateTime DateFromIndexAscending (int item)
{
- int year = (int)((YearData)years [item / 12]).Year;
+ int year = startyear + item/12;
int month = 1 + (item % 12);
return new DateTime(year, month, 1);
@@ -122,7 +95,7 @@
private DateTime DateFromIndexDescending (int item)
{
- int year = (int)((YearData)years [item / 12]).Year;
+ int year = endyear - item/12;
int month = 12 - (item % 12);
return new DateTime (year, month, DateTime.DaysInMonth (year, month)).AddDays (1.0).AddMilliseconds (-.1);
@@ -147,96 +120,67 @@
private int IndexFromDateAscending(DateTime date)
{
int year = date.Year;
- int max_year = ((YearData)years [years.Count - 1]).Year;
- int min_year = ((YearData)years [0]).Year;
+ int min_year = startyear;
+ int max_year = endyear;
if (year < min_year || year > max_year) {
- Console.WriteLine("TimeAdaptor.IndexFromDate year out of range[{1},{2}]: {0}", year, min_year, max_year);
+ Log.DebugFormat ("TimeAdaptor.IndexFromDate year out of range[{1},{2}]: {0}", year, min_year, max_year);
return 0;
}
- int index = date.Month - 1;
-
- for (int i = 0 ; i < years.Count; i++)
- if (year > ((YearData)years[i]).Year)
- index += 12;
-
- return index;
+ return (year - startyear) * 12 + date.Month - 1 ;
}
private int IndexFromDateDescending(DateTime date)
{
int year = date.Year;
- int max_year = ((YearData)years [0]).Year;
- int min_year = ((YearData)years [years.Count - 1]).Year;
+ int min_year = startyear;
+ int max_year = endyear;
if (year < min_year || year > max_year) {
- Console.WriteLine("TimeAdaptor.IndexFromPhoto year out of range[{1},{2}]: {0}", year, min_year, max_year);
+ Log.DebugFormat ("TimeAdaptor.IndexFromPhoto year out of range[{1},{2}]: {0}", year, min_year, max_year);
return 0;
}
- int index = 12 - date.Month;
-
- for (int i = 0; i < years.Count; i++)
- if (year < ((YearData)years[i]).Year)
- index += 12;
-
- return index;
+ return 12 * (endyear - year) + 12 - date.Month;
}
public override FSpot.IBrowsableItem PhotoFromIndex (int item)
{
DateTime start = DateFromIndex (item);
- return query.Items [LookupItem (start)];
+ return query [query.LookupItem (start)];
}
public override event ChangedHandler Changed;
+ uint timer;
protected override void Reload ()
{
- years.Clear ();
-
- Photo [] photos = query.Store.Query ((Tag [])null, null, null, null, null);
-
- Array.Sort (query.Photos);
- Array.Sort (photos);
-
- if (!order_ascending) {
- Array.Reverse (query.Photos);
- Array.Reverse (photos);
- }
+ timer = Log.DebugTimerStart ();
+ Thread reload = new Thread (new ThreadStart (DoReload));
+ reload.IsBackground = true;
+ reload.Priority = ThreadPriority.Lowest;
+ reload.Start ();
+ }
- if (photos.Length > 0) {
- YearData data = new YearData ();
- data.Year = 0;
-
- foreach (Photo photo in photos) {
- int current = photo.Time.Year;
- if (current != data.Year) {
-
- data.Year = current;
- data.Months = new int [12];
- years.Add (data);
- //Console.WriteLine ("Found Year {0}", current);
- }
- if (order_ascending)
- data.Months [photo.Time.Month - 1] += 1;
- else
- data.Months [12 - photo.Time.Month] += 1;
- }
- } else {
- YearData data = new YearData ();
- data.Year = DateTime.Now.Year;
- data.Months = new int [12];
- years.Add (data);
+ int startyear = Int32.MaxValue, endyear = Int32.MinValue;
+ void DoReload ()
+ {
+ Thread.Sleep (200);
+ years = query.Store.PhotosPerMonth ();
+ foreach (int year in years.Keys) {
+ startyear = Math.Min (year,startyear);
+ endyear = Math.Max (year,endyear);
}
-
if (Changed != null)
- Changed (this);
+ Gtk.Application.Invoke(delegate {
+ if (Changed != null)
+ Changed (this);
+ });
+ Log.DebugTimerPrint (timer, "TimeAdaptor REAL Reload took {0}");
}
-
public TimeAdaptor (PhotoQuery query, bool order_ascending)
: base (query, order_ascending)
{ }
Modified: trunk/src/Widgets/PreviewPopup.cs
==============================================================================
--- trunk/src/Widgets/PreviewPopup.cs (original)
+++ trunk/src/Widgets/PreviewPopup.cs Mon Aug 25 12:17:42 2008
@@ -113,7 +113,7 @@
private void UpdateImage ()
{
- FSpot.IBrowsableItem item = view.Collection.Items [Item];
+ FSpot.IBrowsableItem item = view.Collection [Item];
string orig_path = item.DefaultVersionUri.LocalPath;
Modified: trunk/src/Widgets/TrayView.cs
==============================================================================
--- trunk/src/Widgets/TrayView.cs (original)
+++ trunk/src/Widgets/TrayView.cs Mon Aug 25 12:17:42 2008
@@ -38,7 +38,7 @@
cell_width = System.Math.Min (256, available_width / cells_per_row);
width = cell_width - 2 * cell_border_width;
cell_height = (int)(width / ThumbnailRatio) + 2 * cell_border_width;
- total_rows = (int) System.Math.Ceiling (collection.Items.Length / (double)cells_per_row);
+ total_rows = (int) System.Math.Ceiling (collection.Count / (double)cells_per_row);
cells_per_row ++;
} while (total_rows > Allocation.Height / cell_height);
cells_per_row --;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]