[f-spot] Update/split out Term.cs into Term.cs and Literal.cs



commit 01a92340bdda23bca320d4d07410d58d4169d500
Author: Stephen Shaw <sshaw decriptor com>
Date:   Wed Nov 23 21:31:54 2011 -0700

    Update/split out Term.cs into Term.cs and Literal.cs
    
    I converted some properties to auto properties
    Convert ArrayList to List< >
    Rearrange code

 F-Spot.sln                                  |    2 +-
 src/Clients/MainApp/FSpot/Literal.cs        |  584 ++++++++++++++++++++
 src/Clients/MainApp/FSpot/TagQueryWidget.cs |    9 +-
 src/Clients/MainApp/FSpot/Term.cs           |  785 +++++----------------------
 src/Clients/MainApp/MainApp.csproj          |    1 +
 src/Clients/MainApp/Makefile.am             |    1 +
 6 files changed, 737 insertions(+), 645 deletions(-)
---
diff --git a/F-Spot.sln b/F-Spot.sln
index 9cdd534..3a715d3 100644
--- a/F-Spot.sln
+++ b/F-Spot.sln
@@ -387,7 +387,7 @@ Global
 		$0.TextStylePolicy = $2
 		$2.FileWidth = 120
 		$2.RemoveTrailingWhitespace = True
-		$2.inheritsSet = VisualStudio
+		$2.inheritsSet = Mono
 		$2.inheritsScope = text/plain
 		$2.scope = text/x-csharp
 		$0.CSharpFormattingPolicy = $3
