[f-spot: 3/3] Merge branch 'FSPOT_0_6_0_STABLE'



commit 9d5bdcf35b764df791d6e68972f5b6f47496141e
Merge: 282e06e... c48a59d...
Author: Stephane Delcroix <stephane delcroix org>
Date:   Mon Oct 19 09:23:15 2009 +0200

    Merge branch 'FSPOT_0_6_0_STABLE'

 .../FacebookExport/FacebookExport.addin.xml        |    2 +-
 .../Mono.Facebook/FacebookSession.cs               |   18 +++++++++++++++---
 src/MainWindow.cs                                  |    1 +
 3 files changed, 17 insertions(+), 4 deletions(-)
---
diff --cc src/MainWindow.cs
index 92ba798,cf9a967..e32e3f6
--- a/src/MainWindow.cs
+++ b/src/MainWindow.cs
@@@ -27,2576 -24,2746 +27,2577 @@@ using FSpot.Utils
  using FSpot.UI.Dialog;
  using FSpot.Platform;
  
 -using LibGPhoto2;
 -
 -public class MainWindow {
 -
 -    public static MainWindow Toplevel;
 -
 -	Db db;
 -
 -	public Sidebar Sidebar;
 +using GPhoto2;
  
 -	TagSelectionWidget tag_selection_widget;
 -	[GtkBeans.Builder.Object] Gtk.Window main_window;
 -
 -	[GtkBeans.Builder.Object] Gtk.HPaned main_hpaned;
 -	[GtkBeans.Builder.Object] Gtk.VBox left_vbox;
 -	[GtkBeans.Builder.Object] Gtk.VBox group_vbox;
 -	[GtkBeans.Builder.Object] Gtk.VBox view_vbox;
 -
 -	[GtkBeans.Builder.Object] Gtk.VBox toolbar_vbox;
 -
 -	[GtkBeans.Builder.Object] ScrolledWindow icon_view_scrolled;
 -	[GtkBeans.Builder.Object] Box photo_box;
 -	[GtkBeans.Builder.Object] Notebook view_notebook;
 +namespace FSpot
 +{
 +	public class MainWindow
 +	{
 +		public static MainWindow Toplevel;
 +		public Sidebar Sidebar { get; private set; }
  	
 -	ScrolledWindow tag_selection_scrolled;
 -
 -	[GtkBeans.Builder.Object] Label status_label;
 -
 -	[GtkBeans.Builder.Object] Gtk.UIManager uimanager;
 -	// File
 -	[GtkBeans.Builder.Object] Gtk.Action create_version_menu_item;
 -	[GtkBeans.Builder.Object] Gtk.Action delete_version_menu_item;
 -	[GtkBeans.Builder.Object] Gtk.Action rename_version_menu_item;
 -	
 -	[GtkBeans.Builder.Object] Gtk.Action tools;
 -	[GtkBeans.Builder.Object] Gtk.Action export;
 -	[GtkBeans.Builder.Object] Gtk.Action pagesetup_menu_item;
 -	[GtkBeans.Builder.Object] Gtk.Action print;
 -	[GtkBeans.Builder.Object] Gtk.Action send_mail;
 -
 -	// Edit
 -	[GtkBeans.Builder.Object] Gtk.Action copy_location;
 -	[GtkBeans.Builder.Object] Gtk.Action select_none;
 -	[GtkBeans.Builder.Object] Gtk.Action rotate_left;
 -	[GtkBeans.Builder.Object] Gtk.Action rotate_right;
 -
 -	[GtkBeans.Builder.Object] Gtk.Action sharpen;
 -	[GtkBeans.Builder.Object] Gtk.Action adjust_time;
 -
 -	[GtkBeans.Builder.Object] Gtk.Action update_thumbnail;
 -	[GtkBeans.Builder.Object] Gtk.Action delete_from_drive;
 -	[GtkBeans.Builder.Object] Gtk.Action remove_from_catalog;
 -	[GtkBeans.Builder.Object] Gtk.Action set_as_background;
 -
 -	[GtkBeans.Builder.Object] Gtk.Action attach_tag;
 -	[GtkBeans.Builder.Object] Gtk.Action remove_tag;
 -
 -	// View
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction display_toolbar;
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction display_sidebar;
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction display_timeline;
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction display_filmstrip;
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction display_dates_menu_item;
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction display_tags_menu_item;
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction display_ratings_menu_item;
 -
 -	[GtkBeans.Builder.Object] Gtk.Action zoom_in;
 -	[GtkBeans.Builder.Object] Gtk.Action zoom_out;
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction loupe_menu_item;
 -
 -	[GtkBeans.Builder.Object] Gtk.RadioAction tag_icon_hidden;
 -	[GtkBeans.Builder.Object] Gtk.RadioAction tag_icon_small;
 -	[GtkBeans.Builder.Object] Gtk.RadioAction tag_icon_medium;
 -	[GtkBeans.Builder.Object] Gtk.RadioAction tag_icon_large;
 -
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction reverse_order;
 -	public Gtk.ToggleAction ReverseOrderAction {
 -		get { return reverse_order; }
 -	}
 -
 -	// Find
 -	[GtkBeans.Builder.Object] Gtk.Action clear_date_range;
 -	[GtkBeans.Builder.Object] Gtk.Action clear_rating_filter;
 -
 -	[GtkBeans.Builder.Object] Gtk.ToggleAction find_untagged;
 +		TagSelectionWidget tag_selection_widget;
 +		[GtkBeans.Builder.Object] Gtk.Window main_window;
 +		public Gtk.Window Window { 
 +			get { return main_window; }
 +		}
  	
 -	[GtkBeans.Builder.Object] Gtk.Action clear_roll_filter;	
 +		[GtkBeans.Builder.Object] Gtk.HPaned main_hpaned;
 +		[GtkBeans.Builder.Object] Gtk.VBox left_vbox;
 +		[GtkBeans.Builder.Object] Gtk.VBox group_vbox;
 +		[GtkBeans.Builder.Object] Gtk.VBox view_vbox;
  	
 -	// Tags
 -	[GtkBeans.Builder.Object] Gtk.Action edit_selected_tag;
 -	[GtkBeans.Builder.Object] Gtk.Action delete_selected_tag;
 -
 -	[GtkBeans.Builder.Object] Gtk.Action attach_tag_to_selection;
 -	[GtkBeans.Builder.Object] Gtk.Action remove_tag_from_selection;
 +		[GtkBeans.Builder.Object] Gtk.VBox toolbar_vbox;
  	
 -	// Other Widgets
 -	[GtkBeans.Builder.Object] Scale zoom_scale;
 -
 -	[GtkBeans.Builder.Object] VBox info_vbox;
 -
 -	[GtkBeans.Builder.Object] Gtk.HBox tagbar;
 -	[GtkBeans.Builder.Object] Gtk.VBox tag_entry_container;
 -	[GtkBeans.Builder.Object] Gtk.VBox sidebar_vbox;
 -	TagEntry tag_entry;
 -
 -	Gtk.Toolbar toolbar;
 -
 -	FindBar find_bar;
 -
 -	PhotoVersionMenu versions_submenu;
 -
 -	Gtk.ToggleToolButton browse_button;
 -	Gtk.ToggleToolButton edit_button;
 -
 -	InfoBox info_box;
 -	QueryView icon_view;
 -	PhotoView photo_view;
 -	FSpot.FullScreenView fsview;
 -	FSpot.PhotoQuery query;
 -	FSpot.GroupSelector group_selector;
 -	FSpot.QueryWidget query_widget;
 -	MainSelection selection;
 -	
 -	ToolButton rl_button;
 -	ToolButton rr_button;
 -
 -	Label count_label;
 -
 -	Gtk.ToolButton display_next_button;
 -	Gtk.ToolButton display_previous_button;
 +		[GtkBeans.Builder.Object] ScrolledWindow icon_view_scrolled;
 +		[GtkBeans.Builder.Object] Box photo_box;
 +		[GtkBeans.Builder.Object] Notebook view_notebook;
 +		
 +		ScrolledWindow tag_selection_scrolled;
  	
 -	ModeType view_mode;
 -	bool write_metadata = false;
 -
 -	Gdk.Cursor watch = new Gdk.Cursor (Gdk.CursorType.Watch);
 -
 -	// Tag Icon Sizes
 -	public int TagsIconSize {
 -		get { return (int) Tag.TagIconSize; }
 -		set { Tag.TagIconSize = (Tag.IconSize) value; }
 -	}
 -
 -	public PhotoView PhotoView {
 -		get { return photo_view; }
 -	}
 -
 -	private static TargetEntry [] icon_source_target_table = 
 -		new TargetEntry [] {
 -			DragDropTargets.PhotoListEntry,
 -			DragDropTargets.TagQueryEntry,
 -			DragDropTargets.UriListEntry,
 -			DragDropTargets.RootWindowEntry
 -	};
 -	
 -	private static TargetEntry [] icon_dest_target_table = 
 -		new TargetEntry [] {
 -#if ENABLE_REPARENTING
 -			DragDropTargets.PhotoListEntry,
 -#endif
 -			DragDropTargets.TagListEntry,
 -			DragDropTargets.UriListEntry
 -	};
 -	
 -	private static TargetEntry [] tag_target_table = 
 -		new TargetEntry [] {
 -			DragDropTargets.TagListEntry
 -	};
 -	
 -	private static TargetEntry [] tag_dest_target_table = 
 -		new TargetEntry [] {
 -			DragDropTargets.PhotoListEntry,
 -			DragDropTargets.UriListEntry,
 -			DragDropTargets.TagListEntry
 -	};
 -
 -	const int PHOTO_IDX_NONE = -1;
 -
 -	private static Gtk.Tooltips toolTips;
 -	public static Gtk.Tooltips ToolTips {
 -		get {
 -			if (toolTips == null)
 -				toolTips = new Gtk.Tooltips ();
 -			return toolTips;
 +		[GtkBeans.Builder.Object] Label status_label;
 +	
 +		[GtkBeans.Builder.Object] Gtk.UIManager uimanager;
 +		// File
 +		[GtkBeans.Builder.Object] Gtk.Action create_version_menu_item;
 +		[GtkBeans.Builder.Object] Gtk.Action delete_version_menu_item;
 +		[GtkBeans.Builder.Object] Gtk.Action rename_version_menu_item;
 +		
 +		[GtkBeans.Builder.Object] Gtk.Action tools;
 +		[GtkBeans.Builder.Object] Gtk.Action export;
 +		[GtkBeans.Builder.Object] Gtk.Action pagesetup_menu_item;
 +		[GtkBeans.Builder.Object] Gtk.Action print;
 +		[GtkBeans.Builder.Object] Gtk.Action send_mail;
 +	
 +		// Edit
 +		[GtkBeans.Builder.Object] Gtk.Action copy_location;
 +		[GtkBeans.Builder.Object] Gtk.Action select_none;
 +		[GtkBeans.Builder.Object] Gtk.Action rotate_left;
 +		[GtkBeans.Builder.Object] Gtk.Action rotate_right;
 +	
 +		[GtkBeans.Builder.Object] Gtk.Action sharpen;
 +		[GtkBeans.Builder.Object] Gtk.Action adjust_time;
 +	
 +		[GtkBeans.Builder.Object] Gtk.Action update_thumbnail;
 +		[GtkBeans.Builder.Object] Gtk.Action delete_from_drive;
 +		[GtkBeans.Builder.Object] Gtk.Action remove_from_catalog;
 +		[GtkBeans.Builder.Object] Gtk.Action set_as_background;
 +	
 +		[GtkBeans.Builder.Object] Gtk.Action attach_tag;
 +		[GtkBeans.Builder.Object] Gtk.Action remove_tag;
 +	
 +		// View
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction display_toolbar;
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction display_sidebar;
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction display_timeline;
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction display_filmstrip;
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction display_dates_menu_item;
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction display_tags_menu_item;
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction display_ratings_menu_item;
 +	
 +		[GtkBeans.Builder.Object] Gtk.Action zoom_in;
 +		[GtkBeans.Builder.Object] Gtk.Action zoom_out;
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction loupe_menu_item;
 +	
 +		[GtkBeans.Builder.Object] Gtk.RadioAction tag_icon_hidden;
 +		[GtkBeans.Builder.Object] Gtk.RadioAction tag_icon_small;
 +		[GtkBeans.Builder.Object] Gtk.RadioAction tag_icon_medium;
 +		[GtkBeans.Builder.Object] Gtk.RadioAction tag_icon_large;
 +	
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction reverse_order;
 +		public Gtk.ToggleAction ReverseOrderAction {
 +			get { return reverse_order; }
  		}
 -	}
 -
 -	//
 -	// Public Properties
 -	//
 -
 -	public Db Database {
 -		get { return db; }
 -	}
 -
 -	public Gtk.Window Window {
 -		get { return main_window; }
 -	}
  	
 -	public ModeType ViewMode {
 -		get { return view_mode; }
 -	}
 -
 -	public MainSelection Selection {
 -		get { return selection; }
 -	}
 -
 -	public MenuItem FindByTag {
 -		get { return uimanager.GetWidget ("/ui/menubar1/find/find_by_tag") as MenuItem; }
 -	}
 -
 -	public InfoBox InfoBox {
 -		get { return info_box; }
 -	}
 -
 -	//
 -	// Constructor
 -	//
 -	public MainWindow (Db db)
 -	{
 -		this.db = db;
 -
 -		if (Toplevel == null)
 -			Toplevel = this;
 -
 -		GtkBeans.Builder builder = new GtkBeans.Builder ("main_window.ui");
 -		builder.Autoconnect (this);
 -
 -		LoadPreference (Preferences.MAIN_WINDOW_WIDTH);
 -		LoadPreference (Preferences.MAIN_WINDOW_X);
 -		LoadPreference (Preferences.MAIN_WINDOW_MAXIMIZED);
 -		main_window.ShowAll ();
 -
 -		LoadPreference (Preferences.SIDEBAR_POSITION);
 -		LoadPreference (Preferences.METADATA_EMBED_IN_IMAGE);
 -
 -		pagesetup_menu_item.Activated += HandlePageSetupActivated;
 -
 -		toolbar = new Gtk.Toolbar ();
 -		toolbar_vbox.PackStart (toolbar);
 -
 -		ToolButton import_button = GtkUtil.ToolButtonFromTheme ("gtk-add", Catalog.GetString ("Import"), false);
 -		import_button.Clicked += HandleImportCommand;
 -		import_button.SetTooltip (ToolTips, Catalog.GetString ("Import new images"), null);
 -		toolbar.Insert (import_button, -1);
 +		// Find
 +		[GtkBeans.Builder.Object] Gtk.Action clear_date_range;
 +		[GtkBeans.Builder.Object] Gtk.Action clear_rating_filter;
  	
 -		toolbar.Insert (new SeparatorToolItem (), -1);
 -
 -		rl_button = GtkUtil.ToolButtonFromTheme ("object-rotate-left", Catalog.GetString ("Rotate Left"), true);
 -		rl_button.Clicked += HandleRotate270Command;
 -		toolbar.Insert (rl_button, -1);
 -
 -		rr_button = GtkUtil.ToolButtonFromTheme ("object-rotate-right", Catalog.GetString ("Rotate Right"), true);
 -		rr_button.Clicked += HandleRotate90Command;
 -		toolbar.Insert (rr_button, -1);
 -
 -		toolbar.Insert (new SeparatorToolItem (), -1);
 -
 -		browse_button = new ToggleToolButton ();
 -		browse_button.Label = Catalog.GetString ("Browse");
 -		browse_button.IconName = "mode-browse";
 -		browse_button.IsImportant = true;
 -		browse_button.Toggled += HandleToggleViewBrowse;
 -		browse_button.SetTooltip (ToolTips, Catalog.GetString ("Browse many photos simultaneously"), null);
 -		toolbar.Insert (browse_button, -1);
 -
 -		edit_button = new ToggleToolButton ();
 -		edit_button.Label = Catalog.GetString ("Edit Image");
 -		edit_button.IconName = "mode-image-edit";
 -		edit_button.IsImportant = true;
 -		edit_button.Toggled += HandleToggleViewPhoto;
 -		edit_button.SetTooltip (ToolTips, Catalog.GetString ("View and edit a photo"), null);
 -		toolbar.Insert (edit_button, -1);
 -
 -		toolbar.Insert (new SeparatorToolItem (), -1);
 -
 -		ToolButton fs_button = GtkUtil.ToolButtonFromTheme ("view-fullscreen", Catalog.GetString ("Fullscreen"), true);
 -		fs_button.Clicked += HandleViewFullscreen;
 -		fs_button.SetTooltip (ToolTips, Catalog.GetString ("View photos fullscreen"), null);
 -		toolbar.Insert (fs_button, -1);
 -
 -		ToolButton ss_button = GtkUtil.ToolButtonFromTheme ("media-playback-start", Catalog.GetString ("Slideshow"), true);
 -		ss_button.Clicked += HandleViewSlideShow;
 -		ss_button.SetTooltip (ToolTips, Catalog.GetString ("View photos in a slideshow"), null);
 -		toolbar.Insert (ss_button, -1);
 -
 -		SeparatorToolItem white_space = new SeparatorToolItem ();
 -		white_space.Draw = false;
 -		white_space.Expand = true;
 -		toolbar.Insert (white_space, -1);
 -
 -		ToolItem label_item = new ToolItem ();
 -		count_label = new Label (String.Empty);
 -		label_item.Child = count_label;
 -		toolbar.Insert (label_item, -1);
 -
 -		display_previous_button = new ToolButton (Stock.GoBack);
 -		toolbar.Insert (display_previous_button, -1);
 -		display_previous_button.SetTooltip (ToolTips, Catalog.GetString ("Previous photo"), String.Empty);
 -		display_previous_button.Clicked += new EventHandler (HandleDisplayPreviousButtonClicked);
 -
 -		display_next_button = new ToolButton (Stock.GoForward);
 -		toolbar.Insert (display_next_button, -1);
 -		display_next_button.SetTooltip (ToolTips, Catalog.GetString ("Next photo"), String.Empty);
 -		display_next_button.Clicked += new EventHandler (HandleDisplayNextButtonClicked);
 -
 -		Sidebar = new Sidebar ();
 -		ViewModeChanged += Sidebar.HandleMainWindowViewModeChanged;
 -		sidebar_vbox.Add (Sidebar);
 -
 -		tag_selection_scrolled = new ScrolledWindow ();
 -		tag_selection_scrolled.ShadowType = ShadowType.In;
 +		[GtkBeans.Builder.Object] Gtk.ToggleAction find_untagged;
  		
 -		tag_selection_widget = new TagSelectionWidget (db.Tags);
 -		tag_selection_scrolled.Add (tag_selection_widget);
 -
 -		Sidebar.AppendPage (tag_selection_scrolled, Catalog.GetString ("Tags"), "tag");
 -
 -		AddinManager.AddExtensionNodeHandler ("/FSpot/Sidebar", OnSidebarExtensionChanged);
 -
 -		Sidebar.Context = ViewContext.Library;
 - 		
 -		Sidebar.CloseRequested += HideSidebar;
 -		Sidebar.Show ();
 -
 -		info_box = new InfoBox ();
 -		ViewModeChanged += info_box.HandleMainWindowViewModeChanged;
 -		info_box.VersionIdChanged += delegate (InfoBox box, uint version_id) { UpdateForVersionIdChange (version_id);};
 -		sidebar_vbox.PackEnd (info_box, false, false, 0);
 -
 -		info_box.Context = ViewContext.Library;
 +		[GtkBeans.Builder.Object] Gtk.Action clear_roll_filter;	
  		
 -		tag_selection_widget.Selection.Changed += HandleTagSelectionChanged;
 -		tag_selection_widget.KeyPressEvent += HandleTagSelectionKeyPress;
 -		tag_selection_widget.ButtonPressEvent += HandleTagSelectionButtonPressEvent;
 -		tag_selection_widget.PopupMenu += HandleTagSelectionPopupMenu;
 -		
 -		LoadPreference (Preferences.TAG_ICON_SIZE);
 +		// Tags
 +		[GtkBeans.Builder.Object] Gtk.Action edit_selected_tag;
 +		[GtkBeans.Builder.Object] Gtk.Action delete_selected_tag;
 +	
 +		[GtkBeans.Builder.Object] Gtk.Action attach_tag_to_selection;
 +		[GtkBeans.Builder.Object] Gtk.Action remove_tag_from_selection;
  		
 -		try {
 -			query = new FSpot.PhotoQuery (db.Photos);
 -		} catch (System.Exception e) {
 -			//FIXME assume any exception here is due to a corrupt db and handle that.
 -			new RepairDbDialog (e, db.Repair (), main_window);
 -			query = new FSpot.PhotoQuery (db.Photos);
 -		}
 -
 -		UpdateStatusLabel ();
 -		query.Changed += HandleQueryChanged;
 -
 -		db.Photos.ItemsChanged += HandleDbItemsChanged;
 -		db.Tags.ItemsChanged += HandleTagsChanged;
 -		db.Tags.ItemsAdded += HandleTagsChanged;
 -		db.Tags.ItemsRemoved += HandleTagsChanged;
 -#if SHOW_CALENDAR
 -		FSpot.SimpleCalendar cal = new FSpot.SimpleCalendar (query);
 -		cal.DaySelected += HandleCalendarDaySelected;
 -		left_vbox.PackStart (cal, false, true, 0);
 -#endif
 -
 -		group_selector = new FSpot.GroupSelector ();
 -		group_selector.Adaptor = new FSpot.TimeAdaptor (query, Preferences.Get<bool> (Preferences.GROUP_ADAPTOR_ORDER_ASC));
 +		// Other Widgets
 +		[GtkBeans.Builder.Object] Scale zoom_scale;
 +	
 +		[GtkBeans.Builder.Object] VBox info_vbox;
 +	
 +		[GtkBeans.Builder.Object] Gtk.HBox tagbar;
 +		[GtkBeans.Builder.Object] Gtk.VBox tag_entry_container;
 +		[GtkBeans.Builder.Object] Gtk.VBox sidebar_vbox;
 +		TagEntry tag_entry;
 +	
 +		Gtk.Toolbar toolbar;
 +	
 +		FindBar find_bar;
 +	
 +		PhotoVersionMenu versions_submenu;
 +	
 +		Gtk.ToggleToolButton browse_button;
 +		Gtk.ToggleToolButton edit_button;
 +	
 +		QueryView icon_view;
  
 -		group_selector.ShowAll ();
 -		
 -		if (zoom_scale != null) {
 -			zoom_scale.ValueChanged += HandleZoomScaleValueChanged;
 +		PhotoView photo_view;
 +		public PhotoView PhotoView {
 +			get { return photo_view; }
  		}
 -
 -		view_vbox.PackStart (group_selector, false, false, 0);
 -		view_vbox.ReorderChild (group_selector, 0);
 -
 -		find_bar = new FindBar (query, tag_selection_widget.Model);
 -		view_vbox.PackStart (find_bar, false, false, 0);
 -		view_vbox.ReorderChild (find_bar, 1);
 -		main_window.KeyPressEvent += HandleKeyPressEvent;
 -		
 -		query_widget = new FSpot.QueryWidget (query, db);
 -		query_widget.Logic.Changed += HandleQueryLogicChanged;
 -		view_vbox.PackStart (query_widget, false, false, 0);
 -		view_vbox.ReorderChild (query_widget, 2);
 -
 -		icon_view = new QueryView (query);
 -		icon_view.ZoomChanged += HandleZoomChanged;
 -		LoadPreference (Preferences.ZOOM);
 -		LoadPreference (Preferences.SHOW_TAGS);
 -		LoadPreference (Preferences.SHOW_DATES);
 -		LoadPreference (Preferences.SHOW_RATINGS);
 -		icon_view_scrolled.Add (icon_view);
 -		icon_view.DoubleClicked += HandleDoubleClicked;
 -		icon_view.Vadjustment.ValueChanged += HandleIconViewScroll;
 -		icon_view.GrabFocus ();
 -
 -		new FSpot.PreviewPopup (icon_view);
 -
 -		Gtk.Drag.SourceSet (icon_view, Gdk.ModifierType.Button1Mask | Gdk.ModifierType.Button3Mask,
 -				    icon_source_target_table, DragAction.Copy | DragAction.Move);
 -		
 -		icon_view.DragBegin += HandleIconViewDragBegin;
 -		icon_view.DragDataGet += HandleIconViewDragDataGet;
 -
 -		TagMenu tag_menu = new TagMenu (null, Database.Tags);
 -		tag_menu.NewTagHandler += delegate { HandleCreateTagAndAttach (this, null); };
 -		tag_menu.TagSelected += HandleAttachTagMenuSelected;
 -		tag_menu.Populate();
 -		(uimanager.GetWidget("/ui/menubar1/edit2/attach_tag") as MenuItem).Submenu = tag_menu;
 -		
 -		PhotoTagMenu pmenu = new PhotoTagMenu ();
 -		pmenu.TagSelected += HandleRemoveTagMenuSelected;
 -		(uimanager.GetWidget("/ui/menubar1/edit2/remove_tag") as MenuItem).Submenu = pmenu;
 -		
 -		Gtk.Drag.DestSet (icon_view, DestDefaults.All, icon_dest_target_table, 
 -				  DragAction.Copy | DragAction.Move); 
 -
 -		//		icon_view.DragLeave += new DragLeaveHandler (HandleIconViewDragLeave);
 -		icon_view.DragMotion += HandleIconViewDragMotion;
 -		icon_view.DragDrop += HandleIconViewDragDrop;
 -		icon_view.DragDataReceived += HandleIconViewDragDataReceived;
 -		icon_view.KeyPressEvent += HandleIconViewKeyPressEvent;
 -
 -		photo_view = new PhotoView (query);
 -		photo_box.Add (photo_view);
 -
 -		photo_view.DoubleClicked += HandleDoubleClicked;
 -		photo_view.KeyPressEvent += HandlePhotoViewKeyPressEvent;
 -		photo_view.UpdateStarted += HandlePhotoViewUpdateStarted;
 -		photo_view.UpdateFinished += HandlePhotoViewUpdateFinished;
 -
 -		photo_view.View.ZoomChanged += HandleZoomChanged;
 -
 -		// Tag typing: focus the tag entry if the user starts typing a tag
 -		icon_view.KeyPressEvent += HandlePossibleTagTyping;
 -		photo_view.KeyPressEvent += HandlePossibleTagTyping;
 -		tag_entry = new TagEntry (db.Tags);
 -		tag_entry.KeyPressEvent += HandleTagEntryKeyPressEvent;
 -		tag_entry.TagsAttached += HandleTagEntryTagsAttached;
 -		tag_entry.TagsRemoved += HandleTagEntryRemoveTags;
 -		tag_entry.Activated += HandleTagEntryActivate;
 -		tag_entry_container.Add (tag_entry);
 -
 -		Gtk.Drag.DestSet (photo_view, DestDefaults.All, tag_target_table, 
 -				  DragAction.Copy | DragAction.Move); 
 -
 -		photo_view.DragMotion += HandlePhotoViewDragMotion;
 -		photo_view.DragDrop += HandlePhotoViewDragDrop;
 -		photo_view.DragDataReceived += HandlePhotoViewDragDataReceived;
 -
 -		view_notebook.SwitchPage += HandleViewNotebookSwitchPage;
 -		group_selector.Adaptor.GlassSet += HandleAdaptorGlassSet;
 -		group_selector.Adaptor.Changed += HandleAdaptorChanged;
 -		LoadPreference (Preferences.GROUP_ADAPTOR_ORDER_ASC);
 -		LoadPreference (Preferences.FILMSTRIP_ORIENTATION);
 -
 -		this.selection = new MainSelection (this);
 -		this.selection.Changed += HandleSelectionChanged;
 -		this.selection.ItemsChanged += HandleSelectionItemsChanged;
 -		this.selection.Changed += Sidebar.HandleSelectionChanged;
 -		this.selection.ItemsChanged += Sidebar.HandleSelectionItemsChanged;
 -
 -		Mono.Addins.AddinManager.ExtensionChanged += PopulateExtendableMenus;
 -		PopulateExtendableMenus (null, null);
 -
 -		UpdateMenus ();
 -
 -		main_window.ShowAll ();
 -
 -		tagbar.Hide ();
 -		find_bar.Hide ();
 -
 -		UpdateFindByTagMenu ();
 -
 -		LoadPreference (Preferences.SHOW_TOOLBAR);
 -		LoadPreference (Preferences.SHOW_SIDEBAR);
 -		LoadPreference (Preferences.SHOW_TIMELINE);
 -		LoadPreference (Preferences.SHOW_FILMSTRIP);
 -
 -		LoadPreference (Preferences.GNOME_MAILTO_ENABLED);
 +	
 +		FSpot.FullScreenView fsview;
 +		FSpot.PhotoQuery query;
 +		FSpot.GroupSelector group_selector;
 +		FSpot.QueryWidget query_widget;
  		
 -		Preferences.SettingChanged += OnPreferencesChanged;
 -
 -		main_window.DeleteEvent += HandleDeleteEvent;
 +		ToolButton rl_button;
 +		ToolButton rr_button;
 +	
 +		Label count_label;
 +	
 +		Gtk.ToolButton display_next_button;
 +		Gtk.ToolButton display_previous_button;
  		
 -		query_widget.HandleChanged (query);
 -		query_widget.Close ();
 -
 -		// When the icon_view is loaded, set it's initial scroll position
 -		icon_view.SizeAllocated += HandleIconViewReady;
 -
 -		export.Activated += HandleExportActivated;
 -		UpdateToolbar ();
 -
 -		(uimanager.GetWidget("/ui/menubar1/file1/close1") as MenuItem).Hide ();
 -
 -		Banshee.Kernel.Scheduler.Resume ();
 -	}
 -
 -	private void HandleDisplayNextButtonClicked (object sender, EventArgs args)
 -	{
 -		PhotoView.View.Item.MoveNext ();
 -	}
 -
 -	private void HandleDisplayPreviousButtonClicked (object sender, EventArgs args)
 -	{
 -		PhotoView.View.Item.MovePrevious ();
 -	}
 -
 -	private void OnSidebarExtensionChanged (object s, ExtensionNodeEventArgs args) {
 -		// FIXME: No sidebar page removal yet!
 -		if (args.Change == ExtensionChange.Add)
 -			Sidebar.AppendPage ((args.ExtensionNode as SidebarPageNode).GetSidebarPage ());
 -	}
 -
 -	private Photo CurrentPhoto {
 -		get {
 -			int active = ActiveIndex ();
 -			if (active >= 0)
 -				return query [active] as Photo;
 -			else
 -				return null;
 +		bool write_metadata = false;
 +	
 +		Gdk.Cursor watch = new Gdk.Cursor (Gdk.CursorType.Watch);
 +	
 +		// Tag Icon Sizes
 +		public int TagsIconSize {
 +			get { return (int) Tag.TagIconSize; }
 +			set { Tag.TagIconSize = (Tag.IconSize) value; }
  		}
 -	}
 -
 -	// Index into the PhotoQuery.  If -1, no photo is selected or multiple photos are selected.
 -	private int ActiveIndex () 
 -	{
 -		if (selection.Count == 1)
 -			return SelectedIds() [0];
 -		else
 -			return PHOTO_IDX_NONE;
 -	}
 -
 -	// Switching mode.
 -	public enum ModeType {
 -		IconView,
 -		PhotoView
 -	};
 -
 -	public event EventHandler ViewModeChanged;
 -
 -	public void SetViewMode (ModeType value)
 -	{
 -		if (view_mode == value)
 -			return;
 -
 -		view_mode = value;
 -		switch (view_mode) {
 -		case ModeType.IconView:
 -			if (view_notebook.CurrentPage != 0)
 -				view_notebook.CurrentPage = 0;
 -
 -			display_timeline.Sensitive = true;
 -			display_filmstrip.Sensitive = false;
 -			group_selector.Visible = display_timeline.Active;
 -
 -			if (photo_view.View.Loupe != null)
 -				loupe_menu_item.Active = false;
 -			JumpTo (photo_view.Item.Index);
 -			zoom_scale.Value = icon_view.Zoom;
 -			break;
 -		case ModeType.PhotoView:
 -			if (view_notebook.CurrentPage != 1)
 -				view_notebook.CurrentPage = 1;
 -
 -			display_timeline.Sensitive = false;
 -			display_filmstrip.Sensitive = true;
 -			group_selector.Visible = false;
 -			
 -			JumpTo (icon_view.FocusCell);
 -			zoom_scale.Value = photo_view.NormalizedZoom;
 -
 -			photo_view.View.GrabFocus();
 -			break;
 +	
 +		private static TargetEntry [] icon_source_target_table = 
 +			new TargetEntry [] {
 +				DragDropTargets.PhotoListEntry,
 +				DragDropTargets.TagQueryEntry,
 +				DragDropTargets.UriListEntry,
 +				DragDropTargets.RootWindowEntry
 +		};
 +		
 +		private static TargetEntry [] icon_dest_target_table = 
 +			new TargetEntry [] {
 +	#if ENABLE_REPARENTING
 +				DragDropTargets.PhotoListEntry,
 +	#endif
 +				DragDropTargets.TagListEntry,
 +				DragDropTargets.UriListEntry
 +		};
 +		
 +		private static TargetEntry [] tag_target_table = 
 +			new TargetEntry [] {
 +				DragDropTargets.TagListEntry
 +		};
 +		
 +		private static TargetEntry [] tag_dest_target_table = 
 +			new TargetEntry [] {
 +				DragDropTargets.PhotoListEntry,
 +				DragDropTargets.UriListEntry,
 +				DragDropTargets.TagListEntry
 +		};
 +	
 +		const int PHOTO_IDX_NONE = -1;
 +	
 +		private static Gtk.Tooltips toolTips;
 +		public static Gtk.Tooltips ToolTips {
 +			get {
 +				if (toolTips == null)
 +					toolTips = new Gtk.Tooltips ();
 +				return toolTips;
 +			}
  		}
 -		Selection.MarkChanged ();
 -		UpdateToolbar ();
 -		if (ViewModeChanged != null) 
 -			ViewModeChanged (this, null);
 -	}
  	
 -	void UpdateToolbar ()
 -	{
 -		if (browse_button != null) {
 -			bool state = view_mode == ModeType.IconView;
 -			
 -			if (browse_button.Active != state)
 -				browse_button.Active = state;
 +		public Db Database { get; private set; }
 +		public ModeType ViewMode { get; private set; }
 +		public MainSelection Selection { get; private set; }
 +		public InfoBox InfoBox { get; private set; }
 +	
 +		public MenuItem FindByTag {
 +			get { return uimanager.GetWidget ("/ui/menubar1/find/find_by_tag") as MenuItem; }
  		}
 -
 -		if (edit_button != null) {
 -			bool state = view_mode == ModeType.PhotoView;
 +	
 +	
 +		//
 +		// Constructor
 +		//
 +		public MainWindow (Db db)
 +		{
 +			Database = db;
 +	
 +			if (Toplevel == null)
 +				Toplevel = this;
 +	
 +			GtkBeans.Builder builder = new GtkBeans.Builder ("main_window.ui");
 +			builder.Autoconnect (this);
 +	
 +			LoadPreference (Preferences.MAIN_WINDOW_WIDTH);
 +			LoadPreference (Preferences.MAIN_WINDOW_X);
 +			LoadPreference (Preferences.MAIN_WINDOW_MAXIMIZED);
 +			main_window.ShowAll ();
 +	
 +			LoadPreference (Preferences.SIDEBAR_POSITION);
 +			LoadPreference (Preferences.METADATA_EMBED_IN_IMAGE);
 +	
 +			pagesetup_menu_item.Activated += HandlePageSetupActivated;
 +	
 +			toolbar = new Gtk.Toolbar ();
 +			toolbar_vbox.PackStart (toolbar);
 +	
 +			ToolButton import_button = GtkUtil.ToolButtonFromTheme ("gtk-add", Catalog.GetString ("Import"), true);
 +			import_button.Clicked += HandleImportCommand;
 +			import_button.SetTooltip (ToolTips, Catalog.GetString ("Import new images"), null);
 +			toolbar.Insert (import_button, -1);
 +		
 +			toolbar.Insert (new SeparatorToolItem (), -1);
 +	
 +			rl_button = GtkUtil.ToolButtonFromTheme ("object-rotate-left", Catalog.GetString ("Rotate Left"), false);
 +			rl_button.Clicked += HandleRotate270Command;
 +			toolbar.Insert (rl_button, -1);
 +	
 +			rr_button = GtkUtil.ToolButtonFromTheme ("object-rotate-right", Catalog.GetString ("Rotate Right"), false);
 +			rr_button.Clicked += HandleRotate90Command;
 +			toolbar.Insert (rr_button, -1);
 +	
 +			toolbar.Insert (new SeparatorToolItem (), -1);
 +	
 +			browse_button = new ToggleToolButton ();
 +			browse_button.Label = Catalog.GetString ("Browse");
 +			browse_button.IconName = "mode-browse";
 +			browse_button.IsImportant = true;
 +			browse_button.Toggled += HandleToggleViewBrowse;
 +			browse_button.SetTooltip (ToolTips, Catalog.GetString ("Browse many photos simultaneously"), null);
 +			toolbar.Insert (browse_button, -1);
 +	
 +			edit_button = new ToggleToolButton ();
 +			edit_button.Label = Catalog.GetString ("Edit Image");
 +			edit_button.IconName = "mode-image-edit";
 +			edit_button.IsImportant = true;
 +			edit_button.Toggled += HandleToggleViewPhoto;
 +			edit_button.SetTooltip (ToolTips, Catalog.GetString ("View and edit a photo"), null);
 +			toolbar.Insert (edit_button, -1);
 +	
 +			toolbar.Insert (new SeparatorToolItem (), -1);
 +	
 +			ToolButton fs_button = GtkUtil.ToolButtonFromTheme ("view-fullscreen", Catalog.GetString ("Fullscreen"), false);
 +			fs_button.Clicked += HandleViewFullscreen;
 +			fs_button.SetTooltip (ToolTips, Catalog.GetString ("View photos fullscreen"), null);
 +			toolbar.Insert (fs_button, -1);
 +	
 +			ToolButton ss_button = GtkUtil.ToolButtonFromTheme ("media-playback-start", Catalog.GetString ("Slideshow"), false);
 +			ss_button.Clicked += HandleViewSlideShow;
 +			ss_button.SetTooltip (ToolTips, Catalog.GetString ("View photos in a slideshow"), null);
 +			toolbar.Insert (ss_button, -1);
 +	
 +			SeparatorToolItem white_space = new SeparatorToolItem ();
 +			white_space.Draw = false;
 +			white_space.Expand = true;
 +			toolbar.Insert (white_space, -1);
 +	
 +			ToolItem label_item = new ToolItem ();
 +			count_label = new Label (String.Empty);
 +			label_item.Child = count_label;
 +			toolbar.Insert (label_item, -1);
 +	
 +			display_previous_button = new ToolButton (Stock.GoBack);
 +			toolbar.Insert (display_previous_button, -1);
 +			display_previous_button.SetTooltip (ToolTips, Catalog.GetString ("Previous photo"), String.Empty);
 +			display_previous_button.Clicked += new EventHandler (HandleDisplayPreviousButtonClicked);
 +	
 +			display_next_button = new ToolButton (Stock.GoForward);
 +			toolbar.Insert (display_next_button, -1);
 +			display_next_button.SetTooltip (ToolTips, Catalog.GetString ("Next photo"), String.Empty);
 +			display_next_button.Clicked += new EventHandler (HandleDisplayNextButtonClicked);
 +	
 +			Sidebar = new Sidebar ();
 +			ViewModeChanged += Sidebar.HandleMainWindowViewModeChanged;
 +			sidebar_vbox.Add (Sidebar);
 +	
 +			tag_selection_scrolled = new ScrolledWindow ();
 +			tag_selection_scrolled.ShadowType = ShadowType.In;
 +			
 +			tag_selection_widget = new TagSelectionWidget (Database.Tags);
 +			tag_selection_scrolled.Add (tag_selection_widget);
 +	
 +			Sidebar.AppendPage (tag_selection_scrolled, Catalog.GetString ("Tags"), "tag");
 +	
 +			AddinManager.AddExtensionNodeHandler ("/FSpot/Sidebar", OnSidebarExtensionChanged);
 +	
 +			Sidebar.Context = ViewContext.Library;
 +	 		
 +			Sidebar.CloseRequested += HideSidebar;
 +			Sidebar.Show ();
 +	
 +			InfoBox = new InfoBox ();
 +			ViewModeChanged += InfoBox.HandleMainWindowViewModeChanged;
 +			InfoBox.VersionIdChanged += delegate (InfoBox box, uint version_id) { UpdateForVersionIdChange (version_id);};
 +			sidebar_vbox.PackEnd (InfoBox, false, false, 0);
 +	
 +			InfoBox.Context = ViewContext.Library;
 +			
 +			tag_selection_widget.Selection.Changed += HandleTagSelectionChanged;
 +			tag_selection_widget.KeyPressEvent += HandleTagSelectionKeyPress;
 +			tag_selection_widget.ButtonPressEvent += HandleTagSelectionButtonPressEvent;
 +			tag_selection_widget.PopupMenu += HandleTagSelectionPopupMenu;
 +			tag_selection_widget.RowActivated += HandleTagSelectionRowActivated;
 +			
 +			LoadPreference (Preferences.TAG_ICON_SIZE);
 +			
 +			try {
 +				query = new FSpot.PhotoQuery (Database.Photos);
 +			} catch (System.Exception e) {
 +				//FIXME assume any exception here is due to a corrupt db and handle that.
 +				new RepairDbDialog (e, Database.Repair (), main_window);
 +				query = new FSpot.PhotoQuery (Database.Photos);
 +			}
 +	
 +			UpdateStatusLabel ();
 +			query.Changed += HandleQueryChanged;
 +	
 +			Database.Photos.ItemsChanged += HandleDbItemsChanged;
 +			Database.Tags.ItemsChanged += HandleTagsChanged;
 +			Database.Tags.ItemsAdded += HandleTagsChanged;
 +			Database.Tags.ItemsRemoved += HandleTagsChanged;
 +	#if SHOW_CALENDAR
 +			FSpot.SimpleCalendar cal = new FSpot.SimpleCalendar (query);
 +			cal.DaySelected += HandleCalendarDaySelected;
 +			left_vbox.PackStart (cal, false, true, 0);
 +	#endif
 +	
 +			group_selector = new FSpot.GroupSelector ();
 +			group_selector.Adaptor = new FSpot.TimeAdaptor (query, Preferences.Get<bool> (Preferences.GROUP_ADAPTOR_ORDER_ASC));
 +	
 +			group_selector.ShowAll ();
 +			
 +			if (zoom_scale != null) {
 +				zoom_scale.ValueChanged += HandleZoomScaleValueChanged;
 +			}
 +	
 +			view_vbox.PackStart (group_selector, false, false, 0);
 +			view_vbox.ReorderChild (group_selector, 0);
 +	
 +			find_bar = new FindBar (query, tag_selection_widget.Model);
 +			view_vbox.PackStart (find_bar, false, false, 0);
 +			view_vbox.ReorderChild (find_bar, 1);
 +			main_window.KeyPressEvent += HandleKeyPressEvent;
  			
 -			if (edit_button.Active != state)
 -				edit_button.Active = state;
 +			query_widget = new FSpot.QueryWidget (query, Database);
 +			query_widget.Logic.Changed += HandleQueryLogicChanged;
 +			view_vbox.PackStart (query_widget, false, false, 0);
 +			view_vbox.ReorderChild (query_widget, 2);
 +	
 +			icon_view = new QueryView (query);
 +			icon_view.ZoomChanged += HandleZoomChanged;
 +			LoadPreference (Preferences.ZOOM);
 +			LoadPreference (Preferences.SHOW_TAGS);
 +			LoadPreference (Preferences.SHOW_DATES);
 +			LoadPreference (Preferences.SHOW_RATINGS);
 +			icon_view_scrolled.Add (icon_view);
 +			icon_view.DoubleClicked += HandleDoubleClicked;
 +			icon_view.Vadjustment.ValueChanged += HandleIconViewScroll;
 +			icon_view.GrabFocus ();
 +	
 +			new FSpot.PreviewPopup (icon_view);
 +	
 +			Gtk.Drag.SourceSet (icon_view, Gdk.ModifierType.Button1Mask | Gdk.ModifierType.Button3Mask,
 +					    icon_source_target_table, DragAction.Copy | DragAction.Move);
 +			
 +			icon_view.DragBegin += HandleIconViewDragBegin;
 +			icon_view.DragDataGet += HandleIconViewDragDataGet;
 +	
 +			TagMenu tag_menu = new TagMenu (null, Database.Tags);
 +			tag_menu.NewTagHandler += delegate { HandleCreateTagAndAttach (this, null); };
 +			tag_menu.TagSelected += HandleAttachTagMenuSelected;
 +			tag_menu.Populate();
 +			(uimanager.GetWidget("/ui/menubar1/edit2/attach_tag") as MenuItem).Submenu = tag_menu;
 +			
 +			PhotoTagMenu pmenu = new PhotoTagMenu ();
 +			pmenu.TagSelected += HandleRemoveTagMenuSelected;
 +			(uimanager.GetWidget("/ui/menubar1/edit2/remove_tag") as MenuItem).Submenu = pmenu;
 +			
 +			Gtk.Drag.DestSet (icon_view, DestDefaults.All, icon_dest_target_table, 
 +					  DragAction.Copy | DragAction.Move); 
 +	
 +			//		icon_view.DragLeave += new DragLeaveHandler (HandleIconViewDragLeave);
 +			icon_view.DragMotion += HandleIconViewDragMotion;
 +			icon_view.DragDrop += HandleIconViewDragDrop;
 +			icon_view.DragDataReceived += HandleIconViewDragDataReceived;
 +			icon_view.KeyPressEvent += HandleIconViewKeyPressEvent;
 +	
 +			photo_view = new PhotoView (query);
 +			photo_box.Add (photo_view);
 +	
 +			photo_view.DoubleClicked += HandleDoubleClicked;
 +			photo_view.KeyPressEvent += HandlePhotoViewKeyPressEvent;
 +			photo_view.UpdateStarted += HandlePhotoViewUpdateStarted;
 +			photo_view.UpdateFinished += HandlePhotoViewUpdateFinished;
 +	
 +			photo_view.View.ZoomChanged += HandleZoomChanged;
 +	
 +			// Tag typing: focus the tag entry if the user starts typing a tag
 +			icon_view.KeyPressEvent += HandlePossibleTagTyping;
 +			photo_view.KeyPressEvent += HandlePossibleTagTyping;
 +			tag_entry = new TagEntry (Database.Tags);
 +			tag_entry.KeyPressEvent += HandleTagEntryKeyPressEvent;
 +			tag_entry.TagsAttached += HandleTagEntryTagsAttached;
 +			tag_entry.TagsRemoved += HandleTagEntryRemoveTags;
 +			tag_entry.Activated += HandleTagEntryActivate;
 +			tag_entry_container.Add (tag_entry);
 +	
 +			Gtk.Drag.DestSet (photo_view, DestDefaults.All, tag_target_table, 
 +					  DragAction.Copy | DragAction.Move); 
 +	
 +			photo_view.DragMotion += HandlePhotoViewDragMotion;
 +			photo_view.DragDrop += HandlePhotoViewDragDrop;
 +			photo_view.DragDataReceived += HandlePhotoViewDragDataReceived;
 +	
 +			view_notebook.SwitchPage += HandleViewNotebookSwitchPage;
 +			group_selector.Adaptor.GlassSet += HandleAdaptorGlassSet;
 +			group_selector.Adaptor.Changed += HandleAdaptorChanged;
 +			LoadPreference (Preferences.GROUP_ADAPTOR_ORDER_ASC);
 +			LoadPreference (Preferences.FILMSTRIP_ORIENTATION);
 +	
 +			Selection = new MainSelection (this);
 +			Selection.Changed += HandleSelectionChanged;
 +			Selection.ItemsChanged += HandleSelectionItemsChanged;
 +			Selection.Changed += Sidebar.HandleSelectionChanged;
 +			Selection.ItemsChanged += Sidebar.HandleSelectionItemsChanged;
 +	
 +			Mono.Addins.AddinManager.ExtensionChanged += PopulateExtendableMenus;
 +			PopulateExtendableMenus (null, null);
 +	
 +			UpdateMenus ();
 +	
 +			main_window.ShowAll ();
 +	
 +			tagbar.Hide ();
 +			find_bar.Hide ();
 +	
 +			UpdateFindByTagMenu ();
 +	
 +			LoadPreference (Preferences.SHOW_TOOLBAR);
 +			LoadPreference (Preferences.SHOW_SIDEBAR);
 +			LoadPreference (Preferences.SHOW_TIMELINE);
 +			LoadPreference (Preferences.SHOW_FILMSTRIP);
 +	
 +			LoadPreference (Preferences.GNOME_MAILTO_ENABLED);
 +			
 +			Preferences.SettingChanged += OnPreferencesChanged;
 +	
 +			main_window.DeleteEvent += HandleDeleteEvent;
 +			
 +			query_widget.HandleChanged (query);
 +			query_widget.Close ();
 +	
 +			// When the icon_view is loaded, set it's initial scroll position
 +			icon_view.SizeAllocated += HandleIconViewReady;
 +	
 +			export.Activated += HandleExportActivated;
 +			UpdateToolbar ();
 +	
 +			(uimanager.GetWidget("/ui/menubar1/file1/close1") as MenuItem).Hide ();
 +	
 +			Banshee.Kernel.Scheduler.Resume ();
  		}
 -
 -		if (view_mode == ModeType.PhotoView) {
 -			display_previous_button.Visible = true;
 -			display_next_button.Visible = true;
 -			count_label.Visible = true;
 -
 -			bool valid = photo_view.View.Item.IsValid;
 -			bool prev = valid && photo_view.View.Item.Index > 0;
 -			bool next = valid && photo_view.View.Item.Index < query.Count - 1;
 -
 -			display_previous_button.Sensitive = prev;
 -			display_next_button.Sensitive = next;
 -
 -			if (Query == null)
 -				count_label.Text = String.Empty;
 -			else
 -				// Note for translators: This indicates the current photo is photo {0} of {1} out of photos
 -				count_label.Text = String.Format (Catalog.GetString ("{0} of {1}"), Query.Count == 0 ? 0 : photo_view.View.Item.Index + 1, Query.Count == 0 ? 0 : Query.Count);
 -		} else {
 -			display_previous_button.Visible = false;
 -			display_next_button.Visible = false;
 -			count_label.Visible = false;
 +	
 +		private void HandleDisplayNextButtonClicked (object sender, EventArgs args)
 +		{
 +			PhotoView.View.Item.MoveNext ();
  		}
 -
 -	}
 -
 -	private void HandleExportActivated (object o, EventArgs e)
 -	{
 -		FSpot.Extensions.ExportMenuItemNode.SelectedImages = delegate () {return new FSpot.PhotoArray (SelectedPhotos ()); };
 -	}
 -
 -	private void HandleDbItemsChanged (object sender, DbItemEventArgs<Photo> args)
 -	{
 -		foreach (Photo p in args.Items) {
 -			if (p == null)
 -				continue;
 -			if (write_metadata)
 -				FSpot.Jobs.SyncMetadataJob.Create (db.Jobs, p);
 +	
 +		private void HandleDisplayPreviousButtonClicked (object sender, EventArgs args)
 +		{
 +			PhotoView.View.Item.MovePrevious ();
  		}
 -		
 -		if (args is PhotoEventArgs && (args as PhotoEventArgs).Changes.TimeChanged)
 -			query.RequestReload ();
 -	}
 -
 -	private void HandleTagsChanged (object sender, DbItemEventArgs<Tag> args)
 -	{
 -		icon_view.QueueDraw ();
 -		UpdateTagEntryFromSelection ();	
 -	}
 -
 -	void HandleViewNotebookSwitchPage (object sender, SwitchPageArgs args)
 -	{
 -		switch (view_notebook.CurrentPage) {
 -		case 0:
 -			SetViewMode (ModeType.IconView);
 -			break;
 -		case 1:
 -			SetViewMode (ModeType.PhotoView);
 -			break;
 +	
 +		private void OnSidebarExtensionChanged (object s, ExtensionNodeEventArgs args) {
 +			// FIXME: No sidebar page removal yet!
 +			if (args.Change == ExtensionChange.Add)
 +				Sidebar.AppendPage ((args.ExtensionNode as SidebarPageNode).GetSidebarPage ());
  		}
 -	}
 -
 -	private int [] SelectedIds () {
 -		int [] ids = new int [0];
 -
 -		if (fsview != null && fsview.View.Item.IsValid)
 -			ids = new int [] { fsview.View.Item.Index };
 -		else {
 -			switch (view_mode) {
 +	
 +		private Photo CurrentPhoto {
 +			get {
 +				int active = ActiveIndex ();
 +				if (active >= 0)
 +					return query [active] as Photo;
 +				else
 +					return null;
 +			}
 +		}
 +	
 +		// Index into the PhotoQuery.  If -1, no photo is selected or multiple photos are selected.
 +		private int ActiveIndex () 
 +		{
 +			if (Selection.Count == 1)
 +				return SelectedIds() [0];
 +			else
 +				return PHOTO_IDX_NONE;
 +		}
 +	
 +		// Switching mode.
 +		public enum ModeType {
 +			IconView,
 +			PhotoView
 +		};
 +	
 +		public event EventHandler ViewModeChanged;
 +	
 +		public void SetViewMode (ModeType value)
 +		{
 +			if (ViewMode == value)
 +				return;
 +	
 +			ViewMode = value;
 +			switch (ViewMode) {
  			case ModeType.IconView:
 -				ids = icon_view.Selection.Ids;
 +				if (view_notebook.CurrentPage != 0)
 +					view_notebook.CurrentPage = 0;
 +	
 +				display_timeline.Sensitive = true;
 +				display_filmstrip.Sensitive = false;
 +				group_selector.Visible = display_timeline.Active;
 +	
 +				if (photo_view.View.Loupe != null)
 +					loupe_menu_item.Active = false;
 +				JumpTo (photo_view.Item.Index);
 +				zoom_scale.Value = icon_view.Zoom;
  				break;
 -			default:
  			case ModeType.PhotoView:
 -				if (photo_view.Item.IsValid)
 -					ids = new int [] { photo_view.Item.Index };
 +				if (view_notebook.CurrentPage != 1)
 +					view_notebook.CurrentPage = 1;
 +	
 +				display_timeline.Sensitive = false;
 +				display_filmstrip.Sensitive = true;
 +				group_selector.Visible = false;
 +				
 +				JumpTo (icon_view.FocusCell);
 +				zoom_scale.Value = photo_view.NormalizedZoom;
 +	
 +				photo_view.View.GrabFocus();
  				break;
  			}
 -		}
 -
 -		return ids;
 -	}
 -
 -	public class MainSelection : IBrowsableCollection {
 -		MainWindow win;
 -
 -		public MainSelection (MainWindow win)
 -		{
 -			this.win = win;
 -			win.icon_view.Selection.Changed += HandleSelectionChanged;
 -			win.icon_view.Selection.ItemsChanged += HandleSelectionItemsChanged;
 -			win.photo_view.PhotoChanged += HandlePhotoChanged;
 -			win.query.ItemsChanged += HandleQueryItemsChanged;
 +			Selection.MarkChanged ();
 +			UpdateToolbar ();
 +			if (ViewModeChanged != null) 
 +				ViewModeChanged (this, null);
  		}
  		
 -		public int Count {
 -			get {
 -				switch (win.view_mode) {
 -				case ModeType.PhotoView:
 -					return win.photo_view.Item.IsValid ? 1 : 0;
 -				case ModeType.IconView:
 -					return win.icon_view.Selection.Count;
 -				}
 -				return 0;
 +		void UpdateToolbar ()
 +		{
 +			if (browse_button != null) {
 +				bool state = ViewMode == ModeType.IconView;
 +				
 +				if (browse_button.Active != state)
 +					browse_button.Active = state;
  			}
 +	
 +			if (edit_button != null) {
 +				bool state = ViewMode == ModeType.PhotoView;
 +				
 +				if (edit_button.Active != state)
 +					edit_button.Active = state;
 +			}
 +	
 +			if (ViewMode == ModeType.PhotoView) {
 +				display_previous_button.Visible = true;
 +				display_next_button.Visible = true;
 +				count_label.Visible = true;
 +	
 +				bool valid = photo_view.View.Item.IsValid;
 +				bool prev = valid && photo_view.View.Item.Index > 0;
 +				bool next = valid && photo_view.View.Item.Index < query.Count - 1;
 +	
 +				display_previous_button.Sensitive = prev;
 +				display_next_button.Sensitive = next;
 +	
 +				if (Query == null)
 +					count_label.Text = String.Empty;
 +				else
 +					// Note for translators: This indicates the current photo is photo {0} of {1} out of photos
 +					count_label.Text = String.Format (Catalog.GetString ("{0} of {1}"), Query.Count == 0 ? 0 : photo_view.View.Item.Index + 1, Query.Count == 0 ? 0 : Query.Count);
 +			} else {
 +				display_previous_button.Visible = false;
 +				display_next_button.Visible = false;
 +				count_label.Visible = false;
 +			}
 +	
  		}
 -
 -		public int IndexOf (IBrowsableItem item)
 +	
 +		private void HandleExportActivated (object o, EventArgs e)
  		{
 -			switch (win.view_mode) {
 -			case ModeType.PhotoView:
 -				return item == win.photo_view.Item.Current ? 0 : -1;
 -			case ModeType.IconView:
 -				return win.icon_view.Selection.IndexOf (item);
 -			}
 -			return -1;
 +			FSpot.Extensions.ExportMenuItemNode.SelectedImages = delegate () {return new FSpot.PhotoArray (SelectedPhotos ()); };
  		}
 -		
 -		public bool Contains (IBrowsableItem item)
 +	
 +		private void HandleDbItemsChanged (object sender, DbItemEventArgs<Photo> args)
  		{
 -			switch (win.view_mode) {
 -			case ModeType.PhotoView:
 -				return item == win.photo_view.Item.Current ? true : false;
 -			case ModeType.IconView:
 -				return win.icon_view.Selection.Contains (item);
 +			foreach (Photo p in args.Items) {
 +				if (p == null)
 +					continue;
 +				if (write_metadata)
 +					FSpot.Jobs.SyncMetadataJob.Create (Database.Jobs, p);
  			}
 -			return false;
 +			
 +			if (args is PhotoEventArgs && (args as PhotoEventArgs).Changes.TimeChanged)
 +				query.RequestReload ();
  		}
 -		
 -		public void MarkChanged ()
 +	
 +		private void HandleTagsChanged (object sender, DbItemEventArgs<Tag> args)
  		{
 -			if (Changed != null)
 -				Changed (this);
 +			icon_view.QueueDraw ();
 +			UpdateTagEntryFromSelection ();	
  		}
 -
 -		public void MarkChanged (int index, IBrowsableItemChanges changes)
 +	
 +		void HandleViewNotebookSwitchPage (object sender, SwitchPageArgs args)
  		{
 -			throw new System.NotImplementedException ("I didn't think you'd find me");
 +			switch (view_notebook.CurrentPage) {
 +			case 0:
 +				SetViewMode (ModeType.IconView);
 +				break;
 +			case 1:
 +				SetViewMode (ModeType.PhotoView);
 +				break;
 +			}
  		}
 -		
 -		public IBrowsableItem this [int index] {
 -			get {
 -				switch (win.view_mode) {
 +	
 +		private int [] SelectedIds () {
 +			int [] ids = new int [0];
 +	
 +			if (fsview != null && fsview.View.Item.IsValid)
 +				ids = new int [] { fsview.View.Item.Index };
 +			else {
 +				switch (ViewMode) {
 +				case ModeType.IconView:
 +					ids = icon_view.Selection.Ids;
 +					break;
 +				default:
  				case ModeType.PhotoView:
 -					if (index == 0)
 -						return win.photo_view.Item.Current;
 +					if (photo_view.Item.IsValid)
 +						ids = new int [] { photo_view.Item.Index };
  					break;
 -				case ModeType.IconView:
 -					return win.icon_view.Selection [index];
  				}
 -				throw new ArgumentOutOfRangeException ();
  			}
 +	
 +			return ids;
  		}
 -		 
 -		public IBrowsableItem [] Items {
 -			get {
 -				switch (win.view_mode) {
 +	
 +		public class MainSelection : IBrowsableCollection {
 +			MainWindow win;
 +	
 +			public MainSelection (MainWindow win)
 +			{
 +				this.win = win;
 +				win.icon_view.Selection.Changed += HandleSelectionChanged;
 +				win.icon_view.Selection.ItemsChanged += HandleSelectionItemsChanged;
 +				win.photo_view.PhotoChanged += HandlePhotoChanged;
 +				win.query.ItemsChanged += HandleQueryItemsChanged;
 +			}
 +			
 +			public int Count {
 +				get {
 +					switch (win.ViewMode) {
 +					case ModeType.PhotoView:
 +						return win.photo_view.Item.IsValid ? 1 : 0;
 +					case ModeType.IconView:
 +						return win.icon_view.Selection.Count;
 +					}
 +					return 0;
 +				}
 +			}
 +	
 +			public int IndexOf (IBrowsableItem item)
 +			{
 +				switch (win.ViewMode) {
  				case ModeType.PhotoView:
 -					if (win.photo_view.Item.IsValid)
 -						return new IBrowsableItem [] {win.photo_view.Item.Current};
 -
 -					break;
 +					return item == win.photo_view.Item.Current ? 0 : -1;
  				case ModeType.IconView:
 -					return win.icon_view.Selection.Items;
 +					return win.icon_view.Selection.IndexOf (item);
  				}
 -				return new IBrowsableItem [0];
 +				return -1;
  			}
 -		}
 -
 -		private void HandleQueryItemsChanged (IBrowsableCollection collection, BrowsableEventArgs args)
 -		{
 -			// FIXME for now we only listen to changes directly from the query
 -			// when we are in PhotoView mode because we presume that we'll get
 -			// proper notification from the icon view selection in icon view mode
 -			if (win.view_mode != ModeType.PhotoView || ItemsChanged == null) 
 -				return;
 -
 -			foreach (int item in args.Items) {
 -				if (win.photo_view.Item.Index == item ) {
 -					ItemsChanged (this, new BrowsableEventArgs (item, args.Changes));
 -					break;
 +			
 +			public bool Contains (IBrowsableItem item)
 +			{
 +				switch (win.ViewMode) {
 +				case ModeType.PhotoView:
 +					return item == win.photo_view.Item.Current ? true : false;
 +				case ModeType.IconView:
 +					return win.icon_view.Selection.Contains (item);
 +				}
 +				return false;
 +			}
 +			
 +			public void MarkChanged ()
 +			{
 +				if (Changed != null)
 +					Changed (this);
 +			}
 +	
 +			public void MarkChanged (int index, IBrowsableItemChanges changes)
 +			{
 +				throw new System.NotImplementedException ("I didn't think you'd find me");
 +			}
 +			
 +			public IBrowsableItem this [int index] {
 +				get {
 +					switch (win.ViewMode) {
 +					case ModeType.PhotoView:
 +						if (index == 0)
 +							return win.photo_view.Item.Current;
 +						break;
 +					case ModeType.IconView:
 +						return win.icon_view.Selection [index];
 +					}
 +					throw new ArgumentOutOfRangeException ();
 +				}
 +			}
 +			 
 +			public IBrowsableItem [] Items {
 +				get {
 +					switch (win.ViewMode) {
 +					case ModeType.PhotoView:
 +						if (win.photo_view.Item.IsValid)
 +							return new IBrowsableItem [] {win.photo_view.Item.Current};
 +	
 +						break;
 +					case ModeType.IconView:
 +						return win.icon_view.Selection.Items;
 +					}
 +					return new IBrowsableItem [0];
  				}
  			}
 +	
 +			private void HandleQueryItemsChanged (IBrowsableCollection collection, BrowsableEventArgs args)
 +			{
 +				// FIXME for now we only listen to changes directly from the query
 +				// when we are in PhotoView mode because we presume that we'll get
 +				// proper notification from the icon view selection in icon view mode
 +				if (win.ViewMode != ModeType.PhotoView || ItemsChanged == null) 
 +					return;
 +	
 +				foreach (int item in args.Items) {
 +					if (win.photo_view.Item.Index == item ) {
 +						ItemsChanged (this, new BrowsableEventArgs (item, args.Changes));
 +						break;
 +					}
 +				}
 +			}
 +	
 +			private void HandlePhotoChanged (PhotoView sender)
 +			{
 +				if (win.ViewMode == ModeType.PhotoView && Changed != null)
 +					Changed (this);
 +			}
 +	
 +			public void HandleSelectionChanged (IBrowsableCollection collection)
 +			{
 +				if (win.ViewMode == ModeType.IconView && Changed != null)
 +					Changed (this);
 +	
 +	
 +			}
 +	
 +			private void HandleSelectionItemsChanged (IBrowsableCollection collection,  BrowsableEventArgs args)
 +			{
 +				if (win.ViewMode == ModeType.IconView && ItemsChanged != null)
 +					ItemsChanged (this, args);
 +			}
 +	
 +			public event IBrowsableCollectionChangedHandler Changed;
 +			public event IBrowsableCollectionItemsChangedHandler ItemsChanged;
  		}
 -
 -		private void HandlePhotoChanged (PhotoView sender)
 +	
 +		private void HandleSelectionChanged (IBrowsableCollection collection)
  		{
 -			if (win.view_mode == ModeType.PhotoView && Changed != null)
 -				Changed (this);
 +			UpdateMenus ();
 +			UpdateTagEntryFromSelection ();
 +			UpdateStatusLabel ();
 +			UpdateToolbar ();
 +	
 +			InfoBox.Photos = SelectedPhotos ();
  		}
 -
 -		public void HandleSelectionChanged (IBrowsableCollection collection)
 +	
 +		private void HandleSelectionItemsChanged (IBrowsableCollection collection, BrowsableEventArgs args)
  		{
 -			if (win.view_mode == ModeType.IconView && Changed != null)
 -				Changed (this);
 -
 -
 +			UpdateMenus ();
 +			UpdateTagEntryFromSelection ();
 +			photo_view.UpdateTagView ();
 +			InfoBox.Photos = SelectedPhotos ();
  		}
 -
 -		private void HandleSelectionItemsChanged (IBrowsableCollection collection,  BrowsableEventArgs args)
 +	
 +	
 +		//
 +		// Selection Interface
 +		//
 +	
 +		private Photo [] SelectedPhotos (int [] selected_ids)
  		{
 -			if (win.view_mode == ModeType.IconView && ItemsChanged != null)
 -				ItemsChanged (this, args);
 +			Photo [] photo_list = new Photo [selected_ids.Length];
 +		
 +			int i = 0;
 +			foreach (int num in selected_ids)
 +				photo_list [i ++] = query [num] as Photo;
 +			
 +			return photo_list;
 +		}
 +	
 +		public Photo [] SelectedPhotos () 
 +		{
 +			return SelectedPhotos (SelectedIds ());
 +		}
 +	
 +		public PhotoQuery Query {
 +			get { return query; }
  		}
 -
 -		public event IBrowsableCollectionChangedHandler Changed;
 -		public event IBrowsableCollectionItemsChangedHandler ItemsChanged;
 -	}
 -
 -	private void HandleSelectionChanged (IBrowsableCollection collection)
 -	{
 -		UpdateMenus ();
 -		UpdateTagEntryFromSelection ();
 -		UpdateStatusLabel ();
 -		UpdateToolbar ();
 -
 -		info_box.Photos = SelectedPhotos ();
 -	}
 -
 -	private void HandleSelectionItemsChanged (IBrowsableCollection collection, BrowsableEventArgs args)
 -	{
 -		UpdateMenus ();
 -		UpdateTagEntryFromSelection ();
 -		photo_view.UpdateTagView ();
 -		info_box.Photos = SelectedPhotos ();
 -	}
 -
 -
 -	//
 -	// Selection Interface
 -	//
 -
 -	private Photo [] SelectedPhotos (int [] selected_ids)
 -	{
 -		Photo [] photo_list = new Photo [selected_ids.Length];
  	
 -		int i = 0;
 -		foreach (int num in selected_ids)
 -			photo_list [i ++] = query [num] as Photo;
 +		//
 +		// Change Notification functions
 +		//
 +	
 +		private void InvalidateViews ()
 +		{
 +			icon_view.QueueDraw ();
 +			photo_view.Reload ();
 +			if (fsview != null)
 +				fsview.View.Reload ();
 +		}
 +			
 +		//
 +		// Commands
 +		//
 +	
 +		private void RotateSelectedPictures (Gtk.Window parent, RotateDirection direction)
 +		{
 +			RotateCommand command = new RotateCommand (parent);
 +			
 +			int [] selected_ids = SelectedIds ();
 +			if (command.Execute (direction, SelectedPhotos (selected_ids)))
 +				query.MarkChanged (selected_ids, new PhotoChanges () {DataChanged = true});
 +		}
 +	
 +		//
 +		// Tag Selection Drag Handlers
 +		//
  		
 -		return photo_list;
 -	}
 -
 -	public Photo [] SelectedPhotos () 
 -	{
 -		return SelectedPhotos (SelectedIds ());
 -	}
 -
 -	public PhotoQuery Query {
 -		get { return query; }
 -	}
 -
 -	//
 -	// Change Notification functions
 -	//
 -
 -	private void InvalidateViews ()
 -	{
 -		icon_view.QueueDraw ();
 -		photo_view.Reload ();
 -		if (fsview != null)
 -			fsview.View.Reload ();
 -	}
 +		public void AddTagExtended (int [] nums, Tag [] tags)
 +		{
 +			foreach (int num in nums)
 +				(query[num] as Photo).AddTag (tags);
 +			query.Commit (nums);
 +	
 +			foreach (Tag t in tags) {
 +				if (t.Icon != null || t.IconWasCleared)
 +					continue;
 +				// FIXME this needs a lot more work.
 +				Pixbuf icon = null;
 +				try {
 +					Pixbuf tmp = FSpot.PhotoLoader.LoadAtMaxSize (query [nums[0]], 128, 128);
 +					icon = PixbufUtils.TagIconFromPixbuf (tmp);
 +					tmp.Dispose ();
 +				} catch {
 +					icon = null;
 +				}
 +				
 +				t.Icon = icon;
 +				Database.Tags.Commit (t);
 +			}
 +		}
  		
 -	//
 -	// Commands
 -	//
 -
 -	private void RotateSelectedPictures (Gtk.Window parent, RotateDirection direction)
 -	{
 -		RotateCommand command = new RotateCommand (parent);
 +		public void SetFolderQuery (IEnumerable<Uri> uri_list)
 +		{
 +			ShowQueryWidget ();
 +			query_widget.SetFolders (uri_list);
 +		}
  		
 -		int [] selected_ids = SelectedIds ();
 -		if (command.Execute (direction, SelectedPhotos (selected_ids)))
 -			query.MarkChanged (selected_ids, new PhotoChanges () {DataChanged = true});
 -	}
 -
 -	//
 -	// Tag Selection Drag Handlers
 -	//
 +		public void RemoveTags (int [] nums, Tag [] tags)
 +		{
 +			foreach (int num in nums)
 +				(query[num] as Photo).RemoveTag (tags);
 +			query.Commit (nums);
 +		}
  	
 -	public void AddTagExtended (int [] nums, Tag [] tags)
 -	{
 -		foreach (int num in nums)
 -			(query[num] as Photo).AddTag (tags);
 -		query.Commit (nums);
 -
 -		foreach (Tag t in tags) {
 -			if (t.Icon != null || t.IconWasCleared)
 -				continue;
 -			// FIXME this needs a lot more work.
 -			Pixbuf icon = null;
 -			try {
 -				Pixbuf tmp = FSpot.PhotoLoader.LoadAtMaxSize (query [nums[0]], 128, 128);
 -				icon = PixbufUtils.TagIconFromPixbuf (tmp);
 -				tmp.Dispose ();
 -			} catch {
 -				icon = null;
 +		void HandleTagSelectionButtonPressEvent (object sender, ButtonPressEventArgs args)
 +		{
 +			if (args.Event.Button == 3) {
 +				TagPopup popup = new TagPopup ();
 +				popup.Activate (args.Event, tag_selection_widget.TagAtPosition (args.Event.X, args.Event.Y),
 +				tag_selection_widget.TagHighlight);
 +				args.RetVal = true;
  			}
 -			
 -			t.Icon = icon;
 -			db.Tags.Commit (t);
  		}
 -	}
  	
 -	public void SetFolderQuery (IEnumerable<Uri> uri_list)
 -	{
 -		ShowQueryWidget ();
 -		query_widget.SetFolders (uri_list);
 -	}
 -	
 -	public void AddTagsQuery (Tag [] tags)
 -	{
 -		ShowQueryWidget ();
 -		query_widget.Include (tags);
 -	}
 -
 -	public void RemoveTags (int [] nums, Tag [] tags)
 -	{
 -		foreach (int num in nums)
 -			(query[num] as Photo).RemoveTag (tags);
 -		query.Commit (nums);
 -	}
 -
 -	void HandleTagSelectionButtonPressEvent (object sender, ButtonPressEventArgs args)
 -	{
 -		if (args.Event.Button == 3) {
 +		void HandleTagSelectionPopupMenu (object sender, PopupMenuArgs args)
 +		{
  			TagPopup popup = new TagPopup ();
 -			popup.Activate (args.Event, tag_selection_widget.TagAtPosition (args.Event.X, args.Event.Y),
 -			tag_selection_widget.TagHighlight);
 +			popup.Activate (null, null, tag_selection_widget.TagHighlight);
  			args.RetVal = true;
  		}
 -	}
 -
 -	void HandleTagSelectionPopupMenu (object sender, PopupMenuArgs args)
 -	{
 -		TagPopup popup = new TagPopup ();
 -		popup.Activate (null, null, tag_selection_widget.TagHighlight);
 -		args.RetVal = true;
 -	}
 -
 -#if SHOW_CALENDAR
 -	void HandleCalendarDaySelected (object sender, System.EventArgs args)
 -	{
 -		FSpot.SimpleCalendar cal = sender as FSpot.SimpleCalendar;
 -		JumpTo (cal.Date);
 -	}
 -
 -	void JumpTo (System.DateTime time)
 -	{
 -		JumpTo (query.LookupItem (time));*/
 -	}
 -#endif
 -
 -	void JumpTo (int index)
 -	{
 -		switch (view_mode) {
 -		case ModeType.PhotoView:
 -			photo_view.Item.Index = index;
 -			break;
 -		case ModeType.IconView:
 -			icon_view.ScrollTo (index);
 -			icon_view.Throb (index);
 -			break;
 +	
 +		void HandleTagSelectionRowActivated (object sender, RowActivatedArgs args)
 +	 	{
 +	 		ShowQueryWidget ();
 +	 		query_widget.Include (new Tag [] {tag_selection_widget.TagByPath (args.Path)});
  		}
 -	}
 -
 -	void HandleAdaptorGlassSet (FSpot.GroupAdaptor sender, int index)
 -	{
 -		JumpTo (index);
 -	}
 -
 -	void HandleAdaptorChanged (FSpot.GroupAdaptor sender)
 -	{
 -		UpdateGlass ();
 -	}
 -
 -	/*
 -	 * Keep the glass temporal slider in sync with the user's scrolling in the icon_view
 -	 */
 -	private void UpdateGlass ()
 -	{
 -		// If people cant see the timeline don't update it.
 -		if (! display_timeline.Active)
 -			return;
 -
 -		int cell_num = icon_view.TopLeftVisibleCell();
 -		if (cell_num == -1 /*|| cell_num == lastTopLeftCell*/)
 -			return;
 -
 -		FSpot.IBrowsableItem photo = icon_view.Collection [cell_num];
 -#if false
 -		group_selector.Adaptor.GlassSet -= HandleAdaptorGlassSet;
 -		group_selector.Adaptor.SetGlass (group_selector.Adaptor.IndexFromPhoto (photo));
 -		group_selector.Adaptor.GlassSet = HandleAdaptorGlassSet;
 -#else
 -		/* 
 -		 * FIXME this is a lame hack to get around a delegate chain.  This should 
 -		 * actually operate directly on the adaptor not on the selector but I don't have 
 -		 * time to fix it right now.
 +	
 +	
 +	#if SHOW_CALENDAR
 +		void HandleCalendarDaySelected (object sender, System.EventArgs args)
 +		{
 +			FSpot.SimpleCalendar cal = sender as FSpot.SimpleCalendar;
 +			JumpTo (cal.Date);
 +		}
 +	
 +		void JumpTo (System.DateTime time)
 +		{
 +			JumpTo (query.LookupItem (time));*/
 +		}
 +	#endif
 +	
 +		void JumpTo (int index)
 +		{
 +			switch (ViewMode) {
 +			case ModeType.PhotoView:
 +				photo_view.Item.Index = index;
 +				break;
 +			case ModeType.IconView:
 +				icon_view.ScrollTo (index);
 +				icon_view.Throb (index);
 +				break;
 +			}
 +		}
 +	
 +		void HandleAdaptorGlassSet (FSpot.GroupAdaptor sender, int index)
 +		{
 +			JumpTo (index);
 +		}
 +	
 +		void HandleAdaptorChanged (FSpot.GroupAdaptor sender)
 +		{
 +			UpdateGlass ();
 +		}
 +	
 +		/*
 +		 * Keep the glass temporal slider in sync with the user's scrolling in the icon_view
  		 */
 -		group_selector.SetPosition (group_selector.Adaptor.IndexFromPhoto (photo));
 -#endif
 -	}
 +		private void UpdateGlass ()
 +		{
 +			// If people cant see the timeline don't update it.
 +			if (! display_timeline.Active)
 +				return;
  	
 -	void HandleIconViewScroll (object sender, EventArgs args)
 -	{
 -		UpdateGlass ();
 -	}
 -
 -	void HandleIconViewReady (object sender, EventArgs args)
 -	{
 -		LoadPreference (Preferences.GLASS_POSITION);
 -
 -		// We only want to set the position the first time
 -		// the icon_view is ready (eg on startup)
 -		icon_view.SizeAllocated -= HandleIconViewReady;
 -	}
 -
 -	//
 -	// IconView Drag Handlers
 -	//
 -
 -	void HandleIconViewDragBegin (object sender, DragBeginArgs args)
 -	{
 -		Photo [] photos = SelectedPhotos ();
 +			int cell_num = icon_view.TopLeftVisibleCell();
 +			if (cell_num == -1 /*|| cell_num == lastTopLeftCell*/)
 +				return;
 +	
 +			FSpot.IBrowsableItem photo = icon_view.Collection [cell_num];
 +	#if false
 +			group_selector.Adaptor.GlassSet -= HandleAdaptorGlassSet;
 +			group_selector.Adaptor.SetGlass (group_selector.Adaptor.IndexFromPhoto (photo));
 +			group_selector.Adaptor.GlassSet = HandleAdaptorGlassSet;
 +	#else
 +			/* 
 +			 * FIXME this is a lame hack to get around a delegate chain.  This should 
 +			 * actually operate directly on the adaptor not on the selector but I don't have 
 +			 * time to fix it right now.
 +			 */
 +			group_selector.SetPosition (group_selector.Adaptor.IndexFromPhoto (photo));
 +	#endif
 +		}
  		
 -		if (photos.Length > 0) {
 -			int len = Math.Min (photos.Length, 4);
 -			int size = 48;
 -			int border  = 2;
 -			int csize = size/2 + len * size / 2 + 2 * border ;
 -			
 -			Pixbuf container = new Pixbuf (Gdk.Colorspace.Rgb, true, 8, csize, csize);
 -			container.Fill (0x00000000);
 -
 -			bool use_icon = false;;
 -			while (len-- > 0) {
 -				FSpot.PixbufCache.CacheEntry entry = icon_view.Cache.Lookup (photos [len].DefaultVersionUri);
 -
 -				Pixbuf thumbnail = null;
 -				if (entry != null) {
 -					Cms.Profile screen_profile;
 -					if (FSpot.ColorManagement.Profiles.TryGetValue (Preferences.Get<string> (Preferences.COLOR_MANAGEMENT_DISPLAY_PROFILE), out screen_profile)) {
 -						thumbnail = entry.Pixbuf.Copy ();
 -						FSpot.ColorManagement.ApplyProfile (thumbnail, screen_profile);
 -					} else
 -						thumbnail = entry.ShallowCopyPixbuf ();
 -				}
 +		void HandleIconViewScroll (object sender, EventArgs args)
 +		{
 +			UpdateGlass ();
 +		}
 +	
 +		void HandleIconViewReady (object sender, EventArgs args)
 +		{
 +			LoadPreference (Preferences.GLASS_POSITION);
 +	
 +			// We only want to set the position the first time
 +			// the icon_view is ready (eg on startup)
 +			icon_view.SizeAllocated -= HandleIconViewReady;
 +		}
 +	
 +		//
 +		// IconView Drag Handlers
 +		//
 +	
 +		void HandleIconViewDragBegin (object sender, DragBeginArgs args)
 +		{
 +			Photo [] photos = SelectedPhotos ();
 +			
 +			if (photos.Length > 0) {
 +				int len = Math.Min (photos.Length, 4);
 +				int size = 48;
 +				int border  = 2;
 +				int csize = size/2 + len * size / 2 + 2 * border ;
  				
 -				if (thumbnail != null) {
 -					Pixbuf small = PixbufUtils.ScaleToMaxSize (thumbnail, size, size);				
 -
 -					int x = border + len * (size/2) + (size - small.Width)/2;
 -					int y = border + len * (size/2) + (size - small.Height)/2;
 -					Pixbuf box = new Pixbuf (container, x - border, y - border, 
 -								 small.Width + 2 * border, small.Height + 2 * border);
 -
 -					box.Fill (0x000000ff);
 -					small.CopyArea (0, 0, small.Width, small.Height, container, x, y); 
 +				Pixbuf container = new Pixbuf (Gdk.Colorspace.Rgb, true, 8, csize, csize);
 +				container.Fill (0x00000000);
 +	
 +				bool use_icon = false;;
 +				while (len-- > 0) {
 +					FSpot.PixbufCache.CacheEntry entry = icon_view.Cache.Lookup (photos [len].DefaultVersionUri);
 +	
 +					Pixbuf thumbnail = null;
 +					if (entry != null) {
 +						Cms.Profile screen_profile;
 +						if (FSpot.ColorManagement.Profiles.TryGetValue (Preferences.Get<string> (Preferences.COLOR_MANAGEMENT_DISPLAY_PROFILE), out screen_profile)) {
 +							thumbnail = entry.Pixbuf.Copy ();
 +							FSpot.ColorManagement.ApplyProfile (thumbnail, screen_profile);
 +						} else
 +							thumbnail = entry.ShallowCopyPixbuf ();
 +					}
  					
 -					thumbnail.Dispose ();
 -					small.Dispose ();
 -					use_icon = true;
 +					if (thumbnail != null) {
 +						Pixbuf small = PixbufUtils.ScaleToMaxSize (thumbnail, size, size);				
 +	
 +						int x = border + len * (size/2) + (size - small.Width)/2;
 +						int y = border + len * (size/2) + (size - small.Height)/2;
 +						Pixbuf box = new Pixbuf (container, x - border, y - border, 
 +									 small.Width + 2 * border, small.Height + 2 * border);
 +	
 +						box.Fill (0x000000ff);
 +						small.CopyArea (0, 0, small.Width, small.Height, container, x, y); 
 +						
 +						thumbnail.Dispose ();
 +						small.Dispose ();
 +						use_icon = true;
 +					}
  				}
 +				if (use_icon)
 +					Gtk.Drag.SetIconPixbuf (args.Context, container, 0, 0);
 +				container.Dispose ();
  			}
 -			if (use_icon)
 -				Gtk.Drag.SetIconPixbuf (args.Context, container, 0, 0);
 -			container.Dispose ();
  		}
 -	}
 -
 -	void HandleIconViewDragDataGet (object sender, DragDataGetArgs args)
 -	{	
 -		if (args.Info == DragDropTargets.UriListEntry.Info) {
 -			args.SelectionData.SetUriListData (new UriList (SelectedPhotos ()), args.Context.Targets[0]);
 -			return;
 +	
 +		void HandleIconViewDragDataGet (object sender, DragDataGetArgs args)
 +		{	
 +			if (args.Info == DragDropTargets.UriListEntry.Info) {
 +				args.SelectionData.SetUriListData (new UriList (SelectedPhotos ()), args.Context.Targets[0]);
 +				return;
 +			}
 +			
 +			if (args.Info == DragDropTargets.PhotoListEntry.Info) {
 +				args.SelectionData.SetPhotosData (SelectedPhotos (), args.Context.Targets[0]);
 +				return;
 +			}
 +			
 +			if (args.Info == DragDropTargets.RootWindowEntry.Info) {
 +				HandleSetAsBackgroundCommand (null, null);
 +				return;
 +			}
  		}
 -		
 -		if (args.Info == DragDropTargets.PhotoListEntry.Info) {
 -			args.SelectionData.SetPhotosData (SelectedPhotos (), args.Context.Targets[0]);
 -			return;
 +	
 +		void HandleIconViewDragDrop (object sender, DragDropArgs args)
 +		{
 +			args.RetVal = true;
  		}
 -		
 -		if (args.Info == DragDropTargets.RootWindowEntry.Info) {
 -			HandleSetAsBackgroundCommand (null, null);
 -			return;
 +	
 +		void HandleIconViewDragMotion (object sender, DragMotionArgs args)
 +		{
 +			Gdk.Drag.Status (args.Context, args.Context.SuggestedAction, args.Time);
 +			args.RetVal = true;
  		}
 -	}
 -
 -	void HandleIconViewDragDrop (object sender, DragDropArgs args)
 -	{
 -		args.RetVal = true;
 -	}
 -
 -	void HandleIconViewDragMotion (object sender, DragMotionArgs args)
 -	{
 -		Gdk.Drag.Status (args.Context, args.Context.SuggestedAction, args.Time);
 -		args.RetVal = true;
 -	}
 -
 -	public void ImportUriList (UriList list, bool copy) 
 -	{
 -		ImportCommand command = new ImportCommand (main_window);
 -		if (command.ImportFromPaths (db.Photos, list.ToLocalPaths (), copy) > 0) {
 -			query.RollSet = new RollSet (db.Rolls.GetRolls (1)[0]);
 -			UpdateQuery ();
 +	
 +		public void ImportUriList (UriList list, bool copy) 
 +		{
 +			ImportCommand command = new ImportCommand (main_window);
 +			if (command.ImportFromPaths (Database.Photos, list.ToLocalPaths (), copy) > 0) {
 +				query.RollSet = new RollSet (Database.Rolls.GetRolls (1)[0]);
 +				UpdateQuery ();
 +			}
  		}
 -	}
 -
 -	public void ImportFile (string path)
 -	{
 -		ImportCommand command = new ImportCommand (main_window);
 -		if (command.ImportFromFile (db.Photos, path) > 0) {
 -			query.RollSet = new RollSet (db.Rolls.GetRolls (1)[0]);
 -			UpdateQuery ();
 +	
 +		public void ImportFile (string path)
 +		{
 +			ImportCommand command = new ImportCommand (main_window);
 +			if (command.ImportFromFile (Database.Photos, path) > 0) {
 +				query.RollSet = new RollSet (Database.Rolls.GetRolls (1)[0]);
 +				UpdateQuery ();
 +			}
  		}
 -	}
 -
 -#if false
 -	public void ImportUdi (string udi)
 -	{
 -		/* probably a camera we need to contruct on of our gphoto2 uris */
 -		Hal.Device dev = new Hal.Device (Core.HalContext, udi);
 -		string mount_point = dev.GetPropertyString ("volume.mount_point");
 -		int bus = dev.GetPropertyInt ("usb.bus_number");
 -		int device = dev.GetPropertyInt ("usb.linux.device_number");
 -		System.Console.WriteLine ("dev = {1} exists = {2} mount_point = {0} {3},{4}", mount_point, dev, dev.Exists, bus, device);
 -
 -		if (! dev.Exists || mount_point != null) {
 -			ImportFile (mount_point);
 -		} else {
 -			string gphoto_uri = String.Format ("gphoto2:usb:{0},{1}", bus.ToString ("d3") , device.ToString ("d3"));
 -			System.Console.WriteLine ("gphoto_uri = {0}", gphoto_uri);
 -			ImportCamera (gphoto_uri);
 -		} 
 +	
 +	#if false
 +		public void ImportUdi (string udi)
 +		{
 +			/* probably a camera we need to contruct on of our gphoto2 uris */
 +			Hal.Device dev = new Hal.Device (Core.HalContext, udi);
 +			string mount_point = dev.GetPropertyString ("volume.mount_point");
 +			int bus = dev.GetPropertyInt ("usb.bus_number");
 +			int device = dev.GetPropertyInt ("usb.linux.device_number");
 +			System.Console.WriteLine ("dev = {1} exists = {2} mount_point = {0} {3},{4}", mount_point, dev, dev.Exists, bus, device);
 +	
 +			if (! dev.Exists || mount_point != null) {
 +				ImportFile (mount_point);
 +			} else {
 +				string gphoto_uri = String.Format ("gphoto2:usb:{0},{1}", bus.ToString ("d3") , device.ToString ("d3"));
 +				System.Console.WriteLine ("gphoto_uri = {0}", gphoto_uri);
 +				ImportCamera (gphoto_uri);
 +			} 
 +				
 +		}
 +	#endif
 +	
 +		void HandleIconViewDragDataReceived (object sender, DragDataReceivedArgs args)
 +		{
 +		 	Widget source = Gtk.Drag.GetSourceWidget (args.Context);     
  			
 -	}
 -#endif
 -
 -	void HandleIconViewDragDataReceived (object sender, DragDataReceivedArgs args)
 -	{
 -	 	Widget source = Gtk.Drag.GetSourceWidget (args.Context);     
 -		
 -		if (args.Info == DragDropTargets.TagListEntry.Info) {
 -			//
 -			// Translate the event args from viewport space to window space,
 -			// drag events use the viewport.  Owen sends his regrets.
 -			//
 -			int item = icon_view.CellAtPosition (args.X + (int) icon_view.Hadjustment.Value, 
 -							     args.Y + (int) icon_view.Vadjustment.Value);
 -
 -			//Console.WriteLine ("Drop cell = {0} ({1},{2})", item, args.X, args.Y);
 -			if (item >= 0) {
 -				if (icon_view.Selection.Contains (item))
 -					AttachTags (tag_selection_widget.TagHighlight, SelectedIds());
 -				else 
 -					AttachTags (tag_selection_widget.TagHighlight, new int [] {item});
 +			if (args.Info == DragDropTargets.TagListEntry.Info) {
 +				//
 +				// Translate the event args from viewport space to window space,
 +				// drag events use the viewport.  Owen sends his regrets.
 +				//
 +				int item = icon_view.CellAtPosition (args.X + (int) icon_view.Hadjustment.Value, 
 +								     args.Y + (int) icon_view.Vadjustment.Value);
 +	
 +				//Console.WriteLine ("Drop cell = {0} ({1},{2})", item, args.X, args.Y);
 +				if (item >= 0) {
 +					if (icon_view.Selection.Contains (item))
 +						AttachTags (tag_selection_widget.TagHighlight, SelectedIds());
 +					else 
 +						AttachTags (tag_selection_widget.TagHighlight, new int [] {item});
 +				}
 +				
 +				Gtk.Drag.Finish (args.Context, true, false, args.Time);
 +				return;
  			}
  			
 -			Gtk.Drag.Finish (args.Context, true, false, args.Time);
 -			return;
 +			if (args.Info == DragDropTargets.UriListEntry.Info) {
 +	
 +				/* 
 +				 * If the drop is coming from inside f-spot then we don't want to import 
 +				 */
 +				if (source != null)
 +					return;
 +	
 +				UriList list = args.SelectionData.GetUriListData (); 
 +				ImportUriList (list, (args.Context.Action & Gdk.DragAction.Copy) != 0);
 +				
 +				Gtk.Drag.Finish (args.Context, true, false, args.Time);
 +				return;
 +			}
 +			
 +	#if ENABLE_REPARENTING
 +			if (args.Info == DragDropTargets.PhotoListEntry.Info) {
 +				int p_item = icon_view.CellAtPosition (args.X + (int) icon_view.Hadjustment.Value, 
 +								     args.Y + (int) icon_view.Vadjustment.Value);
 +	
 +				if (p_item >= 0) {
 +					if (icon_view.Selection.Contains (p_item)) //We don't want to reparent ourselves!
 +						return;
 +					PhotoVersionCommands.Reparent cmd = new PhotoVersionCommands.Reparent ();
 +					
 +					cmd.Execute (Database.Photos, SelectedPhotos(), query.Photos [p_item], GetToplevel (null));
 +					UpdateQuery ();
 +				}
 +				Gtk.Drag.Finish (args.Context, true, false, args.Time);
 +				return;
 +			}
 +	#endif
  		}
 -		
 -		if (args.Info == DragDropTargets.UriListEntry.Info) {
 -
 -			/* 
 -			 * If the drop is coming from inside f-spot then we don't want to import 
 -			 */
 -			if (source != null)
 +	
 +		//
 +		// IconView event handlers
 +		// 
 +	
 +		void HandleDoubleClicked (object sender, BrowsableEventArgs args)
 +		{
 +			Widget widget = sender as Widget;
 +			if (widget == null)
  				return;
 -
 -			UriList list = args.SelectionData.GetUriListData (); 
 -			ImportUriList (list, (args.Context.Action & Gdk.DragAction.Copy) != 0);
 +	
 +			switch (ViewMode) {
 +			case ModeType.IconView:
 +				icon_view.FocusCell = args.Items[0];
 +				SetViewMode (ModeType.PhotoView);
 +				break;
 +			case ModeType.PhotoView:
 +				SetViewMode (ModeType.IconView);
 +				break;
 +			}
 +		}
 +	
 +		public void HandleCommonPhotoCommands (object sender, Gtk.KeyPressEventArgs args) {
 +			bool alt = ModifierType.Mod1Mask == (args.Event.State & ModifierType.Mod1Mask);
 +			bool shift = ModifierType.ShiftMask == (args.Event.State & ModifierType.ShiftMask);
 +	
 +			if (args.RetVal == null)
 +				args.RetVal = false;
  			
 -			Gtk.Drag.Finish (args.Context, true, false, args.Time);
 -			return;
 +			switch (args.Event.Key) {
 +			case Gdk.Key.Delete:
 +				if (shift)
 +					HandleDeleteCommand (sender, args);
 +				else
 +					HandleRemoveCommand (sender, args);
 +				break;
 +			case Gdk.Key.Key_0:
 +			case Gdk.Key.KP_0:
 +				if (alt)
 +					HandleRatingMenuSelected (0);
 +				break;
 +			case Gdk.Key.Key_1:
 +			case Gdk.Key.KP_1:
 +				if (alt)
 +					HandleRatingMenuSelected (1);
 +				break;
 +			case Gdk.Key.Key_2:
 +			case Gdk.Key.KP_2:
 +				if (alt)
 +					HandleRatingMenuSelected (2);
 +				break;
 +			case Gdk.Key.Key_3:
 +			case Gdk.Key.KP_3:
 +				if (alt)
 +					HandleRatingMenuSelected (3);
 +				break;
 +			case Gdk.Key.Key_4:
 +			case Gdk.Key.KP_4:
 +				if (alt)
 +					HandleRatingMenuSelected (4);
 +				break;
 +			case Gdk.Key.Key_5:
 +			case Gdk.Key.KP_5:
 +				if (alt)
 +					HandleRatingMenuSelected (5);
 +				break;
 +			default:
 +				return; //do not set the RetVal to true
 +			}
 +			args.RetVal = true;
  		}
 -		
 -#if ENABLE_REPARENTING
 -		if (args.Info == DragDropTargets.PhotoListEntry.Info) {
 -			int p_item = icon_view.CellAtPosition (args.X + (int) icon_view.Hadjustment.Value, 
 -							     args.Y + (int) icon_view.Vadjustment.Value);
 -
 -			if (p_item >= 0) {
 -				if (icon_view.Selection.Contains (p_item)) //We don't want to reparent ourselves!
 -					return;
 -				PhotoVersionCommands.Reparent cmd = new PhotoVersionCommands.Reparent ();
 -				
 -				cmd.Execute (db.Photos, SelectedPhotos(), query.Photos [p_item], GetToplevel (null));
 -				UpdateQuery ();
 +	
 +		void HandleIconViewKeyPressEvent (object sender, Gtk.KeyPressEventArgs args)
 +		{
 +			HandleCommonPhotoCommands (sender, args);
 +			if ((bool)args.RetVal)
 +				return;
 +	
 +			switch (args.Event.Key) {
 +			case Gdk.Key.F:
 +			case Gdk.Key.f:
 +				HandleViewFullscreen (sender, args);
 +				args.RetVal = true;
 +				break;
  			}
 -			Gtk.Drag.Finish (args.Context, true, false, args.Time);
 -			return;
  		}
 -#endif
 -	}
 -
 -	//
 -	// IconView event handlers
 -	// 
 -
 -	void HandleDoubleClicked (object sender, BrowsableEventArgs args)
 -	{
 -		Widget widget = sender as Widget;
 -		if (widget == null)
 -			return;
 -
 -		switch (ViewMode) {
 -		case ModeType.IconView:
 -			icon_view.FocusCell = args.Items[0];
 -			SetViewMode (ModeType.PhotoView);
 -			break;
 -		case ModeType.PhotoView:
 -			SetViewMode (ModeType.IconView);
 -			break;
 +	
 +		//
 +		// FullScreenView event handlers.
 +		//
 +	
 +		void HandleFullScreenViewKeyPressEvent (object sender, Gtk.KeyPressEventArgs args)
 +		{
 +			HandleCommonPhotoCommands (sender, args);
 +			if ((bool)args.RetVal)
 +				// this will hide any panels again that might have appeared above the fullscreen view
 +				fsview.Present ();
  		}
 -	}
 -
 -	public void HandleCommonPhotoCommands (object sender, Gtk.KeyPressEventArgs args) {
 -		bool alt = ModifierType.Mod1Mask == (args.Event.State & ModifierType.Mod1Mask);
 -		bool shift = ModifierType.ShiftMask == (args.Event.State & ModifierType.ShiftMask);
 -
 -		if (args.RetVal == null)
 -			args.RetVal = false;
 -		
 -		switch (args.Event.Key) {
 -		case Gdk.Key.Delete:
 -			if (shift)
 -				HandleDeleteCommand (sender, args);
 -			else
 -				HandleRemoveCommand (sender, args);
 -			break;
 -		case Gdk.Key.Key_0:
 -		case Gdk.Key.KP_0:
 -			if (alt)
 -				HandleRatingMenuSelected (0);
 -			break;
 -		case Gdk.Key.Key_1:
 -		case Gdk.Key.KP_1:
 -			if (alt)
 -				HandleRatingMenuSelected (1);
 -			break;
 -		case Gdk.Key.Key_2:
 -		case Gdk.Key.KP_2:
 -			if (alt)
 -				HandleRatingMenuSelected (2);
 -			break;
 -		case Gdk.Key.Key_3:
 -		case Gdk.Key.KP_3:
 -			if (alt)
 -				HandleRatingMenuSelected (3);
 -			break;
 -		case Gdk.Key.Key_4:
 -		case Gdk.Key.KP_4:
 -			if (alt)
 -				HandleRatingMenuSelected (4);
 -			break;
 -		case Gdk.Key.Key_5:
 -		case Gdk.Key.KP_5:
 -			if (alt)
 -				HandleRatingMenuSelected (5);
 -			break;
 -		default:
 -			return; //do not set the RetVal to true
 -		}
 -		args.RetVal = true;
 -	}
 -
 -	void HandleIconViewKeyPressEvent (object sender, Gtk.KeyPressEventArgs args)
 -	{
 -		HandleCommonPhotoCommands (sender, args);
 -		if ((bool)args.RetVal)
 -			return;
 -
 -		switch (args.Event.Key) {
 -		case Gdk.Key.F:
 -		case Gdk.Key.f:
 -			HandleViewFullscreen (sender, args);
 -			args.RetVal = true;
 -			break;
 +	
 +		//
 +		// PhotoView event handlers.
 +		//
 +	
 +		void HandlePhotoViewKeyPressEvent (object sender, Gtk.KeyPressEventArgs args)
 +		{
 +			HandleCommonPhotoCommands (sender, args);
 +			if ((bool)args.RetVal)
 +				return;
 +	
 +			switch (args.Event.Key) {
 +			case Gdk.Key.F:
 +			case Gdk.Key.f:
 +				HandleViewFullscreen (sender, args);
 +				args.RetVal = true;
 +				break;
 +			case Gdk.Key.Escape:
 +				SetViewMode (ModeType.IconView);
 +				args.RetVal = true;
 +				break;
 +			}
  		}
 -	}
 -
 -	//
 -	// FullScreenView event handlers.
 -	//
 -
 -	void HandleFullScreenViewKeyPressEvent (object sender, Gtk.KeyPressEventArgs args)
 -	{
 -		HandleCommonPhotoCommands (sender, args);
 -		if ((bool)args.RetVal)
 -			// this will hide any panels again that might have appeared above the fullscreen view
 -			fsview.Present ();
 -	}
 -
 -	//
 -	// PhotoView event handlers.
 -	//
 -
 -	void HandlePhotoViewKeyPressEvent (object sender, Gtk.KeyPressEventArgs args)
 -	{
 -		HandleCommonPhotoCommands (sender, args);
 -		if ((bool)args.RetVal)
 -			return;
 -
 -		switch (args.Event.Key) {
 -		case Gdk.Key.F:
 -		case Gdk.Key.f:
 -			HandleViewFullscreen (sender, args);
 +	
 +		void HandlePhotoViewUpdateStarted (PhotoView sender)
 +		{
 +			main_window.GdkWindow.Cursor = watch;
 +			// FIXME: use gdk_display_flush() when available
 +			main_window.GdkWindow.Display.Sync ();
 +		}
 +	
 +		void HandlePhotoViewUpdateFinished (PhotoView sender)
 +		{
 +			main_window.GdkWindow.Cursor = null;
 +			// FIXME: use gdk_display_flush() when available
 +			main_window.GdkWindow.Display.Sync ();
 +		}
 +	
 +		//
 +		// PhotoView drag handlers.
 +		//
 +	
 +		void HandlePhotoViewDragDrop (object sender, DragDropArgs args)
 +		{
 +			//Widget source = Gtk.Drag.GetSourceWidget (args.Context);
 +			//Console.WriteLine ("Drag Drop {0}", source == null ? "null" : source.TypeName);
 +	
  			args.RetVal = true;
 -			break;
 -		case Gdk.Key.Escape:
 -			SetViewMode (ModeType.IconView);
 +		}
 +	
 +		void HandlePhotoViewDragMotion (object sender, DragMotionArgs args)
 +		{
 +			//Widget source = Gtk.Drag.GetSourceWidget (args.Context);
 +			//Console.WriteLine ("Drag Motion {0}", source == null ? "null" : source.TypeName);
 +	
 +			Gdk.Drag.Status (args.Context, args.Context.SuggestedAction, args.Time);
  			args.RetVal = true;
 -			break;
  		}
 -	}
 -
 -	void HandlePhotoViewUpdateStarted (PhotoView sender)
 -	{
 -		main_window.GdkWindow.Cursor = watch;
 -		// FIXME: use gdk_display_flush() when available
 -		main_window.GdkWindow.Display.Sync ();
 -	}
 -
 -	void HandlePhotoViewUpdateFinished (PhotoView sender)
 -	{
 -		main_window.GdkWindow.Cursor = null;
 -		// FIXME: use gdk_display_flush() when available
 -		main_window.GdkWindow.Display.Sync ();
 -	}
 -
 -	//
 -	// PhotoView drag handlers.
 -	//
 -
 -	void HandlePhotoViewDragDrop (object sender, DragDropArgs args)
 -	{
 -		//Widget source = Gtk.Drag.GetSourceWidget (args.Context);
 -		//Console.WriteLine ("Drag Drop {0}", source == null ? "null" : source.TypeName);
 -
 -		args.RetVal = true;
 -	}
 -
 -	void HandlePhotoViewDragMotion (object sender, DragMotionArgs args)
 -	{
 -		//Widget source = Gtk.Drag.GetSourceWidget (args.Context);
 -		//Console.WriteLine ("Drag Motion {0}", source == null ? "null" : source.TypeName);
 -
 -		Gdk.Drag.Status (args.Context, args.Context.SuggestedAction, args.Time);
 -		args.RetVal = true;
 -	}
 -
 -	void HandlePhotoViewDragDataReceived (object sender, DragDataReceivedArgs args)
 -	{
 -	 	//Widget source = Gtk.Drag.GetSourceWidget (args.Context);     
 -		//Console.WriteLine ("Drag received {0}", source == null ? "null" : source.TypeName);
 -
 -		HandleAttachTagCommand (sender, null);
 +	
 +		void HandlePhotoViewDragDataReceived (object sender, DragDataReceivedArgs args)
 +		{
 +		 	//Widget source = Gtk.Drag.GetSourceWidget (args.Context);     
 +			//Console.WriteLine ("Drag received {0}", source == null ? "null" : source.TypeName);
 +	
 +			HandleAttachTagCommand (sender, null);
 +			
 +			Gtk.Drag.Finish (args.Context, true, false, args.Time);
 +	
 +	 		photo_view.View.GrabFocus();
 +		}	
 +	
 +		//
 +		// RatingMenu commands
 +		//
  		
 -		Gtk.Drag.Finish (args.Context, true, false, args.Time);
 -
 - 		photo_view.View.GrabFocus();
 -	}	
 -
 -	//
 -	// RatingMenu commands
 -	//
 +		public void HandleRatingMenuSelected (int r) 
 +		{
 +			if (ViewMode == ModeType.PhotoView)
 +				this.photo_view.UpdateRating(r);
  	
 -	public void HandleRatingMenuSelected (int r) 
 -	{
 -		if (view_mode == ModeType.PhotoView)
 -			this.photo_view.UpdateRating(r);
 -
 -		Photo p;
 -		db.BeginTransaction ();
 -		int [] selected_photos = SelectedIds ();
 -		foreach (int num in selected_photos) {
 -			p = query [num] as Photo;
 -			p.Rating = (uint) r;
 -		}
 -		query.Commit (selected_photos);
 -		db.CommitTransaction ();
 -	}
 -
 -	//
 -	// TagMenu commands.
 -	//
 -
 -	public void HandleTagMenuActivate (object sender, EventArgs args)
 -	{
 -
 -		MenuItem parent = sender as MenuItem;
 -		if (parent == null) // We have a Gtk.Action for UI menus, so the "Edit > Remove tag" item needs special treatment
 -			parent = uimanager.GetWidget("/ui/menubar1/edit2/remove_tag") as MenuItem;
 -		if (parent != null && parent.Submenu is PhotoTagMenu) {
 -			PhotoTagMenu menu = (PhotoTagMenu) parent.Submenu;
 -			menu.Populate (SelectedPhotos ()); 
 +			Photo p;
 +			Database.BeginTransaction ();
 +			int [] selected_photos = SelectedIds ();
 +			foreach (int num in selected_photos) {
 +				p = query [num] as Photo;
 +				p.Rating = (uint) r;
 +			}
 +			query.Commit (selected_photos);
 +			Database.CommitTransaction ();
  		}
 -	}
 -
 -	public void HandleAttachTagMenuSelected (Tag t) 
 -	{
 -		db.BeginTransaction ();
 -		AddTagExtended (SelectedIds (), new Tag [] {t});
 -		db.CommitTransaction ();
 -		query_widget.PhotoTagsChanged (new Tag[] {t});
 -	}
  	
 -	public void HandleRequireTag (object sender, EventArgs args)
 - 	{
 -		ShowQueryWidget ();
 -		query_widget.Require (tag_selection_widget.TagHighlight);
 - 	}
 - 
 -	public void HandleUnRequireTag (object sender, EventArgs args)
 -	{
 -		query_widget.UnRequire (tag_selection_widget.TagHighlight);
 - 	}
 -
 -	public void HandleRemoveTagMenuSelected (Tag t)
 -	{
 -		db.BeginTransaction ();
 -		RemoveTags (SelectedIds (), new Tag [] {t});
 -		db.CommitTransaction ();
 -		query_widget.PhotoTagsChanged (new Tag [] {t});
 -	}
 -
 -	//
 -	// Main menu commands
 -	//
 -
 -	void HandleOpenCommand (object sender, EventArgs e)
 -	{
 -		new FSpot.SingleView ();
 -	}
 -
 -	void HandleImportCommand (object sender, EventArgs e)
 -	{
 -		db.Sync = false;
 -		ImportCommand command = new ImportCommand (main_window);
 -		if (command.ImportFromFile (db.Photos, null) > 0) {
 -			query.RollSet = new RollSet (db.Rolls.GetRolls (1)[0]);
 -			UpdateQuery ();
 +		//
 +		// TagMenu commands.
 +		//
 +	
 +		public void HandleTagMenuActivate (object sender, EventArgs args)
 +		{
 +	
 +			MenuItem parent = sender as MenuItem;
 +			if (parent == null) // We have a Gtk.Action for UI menus, so the "Edit > Remove tag" item needs special treatment
 +				parent = uimanager.GetWidget("/ui/menubar1/edit2/remove_tag") as MenuItem;
 +			if (parent != null && parent.Submenu is PhotoTagMenu) {
 +				PhotoTagMenu menu = (PhotoTagMenu) parent.Submenu;
 +				menu.Populate (SelectedPhotos ()); 
 +			}
  		}
 -		db.Sync = true;		
 -	}
 -
 -	void HandleImportFromCameraCommand (object sender, EventArgs e)
 -	{
 -		ImportCamera (null);
 -	}
 -
 -	public void ImportCamera (string camera_device)
 -	{
 -		Log.Debug ("ImportCamera {0}", camera_device);
 -		GPhotoCamera cam = new GPhotoCamera();
 -
 -		try {
 -			int num_cameras = cam.DetectCameras();
 -			int selected_cam = 0;
 -
 -			if (num_cameras < 1) {
 +	
 +		public void HandleAttachTagMenuSelected (Tag t) 
 +		{
 +			Database.BeginTransaction ();
 +			AddTagExtended (SelectedIds (), new Tag [] {t});
 +			Database.CommitTransaction ();
 +			query_widget.PhotoTagsChanged (new Tag[] {t});
 +		}
 +		
 +		public void HandleRequireTag (object sender, EventArgs args)
 +	 	{
 +			ShowQueryWidget ();
 +			query_widget.Require (tag_selection_widget.TagHighlight);
 +	 	}
 +	 
 +		public void HandleUnRequireTag (object sender, EventArgs args)
 +		{
 +			query_widget.UnRequire (tag_selection_widget.TagHighlight);
 +	 	}
 +	
 +		public void HandleRemoveTagMenuSelected (Tag t)
 +		{
 +			Database.BeginTransaction ();
 +			RemoveTags (SelectedIds (), new Tag [] {t});
 +			Database.CommitTransaction ();
 +			query_widget.PhotoTagsChanged (new Tag [] {t});
 +		}
 +	
 +		//
 +		// Main menu commands
 +		//
 +	
 +		void HandleOpenCommand (object sender, EventArgs e)
 +		{
 +			new FSpot.SingleView ();
 +		}
 +	
 +		void HandleImportCommand (object sender, EventArgs e)
 +		{
 +			Database.Sync = false;
 +			ImportCommand command = new ImportCommand (main_window);
 +			if (command.ImportFromFile (Database.Photos, null) > 0) {
 +				query.RollSet = new RollSet (Database.Rolls.GetRolls (1)[0]);
 +				UpdateQuery ();
 +			}
 +			Database.Sync = true;		
 +		}
 +	
 +		void HandleImportFromCameraCommand (object sender, EventArgs e)
 +		{
 +			ImportCamera (null);
 +		}
 +	
 +		public void ImportCamera (string camera_device)
 +		{
 +			Log.Debug ("ImportCamera {0}", camera_device);
 +			GPhotoCamera cam = new GPhotoCamera();
 +	
 +			try {
 +				int num_cameras = cam.DetectCameras();
 +				int selected_cam = 0;
 +	
 +				if (num_cameras < 1) {
 +					HigMessageDialog md = new HigMessageDialog (main_window, DialogFlags.DestroyWithParent, 
 +						MessageType.Warning, ButtonsType.Ok, 
 +						Catalog.GetString ("No cameras detected."),
 +						Catalog.GetString ("F-Spot was unable to find any cameras attached to this system." + 
 +									      "  Double check that the camera is connected and has power")); 
 +	
 +					md.Run ();
 +					md.Destroy ();
 +					return;
 +				} else if (num_cameras == 1) {
 +					selected_cam = 0;
 +				} else {
 +					bool found = false;
 +					if (camera_device != null)
 +						for (int i = 0; i < num_cameras; i++) {
 +							if (camera_device.IndexOf (cam.CameraList.GetValue(i)) != 0) {
 +								selected_cam = i;
 +								found = true;
 +								break;
 +							}
 +					}
 +					
 +					if (!found) {
 +						FSpot.CameraSelectionDialog camselect = new FSpot.CameraSelectionDialog (cam.CameraList);
 +						selected_cam = camselect.Run ();
 +					}
 +				}
 +	
 +				if (selected_cam >= 0) {
 +					cam.SelectCamera (selected_cam);	
 +					cam.InitializeCamera ();
 +	
 +					FSpot.CameraFileSelectionDialog selector = new FSpot.CameraFileSelectionDialog (cam, Database);
 +					if (selector.Run() > 0)
 +						query.RollSet = new RollSet (Database.Rolls.GetRolls (1)[0]);
 +					UpdateQuery ();
 +				}
 +			}
 +			catch (GPhotoException ge) {
 +				System.Console.WriteLine (ge.ToString ());
  				HigMessageDialog md = new HigMessageDialog (main_window, DialogFlags.DestroyWithParent, 
 -					MessageType.Warning, ButtonsType.Ok, 
 -					Catalog.GetString ("No cameras detected."),
 -					Catalog.GetString ("F-Spot was unable to find any cameras attached to this system." + 
 -								      "  Double check that the camera is connected and has power")); 
 -
 +					MessageType.Error, ButtonsType.Ok, 
 +					Catalog.GetString ("Error connecting to camera"),
 +					String.Format (Catalog.GetString ("Received error \"{0}\" while connecting to camera"), 
 +					ge.Message));
 +	
  				md.Run ();
  				md.Destroy ();
 +			} finally {
 +				cam.ReleaseGPhotoResources ();
 +			}
 +		}
 +		void HandlePageSetupActivated (object o, EventArgs e)
 +		{
 +			FSpot.Global.PageSetup = Print.RunPageSetupDialog (this.Window, FSpot.Global.PageSetup, null);
 +		}
 +		
 +		void HandlePrintCommand (object sender, EventArgs e)
 +		{
 +			FSpot.PrintOperation print = new FSpot.PrintOperation (SelectedPhotos ());
 +			print.Run (PrintOperationAction.PrintDialog, null);
 +		}
 +	
 +		public void HandlePreferences (object sender, EventArgs args)
 +		{
 +			var pref = new PreferenceDialog (GetToplevel (sender));
 +			pref.Run ();
 +			pref.Destroy ();
 +		}
 +	
 +		public void HandleManageExtensions (object sender, EventArgs args)
 +		{
 +			Mono.Addins.Gui.AddinManagerWindow.Run (main_window);
 +		}
 +	
 +		private void TestDisplay ()
 +		{
 +			Gtk.Window win = new Gtk.Window ("hello");
 +			VBox box = new VBox ();
 +			box.PackStart (new FSpot.Widgets.ImageDisplay (new BrowsablePointer (new FSpot.PhotoArray (SelectedPhotos ()), 0)));
 +			win.Add (box);
 +			win.ShowAll ();
 +		}
 +	
 +		void HandleSendMailCommand (object sender, EventArgs args)
 +		{
 +			//TestDisplay ();
 +			new FSpot.SendEmail (new FSpot.PhotoArray (SelectedPhotos ()), Window);
 +		}
 +	
 +		public static void HandleHelp (object sender, EventArgs args)
 +		{
 +			GtkBeans.Global.ShowUri (Toplevel.Window.Screen, "ghelp:f-spot");
 +		}
 +	
 +		public static void HandleAbout (object sender, EventArgs args)
 +		{
 +			FSpot.UI.Dialog.AboutDialog.ShowUp ();
 +		}
 +	
 +		void HandleTagSizeChange (object sender, EventArgs args)
 +		{
 +			RadioAction choice = sender as RadioAction;
 +		
 +			//Get this callback twice. Once for the active going menuitem,
 +			//once for the inactive leaving one. Ignore the inactive.
 +			if (!choice.Active)
  				return;
 -			} else if (num_cameras == 1) {
 -				selected_cam = 0;
 +	
 +			int old_size = TagsIconSize;
 +			
 +			if (choice == tag_icon_hidden) {
 +				TagsIconSize = (int) Tag.IconSize.Hidden;
 +			} else if (choice == tag_icon_small) {
 +				TagsIconSize = (int) Tag.IconSize.Small;
 +			} else if (choice == tag_icon_medium) {
 +				TagsIconSize = (int) Tag.IconSize.Medium;
 +			} else if (choice == tag_icon_large) {
 +				TagsIconSize = (int) Tag.IconSize.Large;
  			} else {
 -				bool found = false;
 -				if (camera_device != null)
 -					for (int i = 0; i < num_cameras; i++) {
 -						if (camera_device.IndexOf (cam.CameraList.GetValue(i)) != 0) {
 -							selected_cam = i;
 -							found = true;
 -							break;
 -						}
 -				}
 -				
 -				if (!found) {
 -					FSpot.CameraSelectionDialog camselect = new FSpot.CameraSelectionDialog (cam.CameraList);
 -					selected_cam = camselect.Run ();
 -				}
 +				return;
  			}
 -
 -			if (selected_cam >= 0) {
 -				cam.SelectCamera (selected_cam);	
 -				cam.InitializeCamera ();
 -
 -				FSpot.CameraFileSelectionDialog selector = new FSpot.CameraFileSelectionDialog (cam, db);
 -				if (selector.Run() > 0)
 -					query.RollSet = new RollSet (db.Rolls.GetRolls (1)[0]);
 -				UpdateQuery ();
 +			
 +			if (old_size != TagsIconSize) {
 +				tag_selection_widget.ColumnsAutosize();
 +				Preferences.Set (Preferences.TAG_ICON_SIZE, TagsIconSize);
  			}
  		}
 -		catch (GPhotoException ge) {
 -			System.Console.WriteLine (ge.ToString ());
 -			HigMessageDialog md = new HigMessageDialog (main_window, DialogFlags.DestroyWithParent, 
 -				MessageType.Error, ButtonsType.Ok, 
 -				Catalog.GetString ("Error connecting to camera"),
 -				String.Format (Catalog.GetString ("Received error \"{0}\" while connecting to camera"), 
 -				ge.Message));
 -
 -			md.Run ();
 -			md.Destroy ();
 -		} finally {
 -			cam.ReleaseGPhotoResources ();
 +	
 +		public void HandleFilmstripHorizontal (object sender, EventArgs args)
 +		{
 +			if (photo_view.FilmstripOrientation == Orientation.Horizontal)
 +				return;
 +			(sender as Gtk.CheckMenuItem).Active = false;
 +			photo_view.PlaceFilmstrip (Orientation.Horizontal);
  		}
 -	}
 -	void HandlePageSetupActivated (object o, EventArgs e)
 -	{
 -		FSpot.Global.PageSetup = Print.RunPageSetupDialog (this.Window, FSpot.Global.PageSetup, null);
 -	}
  	
 -	void HandlePrintCommand (object sender, EventArgs e)
 -	{
 -		FSpot.PrintOperation print = new FSpot.PrintOperation (SelectedPhotos ());
 -		print.Run (PrintOperationAction.PrintDialog, null);
 -	}
 -
 -	public void HandlePreferences (object sender, EventArgs args)
 -	{
 -		var pref = new PreferenceDialog (GetToplevel (sender));
 -		pref.Run ();
 -		pref.Destroy ();
 -	}
 -
 -	public void HandleManageExtensions (object sender, EventArgs args)
 -	{
 -		Mono.Addins.Gui.AddinManagerWindow.Run (main_window);
 -	}
 -
 -	private void TestDisplay ()
 -	{
 -		Gtk.Window win = new Gtk.Window ("hello");
 -		VBox box = new VBox ();
 -		box.PackStart (new FSpot.Widgets.ImageDisplay (new BrowsablePointer (new FSpot.PhotoArray (SelectedPhotos ()), 0)));
 -		win.Add (box);
 -		win.ShowAll ();
 -	}
 -
 -	void HandleSendMailCommand (object sender, EventArgs args)
 -	{
 -		//TestDisplay ();
 -		new FSpot.SendEmail (new FSpot.PhotoArray (SelectedPhotos ()), Window);
 -	}
 -
 -	public static void HandleHelp (object sender, EventArgs args)
 -	{
 -		GtkBeans.Global.ShowUri (Toplevel.Window.Screen, "ghelp:f-spot");
 -	}
 -
 -	public static void HandleAbout (object sender, EventArgs args)
 -	{
 -		FSpot.UI.Dialog.AboutDialog.ShowUp ();
 -	}
 -
 -	void HandleTagSizeChange (object sender, EventArgs args)
 -	{
 -		RadioAction choice = sender as RadioAction;
 +		public void HandleFilmstripVertical (object sender, EventArgs args)
 +		{
 +			if (photo_view.FilmstripOrientation == Orientation.Vertical)
 +				return;
 +			(sender as Gtk.CheckMenuItem).Active = false;
 +			photo_view.PlaceFilmstrip (Orientation.Vertical);
 +		}
  	
 -		//Get this callback twice. Once for the active going menuitem,
 -		//once for the inactive leaving one. Ignore the inactive.
 -		if (!choice.Active)
 -			return;
 -
 -		int old_size = TagsIconSize;
 -		
 -		if (choice == tag_icon_hidden) {
 -			TagsIconSize = (int) Tag.IconSize.Hidden;
 -		} else if (choice == tag_icon_small) {
 -			TagsIconSize = (int) Tag.IconSize.Small;
 -		} else if (choice == tag_icon_medium) {
 -			TagsIconSize = (int) Tag.IconSize.Medium;
 -		} else if (choice == tag_icon_large) {
 -			TagsIconSize = (int) Tag.IconSize.Large;
 -		} else {
 -			return;
 +		public void HandleReverseOrder (object sender, EventArgs args)
 +		{
 +			ToggleAction item = sender as ToggleAction;
 +	
 +			if (group_selector.Adaptor.OrderAscending == item.Active)
 +				return;
 +			
 +			group_selector.Adaptor.OrderAscending = item.Active;
 +			query.TimeOrderAsc = item.Active;
 +	
 +			// FIXME this is blah...we need UIManager love here
 +			if (item != reverse_order)
 +				reverse_order.Active = item.Active;
 +			
 +			//update the selection in the timeline
 +			if ( query.Range != null && group_selector.Adaptor is TimeAdaptor) {
 +				group_selector.SetLimitsToDates(query.Range.Start, query.Range.End);
 +				
 +			}
 +	
 +		}
 +	
 +		// Called when the user clicks the X button	
 +		void HandleDeleteEvent (object sender, DeleteEventArgs args)
 +		{
 +			Close();
 +			args.RetVal = true;
 +		}
 +	
 +		void HandleCloseCommand (object sender, EventArgs args)
 +		{
 +			Close();
  		}
  		
 -		if (old_size != TagsIconSize) {
 -			tag_selection_widget.ColumnsAutosize();
 -			Preferences.Set (Preferences.TAG_ICON_SIZE, TagsIconSize);
 +		public void Close ()
 +		{
 +			int x, y, width, height;
 +			main_window.GetPosition (out x, out y);
 +			main_window.GetSize (out width, out height);
 +	
 +			bool maximized = ((main_window.GdkWindow.State & Gdk.WindowState.Maximized) > 0);
 +			Preferences.Set (Preferences.MAIN_WINDOW_MAXIMIZED, maximized);
 +	
 +			if (!maximized) {
 +				Preferences.Set (Preferences.MAIN_WINDOW_X,		x);
 +				Preferences.Set (Preferences.MAIN_WINDOW_Y,		y);
 +				Preferences.Set (Preferences.MAIN_WINDOW_WIDTH,		width);
 +				Preferences.Set (Preferences.MAIN_WINDOW_HEIGHT,	height);
 +			}
 +	
 +			Preferences.Set (Preferences.SHOW_TOOLBAR,		toolbar.Visible);
 +			Preferences.Set (Preferences.SHOW_SIDEBAR,		info_vbox.Visible);
 +			Preferences.Set (Preferences.SHOW_TIMELINE,		display_timeline.Active);
 +			Preferences.Set (Preferences.SHOW_FILMSTRIP,		display_filmstrip.Active);
 +			Preferences.Set (Preferences.SHOW_TAGS,			icon_view.DisplayTags);
 +			Preferences.Set (Preferences.SHOW_DATES,		icon_view.DisplayDates);
 +			Preferences.Set (Preferences.SHOW_RATINGS,		icon_view.DisplayRatings);
 +	
++			Preferences.Set (Preferences.GROUP_ADAPTOR_ORDER_ASC,   group_selector.Adaptor.OrderAscending);
 +			Preferences.Set (Preferences.GLASS_POSITION,		group_selector.GlassPosition);
 +			
 +			Preferences.Set (Preferences.SIDEBAR_POSITION,		main_hpaned.Position);
 +			Preferences.Set (Preferences.ZOOM,			icon_view.Zoom);
 +	
 +			tag_selection_widget.SaveExpandDefaults ();
 +	
 +			this.Window.Destroy ();
  		}
 -	}
 -
 -	public void HandleFilmstripHorizontal (object sender, EventArgs args)
 -	{
 -		if (photo_view.FilmstripOrientation == Orientation.Horizontal)
 -			return;
 -		(sender as Gtk.CheckMenuItem).Active = false;
 -		photo_view.PlaceFilmstrip (Orientation.Horizontal);
 -	}
 -
 -	public void HandleFilmstripVertical (object sender, EventArgs args)
 -	{
 -		if (photo_view.FilmstripOrientation == Orientation.Vertical)
 -			return;
 -		(sender as Gtk.CheckMenuItem).Active = false;
 -		photo_view.PlaceFilmstrip (Orientation.Vertical);
 -	}
 -
 -	public void HandleReverseOrder (object sender, EventArgs args)
 -	{
 -		ToggleAction item = sender as ToggleAction;
 -
 -		if (group_selector.Adaptor.OrderAscending == item.Active)
 -			return;
  		
 -		group_selector.Adaptor.OrderAscending = item.Active;
 -		query.TimeOrderAsc = item.Active;
 -
 -		// FIXME this is blah...we need UIManager love here
 -		if (item != reverse_order)
 -			reverse_order.Active = item.Active;
 +		void HandleCreateVersionCommand (object obj, EventArgs args)
 +		{
 +			PhotoVersionCommands.Create cmd = new PhotoVersionCommands.Create ();
 +	
 +			cmd.Execute (Database.Photos, CurrentPhoto, GetToplevel (null));
 +	//		if (cmd.Execute (db.Photos, CurrentPhoto, GetToplevel (null))) {
 +	//			query.MarkChanged (ActiveIndex (), true, false);
 +	//		}
 +		}
 +	
 +		void HandleDeleteVersionCommand (object obj, EventArgs args)
 +		{
 +			PhotoVersionCommands.Delete cmd = new PhotoVersionCommands.Delete ();
 +	
 +			cmd.Execute (Database.Photos, CurrentPhoto, GetToplevel (null));
 +	//		if (cmd.Execute (db.Photos, CurrentPhoto, GetToplevel (null))) {
 +	//			query.MarkChanged (ActiveIndex (), true, true);
 +	//		}
 +		}
 +	
 +		void HandleRenameVersionCommand (object obj, EventArgs args)
 +		{
 +			PhotoVersionCommands.Rename cmd = new PhotoVersionCommands.Rename ();
 +	
 +			cmd.Execute (Database.Photos, CurrentPhoto, main_window);
 +	//		if (cmd.Execute (db.Photos, CurrentPhoto, main_window)) {
 +	//			query.MarkChanged (ActiveIndex (), true, false);
 +	//		}
 +		}
  		
 -		//update the selection in the timeline
 -		if ( query.Range != null && group_selector.Adaptor is TimeAdaptor) {
 -			group_selector.SetLimitsToDates(query.Range.Start, query.Range.End);
 +		public void HandleCreateTagAndAttach (object sender, EventArgs args)
 +		{
 +			Tag new_tag = CreateTag (sender, args);
 +	
 +			if (new_tag != null)
 +				HandleAttachTagMenuSelected (new_tag);
 +		}
 +	
 +		public void HandleCreateNewCategoryCommand (object sender, EventArgs args)
 +		{
 +			Tag new_tag = CreateTag (sender, args);
  			
 +			if (new_tag != null) {
 +				tag_selection_widget.ScrollTo (new_tag);
 +				tag_selection_widget.TagHighlight = new Tag [] {new_tag};
 +			}
  		}
 -
 -	}
 -
 -	// Called when the user clicks the X button	
 -	void HandleDeleteEvent (object sender, DeleteEventArgs args)
 -	{
 -		Close();
 -		args.RetVal = true;
 -	}
 -
 -	void HandleCloseCommand (object sender, EventArgs args)
 -	{
 -		Close();
 -	}
  	
 -	public void Close ()
 -	{
 -		int x, y, width, height;
 -		main_window.GetPosition (out x, out y);
 -		main_window.GetSize (out width, out height);
 -
 -		bool maximized = ((main_window.GdkWindow.State & Gdk.WindowState.Maximized) > 0);
 -		Preferences.Set (Preferences.MAIN_WINDOW_MAXIMIZED, maximized);
 -
 -		if (!maximized) {
 -			Preferences.Set (Preferences.MAIN_WINDOW_X,		x);
 -			Preferences.Set (Preferences.MAIN_WINDOW_Y,		y);
 -			Preferences.Set (Preferences.MAIN_WINDOW_WIDTH,		width);
 -			Preferences.Set (Preferences.MAIN_WINDOW_HEIGHT,	height);
 +		public Tag CreateTag (object sender, EventArgs args)
 +		{
 +			TagCommands.Create command = new TagCommands.Create (Database.Tags, GetToplevel (sender));
 +			return command.Execute (TagCommands.TagType.Category, tag_selection_widget.TagHighlight);
  		}
 -
 -		Preferences.Set (Preferences.SHOW_TOOLBAR,		toolbar.Visible);
 -		Preferences.Set (Preferences.SHOW_SIDEBAR,		info_vbox.Visible);
 -		Preferences.Set (Preferences.SHOW_TIMELINE,		display_timeline.Active);
 -		Preferences.Set (Preferences.SHOW_FILMSTRIP,		display_filmstrip.Active);
 -		Preferences.Set (Preferences.SHOW_TAGS,			icon_view.DisplayTags);
 -		Preferences.Set (Preferences.SHOW_DATES,		icon_view.DisplayDates);
 -		Preferences.Set (Preferences.SHOW_RATINGS,		icon_view.DisplayRatings);
 -
 -		Preferences.Set (Preferences.GROUP_ADAPTOR_ORDER_ASC,   group_selector.Adaptor.OrderAscending);
 -		Preferences.Set (Preferences.GLASS_POSITION,		group_selector.GlassPosition);
 -		
 -		Preferences.Set (Preferences.SIDEBAR_POSITION,		main_hpaned.Position);
 -		Preferences.Set (Preferences.ZOOM,			icon_view.Zoom);
 -
 -		tag_selection_widget.SaveExpandDefaults ();
 -
 -		this.Window.Destroy ();
 -	}
  	
 -	void HandleCreateVersionCommand (object obj, EventArgs args)
 -	{
 -		PhotoVersionCommands.Create cmd = new PhotoVersionCommands.Create ();
 -
 -		cmd.Execute (db.Photos, CurrentPhoto, GetToplevel (null));
 -//		if (cmd.Execute (db.Photos, CurrentPhoto, GetToplevel (null))) {
 -//			query.MarkChanged (ActiveIndex (), true, false);
 -//		}
 -	}
 -
 -	void HandleDeleteVersionCommand (object obj, EventArgs args)
 -	{
 -		PhotoVersionCommands.Delete cmd = new PhotoVersionCommands.Delete ();
 -
 -		cmd.Execute (db.Photos, CurrentPhoto, GetToplevel (null));
 -//		if (cmd.Execute (db.Photos, CurrentPhoto, GetToplevel (null))) {
 -//			query.MarkChanged (ActiveIndex (), true, true);
 -//		}
 -	}
 -
 -	void HandlePropertiesCommand (object obje, EventArgs args)
 -	{
 -		Photo [] photos = SelectedPhotos ();
 -		
 -	        long length = 0;
 -
 -		foreach (Photo p in photos) {
 -			System.IO.FileInfo fi = new System.IO.FileInfo (p.DefaultVersionUri.LocalPath);
 -
 -			length += fi.Length;
 +		public void HandleAttachTagCommand (object obj, EventArgs args)
 +		{
 +			AttachTags (tag_selection_widget.TagHighlight, SelectedIds ());
  		}
 -
 -		Console.WriteLine ("{0} Selected Photos : Total length = {1} - {2}kB - {3}MB", photos.Length, length, length / 1024, length / (1024 * 1024));
 -	}
 -		
 -	void HandleRenameVersionCommand (object obj, EventArgs args)
 -	{
 -		PhotoVersionCommands.Rename cmd = new PhotoVersionCommands.Rename ();
 -
 -		cmd.Execute (db.Photos, CurrentPhoto, main_window);
 -//		if (cmd.Execute (db.Photos, CurrentPhoto, main_window)) {
 -//			query.MarkChanged (ActiveIndex (), true, false);
 -//		}
 -	}
  	
 -	public void HandleCreateTagAndAttach (object sender, EventArgs args)
 -	{
 -		Tag new_tag = CreateTag (sender, args);
 -
 -		if (new_tag != null)
 -			HandleAttachTagMenuSelected (new_tag);
 -	}
 -
 -	public void HandleCreateNewCategoryCommand (object sender, EventArgs args)
 -	{
 -		Tag new_tag = CreateTag (sender, args);
 -		
 -		if (new_tag != null) {
 -			tag_selection_widget.ScrollTo (new_tag);
 -			tag_selection_widget.TagHighlight = new Tag [] {new_tag};
 +		void AttachTags (Tag [] tags, int [] ids) 
 +		{
 +			Database.BeginTransaction ();
 +			AddTagExtended (ids, tags);
 +			Database.CommitTransaction ();
 +			query_widget.PhotoTagsChanged (tags);
  		}
 -	}
 -
 -	public Tag CreateTag (object sender, EventArgs args)
 -	{
 -		TagCommands.Create command = new TagCommands.Create (db.Tags, GetToplevel (sender));
 -		return command.Execute (TagCommands.TagType.Category, tag_selection_widget.TagHighlight);
 -	}
 -
 -	public void HandleAttachTagCommand (object obj, EventArgs args)
 -	{
 -		AttachTags (tag_selection_widget.TagHighlight, SelectedIds ());
 -	}
 -
 -	void AttachTags (Tag [] tags, int [] ids) 
 -	{
 -		db.BeginTransaction ();
 -		AddTagExtended (ids, tags);
 -		db.CommitTransaction ();
 -		query_widget.PhotoTagsChanged (tags);
 -	}
 -
 -	public void HandleRemoveTagCommand (object obj, EventArgs args)
 -	{
 -		Tag [] tags = this.tag_selection_widget.TagHighlight;
 -
 -		db.BeginTransaction ();
 -		RemoveTags (SelectedIds (), tags);
 -		db.CommitTransaction ();
 -		query_widget.PhotoTagsChanged (tags);
 -	}
 -
 -	public void HandleEditSelectedTag (object sender, EventArgs ea)
 -	{
 -		Tag [] tags = this.tag_selection_widget.TagHighlight;
 -		if (tags.Length != 1)
 -			return;
 -
 -		HandleEditSelectedTagWithTag (tags [0]);
 -	}
 -
 -	public void HandleEditSelectedTagWithTag (Tag tag)
 -	{
 -		if (tag == null)
 -			return;
 -		
 -		EditTagDialog dialog = new EditTagDialog (db, tag, main_window);
 -		if ((ResponseType)dialog.Run () == ResponseType.Ok) {
 -			bool name_changed = false;
 -			try {
 -				if (tag.Name != dialog.TagName) {
 -					tag.Name = dialog.TagName;
 -					name_changed = true;
 +	
 +		public void HandleRemoveTagCommand (object obj, EventArgs args)
 +		{
 +			Tag [] tags = this.tag_selection_widget.TagHighlight;
 +	
 +			Database.BeginTransaction ();
 +			RemoveTags (SelectedIds (), tags);
 +			Database.CommitTransaction ();
 +			query_widget.PhotoTagsChanged (tags);
 +		}
 +	
 +		public void HandleEditSelectedTag (object sender, EventArgs ea)
 +		{
 +			Tag [] tags = this.tag_selection_widget.TagHighlight;
 +			if (tags.Length != 1)
 +				return;
 +	
 +			HandleEditSelectedTagWithTag (tags [0]);
 +		}
 +	
 +		public void HandleEditSelectedTagWithTag (Tag tag)
 +		{
 +			if (tag == null)
 +				return;
 +			
 +			EditTagDialog dialog = new EditTagDialog (Database, tag, main_window);
 +			if ((ResponseType)dialog.Run () == ResponseType.Ok) {
 +				bool name_changed = false;
 +				try {
 +					if (tag.Name != dialog.TagName) {
 +						tag.Name = dialog.TagName;
 +						name_changed = true;
 +					}
 +					tag.Category = dialog.TagCategory;
 +					Database.Tags.Commit (tag, name_changed);
 +				} catch (Exception ex) {
 +					Log.Exception (ex);
  				}
 -				tag.Category = dialog.TagCategory;
 -				db.Tags.Commit (tag, name_changed);
 -			} catch (Exception ex) {
 -				Log.Exception (ex);
  			}
 +	
 +			dialog.Destroy ();
  		}
 -
 -		dialog.Destroy ();
 -	}
 -
 -	public void HandleMergeTagsCommand (object obj, EventArgs args)
 -	{
 -		Tag [] tags = this.tag_selection_widget.TagHighlight;
 -		if (tags.Length < 2)
 -			return;
 -		
 -		// Translators, The singular case will never happen here.
 -		string header = Catalog.GetPluralString ("Merge the selected tag",
 -								    "Merge the {0} selected tags?", tags.Length);
 -		header = String.Format (header, tags.Length);
 -
 -		// If a tag with children tags is selected for merging, we
 -		// should also merge its children..
 -		List<Tag> all_tags = new List<Tag> (tags.Length);
 -		foreach (Tag tag in tags) {
 -			if (! all_tags.Contains (tag))
 -				all_tags.Add (tag);
 +	
 +		public void HandleMergeTagsCommand (object obj, EventArgs args)
 +		{
 +			Tag [] tags = this.tag_selection_widget.TagHighlight;
 +			if (tags.Length < 2)
 +				return;
 +			
 +			// Translators, The singular case will never happen here.
 +			string header = Catalog.GetPluralString ("Merge the selected tag",
 +									    "Merge the {0} selected tags?", tags.Length);
 +			header = String.Format (header, tags.Length);
 +	
 +			// If a tag with children tags is selected for merging, we
 +			// should also merge its children..
 +			List<Tag> all_tags = new List<Tag> (tags.Length);
 +			foreach (Tag tag in tags) {
 +				if (! all_tags.Contains (tag))
 +					all_tags.Add (tag);
 +				else
 +					continue;
 +	
 +				if (! (tag is Category))
 +					continue;
 +	
 +				(tag as Category).AddDescendentsTo (all_tags);
 +			}
 +	
 +			// debug..
 +			tags = all_tags.ToArray ();
 +			System.Array.Sort (tags, new TagRemoveComparer ());
 +	
 +			foreach (Tag tag in tags) {
 +				System.Console.WriteLine ("tag: {0}", tag.Name);
 +			}
 +	
 +			string msg = Catalog.GetString("This operation will merge the selected tags and any sub-tags into a single tag.");
 +	
 +			string ok_caption = Catalog.GetString ("_Merge Tags");
 +			
 +			if (ResponseType.Ok != HigMessageDialog.RunHigConfirmation(main_window, 
 +										   DialogFlags.DestroyWithParent, 
 +										   MessageType.Warning, 
 +										   header, 
 +										   msg, 
 +										   ok_caption))
 +				return;
 +			
 +			// The surviving tag is the last tag, as it is definitely not a child of any other the
 +			// other tags.  removetags will contain the tags to be merged.
 +			Tag survivor = tags[tags.Length - 1];
 +			
 +			Tag [] removetags = new Tag [tags.Length - 1];
 +			Array.Copy (tags, 0, removetags, 0, tags.Length - 1);
 +	
 +			// Add the surviving tag to all the photos with the other tags
 +			Photo [] photos = Database.Photos.Query (removetags);
 +			foreach (Photo p in photos) {
 +				p.AddTag (survivor);
 +			}
 +	
 +			// Remove the defunct tags, which removes them from the photos, commits
 +			// the photos, and removes the tags from the TagStore
 +			Database.BeginTransaction ();
 +			Database.Photos.Remove (removetags);
 +			Database.CommitTransaction ();
 +	
 +			HandleEditSelectedTagWithTag (survivor);
 +		}
 +	
 +		void HandleAdjustTime (object sender, EventArgs args)
 +		{
 +			PhotoList list = new PhotoList (Selection.Items);
 +			list.Sort (new Photo.CompareDateName ());
 +			(new AdjustTimeDialog (Database, list)).Run ();
 +		}
 +	
 +		public void HideLoupe ()
 +		{
 +			loupe_menu_item.Active = false;
 +		}
 +	
 +		void HandleLoupe (object sender, EventArgs args)
 +		{
 +			// Don't steal characters from any text entries
 +			if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 +				Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 +				return;
 +			}
 +			
 +			photo_view.View.ShowHideLoupe ();
 +		}
 +	
 +		void HandleSharpen (object sender, EventArgs args)
 +		{
 +			// Don't steal characters from any text entries
 +			if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 +				Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 +				return;
 +			}
 +			
 +			photo_view.View.ShowSharpener ();
 +		}
 +	
 +		void HandleDisplayToolbar (object sender, EventArgs args)
 +		{
 +			if (display_toolbar.Active)
 +				toolbar.Show ();
  			else
 -				continue;
 -
 -			if (! (tag is Category))
 -				continue;
 -
 -			(tag as Category).AddDescendentsTo (all_tags);
 +				toolbar.Hide ();
  		}
 -
 -		// debug..
 -		tags = all_tags.ToArray ();
 -		System.Array.Sort (tags, new TagRemoveComparer ());
 -
 -		foreach (Tag tag in tags) {
 -			System.Console.WriteLine ("tag: {0}", tag.Name);
 +	
 +		void HandleDisplayTags (object sender, EventArgs args)
 +		{
 +			icon_view.DisplayTags = !icon_view.DisplayTags;
  		}
 -
 -		string msg = Catalog.GetString("This operation will merge the selected tags and any sub-tags into a single tag.");
 -
 -		string ok_caption = Catalog.GetString ("_Merge Tags");
 -		
 -		if (ResponseType.Ok != HigMessageDialog.RunHigConfirmation(main_window, 
 -									   DialogFlags.DestroyWithParent, 
 -									   MessageType.Warning, 
 -									   header, 
 -									   msg, 
 -									   ok_caption))
 -			return;
  		
 -		// The surviving tag is the last tag, as it is definitely not a child of any other the
 -		// other tags.  removetags will contain the tags to be merged.
 -		Tag survivor = tags[tags.Length - 1];
 -		
 -		Tag [] removetags = new Tag [tags.Length - 1];
 -		Array.Copy (tags, 0, removetags, 0, tags.Length - 1);
 -
 -		// Add the surviving tag to all the photos with the other tags
 -		Photo [] photos = db.Photos.Query (removetags);
 -		foreach (Photo p in photos) {
 -			p.AddTag (survivor);
 +		void HandleDisplayDates (object sender, EventArgs args)
 +		{
 +			// Peg the icon_view's value to the MenuItem's active state,
 +			// as icon_view.DisplayDates's get won't always be equal to it's true value
 +			// because of logic to hide dates when zoomed way out.
 +			icon_view.DisplayDates = display_dates_menu_item.Active;
  		}
 -
 -		// Remove the defunct tags, which removes them from the photos, commits
 -		// the photos, and removes the tags from the TagStore
 -		db.BeginTransaction ();
 -		db.Photos.Remove (removetags);
 -		db.CommitTransaction ();
 -
 -		HandleEditSelectedTagWithTag (survivor);
 -	}
 -
 -	void HandleAdjustTime (object sender, EventArgs args)
 -	{
 -		PhotoList list = new PhotoList (Selection.Items);
 -		list.Sort (new Photo.CompareDateName ());
 -		(new AdjustTimeDialog (db, list)).Run ();
 -	}
 -
 -	public void HideLoupe ()
 -	{
 -		loupe_menu_item.Active = false;
 -	}
 -
 -	void HandleLoupe (object sender, EventArgs args)
 -	{
 -		// Don't steal characters from any text entries
 -		if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 -			Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 -			return;
 +	
 +		void HandleDisplayRatings (object sender, EventArgs args)
 +		{
 +			icon_view.DisplayRatings = display_ratings_menu_item.Active;
  		}
 -		
 -		photo_view.View.ShowHideLoupe ();
 -	}
 -
 -	void HandleSharpen (object sender, EventArgs args)
 -	{
 -		// Don't steal characters from any text entries
 -		if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 -			Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 -			return;
 +	
 +		void HandleDisplayGroupSelector (object sender, EventArgs args)
 +		{
 +			if (group_selector.Visible)
 +				group_selector.Hide ();
 +			else
 +				group_selector.Show ();
  		}
 -		
 -		photo_view.View.ShowSharpener ();
 -	}
 -
 -	void HandleDisplayToolbar (object sender, EventArgs args)
 -	{
 -		if (display_toolbar.Active)
 -			toolbar.Show ();
 -		else
 -			toolbar.Hide ();
 -	}
 -
 -	void HandleDisplayTags (object sender, EventArgs args)
 -	{
 -		icon_view.DisplayTags = !icon_view.DisplayTags;
 -	}
  	
 -	void HandleDisplayDates (object sender, EventArgs args)
 -	{
 -		// Peg the icon_view's value to the MenuItem's active state,
 -		// as icon_view.DisplayDates's get won't always be equal to it's true value
 -		// because of logic to hide dates when zoomed way out.
 -		icon_view.DisplayDates = display_dates_menu_item.Active;
 -	}
 -
 -	void HandleDisplayRatings (object sender, EventArgs args)
 -	{
 -		icon_view.DisplayRatings = display_ratings_menu_item.Active;
 -	}
 -
 -	void HandleDisplayGroupSelector (object sender, EventArgs args)
 -	{
 -		if (group_selector.Visible)
 -			group_selector.Hide ();
 -		else
 -			group_selector.Show ();
 -	}
 -
 -	void HandleDisplayFilmstrip (object sender, EventArgs args)
 -	{
 -		photo_view.FilmStripVisibility = display_filmstrip.Active;
 -		if (view_mode == ModeType.PhotoView)
 -			photo_view.QueueDraw ();
 -	}
 -
 -	void HandleDisplayInfoSidebar (object sender, EventArgs args)
 -	{
 -		if (info_vbox.Visible)
 -			info_vbox.Hide ();
 -		else
 -			info_vbox.Show ();
 -	}
 -
 -	void HandleViewSlideShow (object sender, EventArgs args)
 -	{
 -		HandleViewFullscreen (sender, args);
 -		fsview.PlayPause ();
 -	}
 -
 -	void HandleToggleViewBrowse (object sender, EventArgs args)
 -	{
 -		if (view_mode == ModeType.IconView)
 -			browse_button.Active = true;
 -		else if (browse_button.Active)
 -			SetViewMode (ModeType.IconView);
 -	}
 -
 -	void HandleToggleViewPhoto (object sender, EventArgs args)
 -	{
 -		if (view_mode == ModeType.PhotoView)
 -			edit_button.Active = true;
 -		else if (edit_button.Active)
 -			SetViewMode (ModeType.PhotoView);
 -	}
 -
 -	void HandleViewBrowse (object sender, EventArgs args)
 -	{
 -		SetViewMode (ModeType.IconView);
 -	}
 -
 -	void HandleViewPhoto (object sender, EventArgs args)
 -	{
 -		SetViewMode (ModeType.PhotoView);
 -	}
 -
 -	void HandleViewFullscreen (object sender, EventArgs args)
 -	{
 -		int active = (selection.Count > 0 ? SelectedIds() [0] : 0);
 -		if (fsview == null) {
 -			fsview = new FSpot.FullScreenView (query, main_window);
 -			fsview.Destroyed += HandleFullScreenViewDestroy;
 -			fsview.KeyPressEvent += HandleFullScreenViewKeyPressEvent;
 -			fsview.View.Item.Index = active;
 -		} else {
 -			// FIXME this needs to be another mode like PhotoView and IconView mode.
 -			fsview.View.Item.Index = active;
 +		void HandleDisplayFilmstrip (object sender, EventArgs args)
 +		{
 +			photo_view.FilmStripVisibility = display_filmstrip.Active;
 +			if (ViewMode == ModeType.PhotoView)
 +				photo_view.QueueDraw ();
  		}
 -		
 -		fsview.Show ();
 -	}
 -
 -	void HandleFullScreenViewDestroy (object sender, EventArgs args)
 -	{
 -		JumpTo (fsview.View.Item.Index);
 -		fsview = null;
 -	}
  	
 -	void HandleZoomScaleValueChanged (object sender, System.EventArgs args)
 -	{
 -		switch (view_mode) {
 -		case ModeType.PhotoView:
 -			photo_view.View.ZoomChanged -= HandleZoomChanged;
 -			photo_view.NormalizedZoom = zoom_scale.Value;
 -			photo_view.View.ZoomChanged += HandleZoomChanged;
 -			break;
 -		case ModeType.IconView:
 -			icon_view.ZoomChanged -= HandleZoomChanged;
 -			icon_view.Zoom = zoom_scale.Value;
 -			icon_view.ZoomChanged += HandleZoomChanged;
 -			break;
 +		void HandleDisplayInfoSidebar (object sender, EventArgs args)
 +		{
 +			if (info_vbox.Visible)
 +				info_vbox.Hide ();
 +			else
 +				info_vbox.Show ();
  		}
 -		
 -		zoom_in.Sensitive = (zoom_scale.Value != 1.0);
 -		zoom_out.Sensitive = (zoom_scale.Value != 0.0);
 -	}
  	
 -	void HandleQueryChanged (IBrowsableCollection sender)
 -	{
 -		if (find_untagged.Active != query.Untagged)
 -			find_untagged.Active = query.Untagged;
 -		
 -		clear_date_range.Sensitive = (query.Range != null);
 -		clear_rating_filter.Sensitive = (query.RatingRange != null);
 -		update_status_label = true;
 -		GLib.Idle.Add (UpdateStatusLabel);
 -	}
 -
 -	bool update_status_label;
 -	private bool UpdateStatusLabel ()
 -	{
 -		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);
 -		else
 -			status_label.Text = String.Format (Catalog.GetPluralString ("{0} Photo", "{0} Photos", query.Count), query.Count);
 -	
 -		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;
 -		return update_status_label;
 -	}
 +		void HandleViewSlideShow (object sender, EventArgs args)
 +		{
 +			HandleViewFullscreen (sender, args);
 +			fsview.PlayPause ();
 +		}
  	
 -	void HandleZoomChanged (object sender, System.EventArgs args)
 -	{
 -		zoom_scale.ValueChanged -= HandleZoomScaleValueChanged;
 -
 -		double zoom = .5;
 -		switch (view_mode) {
 -		case ModeType.PhotoView:
 -			zoom = photo_view.NormalizedZoom;
 -			zoom_scale.Value = zoom;
 -			break;
 -		case ModeType.IconView:
 -			zoom = icon_view.Zoom;
 -			if (zoom == 0.0 || zoom == 100.0 || zoom != zoom_scale.Value)
 -				zoom_scale.Value = zoom;
 -
 -			break;
 +		void HandleToggleViewBrowse (object sender, EventArgs args)
 +		{
 +			if (ViewMode == ModeType.IconView)
 +				browse_button.Active = true;
 +			else if (browse_button.Active)
 +				SetViewMode (ModeType.IconView);
  		}
 -		
 -		zoom_in.Sensitive = (zoom != 1.0);
 -		zoom_out.Sensitive = (zoom != 0.0);
 -		
 -		zoom_scale.ValueChanged += HandleZoomScaleValueChanged;
 -	}
 -
 -	void HandleZoomOut (object sender, ButtonPressEventArgs args)
 -	{
 -		ZoomOut ();
 -	}
  	
 -	void HandleZoomOut (object sender, EventArgs args)
 -	{
 -		ZoomOut ();
 -	}
 +		void HandleToggleViewPhoto (object sender, EventArgs args)
 +		{
 +			if (ViewMode == ModeType.PhotoView)
 +				edit_button.Active = true;
 +			else if (edit_button.Active)
 +				SetViewMode (ModeType.PhotoView);
 +		}
  	
 -	void HandleZoomIn (object sender, ButtonPressEventArgs args)
 -	{
 -		ZoomIn ();
 -	}
 +		void HandleViewBrowse (object sender, EventArgs args)
 +		{
 +			SetViewMode (ModeType.IconView);
 +		}
  	
 -	void HandleZoomIn (object sender, EventArgs args)
 -	{
 -		ZoomIn ();
 -	}
 +		void HandleViewPhoto (object sender, EventArgs args)
 +		{
 +			SetViewMode (ModeType.PhotoView);
 +		}
  	
 -	private void ZoomOut ()
 -	{
 -		switch (view_mode) {
 -		case ModeType.PhotoView:
 -			photo_view.ZoomOut ();
 -			break;
 -		case ModeType.IconView:
 -			icon_view.ZoomOut ();
 -			break;
 +		void HandleViewFullscreen (object sender, EventArgs args)
 +		{
 +			int active = (Selection.Count > 0 ? SelectedIds() [0] : 0);
 +			if (fsview == null) {
 +				fsview = new FSpot.FullScreenView (query, main_window);
 +				fsview.Destroyed += HandleFullScreenViewDestroy;
 +				fsview.KeyPressEvent += HandleFullScreenViewKeyPressEvent;
 +				fsview.View.Item.Index = active;
 +			} else {
 +				// FIXME this needs to be another mode like PhotoView and IconView mode.
 +				fsview.View.Item.Index = active;
 +			}
 +			
 +			fsview.Show ();
  		}
 -	}
  	
 -	private void ZoomIn ()
 -	{
 -		switch (view_mode) {
 -		case ModeType.PhotoView:
 -			double old_zoom = photo_view.Zoom;
 -			try {
 -				photo_view.ZoomIn ();
 -			} catch {
 -				photo_view.Zoom = old_zoom;
 +		void HandleFullScreenViewDestroy (object sender, EventArgs args)
 +		{
 +			JumpTo (fsview.View.Item.Index);
 +			fsview = null;
 +		}
 +		
 +		void HandleZoomScaleValueChanged (object sender, System.EventArgs args)
 +		{
 +			switch (ViewMode) {
 +			case ModeType.PhotoView:
 +				photo_view.View.ZoomChanged -= HandleZoomChanged;
 +				photo_view.NormalizedZoom = zoom_scale.Value;
 +				photo_view.View.ZoomChanged += HandleZoomChanged;
 +				break;
 +			case ModeType.IconView:
 +				icon_view.ZoomChanged -= HandleZoomChanged;
 +				icon_view.Zoom = zoom_scale.Value;
 +				icon_view.ZoomChanged += HandleZoomChanged;
 +				break;
  			}
  			
 -			break;
 -		case ModeType.IconView:
 -			icon_view.ZoomIn ();
 -			break;
 +			zoom_in.Sensitive = (zoom_scale.Value != 1.0);
 +			zoom_out.Sensitive = (zoom_scale.Value != 0.0);
  		}
 -	}
 -
 -	public void DeleteException (Exception e, string fname)
 -	{
 -		string ok_caption = Catalog.GetString ("_Ok");
 -		string error = Catalog.GetString ("Error Deleting Picture");
 -		string msg;
 -
 -		if (e is UnauthorizedAccessException)
 -			msg = String.Format (
 -				Catalog.GetString ("No permission to delete the file:{1}{0}"), 
 -				fname, Environment.NewLine).Replace ("_", "__");
 -		else
 -			msg = String.Format (
 -				Catalog.GetString ("An error of type {0} occurred while deleting the file:{2}{1}"),
 -				e.GetType (), fname.Replace ("_", "__"), Environment.NewLine);
  		
 -		HigMessageDialog.RunHigConfirmation (
 -			main_window, DialogFlags.DestroyWithParent, MessageType.Error,
 -			error, msg, ok_caption);
 -	}
 -
 -	public Gtk.Window GetToplevel (object sender)
 -	{
 -		Widget wsender = sender as Widget;
 -		Gtk.Window toplevel = null;
 -
 -		if (wsender != null && !(wsender is MenuItem))
 -			toplevel = (Gtk.Window) wsender.Toplevel;
 -		else if (fsview != null)
 -			toplevel = fsview;
 -		else 
 -			toplevel = main_window;
 -
 -		return toplevel;
 -	}
 -
 -	public void HandleDeleteCommand (object sender, EventArgs args)
 -	{
 -		// Don't steal characters from any text entries
 -		if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 -			Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 -			return;
 +		void HandleQueryChanged (IBrowsableCollection sender)
 +		{
 +			if (find_untagged.Active != query.Untagged)
 +				find_untagged.Active = query.Untagged;
 +			
 +			clear_date_range.Sensitive = (query.Range != null);
 +			clear_rating_filter.Sensitive = (query.RatingRange != null);
 +			update_status_label = true;
 +			GLib.Idle.Add (UpdateStatusLabel);
  		}
 +	
 +		bool update_status_label;
 +		private bool UpdateStatusLabel ()
 +		{
 +			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);
 +			else
 +				status_label.Text = String.Format (Catalog.GetPluralString ("{0} Photo", "{0} Photos", query.Count), query.Count);
  		
 -   		Photo[] photos = SelectedPhotos();
 -   		string header = Catalog.GetPluralString ("Delete the selected photo permanently?", 
 -								    "Delete the {0} selected photos permanently?", 
 -								    photos.Length);
 -		header = String.Format (header, photos.Length);
 -		string msg = Catalog.GetPluralString ("This deletes all versions of the selected photo from your drive.", 
 -								 "This deletes all versions of the selected photos from your drive.", 
 -								 photos.Length);
 -		string ok_caption = Catalog.GetPluralString ("_Delete photo", "_Delete photos", photos.Length);
 +			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;
 +			return update_status_label;
 +		}
  		
 -		if (ResponseType.Ok == HigMessageDialog.RunHigConfirmation(GetToplevel (sender), 
 -									   DialogFlags.DestroyWithParent, 
 -									   MessageType.Warning, 
 -									   header, msg, ok_caption)) {                              
 -			
 -			uint timer = Log.DebugTimerStart ();
 -			foreach (Photo photo in photos) {
 -				foreach (uint id in photo.VersionIds) {
 -					try {
 -						photo.DeleteVersion (id, true);
 -					} catch (Exception e) {
 -						DeleteException (e, photo.VersionUri (id).ToString ());
 -					}
 -				}
 +		void HandleZoomChanged (object sender, System.EventArgs args)
 +		{
 +			zoom_scale.ValueChanged -= HandleZoomScaleValueChanged;
 +	
 +			double zoom = .5;
 +			switch (ViewMode) {
 +			case ModeType.PhotoView:
 +				zoom = photo_view.NormalizedZoom;
 +				zoom_scale.Value = zoom;
 +				break;
 +			case ModeType.IconView:
 +				zoom = icon_view.Zoom;
 +				if (zoom == 0.0 || zoom == 100.0 || zoom != zoom_scale.Value)
 +					zoom_scale.Value = zoom;
 +	
 +				break;
  			}
 -			db.Photos.Remove (photos);
  			
 -			UpdateQuery ();
 -			Log.DebugTimerPrint (timer, "HandleDeleteCommand took {0}");
 +			zoom_in.Sensitive = (zoom != 1.0);
 +			zoom_out.Sensitive = (zoom != 0.0);
 +			
 +			zoom_scale.ValueChanged += HandleZoomScaleValueChanged;
  		}
 -	}
 -
 -	public void HandleRemoveCommand (object sender, EventArgs args)
 -	{
 -		// Don't steal characters from any text entries
 -		if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 -			Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 -			return;
 +	
 +		void HandleZoomOut (object sender, ButtonPressEventArgs args)
 +		{
 +			ZoomOut ();
  		}
 -
 -   		Photo[] photos = SelectedPhotos();
 -		if (photos.Length == 0) 
 -			return;
 -
 -   		string header = Catalog.GetPluralString ("Remove the selected photo from F-Spot?",
 -								    "Remove the {0} selected photos from F-Spot?", 
 -								    photos.Length);
 -
 -		header = String.Format (header, photos.Length);
 -		string msg = Catalog.GetString("If you remove photos from the F-Spot catalog all tag information will be lost. The photos remain on your computer and can be imported into F-Spot again.");
 -		string ok_caption = Catalog.GetString("_Remove from Catalog");
 -		if (ResponseType.Ok == HigMessageDialog.RunHigConfirmation(GetToplevel (sender), DialogFlags.DestroyWithParent, 
 -									   MessageType.Warning, header, msg, ok_caption)) {                              
 -			db.Photos.Remove (photos);
 -			UpdateQuery ();
 +		
 +		void HandleZoomOut (object sender, EventArgs args)
 +		{
 +			ZoomOut ();
  		}
 -	}
 -
 -	void HandleSelectAllCommand (object sender, EventArgs args)
 -	{
 -		icon_view.SelectAllCells ();
 -		UpdateStatusLabel();
 -	}
 -
 -	void HandleSelectNoneCommand (object sender, EventArgs args)
 -	{
 -		icon_view.Selection.Clear ();
 -		UpdateStatusLabel();
 -	}
 -
 -	// This ConnectBefore is needed because otherwise the editability of the name
 -	// column will steal returns, spaces, and clicks if the tag name is focused
 -	[GLib.ConnectBefore]
 -	public void HandleTagSelectionKeyPress (object sender, Gtk.KeyPressEventArgs args)
 -	{
 -		args.RetVal = true;
 -
 -		switch (args.Event.Key) {
 -		case Gdk.Key.Delete:
 - 			HandleDeleteSelectedTagCommand (sender, (EventArgs) args);
 -			break;
  		
 -		case Gdk.Key.space:
 -		case Gdk.Key.Return:
 -		case Gdk.Key.KP_Enter:
 -			ShowQueryWidget ();
 -			query_widget.Include (tag_selection_widget.TagHighlight);
 -			break;
 -
 -		case Gdk.Key.F2:
 -			tag_selection_widget.EditSelectedTagName ();
 -			break;
 +		void HandleZoomIn (object sender, ButtonPressEventArgs args)
 +		{
 +			ZoomIn ();
 +		}
  		
 -		default:
 -			args.RetVal = false;
 -			break;
 +		void HandleZoomIn (object sender, EventArgs args)
 +		{
 +			ZoomIn ();
  		}
 -	}
 -
 -	public void HandleDeleteSelectedTagCommand (object sender, EventArgs args)
 -	{
 -		Tag [] tags = this.tag_selection_widget.TagHighlight;
 -
 -		System.Array.Sort (tags, new TagRemoveComparer ());
 -	
 -		//How many pictures are associated to these tags?
 -		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.Count;
 -
 -		string header;
 -		if (tags.Length == 1)
 -			header = String.Format (Catalog.GetString ("Delete tag \"{0}\"?"), tags [0].Name.Replace ("_", "__"));
 -		else
 -			header = String.Format (Catalog.GetString ("Delete the {0} selected tags?"), tags.Length);
  		
 -		header = String.Format (header, tags.Length);
 -		string msg = String.Empty;
 -		if (associated_photos > 0) {
 -			string photodesc = Catalog.GetPluralString ("photo", "photos", associated_photos);
 -			msg = String.Format( 
 -				Catalog.GetPluralString("If you delete this tag, the association with {0} {1} will be lost.",
 -							"If you delete these tags, the association with {0} {1} will be lost.",
 -							tags.Length),
 -				associated_photos, photodesc);
 -		}
 -		string ok_caption = Catalog.GetPluralString ("_Delete tag", "_Delete tags", tags.Length);
 +		private void ZoomOut ()
 +		{
 +			switch (ViewMode) {
 +			case ModeType.PhotoView:
 +				photo_view.ZoomOut ();
 +				break;
 +			case ModeType.IconView:
 +				icon_view.ZoomOut ();
 +				break;
 +			}
 +		}
  		
 -		if (ResponseType.Ok == HigMessageDialog.RunHigConfirmation(main_window, 
 -									   DialogFlags.DestroyWithParent, 
 -									   MessageType.Warning, 
 -									   header, 
 -									   msg, 
 -									   ok_caption)) {                              
 -			try { 				
 -				db.Photos.Remove (tags);
 -			} catch (InvalidTagOperationException e) {
 -				System.Console.WriteLine ("this is something or another");
 -
 -				// A Category is not empty. Can not delete it.
 -				string error_msg = Catalog.GetString ("Tag is not empty");
 -				string error_desc = String.Format (Catalog.GetString ("Can not delete tags that have tags within them.  " + 
 -												 "Please delete tags under \"{0}\" first"),
 -								   e.Tag.Name.Replace ("_", "__"));
 +		private void ZoomIn ()
 +		{
 +			switch (ViewMode) {
 +			case ModeType.PhotoView:
 +				double old_zoom = photo_view.Zoom;
 +				try {
 +					photo_view.ZoomIn ();
 +				} catch {
 +					photo_view.Zoom = old_zoom;
 +				}
  				
 -				HigMessageDialog md = new HigMessageDialog (main_window, DialogFlags.DestroyWithParent, 
 -									    Gtk.MessageType.Error, ButtonsType.Ok, 
 -									    error_msg,
 -									    error_desc);
 -				md.Run ();
 -				md.Destroy ();
 +				break;
 +			case ModeType.IconView:
 +				icon_view.ZoomIn ();
 +				break;
  			}
  		}
 -	}
 -
 -	void HandleUpdateThumbnailCommand (object sender, EventArgs args)
 -	{
 -		ThumbnailCommand command = new ThumbnailCommand (main_window);
 -
 -		int [] selected_ids = SelectedIds ();
 -		if (command.Execute (SelectedPhotos (selected_ids)))
 -			query.MarkChanged (selected_ids, new PhotoChanges {DataChanged = true});
 -	}
 -
 -	public void HandleRotate90Command (object sender, EventArgs args)
 -	{
 -		// Don't steal characters from any text entries
 -		if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 -			Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 -			return;
 +	
 +		public void DeleteException (Exception e, string fname)
 +		{
 +			string ok_caption = Catalog.GetString ("_Ok");
 +			string error = Catalog.GetString ("Error Deleting Picture");
 +			string msg;
 +	
 +			if (e is UnauthorizedAccessException)
 +				msg = String.Format (
 +					Catalog.GetString ("No permission to delete the file:{1}{0}"), 
 +					fname, Environment.NewLine).Replace ("_", "__");
 +			else
 +				msg = String.Format (
 +					Catalog.GetString ("An error of type {0} occurred while deleting the file:{2}{1}"),
 +					e.GetType (), fname.Replace ("_", "__"), Environment.NewLine);
 +			
 +			HigMessageDialog.RunHigConfirmation (
 +				main_window, DialogFlags.DestroyWithParent, MessageType.Error,
 +				error, msg, ok_caption);
  		}
 -		
 -		RotateSelectedPictures (GetToplevel (sender), RotateDirection.Clockwise);
 -	}
 -
 -	public void HandleRotate270Command (object sender, EventArgs args)
 -	{
 -		// Don't steal characters from any text entries
 -		if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 -			Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 -			return;
 +	
 +		public Gtk.Window GetToplevel (object sender)
 +		{
 +			Widget wsender = sender as Widget;
 +			Gtk.Window toplevel = null;
 +	
 +			if (wsender != null && !(wsender is MenuItem))
 +				toplevel = (Gtk.Window) wsender.Toplevel;
 +			else if (fsview != null)
 +				toplevel = fsview;
 +			else 
 +				toplevel = main_window;
 +	
 +			return toplevel;
  		}
 -
 -		RotateSelectedPictures (GetToplevel (sender), RotateDirection.Counterclockwise);
 -	}
 -
 -	public void HandleCopyLocation (object sender, EventArgs args)
 -	{
 -		/*
 -		 * FIXME this should really set uri atoms as well as string atoms
 -		 */
 -		Clipboard primary = Clipboard.Get (Atom.Intern ("PRIMARY", false));
 -		Clipboard clipboard = Clipboard.Get (Atom.Intern ("CLIPBOARD", false));
 -
 -		StringBuilder paths = new StringBuilder ();
 -		
 -		int i = 0;
 -		foreach (Photo p in SelectedPhotos ()) {
 -			if (i++ > 0)
 -				paths.Append (" ");
 -
 -			paths.Append (System.IO.Path.GetFullPath (p.DefaultVersionUri.LocalPath));
 +	
 +		public void HandleDeleteCommand (object sender, EventArgs args)
 +		{
 +			// Don't steal characters from any text entries
 +			if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 +				Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 +				return;
 +			}
 +			
 +	   		Photo[] photos = SelectedPhotos();
 +	   		string header = Catalog.GetPluralString ("Delete the selected photo permanently?", 
 +									    "Delete the {0} selected photos permanently?", 
 +									    photos.Length);
 +			header = String.Format (header, photos.Length);
 +			string msg = Catalog.GetPluralString ("This deletes all versions of the selected photo from your drive.", 
 +									 "This deletes all versions of the selected photos from your drive.", 
 +									 photos.Length);
 +			string ok_caption = Catalog.GetPluralString ("_Delete photo", "_Delete photos", photos.Length);
 +			
 +			if (ResponseType.Ok == HigMessageDialog.RunHigConfirmation(GetToplevel (sender), 
 +										   DialogFlags.DestroyWithParent, 
 +										   MessageType.Warning, 
 +										   header, msg, ok_caption)) {                              
 +				
 +				uint timer = Log.DebugTimerStart ();
 +				foreach (Photo photo in photos) {
 +					foreach (uint id in photo.VersionIds) {
 +						try {
 +							photo.DeleteVersion (id, true);
 +						} catch (Exception e) {
 +							DeleteException (e, photo.VersionUri (id).ToString ());
 +						}
 +					}
 +				}
 +				Database.Photos.Remove (photos);
 +				
 +				UpdateQuery ();
 +				Log.DebugTimerPrint (timer, "HandleDeleteCommand took {0}");
 +			}
  		}
 -		
 -		String data = paths.ToString ();
 -		primary.Text = data;
 -		clipboard.Text = data;
 -	}
 -
 -	void HandleSetAsBackgroundCommand (object sender, EventArgs args)
 -	{
 -		Photo current = CurrentPhoto;
 -
 -		if (current == null)
 -			return;
 -
 -		Desktop.SetBackgroundImage (current.DefaultVersionUri.LocalPath);
 -	}
 -
 -	void HandleSetDateRange (object sender, EventArgs args) {
 -		var date_range_dialog = new DateRangeDialog (query.Range, main_window);
 -		if ((ResponseType)date_range_dialog.Run () == ResponseType.Ok)
 -			query.Range = date_range_dialog.Range;
 -		date_range_dialog.Destroy ();
 -
 -		//update the TimeLine
 -		if (group_selector.Adaptor is TimeAdaptor && query.Range != null) 
 -			group_selector.SetLimitsToDates(query.Range.Start, query.Range.End);
 -	}
 -
 -	public void HandleClearDateRange (object sender, EventArgs args) {
 -		if (group_selector.Adaptor is FSpot.TimeAdaptor) {
 -			group_selector.ResetLimits();
 +	
 +		public void HandleRemoveCommand (object sender, EventArgs args)
 +		{
 +			// Don't steal characters from any text entries
 +			if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 +				Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 +				return;
 +			}
 +	
 +	   		Photo[] photos = SelectedPhotos();
 +			if (photos.Length == 0) 
 +				return;
 +	
 +	   		string header = Catalog.GetPluralString ("Remove the selected photo from F-Spot?",
 +									    "Remove the {0} selected photos from F-Spot?", 
 +									    photos.Length);
 +	
 +			header = String.Format (header, photos.Length);
 +			string msg = Catalog.GetString("If you remove photos from the F-Spot catalog all tag information will be lost. The photos remain on your computer and can be imported into F-Spot again.");
 +			string ok_caption = Catalog.GetString("_Remove from Catalog");
 +			if (ResponseType.Ok == HigMessageDialog.RunHigConfirmation(GetToplevel (sender), DialogFlags.DestroyWithParent, 
 +										   MessageType.Warning, header, msg, ok_caption)) {                              
 +				Database.Photos.Remove (photos);
 +				UpdateQuery ();
 +			}
  		}
 -		query.Range = null;
 -	}
 -
 -	void HandleSelectLastRoll (object sender, EventArgs args) {
 -		query.RollSet = new RollSet (db.Rolls.GetRolls (1));
 -	}
 -
 -	void HandleSelectRolls (object sender, EventArgs args) {
 -		new LastRolls (query, db.Rolls, main_window);
 -	}
 -
 -	void HandleClearRollFilter (object sender, EventArgs args) {
 -		query.RollSet = null;
 -	}
 -
 -	void HandleSetRatingFilter (object sender, EventArgs args) {
 -		new RatingFilterDialog (query, main_window);
 -	}
 -
 -	public void HandleClearRatingFilter (object sender, EventArgs args) {
 -		query.RatingRange = null;
 -	}
 -
 -	void HandleFindUntagged (object sender, EventArgs args) {
 -		if (query.Untagged == find_untagged.Active)
 -			return;
 -
 -		query.Untagged = !query.Untagged;
 -	}
  	
 -	void OnPreferencesChanged (object sender, NotifyEventArgs args)
 -	{
 -		LoadPreference (args.Key);
 -	}
 -
 -	void LoadPreference (String key)
 -	{
 -		switch (key) {
 -		case Preferences.MAIN_WINDOW_MAXIMIZED:
 -			if (Preferences.Get<bool> (key))
 -				main_window.Maximize ();
 -			else
 -				main_window.Unmaximize ();
 -			break;
 -
 -		case Preferences.MAIN_WINDOW_X:
 -		case Preferences.MAIN_WINDOW_Y:
 -			main_window.Move(Preferences.Get<int> (Preferences.MAIN_WINDOW_X),
 -					 Preferences.Get<int> (Preferences.MAIN_WINDOW_Y));
 -			break;
 -		
 -		case Preferences.MAIN_WINDOW_WIDTH:
 -		case Preferences.MAIN_WINDOW_HEIGHT:
 -			if (Preferences.Get<int> (Preferences.MAIN_WINDOW_WIDTH) > 0 &&
 -						  Preferences.Get<int> (Preferences.MAIN_WINDOW_HEIGHT) > 0)
 -				main_window.Resize(Preferences.Get<int> (Preferences.MAIN_WINDOW_WIDTH),
 -						   Preferences.Get<int> (Preferences.MAIN_WINDOW_HEIGHT));
 -
 -			break;
 -		
 -		case Preferences.SHOW_TOOLBAR:
 -			if (display_toolbar.Active != Preferences.Get<bool> (key))
 -				display_toolbar.Active = Preferences.Get<bool> (key);
 -			break;
 -		
 -		case Preferences.SHOW_SIDEBAR:
 -			if (display_sidebar.Active != Preferences.Get<bool> (key))
 -				display_sidebar.Active = Preferences.Get<bool> (key);
 -			break;
 -		
 -		case Preferences.SHOW_TIMELINE:
 -			if (display_timeline.Active != Preferences.Get<bool> (key))
 -				display_timeline.Active = Preferences.Get<bool> (key);
 -			break;
 -		
 -		case Preferences.SHOW_FILMSTRIP:
 -			if (display_filmstrip.Active != Preferences.Get<bool> (key)) {
 -				display_filmstrip.Active = Preferences.Get<bool> (key);
 +		void HandleSelectAllCommand (object sender, EventArgs args)
 +		{
 +			icon_view.SelectAllCells ();
 +			UpdateStatusLabel();
 +		}
 +	
 +		void HandleSelectNoneCommand (object sender, EventArgs args)
 +		{
 +			icon_view.Selection.Clear ();
 +			UpdateStatusLabel();
 +		}
 +	
 +		// This ConnectBefore is needed because otherwise the editability of the name
 +		// column will steal returns, spaces, and clicks if the tag name is focused
 +		[GLib.ConnectBefore]
 +		public void HandleTagSelectionKeyPress (object sender, Gtk.KeyPressEventArgs args)
 +		{
 +			args.RetVal = true;
 +	
 +			switch (args.Event.Key) {
 +			case Gdk.Key.Delete:
 +	 			HandleDeleteSelectedTagCommand (sender, (EventArgs) args);
 +				break;
 +			
 +			case Gdk.Key.space:
 +			case Gdk.Key.Return:
 +			case Gdk.Key.KP_Enter:
 +				ShowQueryWidget ();
 +				query_widget.Include (tag_selection_widget.TagHighlight);
 +				break;
 +	
 +			case Gdk.Key.F2:
 +				tag_selection_widget.EditSelectedTagName ();
 +				break;
 +			
 +			default:
 +				args.RetVal = false;
 +				break;
  			}
 -			break;
 -		
 -		case Preferences.SHOW_TAGS:
 -			if (display_tags_menu_item.Active != Preferences.Get<bool> (key))
 -				display_tags_menu_item.Active = Preferences.Get<bool> (key);
 -			break;
 -		
 -		case Preferences.SHOW_DATES:
 -			if (display_dates_menu_item.Active != Preferences.Get<bool> (key))
 -				display_dates_menu_item.Active = Preferences.Get<bool> (key);
 -				//display_dates_menu_item.Toggle ();
 -			break;
 +		}
 +	
 +		public void HandleDeleteSelectedTagCommand (object sender, EventArgs args)
 +		{
 +			Tag [] tags = this.tag_selection_widget.TagHighlight;
 +	
 +			System.Array.Sort (tags, new TagRemoveComparer ());
  		
 -		case Preferences.SHOW_RATINGS:
 -			if (display_ratings_menu_item.Active != Preferences.Get<bool> (key))
 -				display_ratings_menu_item.Active = Preferences.Get<bool> (key);
 -			break;
 -
 -		case Preferences.GROUP_ADAPTOR_ORDER_ASC:
 -			group_selector.Adaptor.OrderAscending = Preferences.Get<bool> (key);
 -			reverse_order.Active = Preferences.Get<bool> (key);
 -			query.TimeOrderAsc = group_selector.Adaptor.OrderAscending;
 -			break;
 -
 -		case Preferences.GLASS_POSITION:
 -			if (query.Count > 0) {
 -				// If the database has changed since this pref was saved, this could cause
 -				// an exception to be thrown.
 -				try {
 -					IBrowsableItem photo = group_selector.Adaptor.PhotoFromIndex (Preferences.Get<int> (key));
 +			//How many pictures are associated to these tags?
 +			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.Count;
 +	
 +			string header;
 +			if (tags.Length == 1)
 +				header = String.Format (Catalog.GetString ("Delete tag \"{0}\"?"), tags [0].Name.Replace ("_", "__"));
 +			else
 +				header = String.Format (Catalog.GetString ("Delete the {0} selected tags?"), tags.Length);
 +			
 +			header = String.Format (header, tags.Length);
 +			string msg = String.Empty;
 +			if (associated_photos > 0) {
 +				string photodesc = Catalog.GetPluralString ("photo", "photos", associated_photos);
 +				msg = String.Format( 
 +					Catalog.GetPluralString("If you delete this tag, the association with {0} {1} will be lost.",
 +								"If you delete these tags, the association with {0} {1} will be lost.",
 +								tags.Length),
 +					associated_photos, photodesc);
 +			}
 +			string ok_caption = Catalog.GetPluralString ("_Delete tag", "_Delete tags", tags.Length);
 +			
 +			if (ResponseType.Ok == HigMessageDialog.RunHigConfirmation(main_window, 
 +										   DialogFlags.DestroyWithParent, 
 +										   MessageType.Warning, 
 +										   header, 
 +										   msg, 
 +										   ok_caption)) {                              
 +				try { 				
 +					db.Photos.Remove (tags);
 +				} catch (InvalidTagOperationException e) {
 +					System.Console.WriteLine ("this is something or another");
 +	
 +					// A Category is not empty. Can not delete it.
 +					string error_msg = Catalog.GetString ("Tag is not empty");
 +					string error_desc = String.Format (Catalog.GetString ("Can not delete tags that have tags within them.  " + 
 +													 "Please delete tags under \"{0}\" first"),
 +									   e.Tag.Name.Replace ("_", "__"));
  					
 -					if (photo != null)
 -						JumpTo (query.IndexOf (photo));
 -				} catch (Exception) {}
 +					HigMessageDialog md = new HigMessageDialog (main_window, DialogFlags.DestroyWithParent, 
 +										    Gtk.MessageType.Error, ButtonsType.Ok, 
 +										    error_msg,
 +										    error_desc);
 +					md.Run ();
 +					md.Destroy ();
 +				}
  			}
 -
 -			icon_view.GrabFocus ();
 -			break;
 -		case Preferences.SIDEBAR_POSITION:
 -			if (main_hpaned.Position !=Preferences.Get<int> (key) )
 -				main_hpaned.Position = Preferences.Get<int> (key);
 -			break;
 -
 -		case Preferences.TAG_ICON_SIZE:
 -			int s = Preferences.Get<int> (key);
 -			tag_icon_hidden.Active = (s == (int) Tag.IconSize.Hidden);
 -			tag_icon_small.Active = (s == (int) Tag.IconSize.Small);
 -			tag_icon_medium.Active = (s == (int) Tag.IconSize.Medium);
 -			tag_icon_large.Active = (s == (int) Tag.IconSize.Large);
 -
 -			break;
 -
 -		case Preferences.ZOOM:
 -			icon_view.Zoom = Preferences.Get<double> (key);
 -			break;
 -		
 -		case Preferences.METADATA_EMBED_IN_IMAGE:
 -			write_metadata =Preferences.Get<bool> (key) ;
 -			break;
 -		case Preferences.GNOME_MAILTO_ENABLED:
 -			send_mail.Visible = Preferences.Get<bool> (key);
 -			break;
  		}
 -	}
 -
 -	// Version Id updates.
 -
 -	void UpdateForVersionIdChange (uint version_id)
 -	{
 -		CurrentPhoto.DefaultVersionId = version_id;
 -		query.Commit (ActiveIndex ());
 -	}
 -
 -	// Queries.
 -
 -	public void UpdateQuery ()
 -	{
 -		main_window.GdkWindow.Cursor = watch;
 -		main_window.GdkWindow.Display.Sync ();
 -		query.RequestReload ();
 -		main_window.GdkWindow.Cursor = null;
 -	}
 -
 -	void HandleTagSelectionChanged (object obj, EventArgs args)
 -	{
 -		UpdateMenus ();
 -	}
 -
 -	public bool TagIncluded (Tag tag)
 -	{
 -		return query_widget.TagIncluded (tag);
 -	}
  	
 -	public bool TagRequired (Tag tag)
 -	{
 -		return query_widget.TagRequired (tag);
 -	}
 -
 -	private void HandleQueryLogicChanged (object sender, EventArgs args)
 -	{
 -		HandleFindAddTagWith (null, null);
 -	}
 +		void HandleUpdateThumbnailCommand (object sender, EventArgs args)
 +		{
 +			ThumbnailCommand command = new ThumbnailCommand (main_window);
  	
 -	public void HandleIncludeTag (object sender, EventArgs args)
 -	{
 -		ShowQueryWidget ();
 -		query_widget.Include (tag_selection_widget.TagHighlight);
 -	}
 +			int [] selected_ids = SelectedIds ();
 +			if (command.Execute (SelectedPhotos (selected_ids)))
 +				query.MarkChanged (selected_ids, new PhotoChanges {DataChanged = true});
 +		}
  	
 -	public void HandleUnIncludeTag (object sender, EventArgs args)
 -	{
 -		query_widget.UnInclude (tag_selection_widget.TagHighlight);
 - 	}
 +		public void HandleRotate90Command (object sender, EventArgs args)
 +		{
 +			// Don't steal characters from any text entries
 +			if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 +				Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 +				return;
 +			}
 +			
 +			RotateSelectedPictures (GetToplevel (sender), RotateDirection.Clockwise);
 +		}
  	
 -	void HandleFindByTag (object sender, EventArgs args)
 -	{
 -		UpdateFindByTagMenu ();
 -	}
 +		public void HandleRotate270Command (object sender, EventArgs args)
 +		{
 +			// Don't steal characters from any text entries
 +			if (Window.Focus is Gtk.Entry && Gtk.Global.CurrentEvent is Gdk.EventKey) {
 +				Window.Focus.ProcessEvent (Gtk.Global.CurrentEvent);
 +				return;
 +			}
  	
 -	public void UpdateFindByTagMenu ()
 -	{
 -		if (query_widget.Visible) {
 -			query_widget.Close ();
 -		} else {
 -			ShowQueryWidget ();
 +			RotateSelectedPictures (GetToplevel (sender), RotateDirection.Counterclockwise);
  		}
 -	}
  	
 -	void HandleFindAddTagWith (object sender, EventArgs args)
 -	{
 -		MenuItem find_add_tag_with = uimanager.GetWidget ("/ui/menubar1/find/find_add_tag_with") as MenuItem;
 -		if (find_add_tag_with.Submenu != null)
 -			find_add_tag_with.Submenu.Dispose ();
 -		
 -		Gtk.Menu submenu = FSpot.TermMenuItem.GetSubmenu (tag_selection_widget.TagHighlight);
 -		find_add_tag_with.Sensitive = (submenu != null);
 -		if (submenu != null) 
 -			find_add_tag_with.Submenu = submenu;	
 -	}
 +		public void HandleCopyLocation (object sender, EventArgs args)
 +		{
 +			/*
 +			 * FIXME this should really set uri atoms as well as string atoms
 +			 */
 +			Clipboard primary = Clipboard.Get (Atom.Intern ("PRIMARY", false));
 +			Clipboard clipboard = Clipboard.Get (Atom.Intern ("CLIPBOARD", false));
  	
 -	public void HandleAddTagToTerm (object sender, EventArgs args)
 -	{
 -		MenuItem item = sender as MenuItem;
 -		
 -		int item_pos = 0;
 -		foreach (MenuItem i in (item.Parent as Menu).Children) {
 -			if (item == i) {
 -				break;
 +			StringBuilder paths = new StringBuilder ();
 +			
 +			int i = 0;
 +			foreach (Photo p in SelectedPhotos ()) {
 +				if (i++ > 0)
 +					paths.Append (" ");
 +	
 +				paths.Append (System.IO.Path.GetFullPath (p.DefaultVersionUri.LocalPath));
  			}
  			
 -			item_pos++;
 +			String data = paths.ToString ();
 +			primary.Text = data;
 +			clipboard.Text = data;
  		}
 -		// account for All and separator menu items
 -		item_pos -= 2;
 -		
 -		FSpot.Term parent_term = (FSpot.Term) FSpot.LogicWidget.Root.SubTerms [item_pos];
 -		
 -		if (FSpot.LogicWidget.Box != null) {
 -			FSpot.Literal after = parent_term.Last as FSpot.Literal;
 -			FSpot.LogicWidget.Box.InsertTerm (tag_selection_widget.TagHighlight, parent_term, after);
 +	
 +		void HandleSetAsBackgroundCommand (object sender, EventArgs args)
 +		{
 +			Photo current = CurrentPhoto;
 +	
 +			if (current == null)
 +				return;
 +	
 +			Desktop.SetBackgroundImage (current.DefaultVersionUri.LocalPath);
  		}
 -	}
  	
 -	void HandleFindTagIncluded (Tag t)
 -	{
 -		ShowQueryWidget ();
 -		query_widget.Include (new Tag [] {t});
 - 	}
 +		void HandleSetDateRange (object sender, EventArgs args) {
 +			var date_range_dialog = new DateRangeDialog (query.Range, main_window);
 +			if ((ResponseType)date_range_dialog.Run () == ResponseType.Ok)
 +				query.Range = date_range_dialog.Range;
 +			date_range_dialog.Destroy ();
  	
 -	void HandleFindTagRequired (Tag t)
 -	{
 -		ShowQueryWidget ();
 -		query_widget.Require (new Tag [] {t});
 -	}
 -
 -	//
 -	// Handle Main Menu 
 -
 -	void UpdateMenus ()
 -	{
 -		int tags_selected = tag_selection_widget.Selection.CountSelectedRows ();
 -		bool tag_sensitive = tags_selected > 0;
 -		bool active_selection = selection.Count > 0;
 -		bool single_active = CurrentPhoto != null;
 -		MenuItem version_menu_item = uimanager.GetWidget ("/ui/menubar1/file1/version_menu_item") as MenuItem;
 +			//update the TimeLine
 +			if (group_selector.Adaptor is TimeAdaptor && query.Range != null) 
 +				group_selector.SetLimitsToDates(query.Range.Start, query.Range.End);
 +		}
 +	
 +		public void HandleClearDateRange (object sender, EventArgs args) {
 +			if (group_selector.Adaptor is FSpot.TimeAdaptor) {
 +				group_selector.ResetLimits();
 +			}
 +			query.Range = null;
 +		}
 +	
 +		void HandleSelectLastRoll (object sender, EventArgs args) {
 +			query.RollSet = new RollSet (Database.Rolls.GetRolls (1));
 +		}
 +	
 +		void HandleSelectRolls (object sender, EventArgs args) {
 +			new LastRolls (query, Database.Rolls, main_window);
 +		}
 +	
 +		void HandleClearRollFilter (object sender, EventArgs args) {
 +			query.RollSet = null;
 +		}
 +	
 +		void HandleSetRatingFilter (object sender, EventArgs args) {
 +			new RatingFilterDialog (query, main_window);
 +		}
 +	
 +		public void HandleClearRatingFilter (object sender, EventArgs args) {
 +			query.RatingRange = null;
 +		}
 +	
 +		void HandleFindUntagged (object sender, EventArgs args) {
 +			if (query.Untagged == find_untagged.Active)
 +				return;
 +	
 +			query.Untagged = !query.Untagged;
 +		}
  		
 -		if (!single_active) {
 -			version_menu_item.Sensitive = false;
 -			version_menu_item.Submenu = new Menu ();
 -
 -			create_version_menu_item.Sensitive = false;
 -			delete_version_menu_item.Sensitive = false;
 -			rename_version_menu_item.Sensitive = false;
 -
 -			sharpen.Sensitive = false;
 -			loupe_menu_item.Sensitive = false;
 -		} else {
 -			version_menu_item.Sensitive = true;
 -			create_version_menu_item.Sensitive = true;
 +		void OnPreferencesChanged (object sender, NotifyEventArgs args)
 +		{
 +			LoadPreference (args.Key);
 +		}
 +	
 +		void LoadPreference (String key)
 +		{
 +			switch (key) {
 +			case Preferences.MAIN_WINDOW_MAXIMIZED:
 +				if (Preferences.Get<bool> (key))
 +					main_window.Maximize ();
 +				else
 +					main_window.Unmaximize ();
 +				break;
 +	
 +			case Preferences.MAIN_WINDOW_X:
 +			case Preferences.MAIN_WINDOW_Y:
 +				main_window.Move(Preferences.Get<int> (Preferences.MAIN_WINDOW_X),
 +						 Preferences.Get<int> (Preferences.MAIN_WINDOW_Y));
 +				break;
  			
 -			if (CurrentPhoto.DefaultVersionId == Photo.OriginalVersionId) {
 -				delete_version_menu_item.Sensitive = false;
 -				rename_version_menu_item.Sensitive = false;
 -			} else {
 -				delete_version_menu_item.Sensitive = true;
 -				rename_version_menu_item.Sensitive = true;
 +			case Preferences.MAIN_WINDOW_WIDTH:
 +			case Preferences.MAIN_WINDOW_HEIGHT:
 +				if (Preferences.Get<int> (Preferences.MAIN_WINDOW_WIDTH) > 0 &&
 +							  Preferences.Get<int> (Preferences.MAIN_WINDOW_HEIGHT) > 0)
 +					main_window.Resize(Preferences.Get<int> (Preferences.MAIN_WINDOW_WIDTH),
 +							   Preferences.Get<int> (Preferences.MAIN_WINDOW_HEIGHT));
 +	
 +				break;
 +			
 +			case Preferences.SHOW_TOOLBAR:
 +				if (display_toolbar.Active != Preferences.Get<bool> (key))
 +					display_toolbar.Active = Preferences.Get<bool> (key);
 +				break;
 +			
 +			case Preferences.SHOW_SIDEBAR:
 +				if (display_sidebar.Active != Preferences.Get<bool> (key))
 +					display_sidebar.Active = Preferences.Get<bool> (key);
 +				break;
 +			
 +			case Preferences.SHOW_TIMELINE:
 +				if (display_timeline.Active != Preferences.Get<bool> (key))
 +					display_timeline.Active = Preferences.Get<bool> (key);
 +				break;
 +			
 +			case Preferences.SHOW_FILMSTRIP:
 +				if (display_filmstrip.Active != Preferences.Get<bool> (key)) {
 +					display_filmstrip.Active = Preferences.Get<bool> (key);
 +				}
 +				break;
 +			
 +			case Preferences.SHOW_TAGS:
 +				if (display_tags_menu_item.Active != Preferences.Get<bool> (key))
 +					display_tags_menu_item.Active = Preferences.Get<bool> (key);
 +				break;
 +			
 +			case Preferences.SHOW_DATES:
 +				if (display_dates_menu_item.Active != Preferences.Get<bool> (key))
 +					display_dates_menu_item.Active = Preferences.Get<bool> (key);
 +					//display_dates_menu_item.Toggle ();
 +				break;
 +			
 +			case Preferences.SHOW_RATINGS:
 +				if (display_ratings_menu_item.Active != Preferences.Get<bool> (key))
 +					display_ratings_menu_item.Active = Preferences.Get<bool> (key);
 +				break;
 +	
 +			case Preferences.GROUP_ADAPTOR_ORDER_ASC:
 +				group_selector.Adaptor.OrderAscending = Preferences.Get<bool> (key);
 +				reverse_order.Active = Preferences.Get<bool> (key);
 +				query.TimeOrderAsc = group_selector.Adaptor.OrderAscending;
 +				break;
 +	
 +			case Preferences.GLASS_POSITION:
 +				if (query.Count > 0) {
 +					// If the database has changed since this pref was saved, this could cause
 +					// an exception to be thrown.
 +					try {
 +						IBrowsableItem photo = group_selector.Adaptor.PhotoFromIndex (Preferences.Get<int> (key));
 +						
 +						if (photo != null)
 +							JumpTo (query.IndexOf (photo));
 +					} catch (Exception) {}
 +				}
 +	
 +				icon_view.GrabFocus ();
 +				break;
 +			case Preferences.SIDEBAR_POSITION:
 +				if (main_hpaned.Position !=Preferences.Get<int> (key) )
 +					main_hpaned.Position = Preferences.Get<int> (key);
 +				break;
 +	
 +			case Preferences.TAG_ICON_SIZE:
 +				int s = Preferences.Get<int> (key);
 +				tag_icon_hidden.Active = (s == (int) Tag.IconSize.Hidden);
 +				tag_icon_small.Active = (s == (int) Tag.IconSize.Small);
 +				tag_icon_medium.Active = (s == (int) Tag.IconSize.Medium);
 +				tag_icon_large.Active = (s == (int) Tag.IconSize.Large);
 +	
 +				break;
 +	
 +			case Preferences.ZOOM:
 +				icon_view.Zoom = Preferences.Get<double> (key);
 +				break;
 +			
 +			case Preferences.METADATA_EMBED_IN_IMAGE:
 +				write_metadata =Preferences.Get<bool> (key) ;
 +				break;
 +			case Preferences.GNOME_MAILTO_ENABLED:
 +				send_mail.Visible = Preferences.Get<bool> (key);
 +				break;
  			}
 -
 -			versions_submenu = new PhotoVersionMenu (CurrentPhoto);
 -			versions_submenu.VersionIdChanged += delegate (PhotoVersionMenu menu) { UpdateForVersionIdChange (menu.VersionId);};
 -			version_menu_item.Submenu = versions_submenu;
 -
 -			sharpen.Sensitive = (view_mode == ModeType.IconView ? false : true);
 -			loupe_menu_item.Sensitive = (view_mode == ModeType.IconView ? false : true);
  		}
 -
 -		set_as_background.Sensitive = single_active;
 -		adjust_time.Sensitive = active_selection;
 -
 -		attach_tag.Sensitive = active_selection;
 -		remove_tag.Sensitive = active_selection;
 -
 -		rotate_left.Sensitive = active_selection;
 -		rotate_right.Sensitive = active_selection;
 -		update_thumbnail.Sensitive = active_selection;
 -		delete_from_drive.Sensitive = active_selection;
 +	
 +		// Version Id updates.
 +	
 +		void UpdateForVersionIdChange (uint version_id)
 +		{
 +			CurrentPhoto.DefaultVersionId = version_id;
 +			query.Commit (ActiveIndex ());
 +		}
 +	
 +		// Queries.
 +	
 +		public void UpdateQuery ()
 +		{
 +			main_window.GdkWindow.Cursor = watch;
 +			main_window.GdkWindow.Display.Sync ();
 +			query.RequestReload ();
 +			main_window.GdkWindow.Cursor = null;
 +		}
 +	
 +		void HandleTagSelectionChanged (object obj, EventArgs args)
 +		{
 +			UpdateMenus ();
 +		}
 +	
 +		public bool TagIncluded (Tag tag)
 +		{
 +			return query_widget.TagIncluded (tag);
 +		}
 +		
 +		public bool TagRequired (Tag tag)
 +		{
 +			return query_widget.TagRequired (tag);
 +		}
 +	
 +		private void HandleQueryLogicChanged (object sender, EventArgs args)
 +		{
 +			HandleFindAddTagWith (null, null);
 +		}
  		
 -		send_mail.Sensitive = active_selection;
 -		print.Sensitive = active_selection;
 -		select_none.Sensitive = active_selection;
 -		copy_location.Sensitive = active_selection;
 -		remove_from_catalog.Sensitive = active_selection;
 +		public void HandleIncludeTag (object sender, EventArgs args)
 +		{
 +			ShowQueryWidget ();
 +			query_widget.Include (tag_selection_widget.TagHighlight);
 +		}
  		
 -		clear_rating_filter.Sensitive = (query.RatingRange != null);
 -
 -		clear_roll_filter.Sensitive = (query.RollSet != null);
 +		public void HandleUnIncludeTag (object sender, EventArgs args)
 +		{
 +			query_widget.UnInclude (tag_selection_widget.TagHighlight);
 +	 	}
  		
 -		delete_selected_tag.Sensitive = tag_sensitive;
 -		edit_selected_tag.Sensitive = tag_sensitive;
 -
 -
 -		attach_tag_to_selection.Sensitive = tag_sensitive && active_selection;
 -		remove_tag_from_selection.Sensitive = tag_sensitive && active_selection;
 -	
 -		export.Sensitive = active_selection;
 -
 -		MenuItem toolsmenu = uimanager.GetWidget ("/ui/menubar1/tools") as MenuItem;
 -		try {
 -			tools.Visible = (toolsmenu.Submenu as Menu).Children.Length > 0;
 -		} catch {
 -			tools.Visible = false;
 +		void HandleFindByTag (object sender, EventArgs args)
 +		{
 +			UpdateFindByTagMenu ();
  		}
 -
 -		if (rl_button != null) {
 -			if (selection.Count == 0) {
 -				rl_button.Sensitive = false;
 -				rl_button.SetTooltip (ToolTips, Catalog.GetString (String.Empty), null);
 +		
 +		public void UpdateFindByTagMenu ()
 +		{
 +			if (query_widget.Visible) {
 +				query_widget.Close ();
  			} else {
 -				rl_button.Sensitive = true;
 -
 -				string msg = Catalog.GetPluralString ("Rotate selected photo left",
 -								      "Rotate selected photos left", selection.Count);
 -				rl_button.SetTooltip (ToolTips, String.Format (msg, selection.Count), null);
 +				ShowQueryWidget ();
  			}
  		}
  		



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