Re: Tag typing.



Version 2 of the tag typing patch is attached, addressing a number of
the issues in last night's patch.  Various changes:

        - Tags are now case-insensitive, so if you name the tag "New
        York" but type "new york", you get the behavior you expect.
        
        - Select multiple tags in the sidebar and right click to merge
        tags.  It behaves as I described yesterday, removing all tags
        except the first one, which survives (and which the user can
        rename/re-icon as he prefers).  I also had to make the sidebar
        popup menu work in the face of multiselections; it's a bit nicer
        now imho.
        
        - Hitting TAB in the entry will now complete whatever tag you're
        typing to the first match.  There's a lame attempt to display
        the completion to the user beforehand in there, but I turned it
        off because it doesn't work yet.
        
        - A few bugs were fixed.
        
Let me know how this goes for people!

Nat

? f-spot.glade.broken
? f-spot.gladep
? nat.diff
? p
? pp
? tag.diff
? tagger.diff
Index: Db.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/Db.cs,v
retrieving revision 1.7
diff -u -r1.7 Db.cs
--- Db.cs	7 Oct 2005 21:35:39 -0000	1.7
+++ Db.cs	9 Nov 2005 03:19:18 -0000
@@ -24,7 +24,7 @@
 public abstract class DbStore {
 	// DbItem cache.
 
-	Hashtable item_cache;
+	protected Hashtable item_cache;
 	bool cache_is_immortal;
 
 	protected void AddToCache (DbItem item)
Index: MainWindow.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/MainWindow.cs,v
retrieving revision 1.228
diff -u -r1.228 MainWindow.cs
--- MainWindow.cs	2 Nov 2005 08:33:16 -0000	1.228
+++ MainWindow.cs	9 Nov 2005 03:19:18 -0000
@@ -83,6 +83,9 @@
 	[Glade.Widget] Gtk.Image near_image;
 	[Glade.Widget] Gtk.Image far_image;
 
+	[Glade.Widget] Gtk.HBox tagbar;
+	[Glade.Widget] Gtk.Entry tag_entry;
+
 	Gtk.Toolbar toolbar;
 
 	PhotoVersionMenu versions_submenu;
@@ -260,6 +263,12 @@
 		photo_view.UpdateStarted += HandlePhotoViewUpdateStarted;
 		photo_view.UpdateFinished += HandlePhotoViewUpdateFinished;
 
+		// Tag typing: focus the tag entry if the user starts typing a tag
+		icon_view.KeyPressEvent += HandlePossibleTagTyping;
+		photo_view.KeyPressEvent += HandlePossibleTagTyping;
+		tag_entry.KeyPressEvent += HandleTagEntryKeyPressEvent;
+		tag_entry.FocusOutEvent += HandleTagEntryFocusOutEvent;
+
 		Gtk.Drag.DestSet (photo_view, DestDefaults.All, tag_target_table, 
 				  DragAction.Copy | DragAction.Move); 
 
@@ -455,7 +464,6 @@
 	private void RotateSelectedPictures (RotateCommand.Direction direction)
 	{
 		RotateCommand command = new RotateCommand (main_window);
-
 		
 		int [] selected_ids = SelectedIds ();
 		if (command.Execute (direction, SelectedPhotos (selected_ids))) {
@@ -505,13 +513,9 @@
 	{
 		if (args.Event.Button == 3)
 		{
-			TreePath path;
-			tag_selection_widget.Selection.UnselectAll ();
-			if (tag_selection_widget.GetPathAtPos ((int)args.Event.X, (int)args.Event.Y, out path)) {
-				tag_selection_widget.Selection.SelectPath (path);
-			}
 			TagPopup popup = new TagPopup ();
-			popup.Activate (args.Event, tag_selection_widget.TagAtPosition ((int)args.Event.X, (int)args.Event.Y));
+			popup.Activate (args.Event, tag_selection_widget.TagAtPosition ((int)args.Event.X, (int)args.Event.Y),
+					tag_selection_widget.TagHighlight ());
 			args.RetVal = true;
 		}
 	}
@@ -626,6 +630,8 @@
 
 			break;
 		}
+
+		UpdateTagEntryFromSelection ();
 	}
 
 #if SHOW_CALENDAR
@@ -824,6 +830,8 @@
 					AttachTags (tag_selection_widget.TagHighlight (), SelectedIds());
 				else 
 					AttachTags (tag_selection_widget.TagHighlight (), new int [] {item});
+
+				UpdateTagEntryFromSelection ();
 			}
 			break;
 		case (uint)TargetType.UriList:
