Re: Patch to remember state of tree when editing tags
- From: Laurence Hygate <loz flower powernet co uk>
- To: f-spot-list gnome org
- Subject: Re: Patch to remember state of tree when editing tags
- Date: Sun, 17 Oct 2004 21:27:17 +0100
This diff adds sorting. This code made me feel dirty. Surely I'm missing
something?
On Sun, 2004-10-17 at 20:20 +0100, Laurence Hygate wrote:
> Hmm, I need to figure out how to maintain the sort order too.
>
> Loz
>
> On Sun, 2004-10-17 at 18:16 +0100, Laurence Hygate wrote:
> > This is getting complex enough that there is a case for a separate
> > TreeModel implementation. The API for trees seems pretty grim to me.
> >
> > cheers
> >
> > Loz
> >
> > _______________________________________________
> > F-spot-list mailing list
> > F-spot-list gnome org
> > http://mail.gnome.org/mailman/listinfo/f-spot-list
--
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/Makefile.solution.f-spot
? src/MyProgram.cs
? src/TagTreeModel.cs
? src/f-spot.cmbx
? src/f-spot.mdsx
? src/f-spot.pidb
? src/f-spot.prjx
? src/make.sh
Index: src/MainWindow.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/MainWindow.cs,v
retrieving revision 1.102
diff -u -r1.102 MainWindow.cs
--- src/MainWindow.cs 13 Oct 2004 06:01:55 -0000 1.102
+++ src/MainWindow.cs 17 Oct 2004 20:21:14 -0000
@@ -877,15 +877,13 @@
public void HandleCreateNewTagCommand (object sender, EventArgs args)
{
TagCommands.Create command = new TagCommands.Create (db.Tags, main_window);
- if (command.Execute (TagCommands.TagType.Tag))
- tag_selection_widget.Update ();
+ command.Execute (TagCommands.TagType.Tag);
}
public void HandleCreateNewCategoryCommand (object sender, EventArgs args)
{
TagCommands.Create command = new TagCommands.Create (db.Tags, main_window);
- if (command.Execute (TagCommands.TagType.Category))
- tag_selection_widget.Update ();
+ command.Execute (TagCommands.TagType.Category);
}
public void HandleAttachTagCommand (object obj, EventArgs args)
@@ -919,8 +917,7 @@
return;
TagCommands.Edit command = new TagCommands.Edit (db, main_window);
- if (command.Execute (tags [0]))
- tag_selection_widget.Update ();
+ command.Execute (tags [0]);
}
void HandleViewSmall (object sender, EventArgs args)
@@ -1112,7 +1109,6 @@
Tag [] tags = this.tag_selection_widget.TagHighlight ();
db.Photos.Remove (tags);
- tag_selection_widget.Update ();
icon_view.QueueDraw ();
}
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 17 Oct 2004 20:21:15 -0000
@@ -254,7 +254,121 @@
(renderer as CellRendererText).Text = tag.Name;
}
-
+ // Someone show me how I should have done this?
+ // Or is the API as diseased as I have made it look?
+ private bool TreeIterForTag(Tag tag, out TreeIter iter) {
+ TreeIter root;
+ bool valid = Model.GetIterFirst(out root);
+ while (valid) {
+ if (TreeIterForTagRecurse(tag, root, out iter))
+ return true;
+ valid = Model.IterNext (ref root);
+ }
+ return false;
+ }
+
+ // Depth first traversal
+ private bool TreeIterForTagRecurse(Tag tag, TreeIter parent, out TreeIter iter) {
+ bool valid = Model.IterChildren(out iter, parent);
+ while (valid) {
+ if (TreeIterForTagRecurse(tag, iter, out iter))
+ return true;
+ valid = Model.IterNext (ref iter);
+ }
+ GLib.Value value = new GLib.Value();
+ Model.GetValue(parent, 0, ref value);
+ iter = parent;
+ if (tag.Id == (uint) value)
+ return true;
+ return false;
+ }
+
+ // Copy a branch of the tree to a new parent
+ // (note, this doesn't work generically as it only copies the first value of each node)
+ private void CopyBranch(TreeIter src, TreeIter dest, bool is_root, bool is_parent) {
+ TreeIter copy, iter;
+ GLib.Value value = new GLib.Value();
+ TreeStore store = Model as TreeStore;
+ bool valid;
+
+ store.GetValue(src, 0, ref value);
+ if (is_parent) {
+ Tag tag = (Tag)tag_store.Get((uint)value);
+ // we need to figure out where to insert it in the correct order
+ copy = InsertInOrder(dest, is_root, tag);
+ } else {
+ copy = store.AppendValues(dest, (uint)value);
+ }
+
+ valid = Model.IterChildren(out iter, src);
+ while (valid) {
+ // child nodes are already ordered
+ CopyBranch(iter, copy, false, false);
+ valid = Model.IterNext (ref iter);
+ }
+ }
+
+ // insert tag into the correct place in the tree, with parent. return the new TagIter in iter.
+ private TreeIter InsertInOrder(TreeIter parent, bool is_root, Tag tag) {
+ TreeIter iter;
+ TreeStore store = Model as TreeStore;
+ Tag compare;
+ bool valid;
+ if (is_root)
+ valid = store.GetIterFirst(out iter);
+ else
+ valid = store.IterChildren(out iter, parent);
+
+ while (valid) {
+ //I have no desire to figure out a more performant sort over this...
+ GLib.Value value = new GLib.Value();
+ store.GetValue(iter, 0, ref value);
+ compare = (Tag)tag_store.Get((uint)value);
+ if (compare.CompareTo(tag) > 0) {
+ store.InsertBefore(out iter, iter);
+ store.SetValue(iter, 0, tag.Id);
+ return iter;
+ }
+ valid = store.IterNext(ref iter);
+ }
+ if (is_root)
+ store.Append(out iter);
+ else
+ iter = store.Append(parent);
+ store.SetValue(iter, 0, tag.Id);
+ return iter;
+ }
+
+ private void HandleTagDeleted(Tag tag) {
+ TreeIter iter;
+ if (TreeIterForTag(tag, out iter))
+ (Model as TreeStore).Remove(ref iter);
+ }
+
+ private void HandleTagCreated(Tag tag) {
+ TreeIter iter;
+ if (TreeIterForTag(tag.Category, out iter)) {
+ // create dialog doesn't let you create a top level tag...
+ InsertInOrder(iter, false, tag);
+ }
+ }
+
+ private void HandleTagChanged(Tag tag) {
+ TreeStore store = Model as TreeStore;
+ TreeIter iter, category_iter, parent_iter;
+ TreeIterForTag(tag, out iter);
+ bool category_valid = TreeIterForTag(tag.Category, out category_iter);
+ bool parent_valid = Model.IterParent(out parent_iter, iter);
+ if ((category_valid && (category_iter.Equals(parent_iter))) || (!category_valid && !parent_valid)) {
+ // if we haven't been reparented
+ TreePath path = store.GetPath(iter);
+ store.EmitRowChanged(path, iter);
+ } else {
+ // It is a bit tougher. We need to do an annoying clone of structs...
+ CopyBranch(iter, category_iter, !category_valid, true);
+ store.Remove(ref iter);
+ }
+ }
// Constructor.
public TagSelectionWidget (TagStore tag_store)
@@ -275,6 +389,9 @@
Update ();
ExpandAll ();
+ tag_store.TagDeleted += new TagDeletedHandler(HandleTagDeleted);
+ tag_store.TagCreated += new TagCreatedHandler(HandleTagCreated);
+ tag_store.TagChanged += new TagChangedHandler(HandleTagChanged);
}
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 17 Oct 2004 20:21:15 -0000
@@ -173,9 +173,16 @@
}
}
+public delegate void TagCreatedHandler(Tag t);
+public delegate void TagChangedHandler(Tag t);
+public delegate void TagDeletedHandler(Tag t);
public class TagStore : DbStore {
+ public event TagCreatedHandler TagCreated;
+ public event TagChangedHandler TagChanged;
+ public event TagDeletedHandler TagDeleted;
+
Category root_category;
public Category RootCategory {
get {
@@ -365,7 +372,7 @@
Tag tag = new Tag (category, id, name);
AddToCache (tag);
-
+ TagCreated(tag);
return tag;
}
@@ -378,7 +385,7 @@
Category new_category = new Category (parent_category, id, name);
AddToCache (new_category);
-
+ TagCreated(new_category);
return new_category;
}
@@ -411,6 +418,7 @@
command.ExecuteNonQuery ();
command.Dispose ();
+ TagDeleted((Tag)item);
}
@@ -448,6 +456,8 @@
command.ExecuteNonQuery ();
command.Dispose ();
+
+ TagChanged(tag);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]