ANDing categories together
- From: Laurence Hygate <loz flower powernet co uk>
- To: F-Spot list <f-spot-list gnome org>
- Subject: ANDing categories together
- Date: Wed, 20 Oct 2004 20:43:24 +0100
This patch makes categories work the way I intuitively expected. Of
course I'm a geek, so using my opinion for this sort of thing is
dangerous.
* You can select/deselect all tags and categories independently
* Only photos which have all tags are displayed
* A photo is considered to "have" a tag if it is tagged with it or any
of its children
The implementation is a bit sucky, but gets the concept across.
--
Loz
? Makefile.solution.f-spot
? configure.scan
? f-spot.cmbx
? f-spot.mdsx
? make.sh
? po/Makefile
? po/Makefile.in
? po/Makefile.in.in
? po/POTFILES
? po/es.gmo
? src/AssemblyInfo.cs
? src/Main.cs
? src/Makefile.f-spot
? src/MyProgram.cs
? src/f-spot.pidb
? src/f-spot.prjx
Index: src/PhotoStore.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/PhotoStore.cs,v
retrieving revision 1.40
diff -u -r1.40 PhotoStore.cs
--- src/PhotoStore.cs 24 Aug 2004 15:56:04 -0000 1.40
+++ src/PhotoStore.cs 20 Oct 2004 19:36:42 -0000
@@ -967,7 +967,9 @@
public Photo [] Query (Tag [] tags, DateRange range)
{
+ const string AND = " AND ";
string query;
+ string sep = " WHERE ";
bool hide = true;
if (tags != null) {
@@ -1005,38 +1007,44 @@
query_builder.Append (String.Format ("WHERE photos.time >= {0} AND photos.time < {1} ",
DbUtils.UnixTimeFromDateTime (range.Start),
DbUtils.UnixTimeFromDateTime (range.End)));
+ sep = AND;
}
if (hide) {
query_builder.Append (String.Format ("{0} photos.id NOT IN (SELECT photo_id FROM photo_tags WHERE tag_id = {1})",
- range != null ? " AND " : " WHERE ", tag_store.Hidden.Id));
+ sep, tag_store.Hidden.Id));
+ sep = AND;
}
if (tags != null && tags.Length > 0) {
- bool first = true;
foreach (Tag t in tags) {
if (t.Id == tag_store.Hidden.Id)
continue;
-
- if (first) {
- query_builder.Append (String.Format ("{0} photos.id IN (SELECT photo_id FROM photo_tags WHERE tag_id IN (",
- hide || range != null ? " AND " : " WHERE "));
+
+ //Optimizations
+ //1. if t is root then we can ignore
+ //2. maintain table of tag_id, tag_id which is the relation (is_or_is_child_of) and join against that rather than the big in statement
+ bool first = true;
+ foreach (Tag tag in t.MeAndAncestors) {
+ if (first) {
+ query_builder.Append (sep);
+ query_builder.Append(" photos.id IN (SELECT photo_id FROM photo_tags WHERE tag_id IN (");
+ sep = AND;
+ }
+ query_builder.Append (String.Format ("{0}{1} ", first ? "" : ", ", tag.Id));
+ first = false;
}
-
- query_builder.Append (String.Format ("{0}{1} ", first ? "" : ", ", t.Id));
-
- first = false;
+ if (!first)
+ query_builder.Append(")) ");
}
- if (!first)
- query_builder.Append (")) ");
}
query_builder.Append ("ORDER BY photos.time");
query = query_builder.ToString ();
Console.WriteLine ("Query Start {0}", System.DateTime.Now.ToLongTimeString ());
-
+ // Console.WriteLine(query);
SqliteCommand command = new SqliteCommand ();
command.Connection = Connection;
command.CommandText = query;
@@ -1091,7 +1099,7 @@
return id_list.ToArray (typeof (Photo)) as Photo [];
}
-
+
#if TEST_PHOTO_STORE
static void Dump (Photo photo)
{
Index: src/TagSelectionWidget.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/TagSelectionWidget.cs,v
retrieving revision 1.11
diff -u -r1.11 TagSelectionWidget.cs
--- src/TagSelectionWidget.cs 17 Jun 2004 04:05:57 -0000 1.11
+++ src/TagSelectionWidget.cs 20 Oct 2004 19:36:43 -0000
@@ -67,8 +67,8 @@
return false;
else if (selection.ContainsKey (tag.Id))
return true;
- else if (tag.Category != tag_store.RootCategory && IsSelected (tag.Category))
- return true;
+ //else if (tag.Category != tag_store.RootCategory && IsSelected (tag.Category))
+ // return true;
else
return false;
}
@@ -169,6 +169,13 @@
uint tag_id = (uint) value;
Tag tag = tag_store.Get (tag_id) as Tag;
+ // Tags stand alone now
+ if (IsSelected (tag))
+ Unselect (tag);
+ else
+ Select (tag);
+ (Model as TreeStore).EmitRowChanged (path, iter);
+ /*
// Tags under an unselected category are always conceptually unselected.
// They appear as selected just in virtue of being children of a selected category.
if (! IsSelected (tag.Category)) {
@@ -183,7 +190,7 @@
if (tag is Category)
UnselectTagsForCategory (tag as Category);
}
-
+ */
if (SelectionChanged != null)
SelectionChanged (this);
}
Index: src/TagStore.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/TagStore.cs,v
retrieving revision 1.13
diff -u -r1.13 TagStore.cs
--- src/TagStore.cs 18 Aug 2004 00:23:35 -0000 1.13
+++ src/TagStore.cs 20 Oct 2004 19:36:43 -0000
@@ -135,6 +135,20 @@
return Category.CompareTo (tag.Category);
}
}
+
+ public Tag[] MeAndAncestors { //is there a word for that?
+ get {
+ // can be improved we are creating a lot of array lists by recursing this way
+ // should pass an accumulator around instead
+ ArrayList ancestors = new ArrayList();
+ ancestors.Add(this);
+ if (this is Category)
+ foreach (Tag tag in (this as Category).Children)
+ ancestors.AddRange(tag.MeAndAncestors);
+ return (Tag []) ancestors.ToArray (typeof (Tag));
+ }
+ }
+
}
@@ -153,7 +167,7 @@
children_need_sort = true;
}
}
-
+
public void AddChild (Tag child)
{
children.Add (child);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]