@@ -851,7 +859,9 @@
 		info_box.Photo = CurrentPhoto;
 		if (info_display != null)
 			info_display.Photo = CurrentPhoto;
+
 		UpdateMenus ();
+		UpdateTagEntryFromSelection ();
 	}
 
 	void HandleDoubleClicked (IconView icon_view, int clicked_item)
@@ -960,6 +970,8 @@
 		foreach (int num in SelectedIds ()) {
 			AddTagExtended (num, new Tag [] {t});
 		}
+
+		UpdateTagEntryFromSelection ();
 	}
 	
 	void HandleFindTagMenuSelected (Tag t)
@@ -973,6 +985,8 @@
 			query.Photos [num].RemoveTag (t);
 			query.Commit (num);
 		}
+
+		UpdateTagEntryFromSelection ();
 	}
 
 	//
@@ -1338,16 +1352,71 @@
 			query.Photos [num].RemoveTag (tags);
 			query.Commit (num);
 		}
+
+		UpdateTagEntryFromSelection ();
 	}
 
-	public void HandleEditSelectedTag (object obj, EventArgs args)
+	public void HandleEditSelectedTag (object sender, EventArgs ea)
 	{
-		Tag [] tags = tag_selection_widget.TagHighlight ();
+		Tag [] tags = this.tag_selection_widget.TagHighlight ();
 		if (tags.Length != 1)
 			return;
+
+		HandleEditSelectedTagWithTag (tags [0]);
+	}
+
+	public void HandleEditSelectedTagWithTag (Tag tag)
+	{
+		if (tag == null)
+			return;
 		
 		TagCommands.Edit command = new TagCommands.Edit (db, main_window);
-		command.Execute (tags [0]);
+		command.Execute (tag);
+		if (view_mode == ModeType.IconView)
+			icon_view.QueueDraw ();
+	}
+
+	public void HandleMergeTagsCommand (object obj, EventArgs args)
+	{
+		Tag [] tags = this.tag_selection_widget.TagHighlight ();
+		if (tags.Length < 2)
+			return;
+
+		System.Array.Sort (tags, new TagRemoveComparer ());
+		string header = Mono.Posix.Catalog.GetString ("Merge the {0} selected tags?");
+		
+		header = String.Format (header, tags.Length);
+		string msg = Mono.Posix.Catalog.GetString("This operation will delete all but one of the selected tags.");
+		string ok_caption = Mono.Posix.Catalog.GetString ("_Merge tags");
+		
+		if (ResponseType.Ok != HigMessageDialog.RunHigConfirmation(main_window, 
+									   DialogFlags.DestroyWithParent, 
+									   MessageType.Warning, 
+									   header, 
+									   msg, 
+									   ok_caption))
+			return;
+		
+		// The surviving tag is tags [0].  removetags will contain
+		// the tags to be merged.
+		Tag [] removetags = new Tag [tags.Length - 1];
+		Array.Copy (tags, 1, removetags, 0, tags.Length - 1);
+
+
+		// Remove the defunct tags from all the photos and
+		// replace them with the new tag.
+		Photo [] photos = db.Photos.Query (tags, null);
+		foreach (Photo p in photos) {
+			p.RemoveTag (removetags);
+			p.AddTag (tags [0]);
+			db.Photos.Commit (p);
+		}
+
+		// Remove the defunct tags from the tag list.
+		db.Photos.Remove (removetags);
+
+		UpdateTagEntryFromSelection ();
+		icon_view.QueueDraw ();
 	}
 
 	void HandleAdjustColor (object sender, EventArgs args)
@@ -1988,5 +2057,249 @@
 		remove_tag_from_selection.Sensitive = tag_sensitive && active_selection;
 	}
 
