[longomatch] Add base class for plays treeviews



commit c1419bf22071f50cd6432c7580ff3e68a8d685f4
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date:   Mon Sep 6 01:13:34 2010 +0200

    Add base class for plays treeviews

 LongoMatch/Gui/TreeView/ListTreeViewBase.cs |  409 +++++++++++++++++++++++++++
 LongoMatch/Gui/TreeView/PlayersTreeView.cs  |  251 +++++------------
 LongoMatch/Gui/TreeView/PlaysTreeView.cs    |  388 ++-----------------------
 LongoMatch/Gui/TreeView/TagsTreeView.cs     |  181 +-----------
 LongoMatch/LongoMatch.mdp                   |    1 +
 LongoMatch/Makefile.am                      |    1 +
 6 files changed, 522 insertions(+), 709 deletions(-)
---
diff --git a/LongoMatch/Gui/TreeView/ListTreeViewBase.cs b/LongoMatch/Gui/TreeView/ListTreeViewBase.cs
new file mode 100644
index 0000000..44ae2b0
--- /dev/null
+++ b/LongoMatch/Gui/TreeView/ListTreeViewBase.cs
@@ -0,0 +1,409 @@
+// 
+//  Copyright (C) 2010 Andoni Morales Alastruey
+// 
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+// 
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//  
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+// 
+
+using Gdk;
+using Gtk;
+using LongoMatch.Common;
+using LongoMatch.Handlers;
+using LongoMatch.TimeNodes;
+using Mono.Unix;
+using System;
+using System.Collections.Generic;
+
+namespace LongoMatch.Gui.Component
+{
+
+
+	public abstract class ListTreeViewBase:TreeView
+	{
+		// Plays menu
+		protected Menu menu, teamMenu;
+		protected MenuItem local;
+		protected MenuItem visitor;
+		protected MenuItem noTeam;
+		protected MenuItem tag;
+		protected MenuItem delete;
+		protected MenuItem addPLN;
+		protected MenuItem deleteKeyFrame;
+		protected MenuItem snapshot;
+		protected MenuItem name;
+		protected MenuItem players;
+		protected MenuItem localPlayers;
+		protected MenuItem visitorPlayers;
+		
+		
+		protected Gtk.CellRendererText nameCell;
+		protected Gtk.TreeViewColumn nameColumn;
+		protected Color[] colors;
+		protected String[] teams_name;
+		protected bool editing;
+		protected bool projectIsLive;
+
+		protected const string LOCAL_TEAM = "Local Team";
+		protected const string VISITOR_TEAM = "Visitor Team";	
+		
+		public event TimeNodeChangedHandler TimeNodeChanged;
+		public event TimeNodeSelectedHandler TimeNodeSelected;
+		public event TimeNodeDeletedHandler TimeNodeDeleted;
+		public event PlayListNodeAddedHandler PlayListNodeAdded;
+		public event SnapshotSeriesHandler SnapshotSeriesEvent;
+		public event PlayersTaggedHandler PlayersTagged;
+		public event TagPlayHandler TagPlay;
+
+		public ListTreeViewBase ()
+		{
+			Selection.Mode = SelectionMode.Multiple;
+			Selection.SelectFunction = SelectFunction;
+			RowActivated += new RowActivatedHandler(OnTreeviewRowActivated);
+			
+			SetMenu();
+			ProjectIsLive = false;
+			PlayListLoaded = false;
+			colors = null;
+
+			teams_name = new String[3];
+			teams_name[(int)Team.NONE] = Catalog.GetString(Catalog.GetString("None"));
+			teams_name[(int)Team.LOCAL] = Catalog.GetString(Catalog.GetString(LOCAL_TEAM));
+			teams_name[(int)Team.VISITOR] = Catalog.GetString(Catalog.GetString(VISITOR_TEAM));
+			
+			
+			nameColumn = new Gtk.TreeViewColumn();
+			nameColumn.Title = "Name";
+			nameCell = new Gtk.CellRendererText();
+			nameCell.Edited += OnNameCellEdited;
+			Gtk.CellRendererPixbuf miniatureCell = new Gtk.CellRendererPixbuf();
+			nameColumn.PackStart(miniatureCell, true);
+			nameColumn.PackEnd(nameCell, true);
+
+			nameColumn.SetCellDataFunc(miniatureCell, new Gtk.TreeCellDataFunc(RenderMiniature));
+			nameColumn.SetCellDataFunc(nameCell, new Gtk.TreeCellDataFunc(RenderName));
+
+			AppendColumn(nameColumn);
+
+		}
+
+		public Color[]  Colors {
+			set {
+				this.colors = value;
+			}
+		}
+		public bool ProjectIsLive{
+			set{
+				projectIsLive = value;
+				addPLN.Visible = !projectIsLive;
+				snapshot.Visible = !projectIsLive;
+			}
+		}
+		
+		public String LocalTeam {
+			set{
+				Label l1 = (local.Children[0] as Label);
+				Label l2 = (localPlayers.Children[0] as Label);
+				if (value == "")
+					l1.Text = l2.Text = Catalog.GetString(LOCAL_TEAM);
+				else {
+					l1.Text = l2.Text = value;
+				}
+				teams_name[(int)Team.LOCAL] = l1.Text; 
+			}
+		}
+		
+		public string VisitorTeam {
+			set{
+				Label l1 = (visitor.Children[0] as Label);
+				Label l2 = (visitorPlayers.Children[0] as Label);
+				if (value == "")
+					l1.Text = l2.Text = Catalog.GetString(VISITOR_TEAM);
+				else 
+					l1.Text = l2.Text = value;
+				teams_name[(int)Team.VISITOR] = l1.Text; 
+			}
+		}
+
+		public bool PlayListLoaded {
+			set {
+				addPLN.Sensitive = value;
+			}
+		}
+		
+		protected void EmitTimeNodeChanged(TimeNode tn, object o){
+			if (TimeNodeChanged != null)
+				TimeNodeChanged(tn, o);
+		}
+		
+		protected void SetMenu() {
+			Menu playersMenu;
+			MenuItem team;
+			
+			teamMenu = new Menu();
+			local = new MenuItem(Catalog.GetString(LOCAL_TEAM));
+			visitor = new MenuItem(Catalog.GetString(VISITOR_TEAM));
+			noTeam = new MenuItem(Catalog.GetString("No Team"));
+			teamMenu .Append(local);
+			teamMenu .Append(visitor);
+			teamMenu .Append(noTeam);
+
+			playersMenu = new Menu();
+			localPlayers = new MenuItem(Catalog.GetString(LOCAL_TEAM));
+			visitorPlayers = new MenuItem(Catalog.GetString(VISITOR_TEAM));
+			playersMenu.Append(localPlayers);
+			playersMenu.Append(visitorPlayers);
+
+			menu = new Menu();
+			
+			name = new MenuItem(Catalog.GetString("Edit"));
+			team = new MenuItem(Catalog.GetString("Team Selection"));
+			team.Submenu = teamMenu;
+			tag = new MenuItem(Catalog.GetString("Add tag"));
+			players = new MenuItem(Catalog.GetString("Tag player"));
+			players.Submenu = playersMenu;
+			delete = new MenuItem(Catalog.GetString("Delete"));
+			deleteKeyFrame = new MenuItem(Catalog.GetString("Delete key frame"));
+			addPLN = new MenuItem(Catalog.GetString("Add to playlist"));
+			addPLN.Sensitive=false;
+			snapshot = new MenuItem(Catalog.GetString("Export to PGN images"));
+
+			menu.Append(name);
+			menu.Append(tag);
+			menu.Append(players);
+			menu.Append(team);
+			menu.Append(addPLN);
+			menu.Append(delete);
+			menu.Append(deleteKeyFrame);
+			menu.Append(snapshot);
+
+			name.Activated += OnEdit;
+			tag.Activated += OnTag;
+			local.Activated += OnTeamSelection;
+			visitor.Activated += OnTeamSelection;
+			noTeam.Activated += OnTeamSelection;
+			localPlayers.Activated += OnLocalPlayers;
+			visitorPlayers.Activated += OnVisitorPlayers;
+			addPLN.Activated += OnAdded;
+			delete.Activated += OnDeleted;
+			deleteKeyFrame.Activated += OnDeleteKeyFrame;
+			snapshot.Activated += OnSnapshot;
+			menu.ShowAll();
+		}		
+
+		protected void MultiSelectMenu (bool enabled){
+			name.Sensitive = !enabled;
+			snapshot.Sensitive = !enabled;
+			players.Sensitive = !enabled;
+			tag.Sensitive = !enabled;
+		}
+		
+		protected int GetSectionFromIter(TreeIter iter) {
+			TreePath path = Model.GetPath(iter);
+			return int.Parse(path.ToString().Split(':')[0]);
+		}
+		
+		protected object GetValueFromPath(TreePath path){
+			Gtk.TreeIter iter;
+			Model.GetIter(out iter, path);
+			return Model.GetValue(iter,0);					
+		}	
+	
+		protected void RenderMiniature(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
+		{
+			var item = model.GetValue(iter, 0);
+			var c = cell as CellRendererPixbuf;
+
+			if (item is MediaTimeNode){
+				c.Pixbuf = (item as MediaTimeNode).Miniature;
+				if (colors !=null) {
+					c.CellBackgroundGdk = colors[GetSectionFromIter(iter)];
+				} else{ 
+					c.CellBackground = "white";
+				}
+			}
+			else if (item is Player){
+				c.Pixbuf= (item as Player).Photo;
+				c.CellBackground = "white";
+			}
+			else {
+				c.Pixbuf = null;
+				c.CellBackground = "white";
+			}
+		}
+		
+		protected void RenderName(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
+		{
+			object o = model.GetValue(iter, 0);
+			var c = cell as CellRendererText;
+			
+			if (o is MediaTimeNode){
+				//Handle special case in which we replace the text in the cell by the name of the TimeNode
+				//We need to check if we are editing and only change it for the path that's currently beeing edited
+				if (editing && Selection.IterIsSelected(iter)){
+					c.Markup = (o as MediaTimeNode).Name;
+				} else {
+					var mtn = o as MediaTimeNode;
+					/* FIXME: the colors array is set externally and might not match the model!!! */
+					if (colors !=null) {
+						Color col = colors[GetSectionFromIter(iter)];
+						c.CellBackgroundGdk = col;
+						c.BackgroundGdk = col;
+					} else{ 
+						c.Background = "white";
+						c.CellBackground = "white";
+					}
+					c.Markup = mtn.ToString(teams_name[(int)mtn.Team]);
+				}					
+			}else if (o is Player) {
+				c.Background = "white";
+				c.CellBackground = "white";
+				c.Markup = (o as Player).Name;
+			}else if (o is SectionsTimeNode) {
+				c.Markup = (o as TimeNode).Name;
+				c.Background = "white";
+				c.CellBackground = "white";
+			}
+		}	
+
+		protected virtual void OnNameCellEdited(object o, Gtk.EditedArgs args)
+		{
+			Gtk.TreeIter iter;
+			object item;
+			
+			Model.GetIter(out iter, new Gtk.TreePath(args.Path));
+			item = this.Model.GetValue(iter,0);
+			
+			if (item is TimeNode){
+				(item as TimeNode).Name = args.NewText;
+				EmitTimeNodeChanged((item as TimeNode), args.NewText);
+			}else if (item is Player){
+				(item as Player).Name = args.NewText;
+			}
+			editing = false;
+			nameCell.Editable=false;
+			
+		}
+
+		protected virtual void OnTreeviewRowActivated(object o, Gtk.RowActivatedArgs args)
+		{
+			Gtk.TreeIter iter;
+			this.Model.GetIter(out iter, args.Path);
+			object item = this.Model.GetValue(iter, 0);
+			
+			if (!(item is MediaTimeNode))
+				return;
+
+			if (TimeNodeSelected != null && !projectIsLive)
+				this.TimeNodeSelected(item as MediaTimeNode);
+		}
+
+		protected void OnDeleted(object obj, EventArgs args) {
+			if (TimeNodeDeleted == null)
+				return;
+			List<MediaTimeNode> list = new List<MediaTimeNode>();
+			TreePath[] paths = Selection.GetSelectedRows();
+			for (int i=0; i<paths.Length; i++){	
+				list.Add((MediaTimeNode)GetValueFromPath(paths[i]));
+			}
+			// When a TimeNode is deleted from the tree the path changes.
+			// We need first to retrieve all the TimeNodes to delete using the 
+			// current path of each one and then send the TimeNodeDeleted event
+			for (int i=0; i<paths.Length; i++){	
+				TimeNodeDeleted(list[i], int.Parse(paths[i].ToString().Split(':')[0]));
+			}			
+		}
+
+		protected void OnDeleteKeyFrame(object obj, EventArgs args) {
+			MessageDialog md = new MessageDialog((Gtk.Window)Toplevel,
+			                                     DialogFlags.Modal,
+			                                     MessageType.Question,
+			                                     ButtonsType.YesNo,
+			                                     false,
+			                                     Catalog.GetString("Do you want to delete the key frame for this play?")
+			                                    );
+			if (md.Run() == (int)ResponseType.Yes){
+				TreePath[] paths = Selection.GetSelectedRows();
+				for (int i=0; i<paths.Length; i++){	
+					MediaTimeNode tNode = (MediaTimeNode)GetValueFromPath(paths[i]);
+					tNode.KeyFrameDrawing = null;
+				}
+				// Refresh the thumbnails
+				QueueDraw();
+			}
+			md.Destroy();
+		}
+
+		protected virtual void OnEdit(object obj, EventArgs args) {
+			TreePath[] paths = Selection.GetSelectedRows();
+			object o = GetValueFromPath(paths[0]);
+			
+			editing = true;
+			nameCell.Editable = true;
+			if (o is Player)
+				nameCell.Markup = (o as Player).Name;
+			else 
+				nameCell.Markup = (o as TimeNode).Name;
+			SetCursor(paths[0],  nameColumn, true);
+		}
+
+		protected void OnTeamSelection(object obj, EventArgs args) {
+			MenuItem sender = (MenuItem)obj;
+			Team team = Team.NONE;
+			if (sender == local)
+				team = Team.LOCAL;
+			else if (sender == visitor)
+				team = Team.VISITOR;
+			else if (sender == noTeam)
+				team = Team.NONE;
+			
+			TreePath[] paths = Selection.GetSelectedRows();
+			for (int i=0; i<paths.Length; i++){	
+					MediaTimeNode tNode = (MediaTimeNode)GetValueFromPath(paths[i]);
+					tNode.Team = team;
+			}
+		}
+
+		protected void OnAdded(object obj, EventArgs args) {
+			if (PlayListNodeAdded != null){
+				TreePath[] paths = Selection.GetSelectedRows();
+				for (int i=0; i<paths.Length; i++){	
+					MediaTimeNode tNode = (MediaTimeNode)GetValueFromPath(paths[i]);
+					PlayListNodeAdded(tNode);
+				}
+			}
+		}
+		
+		protected void OnTag (object obj, EventArgs args){
+			if (TagPlay != null)
+				TagPlay((MediaTimeNode)GetValueFromPath(Selection.GetSelectedRows()[0]));
+		}
+
+		protected void OnSnapshot(object obj, EventArgs args) {
+			if (SnapshotSeriesEvent != null)
+				SnapshotSeriesEvent((MediaTimeNode)GetValueFromPath(Selection.GetSelectedRows()[0]));
+		}
+
+		protected virtual void OnLocalPlayers(object o, EventArgs args) {
+			if (PlayersTagged != null)
+				PlayersTagged((MediaTimeNode)GetValueFromPath(Selection.GetSelectedRows()[0]), Team.LOCAL);
+		}
+
+		protected virtual void OnVisitorPlayers(object o, EventArgs args) {
+			if (PlayersTagged != null)
+				PlayersTagged((MediaTimeNode)GetValueFromPath(Selection.GetSelectedRows()[0]), Team.VISITOR);
+		}
+		
+		protected abstract bool SelectFunction(TreeSelection selection, TreeModel model, TreePath path, bool selected);
+	}
+}
diff --git a/LongoMatch/Gui/TreeView/PlayersTreeView.cs b/LongoMatch/Gui/TreeView/PlayersTreeView.cs
index 7254459..152f885 100644
--- a/LongoMatch/Gui/TreeView/PlayersTreeView.cs
+++ b/LongoMatch/Gui/TreeView/PlayersTreeView.cs
@@ -16,13 +16,10 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 //
 
-using System;
 using Gdk;
 using Gtk;
-using Mono.Unix;
-using LongoMatch.Handlers;
-using LongoMatch.TimeNodes;
 using LongoMatch.Common;
+using LongoMatch.TimeNodes;
 
 namespace LongoMatch.Gui.Component
 {
@@ -30,49 +27,17 @@ namespace LongoMatch.Gui.Component
 
 	[System.ComponentModel.Category("LongoMatch")]
 	[System.ComponentModel.ToolboxItem(true)]
-	public partial class PlayersTreeView : Gtk.TreeView
+	public partial class PlayersTreeView : ListTreeViewBase
 	{
 
-		public event TimeNodeSelectedHandler TimeNodeSelected;
-		public event TimeNodeChangedHandler TimeNodeChanged;
-		public event PlayListNodeAddedHandler PlayListNodeAdded;
-		public event SnapshotSeriesHandler SnapshotSeriesEvent;
-
-		private TreeIter selectedIter;
-		private Menu menu;
-		private MenuItem addPLN;
-		private MenuItem snapshot;
-		private Gtk.CellRendererText nameCell;
-		private TreePath path;
-		private Gtk.TreeViewColumn nameColumn;
-		//Using TimeNode as in the tree there are Media and Sections timenodes
-		private TimeNode selectedTimeNode;
-		private bool editing;
-		private bool projectIsLive;
-
 		private Team team;
 
 
 		public PlayersTreeView() {
 			team = Team.LOCAL;
-			this.RowActivated += new RowActivatedHandler(OnTreeviewRowActivated);
-
-			SetMenu();
-			ProjectIsLive = false;
-			PlayListLoaded = false;
-
-			nameColumn = new Gtk.TreeViewColumn();
-			nameColumn.Title = "Name";
-			nameCell = new Gtk.CellRendererText();
-			nameCell.Edited += OnNameCellEdited;
-			Gtk.CellRendererPixbuf miniatureCell = new Gtk.CellRendererPixbuf();
-			nameColumn.PackStart(miniatureCell, true);
-			nameColumn.PackEnd(nameCell, true);
-
-			nameColumn.SetCellDataFunc(miniatureCell, new Gtk.TreeCellDataFunc(RenderMiniature));
-			nameColumn.SetCellDataFunc(nameCell, new Gtk.TreeCellDataFunc(RenderName));
-
-			AppendColumn(nameColumn);
+			tag.Visible = false;
+			players.Visible = false;
+			delete.Visible = false;
 		}
 
 		public Team Team {
@@ -84,161 +49,89 @@ namespace LongoMatch.Gui.Component
 			}
 		}
 		
-		public bool ProjectIsLive{
+		new public TreeStore Model{
 			set{
-				projectIsLive = value;
-				addPLN.Visible = !projectIsLive;
-				snapshot.Visible = !projectIsLive;
+				if (value != null){
+					value.SetSortFunc(0, SortFunction);
+					value.SetSortColumnId(0,SortType.Ascending);
+				}
+				base.Model = value;					
 			}
-		}
-
-		public bool PlayListLoaded {
-			set {
-				addPLN.Sensitive = value;
+			get{
+				return base.Model as TreeStore;
 			}
 		}
 
-		private void SetMenu() {
-			MenuItem name;
-			MenuItem delete; 
-
-			menu = new Menu();
-
-			name = new MenuItem(Catalog.GetString("Edit"));
-			delete = new MenuItem(Catalog.GetString("Delete"));
-			snapshot = new MenuItem(Catalog.GetString("Export to PGN images"));
-			addPLN = new MenuItem(Catalog.GetString("Add to playlist"));
-			addPLN.Sensitive=false;
-
-			menu.Append(name);
-			menu.Append(delete);
-			menu.Append(addPLN);
-			menu.Append(snapshot);
-
-			delete.Activated += new EventHandler(OnDeleted);
-			name.Activated += new EventHandler(OnEdit);
-			addPLN.Activated += new EventHandler(OnAdded);
-			snapshot.Activated += new EventHandler(OnSnapshot);
-			menu.ShowAll();
+		protected int SortFunction(TreeModel model, TreeIter a, TreeIter b){
+			object oa;
+			object ob;
+			
+			if (model == null)
+				return 0;	
+			
+			oa = model.GetValue (a, 0);
+			ob = model.GetValue (b, 0);
+			
+			if (oa is Player)
+				return (oa as Player).Name.CompareTo((ob as Player).Name);
+			else 
+				return (oa as TimeNode).Name.CompareTo((ob as TimeNode).Name);
 		}
-
-		protected override bool OnButtonPressEvent(EventButton evnt)
+		
+		override protected bool OnKeyPressEvent (Gdk.EventKey evnt)
 		{
-			object selectedItem;
-
-			//Call base class, to allow normal handling,
-			//such as allowing the row to be selected by the right-click:
-			bool returnValue = base.OnButtonPressEvent(evnt);
+			return false;
+		}
+		
+		override protected void OnNameCellEdited(object o, Gtk.EditedArgs args)
+		{
+			base.OnNameCellEdited(o, args);
+			Model.SetSortFunc(0, SortFunction);
+		}
 
-			//Then do our custom stuff:
+		override protected bool OnButtonPressEvent(EventButton evnt)
+		{			
+			TreePath[] paths = Selection.GetSelectedRows();
+			
 			if ((evnt.Type == EventType.ButtonPress) && (evnt.Button == 3))
 			{
-				this.GetPathAtPos((int)evnt.X,(int)evnt.Y,out path);
-				if (path!=null) {
-					this.Model.GetIter(out selectedIter,path);
-					selectedItem = this.Model.GetValue(selectedIter, 0);
-					if (selectedItem is MediaTimeNode) {
-						selectedTimeNode = selectedItem as MediaTimeNode;
+				// We don't want to unselect the play when several
+				// plays are selected and we clik the right button
+				// For multiedition
+				if (paths.Length <= 1){
+					base.OnButtonPressEvent(evnt);
+					paths = Selection.GetSelectedRows();
+				}
+				
+				if (paths.Length == 1) {
+					TimeNode selectedTimeNode = GetValueFromPath(paths[0]) as TimeNode;
+					if (selectedTimeNode is MediaTimeNode) {
+						deleteKeyFrame.Sensitive = (selectedTimeNode as MediaTimeNode).KeyFrameDrawing != null;
+						MultiSelectMenu(false);
 						menu.Popup();
 					}
-					else {
-						nameCell.Editable = true;
-						this.SetCursor(path,  nameColumn, true);
-					}
+				}
+				else if (paths.Length > 1){
+					MultiSelectMenu(true);
+					menu.Popup();								
 				}
 			}
-			return returnValue;
-		}
-
-		protected void OnDeleted(object obj, EventArgs args) {
-			(Model as TreeStore).Remove(ref selectedIter);
-
-			if (Team == Team.LOCAL)
-				((MediaTimeNode) selectedTimeNode).RemoveLocalPlayer(int.Parse(path.ToString().Split(':')[0]));
-			if (Team == Team.VISITOR)
-				((MediaTimeNode) selectedTimeNode).RemoveVisitorPlayer(int.Parse(path.ToString().Split(':')[0]));
-		}
-
-		protected void OnSnapshot(object obj, EventArgs args) {
-			if (SnapshotSeriesEvent != null)
-				SnapshotSeriesEvent((MediaTimeNode)selectedTimeNode);
-		}
-
-		private void RenderMiniature(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
-		{
-			object item = model.GetValue(iter, 0);
-
-			if (item is MediaTimeNode)
-				(cell as Gtk.CellRendererPixbuf).Pixbuf = (item as MediaTimeNode).Miniature;
-
-			if (item is Player)
-				(cell as Gtk.CellRendererPixbuf).Pixbuf= (item as Player).Photo;
-		}
-
-
-		private void RenderName(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
-		{
-			object item = model.GetValue(iter, 0);
-
-			if (item is MediaTimeNode) {
-				MediaTimeNode tNode = item as MediaTimeNode;
-				if (editing && selectedIter.Equals(iter))
-					(cell as Gtk.CellRendererText).Markup = tNode.Name;
-				else
-					(cell as Gtk.CellRendererText).Markup = (tNode as MediaTimeNode).ToString();
-			}
-
-			else if (item is Player)
-				(cell as Gtk.CellRendererText).Text = (item as Player).Name;
-		}
-
-		protected virtual void OnEdit(object obj, EventArgs args) {
-			editing = true;
-			nameCell.Editable = true;
-			this.SetCursor(path,  nameColumn, true);
+			else 
+				base.OnButtonPressEvent(evnt);
+			return true;
 		}
-
-		protected void OnAdded(object obj, EventArgs args) {
-			if (PlayListNodeAdded != null)
-				PlayListNodeAdded((MediaTimeNode)selectedTimeNode);
-		}
-
-		private void OnNameCellEdited(object o, Gtk.EditedArgs args)
-		{
-			Gtk.TreeIter iter;
-			this.Model.GetIter(out iter, new Gtk.TreePath(args.Path));
-			if (Model.GetValue(iter,0) is TimeNode) {
-				TimeNode tNode = (TimeNode)this.Model.GetValue(iter,0);
-				tNode.Name = args.NewText;
-				nameCell.Editable=false;
-				if (TimeNodeChanged != null)
-					TimeNodeChanged(tNode,args.NewText);
+				
+		override protected bool SelectFunction(TreeSelection selection, TreeModel model, TreePath path, bool selected){
+			// Don't allow multiselection for Players
+			if (!selected && selection.GetSelectedRows().Length > 0){
+				if (selection.GetSelectedRows().Length == 1 &&
+				    GetValueFromPath(selection.GetSelectedRows()[0]) is Player)
+					return false;	
+				return !(GetValueFromPath(path) is Player);										
 			}
-			else {
-				Player player = (Player)this.Model.GetValue(iter,0);
-				player.Name = args.NewText;
-				nameCell.Editable=false;
-			}
-			editing = false;
-		}
-
-
-		protected virtual void OnTreeviewRowActivated(object o, Gtk.RowActivatedArgs args)
-		{
-			Gtk.TreeIter iter;
-
-			object item;
-			this.Model.GetIter(out iter, args.Path);
-			item = this.Model.GetValue(iter, 0);
-
-			if (item is MediaTimeNode && TimeNodeSelected != null
-			    && !projectIsLive)
-				this.TimeNodeSelected(item as MediaTimeNode);
-		}
-		
-		protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
-		{
-			return false;
+			// Always unselect
+			else
+				return true;
 		}
 	}
 }
diff --git a/LongoMatch/Gui/TreeView/PlaysTreeView.cs b/LongoMatch/Gui/TreeView/PlaysTreeView.cs
index f972232..291ab8d 100644
--- a/LongoMatch/Gui/TreeView/PlaysTreeView.cs
+++ b/LongoMatch/Gui/TreeView/PlaysTreeView.cs
@@ -18,14 +18,11 @@
 //
 //
 
-using System;
-using System.Collections.Generic;
 using Gdk;
 using Gtk;
-using Mono.Unix;
-using LongoMatch.Handlers;
-using LongoMatch.TimeNodes;
 using LongoMatch.Common;
+using LongoMatch.TimeNodes;
+using System;
 
 namespace LongoMatch.Gui.Component
 {
@@ -33,75 +30,16 @@ namespace LongoMatch.Gui.Component
 
 	[System.ComponentModel.Category("LongoMatch")]
 	[System.ComponentModel.ToolboxItem(true)]
-	public class PlaysTreeView : Gtk.TreeView
+	public class PlaysTreeView : ListTreeViewBase
 	{
 
-		public event TimeNodeChangedHandler TimeNodeChanged;
-		public event TimeNodeSelectedHandler TimeNodeSelected;
-		public event TimeNodeDeletedHandler TimeNodeDeleted;
-		public event PlayListNodeAddedHandler PlayListNodeAdded;
-		public event SnapshotSeriesHandler SnapshotSeriesEvent;
-		public event PlayersTaggedHandler PlayersTagged;
-		public event TagPlayHandler TagPlay;
 
-		// Plays menu
-		private Menu menu, teamMenu;
-		private MenuItem local;
-		private	MenuItem visitor;
-		private MenuItem noTeam;
-		private MenuItem tag;
-		private MenuItem addPLN;
-		private MenuItem deleteKeyFrame;
-		private MenuItem snapshot;
-		private MenuItem name;
-		private MenuItem players;
-		private MenuItem localPlayers;
-		private MenuItem visitorPlayers;
-		
 		//Categories menu
 		private Menu categoriesMenu;
 		private RadioAction sortByName, sortByStart, sortByStop, sortByDuration;
 		
-		private Gtk.CellRendererText nameCell;
-		private Gtk.TreeViewColumn nameColumn;
-		private Color[] colors;
-		private String[] teams_name;
-		private bool editing;
-		private bool projectIsLive;
-
-		private const string LOCAL_TEAM = "Local Team";
-		private const string VISITOR_TEAM = "Visitor Team";	
-		
 		public PlaysTreeView() {
-			Selection.Mode = SelectionMode.Multiple;
-			Selection.SelectFunction = SelectFunction;
-			this.RowActivated += new RowActivatedHandler(OnTreeviewRowActivated);
-			
-			SetMenu();
 			SetCategoriesMenu();
-			ProjectIsLive = false;
-			PlayListLoaded = false;
-
-			colors = new Color[20];
-			teams_name = new String[3];
-			teams_name[(int)Team.NONE] = Catalog.GetString(Catalog.GetString("None"));
-			teams_name[(int)Team.LOCAL] = Catalog.GetString(Catalog.GetString(LOCAL_TEAM));
-			teams_name[(int)Team.VISITOR] = Catalog.GetString(Catalog.GetString(VISITOR_TEAM));
-
-			nameColumn = new Gtk.TreeViewColumn();
-			nameColumn.Title = "Name";
-			nameColumn.SortOrder = SortType.Ascending;
-			nameCell = new Gtk.CellRendererText();
-			nameCell.Edited += OnNameCellEdited;
-			Gtk.CellRendererPixbuf miniatureCell = new Gtk.CellRendererPixbuf();
-			nameColumn.PackStart(miniatureCell, true);
-			nameColumn.PackEnd(nameCell, true);
-
-			nameColumn.SetCellDataFunc(miniatureCell, new Gtk.TreeCellDataFunc(RenderMiniature));
-			nameColumn.SetCellDataFunc(nameCell, new Gtk.TreeCellDataFunc(RenderName));
-
-			this.AppendColumn(nameColumn);
-			
 		}
 		
 		new public TreeStore Model{
@@ -113,109 +51,9 @@ namespace LongoMatch.Gui.Component
 				base.Model = value;					
 			}
 			get{
-				return (TreeStore)base.Model;
-			}
-		}
-
-		public bool ProjectIsLive{
-			set{
-				projectIsLive = value;
-				addPLN.Visible = !projectIsLive;
-				snapshot.Visible = !projectIsLive;
+				return base.Model as TreeStore;
 			}
 		}
-		
-		public Color[]  Colors {
-			set {
-				this.colors = value;
-			}
-		}
-		
-		public String LocalTeam {
-			set{
-				Label l1 = (local.Children[0] as Label);
-				Label l2 = (localPlayers.Children[0] as Label);
-				if (value == "")
-					l1.Text = l2.Text = Catalog.GetString(LOCAL_TEAM);
-				else {
-					l1.Text = l2.Text = value;
-				}
-				teams_name[(int)Team.LOCAL] = l1.Text; 
-			}
-		}
-		
-		public string VisitorTeam {
-			set{
-				Label l1 = (visitor.Children[0] as Label);
-				Label l2 = (visitorPlayers.Children[0] as Label);
-				if (value == "")
-					l1.Text = l2.Text = Catalog.GetString(VISITOR_TEAM);
-				else 
-					l1.Text = l2.Text = value;
-				teams_name[(int)Team.VISITOR] = l1.Text; 
-			}
-		}
-
-		public bool PlayListLoaded {
-			set {
-				addPLN.Sensitive = value;
-			}
-		}
-		
-		private void SetMenu() {
-			Menu playersMenu;
-			MenuItem team, quit;
-			
-			teamMenu = new Menu();
-			local = new MenuItem(Catalog.GetString(LOCAL_TEAM));
-			visitor = new MenuItem(Catalog.GetString(VISITOR_TEAM));
-			noTeam = new MenuItem(Catalog.GetString("No Team"));
-			teamMenu .Append(local);
-			teamMenu .Append(visitor);
-			teamMenu .Append(noTeam);
-
-			playersMenu = new Menu();
-			localPlayers = new MenuItem(Catalog.GetString(LOCAL_TEAM));
-			visitorPlayers = new MenuItem(Catalog.GetString(VISITOR_TEAM));
-			playersMenu.Append(localPlayers);
-			playersMenu.Append(visitorPlayers);
-
-			menu = new Menu();
-			
-			name = new MenuItem(Catalog.GetString("Edit"));
-			team = new MenuItem(Catalog.GetString("Team Selection"));
-			team.Submenu = teamMenu;
-			tag = new MenuItem(Catalog.GetString("Add tag"));
-			players = new MenuItem(Catalog.GetString("Tag player"));
-			players.Submenu = playersMenu;
-			quit = new MenuItem(Catalog.GetString("Delete"));
-			deleteKeyFrame = new MenuItem(Catalog.GetString("Delete key frame"));
-			addPLN = new MenuItem(Catalog.GetString("Add to playlist"));
-			addPLN.Sensitive=false;
-			snapshot = new MenuItem(Catalog.GetString("Export to PGN images"));
-
-			menu.Append(name);
-			menu.Append(tag);
-			menu.Append(players);
-			menu.Append(team);
-			menu.Append(addPLN);
-			menu.Append(quit);
-			menu.Append(deleteKeyFrame);
-			menu.Append(snapshot);
-
-			name.Activated += OnEdit;
-			tag.Activated += OnTag;
-			local.Activated += OnTeamSelection;
-			visitor.Activated += OnTeamSelection;
-			noTeam.Activated += OnTeamSelection;
-			localPlayers.Activated += OnLocalPlayers;
-			visitorPlayers.Activated += OnVisitorPlayers;
-			addPLN.Activated += OnAdded;
-			quit.Activated += OnDeleted;
-			deleteKeyFrame.Activated += OnDeleteKeyFrame;
-			snapshot.Activated += OnSnapshot;
-			menu.ShowAll();
-		}
 
 		private void SetCategoriesMenu(){
 			Action edit, sortMenu;			
@@ -285,25 +123,7 @@ namespace LongoMatch.Gui.Component
 			}
 		}
 		
-		private int GetSectionFromIter(TreeIter iter) {
-			TreePath path = Model.GetPath(iter);
-			return int.Parse(path.ToString().Split(':')[0]);
-		}
-
-		private TimeNode GetValueFromPath(TreePath path){
-			Gtk.TreeIter iter;
-			Model.GetIter(out iter, path);
-			return (TimeNode)Model.GetValue(iter,0);					
-		}	
-		
-		private void MultiSelectMenu (bool enabled){
-			name.Sensitive = !enabled;
-			snapshot.Sensitive = !enabled;
-			players.Sensitive = !enabled;
-			tag.Sensitive = !enabled;
-		}
-		
-		private int SortFunction(TreeModel model, TreeIter a, TreeIter b){
+		protected int SortFunction(TreeModel model, TreeIter a, TreeIter b){
 			TreeStore store;
 			TimeNode tna, tnb;
 			TreeIter parent;
@@ -350,7 +170,26 @@ namespace LongoMatch.Gui.Component
 			}			
 		}
 		
-		private bool SelectFunction(TreeSelection selection, TreeModel model, TreePath path, bool selected){
+		private void OnSortActivated (object o, EventArgs args){
+			SectionsTimeNode category;
+			RadioAction sender;
+			
+			sender = o as RadioAction;
+			category = GetValueFromPath(Selection.GetSelectedRows()[0]) as SectionsTimeNode;
+			
+			if (sender == sortByName)
+				category.SortMethod = SortMethodType.SortByName;
+			else if (sender == sortByStart)
+				category.SortMethod = SortMethodType.SortByName;
+			else if (sender == sortByStop)
+				category.SortMethod = SortMethodType.SortByStopTime;
+			else 
+				category.SortMethod = SortMethodType.SortByDuration;
+			// Redorder plays
+			Model.SetSortFunc(0, SortFunction);
+		}
+		
+		override protected bool SelectFunction(TreeSelection selection, TreeModel model, TreePath path, bool selected){
 			// Don't allow multiselect for categories
 			if (!selected && selection.GetSelectedRows().Length > 0){
 				if (selection.GetSelectedRows().Length == 1 &&
@@ -363,53 +202,13 @@ namespace LongoMatch.Gui.Component
 				return true;
 		}
 		
-		private void RenderMiniature(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
-		{
-			TimeNode tNode = (TimeNode) model.GetValue(iter, 0);
-			if (tNode is MediaTimeNode) {
-				(cell as Gtk.CellRendererPixbuf).Pixbuf = ((MediaTimeNode)tNode).Miniature;
-				(cell as Gtk.CellRendererPixbuf).CellBackgroundGdk = colors[GetSectionFromIter(iter)];
-			}
-			else {
-				(cell as Gtk.CellRendererPixbuf).Pixbuf = null;
-				(cell as Gtk.CellRendererPixbuf).CellBackground = "white";
-			}
-		}
-
-		private void RenderName(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
-		{
-			TimeNode tNode = (TimeNode) model.GetValue(iter, 0);
-
-			//Handle special case in which we replace the text in the cell by the name of the TimeNode
-			//We need to check if we are editing and only change it for the path that's currently beeing edited
-
-			if (editing && Selection.IterIsSelected(iter))
-				(cell as Gtk.CellRendererText).Markup = tNode.Name;
-			else if (tNode is MediaTimeNode) {
-				MediaTimeNode mTNode = (MediaTimeNode) tNode;
-				(cell as Gtk.CellRendererText).BackgroundGdk = colors[GetSectionFromIter(iter)];
-				(cell as Gtk.CellRendererText).CellBackgroundGdk = colors[GetSectionFromIter(iter)];
-				(cell as Gtk.CellRendererText).Markup = mTNode.ToString(teams_name[(int)mTNode.Team]);
-			}
-			else {
-				(cell as Gtk.CellRendererText).Background = "white";
-				(cell as Gtk.CellRendererText).CellBackground = "white";
-				(cell as Gtk.CellRendererText).Markup =tNode.Name;
-			}
-		}	
-
-		protected virtual void OnTreeviewRowActivated(object o, Gtk.RowActivatedArgs args)
+		override protected void OnNameCellEdited(object o, Gtk.EditedArgs args)
 		{
-			Gtk.TreeIter iter;
-			this.Model.GetIter(out iter, args.Path);
-			TimeNode tNode = (TimeNode)this.Model.GetValue(iter, 0);
-
-			if (tNode is MediaTimeNode && TimeNodeSelected != null
-			    && !projectIsLive)
-				this.TimeNodeSelected((MediaTimeNode)tNode);
+			base.OnNameCellEdited(o, args);
+			Model.SetSortFunc(0, SortFunction);
 		}
 
-		protected override bool OnButtonPressEvent(EventButton evnt)
+		override protected bool OnButtonPressEvent(EventButton evnt)
 		{			
 			TreePath[] paths = Selection.GetSelectedRows();
 			
@@ -424,7 +223,7 @@ namespace LongoMatch.Gui.Component
 				}
 				
 				if (paths.Length == 1) {
-					TimeNode selectedTimeNode = GetValueFromPath(paths[0]);
+					TimeNode selectedTimeNode = GetValueFromPath(paths[0]) as TimeNode;
 					if (selectedTimeNode is MediaTimeNode) {
 						deleteKeyFrame.Sensitive = (selectedTimeNode as MediaTimeNode).KeyFrameDrawing != null;
 						MultiSelectMenu(false);
@@ -445,133 +244,6 @@ namespace LongoMatch.Gui.Component
 			return true;
 		}
 		
-		private void OnSortActivated (object o, EventArgs args){
-			SectionsTimeNode category;
-			RadioAction sender;
-			
-			sender = o as RadioAction;
-			category = GetValueFromPath(Selection.GetSelectedRows()[0]) as SectionsTimeNode;
-			
-			if (sender == sortByName)
-				category.SortMethod = SortMethodType.SortByName;
-			else if (sender == sortByStart)
-				category.SortMethod = SortMethodType.SortByName;
-			else if (sender == sortByStop)
-				category.SortMethod = SortMethodType.SortByStopTime;
-			else 
-				category.SortMethod = SortMethodType.SortByDuration;
-			// Redorder plays
-			Model.SetSortFunc(0, SortFunction);
-		}
-		
-		private void OnNameCellEdited(object o, Gtk.EditedArgs args)
-		{
-			Gtk.TreeIter iter;
-			TimeNode tNode;
-			
-			Model.GetIter(out iter, new Gtk.TreePath(args.Path));
-			tNode = (TimeNode)this.Model.GetValue(iter,0);
-			tNode.Name = args.NewText;
-			editing = false;
-			nameCell.Editable=false;
-			if (TimeNodeChanged != null)
-				TimeNodeChanged(tNode,args.NewText);
-			
-			// Redorder plays
-			Model.SetSortFunc(0, SortFunction);
-		}
-
-		protected void OnDeleted(object obj, EventArgs args) {
-			if (TimeNodeDeleted == null)
-				return;
-			List<MediaTimeNode> list = new List<MediaTimeNode>();
-			TreePath[] paths = Selection.GetSelectedRows();
-			for (int i=0; i<paths.Length; i++){	
-				list.Add((MediaTimeNode)GetValueFromPath(paths[i]));
-			}
-			// When a TimeNode is deleted from the tree the path changes.
-			// We need first to retrieve all the TimeNodes to delete using the 
-			// current path of each one and then send the TimeNodeDeleted event
-			for (int i=0; i<paths.Length; i++){	
-				TimeNodeDeleted(list[i], int.Parse(paths[i].ToString().Split(':')[0]));
-			}			
-		}
-		
-		protected void OnDeleteKeyFrame(object obj, EventArgs args) {
-			MessageDialog md = new MessageDialog((Gtk.Window)Toplevel,
-			                                     DialogFlags.Modal,
-			                                     MessageType.Question,
-			                                     ButtonsType.YesNo,
-			                                     false,
-			                                     Catalog.GetString("Do you want to delete the key frame for this play?")
-			                                    );
-			if (md.Run() == (int)ResponseType.Yes){
-				TreePath[] paths = Selection.GetSelectedRows();
-				for (int i=0; i<paths.Length; i++){	
-					MediaTimeNode tNode = (MediaTimeNode)GetValueFromPath(paths[i]);
-					tNode.KeyFrameDrawing = null;
-				}
-				// Refresh the thumbnails
-				QueueDraw();
-			}
-			md.Destroy();
-		}
-
-		protected virtual void OnEdit(object obj, EventArgs args) {
-			TreePath[] paths = Selection.GetSelectedRows();
-			editing = true;
-			nameCell.Editable = true;
-			nameCell.Markup = GetValueFromPath(paths[0]).Name;
-			SetCursor(paths[0],  nameColumn, true);
-		}
-
-		protected void OnTeamSelection(object obj, EventArgs args) {
-			MenuItem sender = (MenuItem)obj;
-			Team team = Team.NONE;
-			if (sender == local)
-				team = Team.LOCAL;
-			else if (sender == visitor)
-				team = Team.VISITOR;
-			else if (sender == noTeam)
-				team = Team.NONE;
-			
-			TreePath[] paths = Selection.GetSelectedRows();
-			for (int i=0; i<paths.Length; i++){	
-					MediaTimeNode tNode = (MediaTimeNode)GetValueFromPath(paths[i]);
-					tNode.Team = team;
-			}
-		}
-
-		protected void OnAdded(object obj, EventArgs args) {
-			if (PlayListNodeAdded != null){
-				TreePath[] paths = Selection.GetSelectedRows();
-				for (int i=0; i<paths.Length; i++){	
-					MediaTimeNode tNode = (MediaTimeNode)GetValueFromPath(paths[i]);
-					PlayListNodeAdded(tNode);
-				}
-			}
-		}
-		
-		protected void OnTag (object obj, EventArgs args){
-			if (TagPlay != null)
-				TagPlay((MediaTimeNode)GetValueFromPath(Selection.GetSelectedRows()[0]));
-		}
-
-		protected void OnSnapshot(object obj, EventArgs args) {
-			if (SnapshotSeriesEvent != null)
-				SnapshotSeriesEvent((MediaTimeNode)GetValueFromPath(Selection.GetSelectedRows()[0]));
-		}
-
-		protected virtual void OnLocalPlayers(object o, EventArgs args) {
-			if (PlayersTagged != null)
-				PlayersTagged((MediaTimeNode)GetValueFromPath(Selection.GetSelectedRows()[0]), Team.LOCAL);
-		}
-
-		protected virtual void OnVisitorPlayers(object o, EventArgs args) {
-			if (PlayersTagged != null)
-				PlayersTagged((MediaTimeNode)GetValueFromPath(Selection.GetSelectedRows()[0]), Team.VISITOR);
-		}
-		
 		protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
 		{
 			return false;
diff --git a/LongoMatch/Gui/TreeView/TagsTreeView.cs b/LongoMatch/Gui/TreeView/TagsTreeView.cs
index baea269..bbc67f7 100644
--- a/LongoMatch/Gui/TreeView/TagsTreeView.cs
+++ b/LongoMatch/Gui/TreeView/TagsTreeView.cs
@@ -18,12 +18,8 @@
 //
 //
 
-using System;
-using System.Collections.Generic;
 using Gdk;
 using Gtk;
-using Mono.Unix;
-using LongoMatch.Handlers;
 using LongoMatch.TimeNodes;
 
 namespace LongoMatch.Gui.Component
@@ -32,136 +28,16 @@ namespace LongoMatch.Gui.Component
 
 	[System.ComponentModel.Category("LongoMatch")]
 	[System.ComponentModel.ToolboxItem(true)]
-	public class TagsTreeView : Gtk.TreeView
+	public class TagsTreeView : ListTreeViewBase
 	{
 
-		public event TimeNodeChangedHandler TimeNodeChanged;
-		public event TimeNodeSelectedHandler TimeNodeSelected;
-		public event PlayListNodeAddedHandler PlayListNodeAdded;
-		public event SnapshotSeriesHandler SnapshotSeriesEvent;
-
-		private Menu menu;
-		private MenuItem addPLN;
-		private MenuItem name;
-		private MenuItem snapshot;
-		private MenuItem deleteKeyFrame;
-		
-		private Gtk.CellRendererText nameCell;
-		private Gtk.TreeViewColumn nameColumn;
-		private bool editing;
-		private bool projectIsLive;
-		
-
 		public TagsTreeView() {			
-			Selection.Mode = SelectionMode.Multiple;			
-			RowActivated += new RowActivatedHandler(OnTreeviewRowActivated);
-	
-			SetMenu();
-			PlayListLoaded = false;
-			ProjectIsLive = false;
-
-			nameColumn = new Gtk.TreeViewColumn();
-			nameColumn.Title = "Tag";
-			nameCell = new Gtk.CellRendererText();
-			nameCell.Edited += OnNameCellEdited;
-			Gtk.CellRendererPixbuf miniatureCell = new Gtk.CellRendererPixbuf();
-			nameColumn.PackStart(miniatureCell, true);
-			nameColumn.PackEnd(nameCell, true);
-
-			nameColumn.SetCellDataFunc(miniatureCell, new Gtk.TreeCellDataFunc(RenderMiniature));
-			nameColumn.SetCellDataFunc(nameCell, new Gtk.TreeCellDataFunc(RenderName));
-
-			AppendColumn(nameColumn);
-		}
-
-		public bool PlayListLoaded {
-			set {
-				addPLN.Sensitive = value;
-			}
-		}	
-		
-		public bool ProjectIsLive{
-			set{
-				projectIsLive = value;
-				addPLN.Visible = !projectIsLive;
-				snapshot.Visible = !projectIsLive;
-			}
+			tag.Visible = false;
+			players.Visible = false;
+			delete.Visible = false;
 		}
 
-		private void SetMenu() {
-			menu = new Menu();
-
-			name = new MenuItem(Catalog.GetString("Edit"));
-			deleteKeyFrame = new MenuItem(Catalog.GetString("Delete key frame"));
-			snapshot = new MenuItem(Catalog.GetString("Export to PGN images"));
-			addPLN = new MenuItem(Catalog.GetString("Add to playlist"));
-			addPLN.Sensitive=false;
-
-			menu.Append(name);
-			menu.Append(deleteKeyFrame);
-			menu.Append(addPLN);
-			menu.Append(snapshot);
-
-			name.Activated += new EventHandler(OnEdit);
-			deleteKeyFrame.Activated += OnDeleteKeyFrame;
-			addPLN.Activated += new EventHandler(OnAdded);
-			snapshot.Activated += new EventHandler(OnSnapshot);
-			menu.ShowAll();
-		}		
-
-		private MediaTimeNode GetValueFromPath(TreePath path){
-			Gtk.TreeIter iter;
-			Model.GetIter(out iter, path);
-			return Model.GetValue(iter,0) as MediaTimeNode;					
-		}	
-		
-		private void MultiSelectMenu (bool enabled){
-			name.Sensitive = !enabled;
-			snapshot.Sensitive = !enabled;
-		}
-		
-		private void RenderMiniature(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
-		{
-			MediaTimeNode tNode = model.GetValue(iter, 0) as MediaTimeNode;
-			(cell as Gtk.CellRendererPixbuf).Pixbuf = tNode.Miniature;
-		}
-
-		private void RenderName(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
-		{
-			MediaTimeNode tNode = (MediaTimeNode) model.GetValue(iter, 0);
-
-			//Handle special case in which we replace the text in the cell by the name of the TimeNode
-			//We need to check if we are editing and only change it for the path that's currently beeing edited
-
-			if (editing && Selection.IterIsSelected(iter))
-				(cell as Gtk.CellRendererText).Markup = tNode.Name;
-			else 
-				(cell as Gtk.CellRendererText).Markup = tNode.ToString();
-		}
-
-		private void OnNameCellEdited(object o, Gtk.EditedArgs args)
-		{
-			Gtk.TreeIter iter;
-			Model.GetIter(out iter, new Gtk.TreePath(args.Path));
-			MediaTimeNode tNode = Model.GetValue(iter,0) as MediaTimeNode;
-			tNode.Name = args.NewText;
-			editing = false;
-			nameCell.Editable=false;
-			if (TimeNodeChanged != null)
-				TimeNodeChanged(tNode,args.NewText);
-		}
-		
-		protected virtual void OnTreeviewRowActivated(object o, Gtk.RowActivatedArgs args)
-		{
-			Gtk.TreeIter iter;
-			Model.GetIter(out iter, args.Path);
-			MediaTimeNode tNode = Model.GetValue(iter, 0) as MediaTimeNode;
-
-			if (TimeNodeSelected != null && !projectIsLive)
-				TimeNodeSelected(tNode);
-		}
-
-		protected override bool OnButtonPressEvent(EventButton evnt)
+		override protected bool OnButtonPressEvent(EventButton evnt)
 		{			
 			TreePath[] paths = Selection.GetSelectedRows();
 			
@@ -176,7 +52,7 @@ namespace LongoMatch.Gui.Component
 				}
 				
 				if (paths.Length == 1) {
-					MediaTimeNode selectedTimeNode = GetValueFromPath(paths[0]);
+					MediaTimeNode selectedTimeNode = GetValueFromPath(paths[0]) as MediaTimeNode;
 					deleteKeyFrame.Sensitive = selectedTimeNode.KeyFrameDrawing != null;
 					MultiSelectMenu(false);
 					menu.Popup();
@@ -191,50 +67,11 @@ namespace LongoMatch.Gui.Component
 			return true;
 		}		
 		
-		protected void OnDeleteKeyFrame(object obj, EventArgs args) {
-			MessageDialog md = new MessageDialog((Gtk.Window)Toplevel,
-			                                     DialogFlags.Modal,
-			                                     MessageType.Question,
-			                                     ButtonsType.YesNo,
-			                                     false,
-			                                     Catalog.GetString("Do you want to delete the key frame for this play?")
-			                                    );
-			if (md.Run() == (int)ResponseType.Yes){
-				TreePath[] paths = Selection.GetSelectedRows();
-				for (int i=0; i<paths.Length; i++){	
-					MediaTimeNode tNode = GetValueFromPath(paths[i]);
-					tNode.KeyFrameDrawing = null;
-				}
-				// Refresh the thumbnails
-				QueueDraw();
-			}
-			md.Destroy();
-		}
-
-		protected virtual void OnEdit(object obj, EventArgs args) {
-			TreePath[] paths = Selection.GetSelectedRows();
-			editing = true;
-			nameCell.Editable = true;
-			nameCell.Markup = GetValueFromPath(paths[0]).Name;
-			SetCursor(paths[0],  nameColumn, true);
-		}
-		
-		protected void OnAdded(object obj, EventArgs args) {
-			if (PlayListNodeAdded != null){
-				TreePath[] paths = Selection.GetSelectedRows();
-				for (int i=0; i<paths.Length; i++){	
-					MediaTimeNode tNode = GetValueFromPath(paths[i]);
-					PlayListNodeAdded(tNode);
-				}
-			}
+		override protected bool SelectFunction(TreeSelection selection, TreeModel model, TreePath path, bool selected){
+			return true;
 		}
 		
-		protected void OnSnapshot(object obj, EventArgs args) {
-			if (SnapshotSeriesEvent != null)
-				SnapshotSeriesEvent(GetValueFromPath(Selection.GetSelectedRows()[0]));
-		}	
-		
-		protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
+		override protected bool OnKeyPressEvent (Gdk.EventKey evnt)
 		{
 			return false;
 		}
diff --git a/LongoMatch/LongoMatch.mdp b/LongoMatch/LongoMatch.mdp
index 351d1cb..4d7af62 100644
--- a/LongoMatch/LongoMatch.mdp
+++ b/LongoMatch/LongoMatch.mdp
@@ -184,6 +184,7 @@
     <File subtype="Code" buildaction="Compile" name="gtk-gui/LongoMatch.Gui.Dialog.ProjectSelectionDialog.cs" />
     <File subtype="Code" buildaction="Compile" name="gtk-gui/LongoMatch.Gui.Dialog.EndCaptureDialog.cs" />
     <File subtype="Code" buildaction="Compile" name="gtk-gui/LongoMatch.Gui.Dialog.BusyDialog.cs" />
+    <File subtype="Code" buildaction="Compile" name="Gui/TreeView/ListTreeViewBase.cs" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
diff --git a/LongoMatch/Makefile.am b/LongoMatch/Makefile.am
index f7d9561..27ff1f4 100644
--- a/LongoMatch/Makefile.am
+++ b/LongoMatch/Makefile.am
@@ -191,6 +191,7 @@ FILES = \
 	Gui/TreeView/CategoriesTreeView.cs \
 	Gui/TreeView/PlayerPropertiesTreeView.cs \
 	Gui/TreeView/PlayersTreeView.cs \
+	Gui/TreeView/ListTreeViewBase.cs \
 	Gui/TreeView/PlayListTreeView.cs \
 	Gui/TreeView/PlaysTreeView.cs \
 	Gui/TreeView/TagsTreeView.cs \



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