diff --git a/src/Clients/MainApp/FSpot/Literal.cs b/src/Clients/MainApp/FSpot/Literal.cs
new file mode 100644
index 0000000..662c763
--- /dev/null
+++ b/src/Clients/MainApp/FSpot/Literal.cs
@@ -0,0 +1,584 @@
+//
+// Literal.cs
+//
+// Author:
+//   Gabriel Burt <gabriel burt gmail com>
+//   Stephane Delcroix <stephane delcroix org>
+//   Stephen Shaw <sshaw decriptor com>
+//
+// Copyright (C) 2007-2009 Novell, Inc.
+// Copyright (C) 2007 Gabriel Burt
+// Copyright (C) 2007-2009 Stephane Delcroix
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+// This has to do with Finding photos based on tags
+// http://mail.gnome.org/archives/f-spot-list/2005-November/msg00053.html
+// http://bugzilla-attachments.gnome.org/attachment.cgi?id=54566
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using Mono.Unix;
+using Gtk;
+using Gdk;
+using Hyena;
+using FSpot.Core;
+
+namespace FSpot
+{
+	public abstract class AbstractLiteral : Term
+	{
+		public AbstractLiteral(Term parent, Literal after) : base (parent, after) { }
+
+		public override Term Invert (bool recurse)
+		{
+			is_negated = !is_negated;
+			return this;
+		}
+	}
+
+	// TODO rename to TagLiteral?
+	public class Literal : AbstractLiteral
+	{
+		public Literal (Tag tag) : this (null, tag, null) {	}
+
+		public Literal (Term parent, Tag tag, Literal after) : base (parent, after) {
+			Tag = tag;
+		}
+
+		static Literal ()
+		{
+			FocusedLiterals = new List<Literal> ();
+		}
+
+		#region Properties
+		public static List<Literal> FocusedLiterals { get; set; }
+
+		public Tag Tag { get; private set; }
+
+		public override bool IsNegated {
+			get {
+				return is_negated;
+			}
+
+			set {
+				if (is_negated == value)
+					return;
+
+				is_negated = value;
+
+				NormalIcon = null;
+				NegatedIcon = null;
+				Update ();
+
+				if (NegatedToggled != null)
+					NegatedToggled (this);
+			}
+		}
+
+		private Pixbuf NegatedIcon
+		{
+			get {
+				if (negated_icon != null)
+					return negated_icon;
+
+				if (NormalIcon == null)
+					return null;
+
+				negated_icon = NormalIcon.Copy ();
+
+				int offset = ICON_SIZE - overlay_size;
+				NegatedOverlay.Composite (negated_icon, offset, 0, overlay_size, overlay_size, offset, 0, 1.0, 1.0, InterpType.Bilinear, 200);
+
+				return negated_icon;
+			}
+
+			set {
+				negated_icon = null;
+			}
+		}
+
+		public Widget Widget {
+			get {
+				if (widget != null)
+					return widget;
+
+				container = new EventBox ();
+				box = new HBox ();
+
+				handle_box = new LiteralBox ();
+				handle_box.BorderWidth = 1;
+
+				label = new Label (System.Web.HttpUtility.HtmlEncode (Tag.Name));
+				label.UseMarkup = true;
+
+				image = new Gtk.Image (NormalIcon);
+
+				container.CanFocus = true;
+
+				container.KeyPressEvent  += KeyHandler;
+				container.ButtonPressEvent += HandleButtonPress;
+				container.ButtonReleaseEvent += HandleButtonRelease;
+				container.EnterNotifyEvent += HandleMouseIn;
+				container.LeaveNotifyEvent += HandleMouseOut;
+
+				//new PopupManager (new LiteralPopup (container, this));
+
+				// Setup this widget as a drag source (so tags can be moved after being placed)
+				container.DragDataGet += HandleDragDataGet;
+				container.DragBegin += HandleDragBegin;
+				container.DragEnd += HandleDragEnd;
+
+				Gtk.Drag.SourceSet (container, Gdk.ModifierType.Button1Mask | Gdk.ModifierType.Button3Mask,
+						tag_target_table, DragAction.Copy | DragAction.Move);
+
+				// Setup this widget as a drag destination (so tags can be added to our parent's Term)
+				container.DragDataReceived += HandleDragDataReceived;
+				container.DragMotion += HandleDragMotion;
+				container.DragLeave += HandleDragLeave;
+
+				Gtk.Drag.DestSet (container, DestDefaults.All, tag_dest_target_table,
+						DragAction.Copy | DragAction.Move );
+
+				container.TooltipText = Tag.Name;
+
+				label.Show ();
+				image.Show ();
+
+				if (Tag.Icon == null) {
+					handle_box.Add (label);
+				} else {
+					handle_box.Add (image);
+				}
+
+				handle_box.Show ();
+
+				box.Add (handle_box);
+				box.Show ();
+
+				container.Add (box);
+
+				widget = container;
+
+				return widget;
+			}
+		}
+
+		private Pixbuf NormalIcon
+		{
+			get {
+				if (normal_icon != null)
+					return normal_icon;
+
+				Pixbuf scaled = null;
+				scaled = Tag.Icon;
+
+				for (Category category = Tag.Category; category != null && scaled == null; category = category.Category)
+					scaled = category.Icon;
+
+				if (scaled == null)
+					return null;
+
+				if (scaled.Width != ICON_SIZE)
+					scaled = scaled.ScaleSimple (ICON_SIZE, ICON_SIZE, InterpType.Bilinear);
+
+				normal_icon = scaled;
+
+				return normal_icon;
+			}
+
+			set {
+				normal_icon = null;
+			}
+		}
+		#endregion
+
+		#region Methods
+		public void Update ()
+		{
+			// Clear out the old icons
+			normal_icon = null;
+			negated_icon = null;
+			if (IsNegated) {
+				widget.TooltipText = String.Format (Catalog.GetString ("Not {0}"), Tag.Name);
+				label.Text = "<s>" + System.Web.HttpUtility.HtmlEncode (Tag.Name) + "</s>";
+				image.Pixbuf = NegatedIcon;
+			} else {
+				widget.TooltipText = Tag.Name;
+				label.Text = System.Web.HttpUtility.HtmlEncode (Tag.Name);
+				image.Pixbuf = NormalIcon;
+			}
+
+			label.UseMarkup = true;
+
+			// Show the icon unless it's null
+			if (Tag.Icon == null && container.Children [0] == image) {
+				container.Remove (image);
+				container.Add (label);
+			} else if (Tag.Icon != null && container.Children [0] == label) {
+				container.Remove (label);
+				container.Add (image);
+			}
+
+
+			if (isHoveredOver && image.Pixbuf != null ) {
+				// Brighten the image slightly
+				Pixbuf brightened = image.Pixbuf.Copy ();
+				image.Pixbuf.SaturateAndPixelate (brightened, 1.85f, false);
+				//Pixbuf brightened = PixbufUtils.Glow (image.Pixbuf, .6f);
+
+				image.Pixbuf = brightened;
+			}
+		}
+
+		public void RemoveSelf ()
+		{
+			if (Removing != null)
+				Removing (this);
+
+			if (Parent != null)
+				Parent.Remove (this);
+
+			if (Removed != null)
+				Removed (this);
+		}
+
+		public override string SqlCondition ()
+		{
+			StringBuilder ids = new StringBuilder (Tag.Id.ToString ());
+
+			if (Tag is Category) {
+				List<Tag> tags = new List<Tag> ();
+				(Tag as Category).AddDescendentsTo (tags);
+
+				for (int i = 0; i < tags.Count; i++)
+					ids.Append (", " + (tags [i] as Tag).Id.ToString ());
+			}
+
+			return String.Format (
+					"id {0}IN (SELECT photo_id FROM photo_tags WHERE tag_id IN ({1}))",
+					(IsNegated ? "NOT " : String.Empty), ids.ToString ());
+		}
+
+		public override Gtk.Widget SeparatorWidget ()
+		{
+			return new Label ("ERR");
+		}
+
+		private static Pixbuf NegatedOverlay
+		{
+			get {
+				if (negated_overlay == null) {
+					System.Reflection.Assembly assembly = System.Reflection.Assembly.GetCallingAssembly ();
+					negated_overlay = new Pixbuf (assembly.GetManifestResourceStream ("f-spot-not.png"));
+					negated_overlay = negated_overlay.ScaleSimple (overlay_size, overlay_size, InterpType.Bilinear);
+				}
+
+				return negated_overlay;
+			}
+		}
+
+		public static void RemoveFocusedLiterals ()
+		{
+			if (focusedLiterals != null)
+				foreach (Literal literal in focusedLiterals)
+					literal.RemoveSelf ();
+		}
+		#endregion
+
+		#region Handlers
+		private void KeyHandler (object o, KeyPressEventArgs args)
+		{
+			args.RetVal = false;
+
+			switch (args.Event.Key) {
+				case Gdk.Key.Delete:
+					RemoveFocusedLiterals ();
+					args.RetVal = true;
+					return;
+			}
+		}
+
+		private void HandleButtonPress (object o, ButtonPressEventArgs args)
+		{
+			args.RetVal = true;
+
+			switch (args.Event.Type) {
+				case EventType.TwoButtonPress:
+					if (args.Event.Button == 1)
+						IsNegated = !IsNegated;
+					else
+						args.RetVal = false;
+					return;
+
+				case EventType.ButtonPress:
+					Widget.GrabFocus ();
+
+					if (args.Event.Button == 1) {
+						// TODO allow multiple selection of literals so they can be deleted, modified all at once
+						//if ((args.Event.State & ModifierType.ControlMask) != 0) {
+						//}
+
+					}
+					else if (args.Event.Button == 3)
+					{
+						LiteralPopup popup = new LiteralPopup ();
+						popup.Activate (args.Event, this);
+					}
+
+					return;
+
+				default:
+					args.RetVal = false;
+					return;
+			}
+		}
+
+		private void HandleButtonRelease (object o, ButtonReleaseEventArgs args)
+		{
+			args.RetVal = true;
+
+			switch (args.Event.Type) {
+				case EventType.TwoButtonPress:
+					args.RetVal = false;
+					return;
+
+				case EventType.ButtonPress:
+					if (args.Event.Button == 1) {
+					}
+					return;
+
+				default:
+					args.RetVal = false;
+					return;
+			}
+		}
+
+		private void HandleMouseIn (object o, EnterNotifyEventArgs args)
+		{
+			isHoveredOver = true;
+			Update ();
+		}
+
+		private void HandleMouseOut (object o, LeaveNotifyEventArgs args)
+		{
+			isHoveredOver = false;
+			Update ();
+		}
+
+		void HandleDragDataGet (object sender, DragDataGetArgs args)
+		{
+			args.RetVal = true;
+
+			if (args.Info == DragDropTargets.TagListEntry.Info || args.Info == DragDropTargets.TagQueryEntry.Info) {
+
+				// FIXME: do really write data
+				Byte [] data = Encoding.UTF8.GetBytes (String.Empty);
+				Atom [] targets = args.Context.Targets;
+
+				args.SelectionData.Set (targets[0], 8, data, data.Length);
+
+				return;
+			}
+
+			// Drop cancelled
+			args.RetVal = false;
+
+			foreach (Widget w in hiddenWidgets)
+				w.Visible = true;
+
+			focusedLiterals = null;
+		}
+
+		void HandleDragBegin (object sender, DragBeginArgs args)
+		{
+			Gtk.Drag.SetIconPixbuf (args.Context, image.Pixbuf, 0, 0);
+
+			focusedLiterals.Add (this);
+
+			// Hide the tag and any separators that only exist because of it
+			container.Visible = false;
+			hiddenWidgets.Add (container);
+			foreach (Widget w in LogicWidget.Box.HangersOn (this)) {
+				hiddenWidgets.Add (w);
+				w.Visible = false;
+			}
+		}
+
+		void HandleDragEnd (object sender, DragEndArgs args)
+		{
+			// Remove any literals still marked as focused, because
+			// the user is throwing them away.
+			RemoveFocusedLiterals ();
+
+			focusedLiterals = new List<Literal> ();
+			args.RetVal = true;
+		}
+
+		private void HandleDragDataReceived (object o, DragDataReceivedArgs args)
+		{
+			args.RetVal = true;
+
+			if (args.Info == DragDropTargets.TagListEntry.Info) {
+
+				if (TagsAdded != null)
+					TagsAdded (args.SelectionData.GetTagsData (), Parent, this);
+
+				return;
+			}
+
+			if (args.Info == DragDropTargets.TagQueryEntry.Info) {
+
+				if (! focusedLiterals.Contains(this))
+					if (LiteralsMoved != null)
+						LiteralsMoved (focusedLiterals, Parent, this);
+
+				// Unmark the literals as focused so they don't get nixed
+				focusedLiterals = null;
+			}
+		}
+
+		private bool preview = false;
+		private Gtk.Widget preview_widget;
+		private void HandleDragMotion (object o, DragMotionArgs args)
+		{
+			if (!preview) {
+				if (preview_widget == null) {
+					preview_widget = new Gtk.Label (" | ");
+					box.Add (preview_widget);
+				}
+
+				preview_widget.Show ();
+			}
+		}
+
+		private void HandleDragLeave (object o, EventArgs args)
+		{
+			preview = false;
+			preview_widget.Hide ();
+		}
+
+		public void HandleToggleNegatedCommand (object o, EventArgs args)
+		{
+			IsNegated = !IsNegated;
+		}
+
+		public void HandleRemoveCommand (object o, EventArgs args)
+		{
+			RemoveSelf ();
+		}
+
+		public void HandleAttachTagCommand (Tag t)
+		{
+			if (AttachTag != null)
+				AttachTag (t, Parent, this);
+		}
+
+		public void HandleRequireTag (object sender, EventArgs args)
+		{
+			if (RequireTag != null)
+				RequireTag (new Tag [] {this.Tag});
+		}
+
+		public void HandleUnRequireTag (object sender, EventArgs args)
+		{
+			if (UnRequireTag != null)
+				UnRequireTag (new Tag [] {this.Tag});
+		}
+
+		private const int ICON_SIZE = 24;
+
+		private const int overlay_size = (int) (.40 * ICON_SIZE);
+
+		private static TargetEntry [] tag_target_table =
+			new TargetEntry [] { DragDropTargets.TagQueryEntry };
+
+		private static TargetEntry [] tag_dest_target_table =
+			new TargetEntry [] {
+				DragDropTargets.TagListEntry,
+				DragDropTargets.TagQueryEntry
+			};
+
+		private static List<Literal> focusedLiterals = new List<Literal> ();
+		private static List<Widget> hiddenWidgets = new List<Widget> ();
+		private Gtk.Container container;
+		private LiteralBox handle_box;
+		private Gtk.Box box;
+		private Gtk.Image image;
+		private Gtk.Label label;
+
+		private Pixbuf normal_icon;
+		//private EventBox widget;
+		private Widget widget;
+		private Pixbuf negated_icon;
+		private static Pixbuf negated_overlay;
+		private bool isHoveredOver = false;
+
+		public delegate void NegatedToggleHandler (Literal group);
+		public event NegatedToggleHandler NegatedToggled;
+
+		public delegate void RemovingHandler (Literal group);
+		public event RemovingHandler Removing;
+
+		public delegate void RemovedHandler (Literal group);
+		public event RemovedHandler Removed;
+
+		public delegate void TagsAddedHandler (Tag[] tags, Term parent, Literal after);
+		public event TagsAddedHandler TagsAdded;
+
+		public delegate void AttachTagHandler (Tag tag, Term parent, Literal after);
+		public event AttachTagHandler AttachTag;
+
+		public delegate void TagRequiredHandler (Tag [] tags);
+		public event TagRequiredHandler RequireTag;
+
+		public delegate void TagUnRequiredHandler (Tag [] tags);
+		public event TagUnRequiredHandler UnRequireTag;
+
+		public delegate void LiteralsMovedHandler (List<Literal> literals, Term parent, Literal after);
+		public event LiteralsMovedHandler LiteralsMoved;
+		#endregion
+	}
+
+	public class TextLiteral : AbstractLiteral {
+		private string text;
+
+		public TextLiteral (Term parent, string text) : base (parent, null)
+		{
+			this.text = text;
+		}
+
+		public override string SqlCondition ()
+		{
+			return String.Format (
+					"id {0}IN (SELECT id FROM photos WHERE base_uri LIKE '%{1}%' OR filename LIKE '%{1}%' OR description LIKE '%{1}%')",
+					(IsNegated ? "NOT " : ""), EscapeQuotes(text)
+					);
+		}
+
+		protected static string EscapeQuotes (string v)
+		{
+			return v == null ? String.Empty : v.Replace("'", "''");
+		}
+	}
+}
diff --git a/src/Clients/MainApp/FSpot/TagQueryWidget.cs b/src/Clients/MainApp/FSpot/TagQueryWidget.cs
index 93aeda8..d0a58e5 100644
--- a/src/Clients/MainApp/FSpot/TagQueryWidget.cs
+++ b/src/Clients/MainApp/FSpot/TagQueryWidget.cs
@@ -31,6 +31,7 @@
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Text;
 using Mono.Unix;
 using Gtk;