+	// Tag typing
+
+	private ArrayList selected_photos_tagnames;
+
+	private void UpdateTagEntryFromSelection ()
+	{
+		Hashtable taghash = new Hashtable ();
+
+		Photo [] sel = SelectedPhotos (SelectedIds ());
+		foreach (Photo p in sel) {
+			foreach (Tag t in p.Tags) {
+				int count = 1;
+				string tagname = t.Name;
+
+				if (taghash.Contains (tagname))
+					count = ((int) taghash [tagname]) + 1;
+
+				taghash [tagname] = count;
+			}
+		}
+
+		selected_photos_tagnames = new ArrayList ();
+		foreach (string tagname in taghash.Keys)
+			if ((int) (taghash [tagname]) == sel.Length)
+				selected_photos_tagnames.Add (tagname);
+		selected_photos_tagnames.Sort ();
+
+		string taglist = "";
+		foreach (string tagname in selected_photos_tagnames) {
+			if (taglist == "")
+				taglist = tagname;
+			else
+				taglist = taglist + ", " + tagname;
+		}
+
+		tag_entry.Text = taglist;
+	}
+
+	public void HandlePossibleTagTyping (object sender, Gtk.KeyPressEventArgs args)
+	{
+		if (tagbar.Visible && tag_entry.HasFocus)
+			return;
+
+		char c = System.Convert.ToChar (Gdk.Keyval.ToUnicode ((uint) args.Event.Key));
+		if (! System.Char.IsLetter (c))
+			return;
+
+		if (! tagbar.Visible)
+			tagbar.Show ();
+		
+		if (tag_entry.Text.Length > 0)
+			tag_entry.Text += ", ";
+		tag_entry.Text += c;
+
+		tagbar.Show ();
+		tag_entry.GrabFocus ();
+		tag_entry.SelectRegion (-1, -1);
+	}
+
+	public void HandleTagEntryActivate (object sender, EventArgs args)
+	{
+		string [] tagnames = GetTypedTagNames ();
+
+		// Add any new tags to the selected photos
+		Category default_category = null;
+		Tag [] selection = tag_selection_widget.TagHighlight ();
+		if (selection.Length > 0) {
+			if (selection [0] is Category)
+				default_category = (Category) selection [0];
+			else
+				default_category = selection [0].Category;
+		}
+
+		foreach (string tagname in tagnames) {
+			if (tagname.Length == 0)
+				continue;
+			
+			Tag t = db.Tags.GetTagByName (tagname);
+			if (t == null) {
+				t = db.Tags.CreateTag (default_category, tagname);
+				db.Tags.Commit (t);
+			}
+
+			Tag [] tags = new Tag [1];
+			tags [0] = t;
+
+			foreach (int num in SelectedIds ())
+				AddTagExtended (num, tags);
+		}
+
+		// Remove any removed tags from the selected photos
+		foreach (string tagname in selected_photos_tagnames) {
+			if (! IsTagInList (tagnames, tagname)) {
+				
+				Tag tag = db.Tags.GetTagByName (tagname);
+
+				foreach (int num in SelectedIds ()) {
+					query.Photos [num].RemoveTag (tag);
+					query.Commit (num);
+				}
+			}
+		}
+
+		UpdateTagEntryFromSelection ();
+		if (view_mode == ModeType.IconView) {
+			icon_view.QueueDraw ();
+			icon_view.GrabFocus ();
+		} else {
+			photo_view.QueueDraw ();
+			photo_view.GrabFocus ();
+		}
+	}
+
+	private void HideTagbar ()
+	{
+		if (! tagbar.Visible)
+			return;
+		
+		// Cancel any pending edits...
+		UpdateTagEntryFromSelection ();
+
+		tagbar.Hide ();
+
+		if (view_mode == ModeType.IconView)
+			icon_view.GrabFocus ();
+		else
+			photo_view.GrabFocus ();
+	}
+
+	public void HandleTagBarCloseButtonPressed (object sender, EventArgs args)
+	{
+		HideTagbar ();
+	}
+
+	public void HandleTagEntryKeyPressEvent (object sender, Gtk.KeyPressEventArgs args)
+	{
+		args.RetVal = false;
+		
+		if (args.Event.Key == Gdk.Key.Escape) {
+			HideTagbar (); 
+			args.RetVal = true;
+		} else if (args.Event.Key == Gdk.Key.Tab) {
+			DoTagCompletion ();
+			args.RetVal = true;
+		}
+	}
+
+	public void HandleTagEntryChanged (object sender, EventArgs args)
+	{
+		using (new Timer ("Completion")) {
+			UpdateTagCompletionSuggestion ();
+		}
+	}
+
+	private void UpdateTagCompletionSuggestion ()
+	{
+#if YOU_ARE_CAUGHT_IN_A_MAZE_OF_TWISTY_SIGNAL_EMISSIONS_ALL_ALIKE
+		if (tag_typing_ignore_signal) {
+			Console.WriteLine ("Ignoring signal...");
+			return;
+		}
+		
+		int pos = tag_entry.Position;
+		Console.WriteLine ("Update completion: " + pos + " - [" + tag_entry.Text.Substring (0, pos) + "]"
+				   + "{" + tag_entry.Text.Substring (pos) + "}");
+
+		string right_of_cursor = tag_entry.Text.Substring (pos);
+
+		int last_comma = tag_entry.Text.LastIndexOf (',');
+		if (last_comma > pos)
+			return;
+
+		string typed_so_far = tag_entry.Text.Substring (last_comma + 1).TrimStart (new char [] {' '});
+		Console.WriteLine ("Typed so far: [" + typed_so_far + "]");
+		if (typed_so_far == null || typed_so_far.Length == 0)
+			return;
+
+		Tag [] tags = db.Tags.GetTagsByNameStart (typed_so_far);
+		if (tags == null)
+			return;
+		foreach (Tag t in tags)
+			Console.WriteLine ("Completable: [" + t.Name + "]");
+
+		string you_complete_me = tags [0].Name.Substring (typed_so_far.Length);
+		tag_typing_ignore_signal = true;
+		tag_entry.Text = tag_entry.Text.Substring (0, pos + 1) + you_complete_me;
+		tag_typing_ignore_signal = false;
+		//		GLib.Idle.Add (new GLib.IdleHandler (delegate {
+		//			tag_entry.SelectRegion (tag_entry.Text.Length - you_complete_me.Length, tag_entry.Text.Length);
+		//			return false;
+		//		}));
+		//		Application.Run ();
+#endif
+	}
+
+	private void DoTagCompletion ()
+	{
+		string right_of_cursor = tag_entry.Text.Substring (tag_entry.Position);
+		if (right_of_cursor.Length > 1)
+			return;
+
+		int last_comma = tag_entry.Text.LastIndexOf (',');
+		if (last_comma > tag_entry.Position)
+			return;
+
+		string typed_so_far = tag_entry.Text.Substring (last_comma + 1).TrimStart (new char [] {' '});
+		if (typed_so_far == null || typed_so_far.Length == 0)
+			return;
+
+		Tag [] tags = db.Tags.GetTagsByNameStart (typed_so_far);
+		if (tags == null)
+			return;
+		string you_complete_me = tags [0].Name.Substring (typed_so_far.Length);
+		tag_entry.Text += you_complete_me + ", ";
+		tag_entry.Position = tag_entry.Text.Length;
+	}
+
+	public void HandleTagEntryFocusOutEvent (object sender, EventArgs args)
+	{
+		UpdateTagEntryFromSelection ();
+	}
+
+	private string [] GetTypedTagNames ()
+	{
+		string [] tagnames = tag_entry.Text.Split (new char [] {','});
+
+		ArrayList list = new ArrayList ();
+		for (int i = 0; i < tagnames.Length; i ++) {
+			string s = tagnames [i].Trim ();
+
+			if (s.Length > 0)
+				list.Add (s);
+		}
+
+		return (string []) (list.ToArray (typeof (string)));
+	}
+
+	private bool IsTagInList (string [] tags, string tag)
+	{
+		foreach (string t in tags)
+			if (t == tag)
+				return true;
+		return false;
+	}
 }
 