@@ -374,7 +375,7 @@ namespace FSpot
 			}
 		}
 
-		private void HandleLiteralsMoved (ArrayList literals, Term parent, Literal after)
+		private void HandleLiteralsMoved (List<Literal> literals, Term parent, Literal after)
 		{
 			preventUpdate = true;
 			foreach (Literal term in literals) {
@@ -386,7 +387,7 @@ namespace FSpot
 				term.RemoveSelf ();
 
 				// Add it to where it was dropped
-				ArrayList groups = InsertTerm (new Tag[] {tag}, parent, after);
+				List<Literal> groups = InsertTerm (new Tag[] {tag}, parent, after);
 
 				if (term.IsNegated)
 					foreach (Literal group in groups)
@@ -637,7 +638,7 @@ namespace FSpot
 			UpdateQuery ();
 		}
 
-		public ArrayList InsertTerm (Tag [] tags, Term parent, Literal after)
+		public List<Literal> InsertTerm (Tag [] tags, Term parent, Literal after)
 		{
 			int position;
 			if (after != null)
@@ -645,7 +646,7 @@ namespace FSpot
 			else
 				position = Children.Length - 1;
 
-			ArrayList added = new ArrayList ();
+			List<Literal> added = new List<Literal>();
 
 			foreach (Tag tag in tags) {
 				//Console.WriteLine ("Adding tag {0}", tag.Name);
diff --git a/src/Clients/MainApp/FSpot/Term.cs b/src/Clients/MainApp/FSpot/Term.cs
index a4bc82e..4f69113 100644
--- a/src/Clients/MainApp/FSpot/Term.cs
+++ b/src/Clients/MainApp/FSpot/Term.cs
@@ -4,6 +4,7 @@
 // Author:
 //   Gabriel Burt <gabriel burt gmail com>
 //   Stephane Delcroix <stephane delcroix org>
+//   Stephen Shaw <sshaw decriptor com>
 //
 // Copyright (C) 2007-2009 Novell, Inc.
 // Copyright (C) 2007 Gabriel Burt
@@ -29,6 +30,9 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+// This has to do with Finding photos based on tags
+// http://mail.gnome.org/archives/f-spot-list/2005-November/msg00053.html
+// http://bugzilla-attachments.gnome.org/attachment.cgi?id=54566
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -39,46 +43,50 @@ using Gdk;
 using Hyena;
 using FSpot.Core;
 
-namespace FSpot {
-	public abstract class Term {
-		private ArrayList sub_terms = new ArrayList ();
+namespace FSpot
+{
+	public abstract class Term
+	{
 		private Term parent = null;
-
 		protected bool is_negated = false;
 		protected Tag tag = null;
 
 		public Term (Term parent, Literal after)
 		{
 			this.parent = parent;
+			SubTerms = new List<Term> ();
 
 			if (parent != null) {
-				if (after == null)
+				if (after == null) {
 					parent.Add (this);
-				else
+				} else {
 					parent.SubTerms.Insert (parent.SubTerms.IndexOf (after) + 1, this);
+				}
 			}
 		}
 
-		/** Properties **/
+		#region Properties
 		public bool HasMultiple {
 			get {
 				return (SubTerms.Count > 1);
 			}
 		}
 
-		public ArrayList SubTerms {
-			get {
-				return sub_terms;
-			}
-		}
+		public List<Term> SubTerms { get; private set; }
 
+		/// <summary>
+		/// Returns the last Literal in term
+		/// </summary>
+		/// <value>
+		/// last Literal in term, else null
+		/// </value>
 		public Term Last {
 			get {
-				// Return the last Literal in this term
-				if (SubTerms.Count > 0)
-					return SubTerms[SubTerms.Count - 1] as Term;
-				else
+				if (SubTerms.Count > 0) {
+					return SubTerms [SubTerms.Count - 1];
+				} else {
 					return null;
+				}
 			}
 		}
 
@@ -91,32 +99,34 @@ namespace FSpot {
 		public Term Parent {
 			get { return parent; }
 			set {
-				if (parent == value)
+				if (parent == value) {
 					return;
+				}
 
 				// If our parent was already set, remove ourself from it
-				if (parent != null)
-					parent.Remove(this);
+				if (parent != null) {
+					parent.Remove (this);
+				}
 
 				// Add ourself to our new parent
 				parent = value;
-				parent.Add(this);
+				parent.Add (this);
 			}
 		}
 
 		public virtual bool IsNegated {
 			get { return is_negated; }
 			set {
-				if (is_negated != value)
-					Invert(false);
+				if (is_negated != value) {
+					Invert (false);
+				}
 
 				is_negated = value;
 			}
 		}
+		#endregion
 
-
-		/** Methods **/
-
+		#region Methods
 		public void Add (Term term)
 		{
 			SubTerms.Add (term);
@@ -127,82 +137,91 @@ namespace FSpot {
 			SubTerms.Remove (term);
 
 			// Remove ourselves if we're now empty
-			if (SubTerms.Count == 0)
-				if (Parent != null)
-					Parent.Remove (this);
+			if (SubTerms.Count == 0 && Parent != null) {
+				Parent.Remove (this);
+			}
 		}
 
 		public void CopyAndInvertSubTermsFrom (Term term, bool recurse)
 		{
 			is_negated = true;
-			ArrayList termsToMove = new ArrayList(term.SubTerms);
+			List<Term> termsToMove = new List<Term> (term.SubTerms);
+
 			foreach (Term subterm in termsToMove) {
-				if (recurse)
-					subterm.Invert(true).Parent = this;
-				else
+				if (recurse) {
+					subterm.Invert (true).Parent = this;
+				} else {
 					subterm.Parent = this;
+				}
 			}
 		}
 
-		public ArrayList FindByTag (Tag t)
+		public List<Term> FindByTag (Tag t)
 		{
 			return FindByTag (t, true);
 		}
 
-		public ArrayList FindByTag (Tag t, bool recursive)
+		public List<Term> FindByTag (Tag t, bool recursive)
 		{
-			ArrayList results = new ArrayList ();
+			List<Term> results = new List<Term> ();
 
-			if (tag != null && tag == t)
+			if (tag != null && tag == t) {
 				results.Add (this);
+			}
 
-			if (recursive)
-				foreach (Term term in SubTerms)
-				results.AddRange (term.FindByTag (t, true));
-			else
+			if (recursive) {
 				foreach (Term term in SubTerms) {
-				foreach (Term literal in SubTerms) {
-					if (literal.tag != null && literal.tag == t) {
-						results.Add (literal);
-					}
+					results.AddRange (term.FindByTag (t, true));
 				}
+			} else {
+				foreach (Term term in SubTerms) {
+					foreach (Term literal in SubTerms) {
+						if (literal.tag != null && literal.tag == t) {
+							results.Add (literal);
+						}
+					}
 
-				if (term.tag != null && term.tag == t) {
-					results.Add (term);
+					if (term.tag != null && term.tag == t) {
+						results.Add (term);
+					}
 				}
 			}
 
 			return results;
 		}
 
-		public ArrayList LiteralParents ()
+		public List<Term> LiteralParents ()
 		{
-			ArrayList results = new ArrayList ();
+			List<Term> results = new List<Term> ();
 
 			bool meme = false;
 			foreach (Term term in SubTerms) {
-				if (term is Literal)
+				if (term is Literal) {
 					meme = true;
+				}
 
 				results.AddRange (term.LiteralParents ());
 			}
 
-			if (meme)
+			if (meme) {
 				results.Add (this);
+			}
 
 			return results;
 		}
 
-		public bool TagIncluded(Tag t)
+		public bool TagIncluded (Tag t)
 		{
-			ArrayList parents = LiteralParents ();
+			List<Term> parents = LiteralParents ();
 
-			if (parents.Count == 0)
+			if (parents.Count == 0) {
 				return false;
+			}
 
 			foreach (Term term in parents) {
 				bool termHasTag = false;
 				bool onlyTerm = true;
+
 				foreach (Term literal in term.SubTerms) {
 					if (literal.tag != null) {
 						if (literal.tag == t) {
@@ -213,29 +232,31 @@ namespace FSpot {
 					}
 				}
 
-				if (termHasTag && onlyTerm)
+				if (termHasTag && onlyTerm) {
 					return true;
+				}
 			}
 
 			return false;
 		}
 
-		public bool TagRequired(Tag t)
+		public bool TagRequired (Tag t)
 		{
 			int count, grouped_with;
-			return TagRequired(t, out count, out grouped_with);
+			return TagRequired (t, out count, out grouped_with);
 		}
 
-		public bool TagRequired(Tag t, out int num_terms, out int grouped_with)
+		public bool TagRequired (Tag t, out int num_terms, out int grouped_with)
 		{
-			ArrayList parents = LiteralParents ();
+			List<Term> parents = LiteralParents ();
 
 			num_terms = 0;
 			grouped_with = 100;
 			int min_grouped_with = 100;
 
-			if (parents.Count == 0)
+			if (parents.Count == 0) {
 				return false;
+			}
 
 			foreach (Term term in parents) {
 				bool termHasTag = false;
@@ -255,11 +276,13 @@ namespace FSpot {
 					}
 				}
 
-				if (grouped_with < min_grouped_with)
+				if (grouped_with < min_grouped_with) {
 					min_grouped_with = grouped_with;
+				}
 
-				if (!termHasTag)
+				if (!termHasTag) {
 					return false;
+				}
 			}
 
 			grouped_with = min_grouped_with;
@@ -267,23 +290,28 @@ namespace FSpot {
 			return true;
 		}
 
-		public abstract Term Invert(bool recurse);
+		public abstract Term Invert (bool recurse);
 
-		// Recursively generate the SQL condition clause that this
-		// term represents.
+		/// <summary>
+		/// Recursively generate the SQL condition clause that this term represents.
+		/// </summary>
+		/// <returns>
+		/// The condition string
+		/// </returns>
 		public virtual string SqlCondition ()
 		{
 			StringBuilder condition = new StringBuilder ("(");
 
 			for (int i = 0; i < SubTerms.Count; i++) {
-				Term term = SubTerms[i] as Term;
+				Term term = SubTerms [i] as Term;
 				condition.Append (term.SqlCondition ());
 
-				if (i != SubTerms.Count - 1)
+				if (i != SubTerms.Count - 1) {
 					condition.Append (SQLOperator ());
+				}
 			}
 
-			condition.Append(")");
+			condition.Append (")");
 
 			return condition.ToString ();
 		}
@@ -298,7 +326,8 @@ namespace FSpot {
 			return String.Empty;
 		}
 
-		protected static Hashtable op_term_lookup = new Hashtable();
+		protected static Hashtable op_term_lookup = new Hashtable ();
+
 		public static Term TermFromOperator (string op, Term parent, Literal after)
 		{
 			//Console.WriteLine ("finding type for operator {0}", op);
@@ -316,52 +345,55 @@ namespace FSpot {
 			Log.DebugFormat ("Do not have Term for operator {0}", op);
 			return null;
 		}
+		#endregion
 	}
 
-	public class AndTerm : Term {
-		static ArrayList operators = new ArrayList ();
-		static AndTerm () {
-			operators.Add (Catalog.GetString (" and "));
-			//operators.Add (Catalog.GetString (" && "));
-			operators.Add (Catalog.GetString (", "));
-		}
+	public class AndTerm : Term
+	{
+		public static List<string> Operators { get; private set; }
 
-		public static ArrayList Operators {
-			get { return operators; }
+		static AndTerm ()
+		{
+			Operators = new List<string> ();
+			Operators.Add (Catalog.GetString (" and "));
+			//Operators.Add (Catalog.GetString (" && "));
+			Operators.Add (Catalog.GetString (", "));
 		}
 
-		public AndTerm (Term parent, Literal after) : base (parent, after) {}
+		public AndTerm (Term parent, Literal after) : base (parent, after)
+		{
+		}
 
 		public override Term Invert (bool recurse)
 		{
-			OrTerm newme = new OrTerm(Parent, null);
-			newme.CopyAndInvertSubTermsFrom(this, recurse);
-			if (Parent != null)
-				Parent.Remove(this);
+			OrTerm newme = new OrTerm (Parent, null);
+			newme.CopyAndInvertSubTermsFrom (this, recurse);
+			if (Parent != null) {
+				Parent.Remove (this);
+			}
 			return newme;
 		}
 
 		public override Widget SeparatorWidget ()
 		{
-			Widget sep = new Label (String.Empty);
-			sep.SetSizeRequest (3, 1);
-			sep.Show ();
-			return sep;
-			//return null;
+			Widget separator = new Label (String.Empty);
+			separator.SetSizeRequest (3, 1);
+			separator.Show ();
+			return separator;
 		}
 
 		public override string SqlCondition ()
 		{
 			StringBuilder condition = new StringBuilder ("(");
 
-			condition.Append (base.SqlCondition());
+			condition.Append (base.SqlCondition ());
 
 			Tag hidden = App.Instance.Database.Tags.Hidden;
 			if (hidden != null) {
 				if (FindByTag (hidden, true).Count == 0) {
 					condition.Append (String.Format (
-								  " AND id NOT IN (SELECT photo_id FROM photo_tags WHERE tag_id = {0})", hidden.Id
-							  ));
+								" AND id NOT IN (SELECT photo_id FROM photo_tags WHERE tag_id = {0})", hidden.Id
+								));
 				}
 			}
 
@@ -376,41 +408,44 @@ namespace FSpot {
 		}
 	}
 
-	public class OrTerm : Term {
-		static ArrayList operators = new ArrayList ();
-		static OrTerm () {
-			operators.Add (Catalog.GetString (" or "));
-			//operators.Add (Catalog.GetString (" || "));
+	public class OrTerm : Term
+	{
+		public static List<string> Operators { get; private set; }
+
+		static OrTerm ()
+		{
+			Operators = new List<string> ();
+			Operators.Add (Catalog.GetString (" or "));
+			//Operators.Add (Catalog.GetString (" || "));
+		}
+
+		public OrTerm (Term parent, Literal after) : base (parent, after)
+		{
 		}
 
-		public static OrTerm FromTags(Tag [] from_tags)
+		public static OrTerm FromTags (Tag [] from_tags)
 		{
-			if (from_tags == null || from_tags.Length == 0)
+			if (from_tags == null || from_tags.Length == 0) {
 				return null;
+			}
 
-			OrTerm or = new OrTerm(null, null);
+			OrTerm or = new OrTerm (null, null);
 			foreach (Tag t in from_tags) {
-				Literal l = new Literal(t);
+				Literal l = new Literal (t);
 				l.Parent = or;
 			}
 			return or;
 		}
 
-
-		public static ArrayList Operators {
-			get { return operators; }
-		}
-
-		public OrTerm (Term parent, Literal after) : base (parent, after) {}
-
 		private static string OR = Catalog.GetString ("or");
 
 		public override Term Invert (bool recurse)
 		{
-			AndTerm newme = new AndTerm(Parent, null);
-			newme.CopyAndInvertSubTermsFrom(this, recurse);
-			if (Parent != null)
-				Parent.Remove(this);
+			AndTerm newme = new AndTerm (Parent, null);
+			newme.CopyAndInvertSubTermsFrom (this, recurse);
+			if (Parent != null) {
+				Parent.Remove (this);
+			}
 			return newme;
 		}
 
@@ -426,534 +461,4 @@ namespace FSpot {
 			return " OR ";
 		}
 	}
-
-	public abstract class AbstractLiteral : Term {
-		public AbstractLiteral(Term parent, Literal after) : base (parent, after) {}
-
-		public override Term Invert (bool recurse)
-		{
-			is_negated = !is_negated;
-			return this;
-		}
-	}
-
-	// TODO rename to TagLiteral?
-	public class Literal : AbstractLiteral {
-		public Literal (Tag tag) : this (null, tag, null)
-		{
-		}
-
-		public Literal (Term parent, Tag tag, Literal after) : base (parent, after) {
-			Tag = tag;
-		}
-
-		/** Properties **/
-
-		public static ArrayList FocusedLiterals { get; set; }
-		public Tag Tag { get; private set; }
-
-		public override bool IsNegated {
-			get {
-				return is_negated;
-			}
-
-			set {
-				if (is_negated == value)
-					return;
-
-				is_negated = value;
-
-				NormalIcon = null;
-				NegatedIcon = null;
-				Update ();
-
-				if (NegatedToggled != null)
-					NegatedToggled (this);
-			}
-		}
-
-		private Pixbuf NegatedIcon
-		{
-			get {
-				if (negated_icon != null)
-					return negated_icon;
-
-				if (NormalIcon == null)
-					return null;
-
-				negated_icon = NormalIcon.Copy ();
-
-				int offset = ICON_SIZE - overlay_size;
-				NegatedOverlay.Composite (negated_icon, offset, 0, overlay_size, overlay_size, offset, 0, 1.0, 1.0, InterpType.Bilinear, 200);
-
-				return negated_icon;
-			}
-
-			set {
-				negated_icon = null;
-			}
-		}
-
-		public Widget Widget {
-			get {
-				if (widget != null)
-					return widget;
-
-				container = new EventBox ();
-				box = new HBox ();
-
-				handle_box = new LiteralBox ();
-				handle_box.BorderWidth = 1;
-
-				label = new Label (System.Web.HttpUtility.HtmlEncode (tag.Name));
-				label.UseMarkup = true;
-
-				image = new Gtk.Image (NormalIcon);
-
-				container.CanFocus = true;
-
-				container.KeyPressEvent  += KeyHandler;
-				container.ButtonPressEvent += HandleButtonPress;
-				container.ButtonReleaseEvent += HandleButtonRelease;
-				container.EnterNotifyEvent += HandleMouseIn;
-				container.LeaveNotifyEvent += HandleMouseOut;
-
-				//new PopupManager (new LiteralPopup (container, this));
-
-				// Setup this widget as a drag source (so tags can be moved after being placed)
-				container.DragDataGet += HandleDragDataGet;
-				container.DragBegin += HandleDragBegin;
-				container.DragEnd += HandleDragEnd;
-
-				Gtk.Drag.SourceSet (container, Gdk.ModifierType.Button1Mask | Gdk.ModifierType.Button3Mask,
-						    tag_target_table, DragAction.Copy | DragAction.Move);
-
-				// Setup this widget as a drag destination (so tags can be added to our parent's Term)
-				container.DragDataReceived += HandleDragDataReceived;
-				container.DragMotion += HandleDragMotion;
-				container.DragLeave += HandleDragLeave;
-
-				Gtk.Drag.DestSet (container, DestDefaults.All, tag_dest_target_table,
-						  DragAction.Copy | DragAction.Move );
-
-				container.TooltipText = tag.Name;
-
-				label.Show ();
-				image.Show ();
-
-				if (tag.Icon == null) {
-					handle_box.Add (label);
-				} else {
-					handle_box.Add (image);
-				}
-
-				handle_box.Show ();
-
-				box.Add (handle_box);
-				box.Show ();
-
-				container.Add (box);
-
-				widget = container;
-
-				return widget;
-			}
-		}
-
-		private Pixbuf NormalIcon
-		{
-			get {
-				if (normal_icon != null)
-					return normal_icon;
-
-				Pixbuf scaled = null;
-				scaled = tag.Icon;
-
-				for (Category category = tag.Category; category != null && scaled == null; category = category.Category)
-					scaled = category.Icon;
-
-				if (scaled == null)
-					return null;
-
-				if (scaled.Width != ICON_SIZE) {
-					scaled = scaled.ScaleSimple (ICON_SIZE, ICON_SIZE, InterpType.Bilinear);
-				}
-
-				normal_icon = scaled;
-
-				return normal_icon;
-			}
-
-			set {
-				normal_icon = null;
-			}
-		}
-
-		/** Methods **/
-		public void Update ()
-		{
-			// Clear out the old icons
-			normal_icon = null;
-			negated_icon = null;
-			if (IsNegated) {
-				widget.TooltipText = String.Format (Catalog.GetString ("Not {0}"), tag.Name);
-				label.Text = "<s>" + System.Web.HttpUtility.HtmlEncode (tag.Name) + "</s>";
-				image.Pixbuf = NegatedIcon;
-			} else {
-				widget.TooltipText = tag.Name;
-				label.Text = System.Web.HttpUtility.HtmlEncode (tag.Name);
-				image.Pixbuf = NormalIcon;
-			}
-
-			label.UseMarkup = true;
-
-			// Show the icon unless it's null
-			if (tag.Icon == null && container.Children [0] == image) {
-				container.Remove (image);
-				container.Add (label);
-			} else if (tag.Icon != null && container.Children [0] == label) {
-				container.Remove (label);
-				container.Add (image);
-			}
-
-
-			if (isHoveredOver && image.Pixbuf != null ) {
-				// Brighten the image slightly
-				Pixbuf brightened = image.Pixbuf.Copy ();
-				image.Pixbuf.SaturateAndPixelate (brightened, 1.85f, false);
-				//Pixbuf brightened = PixbufUtils.Glow (image.Pixbuf, .6f);
-
-				image.Pixbuf = brightened;
-			}
-		}
-
-		public void RemoveSelf ()
-		{
-			if (Removing != null)
-				Removing (this);
-
-			if (Parent != null)
-				Parent.Remove (this);
-
-			if (Removed != null)
-				Removed (this);
-		}
-
-		public override string SqlCondition ()
-		{
-			StringBuilder ids = new StringBuilder (tag.Id.ToString ());
-
-			if (tag is Category) {
-				List<Tag> tags = new List<Tag> ();
-				(tag as Category).AddDescendentsTo (tags);
-
-				for (int i = 0; i < tags.Count; i++)
-					ids.Append (", " + (tags [i] as Tag).Id.ToString ());
-			}
-
-			return String.Format (
-				       "id {0}IN (SELECT photo_id FROM photo_tags WHERE tag_id IN ({1}))",
-				       (IsNegated ? "NOT " : String.Empty), ids.ToString ());
-		}
-
-		public override Gtk.Widget SeparatorWidget ()
-		{
-			return new Label ("ERR");
-		}
-
-		private static Pixbuf NegatedOverlay
-		{
-			get {
-				if (negated_overlay == null) {
-					System.Reflection.Assembly assembly = System.Reflection.Assembly.GetCallingAssembly ();
-					negated_overlay = new Pixbuf (assembly.GetManifestResourceStream ("f-spot-not.png"));
-					negated_overlay = negated_overlay.ScaleSimple (overlay_size, overlay_size, InterpType.Bilinear);
-				}
-
-				return negated_overlay;
-			}
-		}
-
-		public static void RemoveFocusedLiterals ()
-		{
-			if (focusedLiterals != null)
-				foreach (Literal literal in focusedLiterals)
-				literal.RemoveSelf ();
-		}
-
-		/** Handlers **/
-
-		private void KeyHandler (object o, KeyPressEventArgs args)
-		{
-			args.RetVal = false;
-
-			switch (args.Event.Key) {
-			case Gdk.Key.Delete:
-				RemoveFocusedLiterals ();
-				args.RetVal = true;
-				return;
-			}
-		}
-
-		private void HandleButtonPress (object o, ButtonPressEventArgs args)
-		{
-			args.RetVal = true;
-
-			switch (args.Event.Type) {
-			case EventType.TwoButtonPress:
-				if (args.Event.Button == 1)
-					IsNegated = !IsNegated;
-				else
-					args.RetVal = false;
-				return;
-
-			case EventType.ButtonPress:
-				Widget.GrabFocus ();
-
-				if (args.Event.Button == 1) {
-					// TODO allow multiple selection of literals so they can be deleted, modified all at once
-					//if ((args.Event.State & ModifierType.ControlMask) != 0) {
-					//}
-
-				}
-				else if (args.Event.Button == 3)
-				{
-					LiteralPopup popup = new LiteralPopup ();
-					popup.Activate (args.Event, this);
-				}
-
-				return;
-
-			default:
-				args.RetVal = false;
-				return;
-			}
-		}
-
-		private void HandleButtonRelease (object o, ButtonReleaseEventArgs args)
-		{
-			args.RetVal = true;
-
-			switch (args.Event.Type) {
-			case EventType.TwoButtonPress:
-				args.RetVal = false;
-				return;
-
-			case EventType.ButtonPress:
-				if (args.Event.Button == 1) {
-				}
-				return;
-
-			default:
-				args.RetVal = false;
-				return;
-			}
-		}
-
-		private void HandleMouseIn (object o, EnterNotifyEventArgs args)
-		{
-			isHoveredOver = true;
-			Update ();
-		}
-
-		private void HandleMouseOut (object o, LeaveNotifyEventArgs args)
-		{
-			isHoveredOver = false;
-			Update ();
-		}
-
-		void HandleDragDataGet (object sender, DragDataGetArgs args)
-		{
-			args.RetVal = true;
-
-			if (args.Info == DragDropTargets.TagListEntry.Info || args.Info == DragDropTargets.TagQueryEntry.Info) {
-
-				// FIXME: do really write data
-				Byte [] data = Encoding.UTF8.GetBytes (String.Empty);
-				Atom [] targets = args.Context.Targets;
-
-				args.SelectionData.Set (targets[0], 8, data, data.Length);
-
-				return;
-			}
-
-			// Drop cancelled
-			args.RetVal = false;
-
-			foreach (Widget w in hiddenWidgets)
-				w.Visible = true;
-
-			focusedLiterals = null;
-		}
-
-		void HandleDragBegin (object sender, DragBeginArgs args)
-		{
-			Gtk.Drag.SetIconPixbuf (args.Context, image.Pixbuf, 0, 0);
-
-			focusedLiterals.Add (this);
-
-			// Hide the tag and any separators that only exist because of it
-			container.Visible = false;
-			hiddenWidgets.Add (container);
-			foreach (Widget w in LogicWidget.Box.HangersOn (this)) {
-				hiddenWidgets.Add (w);
-				w.Visible = false;
-			}
-		}
-
-		void HandleDragEnd (object sender, DragEndArgs args)
-		{
-			// Remove any literals still marked as focused, because
-			// the user is throwing them away.
-			RemoveFocusedLiterals ();
-
-			focusedLiterals = new ArrayList();
-			args.RetVal = true;
-		}
-
-		private void HandleDragDataReceived (object o, DragDataReceivedArgs args)
-		{
-			args.RetVal = true;
-
-			if (args.Info == DragDropTargets.TagListEntry.Info) {
-
-				if (TagsAdded != null)
-					TagsAdded (args.SelectionData.GetTagsData (), Parent, this);
-
-				return;
-			}
-
-			if (args.Info == DragDropTargets.TagQueryEntry.Info) {
-
-				if (! focusedLiterals.Contains(this))
-					if (LiteralsMoved != null)
-						LiteralsMoved (focusedLiterals, Parent, this);
-
-				// Unmark the literals as focused so they don't get nixed
-				focusedLiterals = null;
-			}
-		}
-
-		private bool preview = false;
-		private Gtk.Widget preview_widget;
-		private void HandleDragMotion (object o, DragMotionArgs args)
-		{
-			if (!preview) {
-				if (preview_widget == null) {
-					preview_widget = new Gtk.Label (" | ");
-					box.Add (preview_widget);
-				}
-
-				preview_widget.Show ();
-			}
-		}
-
-		private void HandleDragLeave (object o, EventArgs args)
-		{
-			preview = false;
-			preview_widget.Hide ();
-		}
-
-		public void HandleToggleNegatedCommand (object o, EventArgs args)
-		{
-			IsNegated = !IsNegated;
-		}
-
-		public void HandleRemoveCommand (object o, EventArgs args)
-		{
-			RemoveSelf ();
-		}
-
-		public void HandleAttachTagCommand (Tag t)
-		{
-			if (AttachTag != null)
-				AttachTag (t, Parent, this);
-		}
-
-		public void HandleRequireTag (object sender, EventArgs args)
-		{
-			if (RequireTag != null)
-				RequireTag (new Tag [] {this.Tag});
-		}
-
-		public void HandleUnRequireTag (object sender, EventArgs args)
-		{
-			if (UnRequireTag != null)
-				UnRequireTag (new Tag [] {this.Tag});
-		}
-
-		private const int ICON_SIZE = 24;
-
-		private const int overlay_size = (int) (.40 * ICON_SIZE);
-
-		private static TargetEntry [] tag_target_table =
-			new TargetEntry [] { DragDropTargets.TagQueryEntry };
-
-		private static TargetEntry [] tag_dest_target_table =
-			new TargetEntry [] {
-				DragDropTargets.TagListEntry,
-				DragDropTargets.TagQueryEntry
-			};
-
-		private static ArrayList focusedLiterals = new ArrayList();
-		private static ArrayList hiddenWidgets = new ArrayList();
-		private Gtk.Container container;
-		private LiteralBox handle_box;
-		private Gtk.Box box;
-		private Gtk.Image image;
-		private Gtk.Label label;
-
-		private Pixbuf normal_icon;
-		//private EventBox widget;
-		private Widget widget;
-		private Pixbuf negated_icon;
-		private static Pixbuf negated_overlay;
-		private bool isHoveredOver = false;
-
-		public delegate void NegatedToggleHandler (Literal group);
-		public event NegatedToggleHandler NegatedToggled;
-
-		public delegate void RemovingHandler (Literal group);
-		public event RemovingHandler Removing;
-
-		public delegate void RemovedHandler (Literal group);
-		public event RemovedHandler Removed;
-
-		public delegate void TagsAddedHandler (Tag[] tags, Term parent, Literal after);
-		public event TagsAddedHandler TagsAdded;
-
-		public delegate void AttachTagHandler (Tag tag, Term parent, Literal after);
-		public event AttachTagHandler AttachTag;
-
-		public delegate void TagRequiredHandler (Tag [] tags);
-		public event TagRequiredHandler RequireTag;
-
-		public delegate void TagUnRequiredHandler (Tag [] tags);
-		public event TagUnRequiredHandler UnRequireTag;
-
-		public delegate void LiteralsMovedHandler (ArrayList literals, Term parent, Literal after);
-		public event LiteralsMovedHandler LiteralsMoved;
-	}
-
-	public class TextLiteral : AbstractLiteral {
-		private string text;
-
-		public TextLiteral (Term parent, string text) : base (parent, null)
-		{
-			this.text = text;
-		}
-
-		public override string SqlCondition ()
-		{
-			return String.Format (
-				       "id {0}IN (SELECT id FROM photos WHERE base_uri LIKE '%{1}%' OR filename LIKE '%{1}%' OR description LIKE '%{1}%')",
-				       (IsNegated ? "NOT " : ""), EscapeQuotes(text)
-			       );
-		}
-
-		protected static string EscapeQuotes (string v)
-		{
-			return v == null ? String.Empty : v.Replace("'", "''");
-		}
-	}
 }
diff --git a/src/Clients/MainApp/MainApp.csproj b/src/Clients/MainApp/MainApp.csproj
index d625a90..d04e018 100644
--- a/src/Clients/MainApp/MainApp.csproj
+++ b/src/Clients/MainApp/MainApp.csproj
@@ -207,6 +207,7 @@
     <Compile Include="Pinta\ColorBgra.cs" />
     <Compile Include="Pinta\CairoExtensions.cs" />
     <Compile Include="Pinta\GaussianBlurEffect.cs" />
+    <Compile Include="FSpot\Literal.cs" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="..\..\..\COPYING">
diff --git a/src/Clients/MainApp/Makefile.am b/src/Clients/MainApp/Makefile.am
index 4a80098..84f31e9 100644
--- a/src/Clients/MainApp/Makefile.am
+++ b/src/Clients/MainApp/Makefile.am
@@ -137,6 +137,7 @@ SOURCES =  \
 	FSpot/InfoOverlay.cs \
 	FSpot/ItemAction.cs \
 	FSpot/JobStore.cs \
+	FSpot/Literal.cs \
 	FSpot/main.cs \
 	FSpot/MainWindow.cs \
 	FSpot/MetaStore.cs \



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]