Index: PhotoStore.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/PhotoStore.cs,v
retrieving revision 1.72
diff -u -r1.72 PhotoStore.cs
--- PhotoStore.cs	2 Nov 2005 08:33:15 -0000	1.72
+++ PhotoStore.cs	9 Nov 2005 03:19:18 -0000
@@ -1273,7 +1273,7 @@
 		db.Photos.Commit (me_in_sf);
 
 		me_in_sf.RemoveTag (favorites_tag);
-		me_in_sf.Description = "Myself and the SF skyline";
+     		me_in_sf.Description = "Myself and the SF skyline";
 		me_in_sf.CreateVersion ("cropped", Photo.OriginalVersionId);
 		me_in_sf.CreateVersion ("UM-ed", Photo.OriginalVersionId);
 		db.Photos.Commit (me_in_sf);
Index: PhotoView.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/PhotoView.cs,v
retrieving revision 1.68
diff -u -r1.68 PhotoView.cs
--- PhotoView.cs	2 Nov 2005 08:33:15 -0000	1.68
+++ PhotoView.cs	9 Nov 2005 03:19:18 -0000
@@ -253,7 +253,6 @@
 		}
 
 		Photo photo = (Photo)Item.Current;
-		Exif.ExifData exif_data = new Exif.ExifData (photo.DefaultVersionPath);
 
 		Pixbuf edited;
 		if (redeye) {
@@ -273,7 +272,6 @@
 		// be fixed there.
 		photo_view.Pixbuf = edited;
 		photo_view.UnsetSelection ();
-		bool version = false;
 
 		try {
 			bool create_version = photo.DefaultVersionId == Photo.OriginalVersionId;
Index: TagCommands.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/TagCommands.cs,v
retrieving revision 1.28
diff -u -r1.28 TagCommands.cs
--- TagCommands.cs	28 Oct 2005 19:52:30 -0000	1.28
+++ TagCommands.cs	9 Nov 2005 03:19:18 -0000
@@ -323,6 +323,7 @@
 			}
 			
 			this.Dialog.Destroy ();
+
 			return success;
 		}
 
Index: TagPopup.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/TagPopup.cs,v
retrieving revision 1.3
diff -u -r1.3 TagPopup.cs
--- TagPopup.cs	22 Oct 2005 06:10:27 -0000	1.3
+++ TagPopup.cs	9 Nov 2005 03:19:18 -0000
@@ -12,7 +12,7 @@
 using System;
 
 public class TagPopup {
-	public void Activate (Gdk.EventButton eb, Tag tag)
+	public void Activate (Gdk.EventButton eb, Tag tag, Tag [] tags)
 	{
 		int count = MainWindow.Toplevel.SelectedIds ().Length;
 		Gtk.Menu popup_menu = new Gtk.Menu ();
@@ -24,19 +24,30 @@
 		
 		GtkUtil.MakeMenuSeparator (popup_menu);
 
-		GtkUtil.MakeMenuItem (popup_menu, Mono.Posix.Catalog.GetString ("Edit Tag"),
-				      new EventHandler (MainWindow.Toplevel.HandleEditSelectedTag), tag != null);
+		string editstr = String.Format (Mono.Posix.Catalog.GetString ("Edit Tag `{0}'"), tag.Name);
+		GtkUtil.MakeMenuItem (popup_menu, editstr, delegate { MainWindow.Toplevel.HandleEditSelectedTagWithTag (tag); }, true);
 
-		GtkUtil.MakeMenuItem (popup_menu, Mono.Posix.Catalog.GetString ("Delete Tag"),
-				      new EventHandler (MainWindow.Toplevel.HandleDeleteSelectedTagCommand), tag != null);
-				      
+		GtkUtil.MakeMenuItem (popup_menu,
+				      Mono.Posix.Catalog.GetPluralString ("Delete Tag", "Delete Tags", tags.Length),
+				      new EventHandler (MainWindow.Toplevel.HandleDeleteSelectedTagCommand), tags != null && tags.Length > 0);
+		
 		GtkUtil.MakeMenuSeparator (popup_menu);
 
-		GtkUtil.MakeMenuItem (popup_menu, Mono.Posix.Catalog.GetString ("Attach Tag To Selection"),
+		GtkUtil.MakeMenuItem (popup_menu,
+				      Mono.Posix.Catalog.GetPluralString ("Attach Tag To Selection", "Attach Tags To Selection", tags.Length),
 				      new EventHandler (MainWindow.Toplevel.HandleAttachTagCommand), count > 0);
 
-		GtkUtil.MakeMenuItem (popup_menu, Mono.Posix.Catalog.GetString ("Remove Tag From Selection"),
+		GtkUtil.MakeMenuItem (popup_menu,
+				      Mono.Posix.Catalog.GetPluralString ("Remove Tag From Selection", "Remove Tags From Selection", tags.Length),
 				      new EventHandler (MainWindow.Toplevel.HandleRemoveTagCommand), count > 0);
+
+		if (tags.Length > 1) {
+			GtkUtil.MakeMenuSeparator (popup_menu);
+
+			GtkUtil.MakeMenuItem (popup_menu, Mono.Posix.Catalog.GetString ("Merge Tags"),
+					      new EventHandler (MainWindow.Toplevel.HandleMergeTagsCommand), tags.Length > 1);
+
+		}
 
 		popup_menu.Popup (null, null, null, eb.Button, eb.Time);
 	}
Index: TagSelectionWidget.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/TagSelectionWidget.cs,v
retrieving revision 1.21
diff -u -r1.21 TagSelectionWidget.cs
--- TagSelectionWidget.cs	2 Nov 2005 05:35:57 -0000	1.21
+++ TagSelectionWidget.cs	9 Nov 2005 03:19:19 -0000
@@ -290,7 +290,7 @@
 	{
 		TreeIter root = TreeIter.Zero;
 		iter = TreeIter.Zero;
-	
+
 		bool valid = Model.GetIterFirst (out root);
 		
 		while (valid) {
@@ -399,12 +399,14 @@
 	
 	private void HandleTagCreated (Tag tag) 
 	{
-		TreeIter iter;
+		TreeIter iter = TreeIter.Zero;
 
-		if (TreeIterForTag (tag.Category, out iter)) {
-			// create dialog doesn't let you create a top level tag...
-			InsertInOrder (iter, false, tag);
-		}
+		if (tag.Category != tag_store.RootCategory)
+			TreeIterForTag (tag.Category, out iter);
+
+		InsertInOrder (iter,
+			       tag.Category.Name == tag_store.RootCategory.Name,
+			       tag);
 	}
 	
 	private void HandleTagChanged (Tag tag) 
Index: TagStore.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/TagStore.cs,v
retrieving revision 1.20
diff -u -r1.20 TagStore.cs
--- TagStore.cs	28 Oct 2005 19:52:30 -0000	1.20
+++ TagStore.cs	9 Nov 2005 03:19:19 -0000
@@ -268,6 +268,30 @@
 		}
 	}
 
+	public Tag GetTagByName (string name)
+	{
+		foreach (Tag t in this.item_cache.Values) {
+			if (t.Name.ToLower () == name.ToLower ())
+				return t;
+		}
+
+		return null;
+	}
+
+	public Tag [] GetTagsByNameStart (string s)
+	{
+		ArrayList l = new ArrayList ();
+		foreach (Tag t in this.item_cache.Values) {
+			if (t.Name.ToLower ().StartsWith (s.ToLower ()))
+				l.Add (t);
+		}
+
+		if (l.Count == 0)
+			return null;
+
+		return (Tag []) (l.ToArray (typeof (Tag)));
+	}
+
 	// In this store we keep all the items (i.e. the tags) in memory at all times.  This is
 	// mostly to simplify handling of the parent relationship between tags, but it also makes it
 	// a little bit faster.  We achieve this by passing "true" as the cache_is_immortal to our
Index: f-spot.glade
===================================================================
RCS file: /cvs/gnome/f-spot/src/f-spot.glade,v
retrieving revision 1.115
diff -u -r1.115 f-spot.glade
--- f-spot.glade	7 Nov 2005 20:06:48 -0000	1.115
+++ f-spot.glade	9 Nov 2005 03:19:19 -0000
@@ -6735,7 +6735,7 @@
 		      <signal name="activate" handler="HandleSendMailCommand" last_modification_time="Mon, 07 Jun 2004 22:31:01 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image22">
+			<widget class="GtkImage" id="image24">
 			  <property name="visible">True</property>
 			  <property name="stock">gnome-stock-mail-fwd</property>
 			  <property name="icon_size">1</property>
@@ -7065,7 +7065,7 @@
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">_Month</property>
 			      <property name="use_underline">True</property>
-			      <property name="active">True</property>
+			      <property name="active">False</property>
 			      <signal name="activate" handler="HandleArrangeByTime" last_modification_time="Fri, 20 Aug 2004 22:26:32 GMT"/>
 			    </widget>
 			  </child>
@@ -7405,7 +7405,90 @@
 		  <property name="spacing">0</property>
 
 		  <child>
-		    <placeholder/>
+		    <widget class="GtkHBox" id="tagbar">
+		      <property name="border_width">2</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">1</property>
+
+		      <child>
+			<widget class="GtkLabel" id="label160">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Tags: </property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="tag_entry">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="has_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">*</property>
+			  <property name="activates_default">False</property>
+			  <signal name="activate" handler="HandleTagEntryActivate" last_modification_time="Mon, 07 Nov 2005 20:18:18 GMT"/>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="tag_close_button">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="relief">GTK_RELIEF_NONE</property>
+			  <property name="focus_on_click">True</property>
+			  <signal name="pressed" handler="HandleTagBarCloseButtonPressed" last_modification_time="Tue, 08 Nov 2005 01:22:39 GMT"/>
+
+			  <child>
+			    <widget class="GtkImage" id="image23">
+			      <property name="visible">True</property>
+			      <property name="stock">gtk-close</property>
+			      <property name="icon_size">4</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">True</property>
+		      <property name="pack_type">GTK_PACK_END</property>
+		    </packing>
 		  </child>
 
 		  <child>
@@ -7671,6 +7754,7 @@
 	  <property name="padding">0</property>
 	  <property name="expand">False</property>
 	  <property name="fill">False</property>
+	  <property name="pack_type">GTK_PACK_END</property>
 	</packing>
       </child>
     </widget>


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