changeset 62:0e7c257ca8d6 WarFoundry_v0.1beta2_Winforms

Fixes #164: Show unit cost in army tree * Add points value in army tree for units, category and army (aggregating as it goes up the tree) * Add code to update tree node text as points values change * Remove references to now deprecated points-related properties Also: * Add rolling log file appender to logging config
author IBBoard <dev@ibboard.co.uk>
date Sat, 19 Sep 2009 19:44:45 +0000
parents a0ec03c24cd9
children 4db2c1086a85
files FrmArmyTree.cs FrmMain.cs FrmUnit.cs WarFoundry.exe.log4net
diffstat 4 files changed, 473 insertions(+), 443 deletions(-) [+]
line wrap: on
line diff
--- a/FrmArmyTree.cs	Sat Sep 19 16:01:43 2009 +0000
+++ b/FrmArmyTree.cs	Sat Sep 19 19:44:45 2009 +0000
@@ -1,431 +1,452 @@
-// This file (FrmArmyTree.cs) is a part of the IBBoard.WarFoundry.GUI.WinForms project and is copyright 2009 IBBoard.
-//
-// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.
-
-using System;
-using System.Drawing;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Windows.Forms;
+// This file (FrmArmyTree.cs) is a part of the IBBoard.WarFoundry.GUI.WinForms project and is copyright 2009 IBBoard.
+//
+// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.
+
+using System;
+using System.Drawing;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Windows.Forms;
 using IBBoard.Commands;
-using IBBoard.Windows.Forms.I18N;
-using IBBoard.Windows.Forms;
-using IBBoard.WarFoundry.API;
-using IBBoard.WarFoundry.API.Commands;
-using IBBoard.WarFoundry.API.Objects;
-
-namespace IBBoard.WarFoundry.GUI.WinForms
-{
-	/// <summary>
-	/// Summary description for FrmArmyTree.
-	/// </summary>
-	public class FrmArmyTree : IBBoard.Windows.Forms.IBBForm
-	{
-		private System.Windows.Forms.TreeView treeView;
-		private IContainer components;
-		private Dictionary<string, TreeNode> nodes;
-		private System.Windows.Forms.ContextMenu contextMenu;
-		private IBBMenuItem miDelete;
-		private IBBMenuItem miEdit;
-		
-		private ObjectAddDelegate UnitAddedMethod;
-		private ObjectRemoveDelegate UnitRemovedMethod;
-		private StringValChangedDelegate UnitNameChangedMethod, ArmyNameChangedMethod, TreeNameChangedMethod;
-		private ToolBar toolBar;
-		private IBBToolBarButton bttnEdit;
-		private IBBToolBarButton bttnDelete;
-		private ImageList imageList;
-		private CommandStack commandStack;
-
-		public FrmArmyTree(CommandStack cmdStack)
-		{
-			commandStack = cmdStack;
-			InitializeComponent();
-			UnitAddedMethod = new ObjectAddDelegate(UnitAdded);
-			UnitRemovedMethod = new ObjectRemoveDelegate(UnitRemoved);
-			UnitNameChangedMethod = new StringValChangedDelegate(UpdateUnitName);
-			ArmyNameChangedMethod = new StringValChangedDelegate(UpdateArmyName);
-			TreeNameChangedMethod = new StringValChangedDelegate(FrmArmyTree_TreeNameChanged);
-			nodes = new Dictionary<string, TreeNode>();
-			this.Name = "ArmyTree";			
-			WarFoundryCore.ArmyChanged+= new ArmyChangedDelegate(FrmArmyTree_ArmyChanged);
-
-			foreach (Control ctrl in Controls)
-			{
-				ControlTranslator.TranslateControl(ctrl);
-			}
-
-			foreach (Component comp in components.Components)
-			{
-				ControlTranslator.TranslateComponent(comp);
-			}
-
-			foreach (IBBMenuItem mi in contextMenu.MenuItems)
-			{
-				ControlTranslator.TranslateComponent(mi);
-			}
-		}
-
-		/// <summary>
-		/// Clean up any resources being used.
-		/// </summary>
-		protected override void Dispose( bool disposing )
-		{
-			if( disposing )
-			{
-				if(components != null)
-				{
-					components.Dispose();
-				}
-			}
-			base.Dispose( disposing );
-		}
-
-		#region Windows Form Designer generated code
-		/// <summary>
-		/// Required method for Designer support - do not modify
-		/// the contents of this method with the code editor.
-		/// </summary>
-		private void InitializeComponent()
-		{
-			this.components = new System.ComponentModel.Container();
-			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmArmyTree));
-			this.contextMenu = new System.Windows.Forms.ContextMenu();
-			this.miEdit = new IBBoard.Windows.Forms.IBBMenuItem();
-			this.miDelete = new IBBoard.Windows.Forms.IBBMenuItem();
-			this.imageList = new System.Windows.Forms.ImageList(this.components);
-			this.toolBar = new System.Windows.Forms.ToolBar();
-			this.bttnEdit = new IBBoard.Windows.Forms.IBBToolBarButton();
-			this.bttnDelete = new IBBoard.Windows.Forms.IBBToolBarButton();
-			this.treeView = new System.Windows.Forms.TreeView();
-			this.SuspendLayout();
-			// 
-			// contextMenu
-			// 
-			this.contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
-            this.miEdit,
-            this.miDelete});
-			this.contextMenu.Popup += new System.EventHandler(this.contextMenu_Popup);
-			// 
-			// miEdit
-			// 
-			this.miEdit.Index = 0;
-			this.miEdit.Text = "&edit unit";
-			this.miEdit.Click += new System.EventHandler(this.miEdit_Click);
-			// 
-			// miDelete
-			// 
-			this.miDelete.Index = 1;
-			this.miDelete.Text = "&delete unit";
-			this.miDelete.Click += new System.EventHandler(this.miDelete_Click);
-			// 
-			// imageList
-			// 
-			this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer) (resources.GetObject("imageList.ImageStream")));
-			this.imageList.TransparentColor = System.Drawing.Color.Transparent;
-			this.imageList.Images.SetKeyName(0, "gtk-edit.png");
-			this.imageList.Images.SetKeyName(1, "edit-delete.png");
-			// 
-			// toolBar
-			// 
-			this.toolBar.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
-            this.bttnEdit,
-            this.bttnDelete});
-			this.toolBar.ButtonSize = new System.Drawing.Size(16, 16);
-			this.toolBar.DropDownArrows = true;
-			this.toolBar.ImageList = this.imageList;
-			this.toolBar.Location = new System.Drawing.Point(0, 0);
-			this.toolBar.Name = "toolBar";
-			this.toolBar.ShowToolTips = true;
-			this.toolBar.Size = new System.Drawing.Size(240, 28);
-			this.toolBar.TabIndex = 3;
-			this.toolBar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
-			// 
-			// bttnEdit
-			// 
-			this.bttnEdit.Enabled = false;
-			this.bttnEdit.ImageIndex = 0;
-			this.bttnEdit.Name = "bttnEdit";
-			// 
-			// bttnDelete
-			// 
-			this.bttnDelete.Enabled = false;
-			this.bttnDelete.ImageIndex = 1;
-			this.bttnDelete.Name = "bttnDelete";
-			// 
-			// treeView
-			// 
-			this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-						| System.Windows.Forms.AnchorStyles.Left)
-						| System.Windows.Forms.AnchorStyles.Right)));
-			this.treeView.ContextMenu = this.contextMenu;
-			this.treeView.FullRowSelect = true;
-			this.treeView.Location = new System.Drawing.Point(0, 28);
-			this.treeView.Name = "treeView";
-			this.treeView.Size = new System.Drawing.Size(240, 250);
-			this.treeView.TabIndex = 0;
-			this.treeView.DoubleClick += new System.EventHandler(this.treeView_DoubleClick);
-			this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect);
-			this.treeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeView_MouseDown);
-			// 
-			// FrmArmyTree
-			// 
-			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
-			this.ClientSize = new System.Drawing.Size(240, 277);
-			this.ControlBox = false;
-			this.Controls.Add(this.toolBar);
-			this.Controls.Add(this.treeView);
-			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
-			this.MaximizeBox = false;
-			this.MinimizeBox = false;
-			this.Name = "FrmArmyTree";
-			this.Text = "FrmArmyTree";
-			this.ResumeLayout(false);
-			this.PerformLayout();
-
-		}
-		#endregion
-
-		private void ClearArmy()
-		{
-			nodes.Clear();
-			treeView.Nodes.Clear();
-		}
-
-		private void SetArmy(Army army)
-		{
-			ClearArmy();
-
-			if (army != null)
-			{
-				ArmyCategory[] cats = army.Categories;
-				TreeNode[] catNodes = new TreeNode[cats.Length];
-				Unit[] units;
-
-				for (int i = 0; i < cats.Length; i++)
-				{
-					units = army.GetUnits(cats[i]);
-					cats[i].NameChanged += TreeNameChangedMethod;
-					TreeNode[] unitNodes = new TreeNode[units.Length];
-					TreeNode temp;
-
-					for (int j = 0; j < units.Length; j++)
-					{
-						unitNodes[j] = CreateTreeNode(units[j]);
-					}
-
-					temp = new TreeNode(cats[i].Name, unitNodes);
-					temp.Tag = cats[i];
-					catNodes[i] = temp;
-					nodes[cats[i].ID] = temp;
+using IBBoard.Lang;
+using IBBoard.Windows.Forms.I18N;
+using IBBoard.Windows.Forms;
+using IBBoard.WarFoundry.API;
+using IBBoard.WarFoundry.API.Commands;
+using IBBoard.WarFoundry.API.Objects;
+
+namespace IBBoard.WarFoundry.GUI.WinForms
+{
+	/// <summary>
+	/// Summary description for FrmArmyTree.
+	/// </summary>
+	public class FrmArmyTree : IBBoard.Windows.Forms.IBBForm
+	{
+		private System.Windows.Forms.TreeView treeView;
+		private IContainer components;
+		private Dictionary<string, TreeNode> nodes;
+		private System.Windows.Forms.ContextMenu contextMenu;
+		private IBBMenuItem miDelete;
+		private IBBMenuItem miEdit;
+		
+		private ObjectAddDelegate UnitAddedMethod;
+		private ObjectRemoveDelegate UnitRemovedMethod;
+		private StringValChangedDelegate UnitNameChangedMethod, ArmyNameChangedMethod, TreeNameChangedMethod;
+		private ToolBar toolBar;
+		private IBBToolBarButton bttnEdit;
+		private IBBToolBarButton bttnDelete;
+		private ImageList imageList;
+		private CommandStack commandStack;
+
+		public FrmArmyTree(CommandStack cmdStack)
+		{
+			commandStack = cmdStack;
+			InitializeComponent();
+			UnitAddedMethod = new ObjectAddDelegate(UnitAdded);
+			UnitRemovedMethod = new ObjectRemoveDelegate(UnitRemoved);
+			UnitNameChangedMethod = new StringValChangedDelegate(UpdateUnitName);
+			ArmyNameChangedMethod = new StringValChangedDelegate(UpdateArmyName);
+			TreeNameChangedMethod = new StringValChangedDelegate(FrmArmyTree_TreeNameChanged);
+			nodes = new Dictionary<string, TreeNode>();
+			this.Name = "ArmyTree";			
+			WarFoundryCore.ArmyChanged+= new ArmyChangedDelegate(FrmArmyTree_ArmyChanged);
+
+			foreach (Control ctrl in Controls)
+			{
+				ControlTranslator.TranslateControl(ctrl);
+			}
+
+			foreach (Component comp in components.Components)
+			{
+				ControlTranslator.TranslateComponent(comp);
+			}
+
+			foreach (IBBMenuItem mi in contextMenu.MenuItems)
+			{
+				ControlTranslator.TranslateComponent(mi);
+			}
+		}
+
+		/// <summary>
+		/// Clean up any resources being used.
+		/// </summary>
+		protected override void Dispose( bool disposing )
+		{
+			if( disposing )
+			{
+				if(components != null)
+				{
+					components.Dispose();
+				}
+			}
+			base.Dispose( disposing );
+		}
+
+		#region Windows Form Designer generated code
+		/// <summary>
+		/// Required method for Designer support - do not modify
+		/// the contents of this method with the code editor.
+		/// </summary>
+		private void InitializeComponent()
+		{
+			this.components = new System.ComponentModel.Container();
+			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmArmyTree));
+			this.contextMenu = new System.Windows.Forms.ContextMenu();
+			this.miEdit = new IBBoard.Windows.Forms.IBBMenuItem();
+			this.miDelete = new IBBoard.Windows.Forms.IBBMenuItem();
+			this.imageList = new System.Windows.Forms.ImageList(this.components);
+			this.toolBar = new System.Windows.Forms.ToolBar();
+			this.bttnEdit = new IBBoard.Windows.Forms.IBBToolBarButton();
+			this.bttnDelete = new IBBoard.Windows.Forms.IBBToolBarButton();
+			this.treeView = new System.Windows.Forms.TreeView();
+			this.SuspendLayout();
+			// 
+			// contextMenu
+			// 
+			this.contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
+            this.miEdit,
+            this.miDelete});
+			this.contextMenu.Popup += new System.EventHandler(this.contextMenu_Popup);
+			// 
+			// miEdit
+			// 
+			this.miEdit.Index = 0;
+			this.miEdit.Text = "&edit unit";
+			this.miEdit.Click += new System.EventHandler(this.miEdit_Click);
+			// 
+			// miDelete
+			// 
+			this.miDelete.Index = 1;
+			this.miDelete.Text = "&delete unit";
+			this.miDelete.Click += new System.EventHandler(this.miDelete_Click);
+			// 
+			// imageList
+			// 
+			this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer) (resources.GetObject("imageList.ImageStream")));
+			this.imageList.TransparentColor = System.Drawing.Color.Transparent;
+			this.imageList.Images.SetKeyName(0, "gtk-edit.png");
+			this.imageList.Images.SetKeyName(1, "edit-delete.png");
+			// 
+			// toolBar
+			// 
+			this.toolBar.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
+            this.bttnEdit,
+            this.bttnDelete});
+			this.toolBar.ButtonSize = new System.Drawing.Size(16, 16);
+			this.toolBar.DropDownArrows = true;
+			this.toolBar.ImageList = this.imageList;
+			this.toolBar.Location = new System.Drawing.Point(0, 0);
+			this.toolBar.Name = "toolBar";
+			this.toolBar.ShowToolTips = true;
+			this.toolBar.Size = new System.Drawing.Size(240, 28);
+			this.toolBar.TabIndex = 3;
+			this.toolBar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
+			// 
+			// bttnEdit
+			// 
+			this.bttnEdit.Enabled = false;
+			this.bttnEdit.ImageIndex = 0;
+			this.bttnEdit.Name = "bttnEdit";
+			// 
+			// bttnDelete
+			// 
+			this.bttnDelete.Enabled = false;
+			this.bttnDelete.ImageIndex = 1;
+			this.bttnDelete.Name = "bttnDelete";
+			// 
+			// treeView
+			// 
+			this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+						| System.Windows.Forms.AnchorStyles.Left)
+						| System.Windows.Forms.AnchorStyles.Right)));
+			this.treeView.ContextMenu = this.contextMenu;
+			this.treeView.FullRowSelect = true;
+			this.treeView.Location = new System.Drawing.Point(0, 28);
+			this.treeView.Name = "treeView";
+			this.treeView.Size = new System.Drawing.Size(240, 250);
+			this.treeView.TabIndex = 0;
+			this.treeView.DoubleClick += new System.EventHandler(this.treeView_DoubleClick);
+			this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect);
+			this.treeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeView_MouseDown);
+			// 
+			// FrmArmyTree
+			// 
+			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
+			this.ClientSize = new System.Drawing.Size(240, 277);
+			this.ControlBox = false;
+			this.Controls.Add(this.toolBar);
+			this.Controls.Add(this.treeView);
+			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
+			this.MaximizeBox = false;
+			this.MinimizeBox = false;
+			this.Name = "FrmArmyTree";
+			this.Text = "FrmArmyTree";
+			this.ResumeLayout(false);
+			this.PerformLayout();
+
+		}
+		#endregion
+
+		private void ClearArmy()
+		{
+			nodes.Clear();
+			treeView.Nodes.Clear();
+		}
+
+		private void SetArmy(Army army)
+		{
+			ClearArmy();
+
+			if (army != null)
+			{
+				ArmyCategory[] cats = army.Categories;
+				TreeNode[] catNodes = new TreeNode[cats.Length];
+				Unit[] units;
+
+				for (int i = 0; i < cats.Length; i++)
+				{
+					ArmyCategory cat = cats[i];
+					units = army.GetUnits(cat);
+					cat.NameChanged += TreeNameChangedMethod;
+					cat.PointsValueChanged += NodePointsValueChanged;
+					TreeNode[] unitNodes = new TreeNode[units.Length];
+					TreeNode temp;
+
+					for (int j = 0; j < units.Length; j++)
+					{
+						unitNodes[j] = CreateTreeNode(units[j]);
+					}
+
+					temp = new TreeNode(CreateNodeName(cat), unitNodes);
+					temp.Tag = cat;
+					catNodes[i] = temp;
+					nodes[cat.ID] = temp;
 				}
 
-				TreeNode root = new TreeNode(army.Name, catNodes);
+				TreeNode root = new TreeNode(CreateNodeName(army), catNodes);
 				root.Tag = army;
-				treeView.Nodes.Add(root);
-				root.ExpandAll();
-			}
-		}
-
-		private TreeNode CreateTreeNode(Unit unit)
-		{
-			TreeNode temp = new TreeNode(unit.Name);
-			temp.Tag = unit;
-			unit.NameChanged+= UnitNameChangedMethod;
-			nodes[unit.ID] = temp;
-			return temp;
-		}
-
-		public void FrmArmyTree_ArmyChanged(Army oldArmy, Army newArmy)
-		{
-			if (oldArmy != null)
-			{
-				oldArmy.UnitAdded -= UnitAddedMethod;
-				oldArmy.UnitRemoved -= UnitRemovedMethod;
-			}
-
-			if (newArmy != null)
-			{
-				newArmy.UnitAdded += UnitAddedMethod;
-				newArmy.UnitRemoved += UnitRemovedMethod;
-			}
-
-			SetArmy(newArmy);
-		}
-
-		private void UnitAdded(WarFoundryObject obj)
-		{
-			if (obj is Unit)
-			{
-				Unit unit = (Unit)obj;
-				ArmyCategory cat = unit.Category;
-				TreeNode parent = nodes[cat.ID];
-				TreeNode unitNode = CreateTreeNode(unit);
-				parent.Nodes.Add(unitNode);
-				parent.Expand(); //make sure it's expanded
-			}
-		}
-
-		public new FrmMain MdiParent
+				army.PointsValueChanged += NodePointsValueChanged;
+				nodes[army.ID] = root;
+				treeView.Nodes.Add(root);
+				root.ExpandAll();
+			}
+		}
+		
+		private string CreateNodeName(ICostedWarFoundryObject obj)
+		{
+			return Translation.GetTranslation("treeNodeText", "{0} ({1}pts)", obj.Name, obj.Points);
+		}
+
+		private void NodePointsValueChanged(WarFoundryObject obj, double oldValue, double newValue)
 		{
-			get { return (FrmMain) base.MdiParent; }
-			set { base.MdiParent = value; }
-		}
-
-		private void UnitRemoved(WarFoundryObject obj)
-		{
-			if (obj is Unit)
-			{
-				Unit unit = (Unit)obj;
-				RemoveUnitFromTree(unit);
-			}
-		}
-
-		private void RemoveUnitFromTree(Unit unit)
-		{
-			TreeNode unitNode = nodes[unit.ID];
-			unit.NameChanged-= UnitNameChangedMethod;
-
-			if (unitNode!=null)
-			{
-				unitNode.Remove();
-				nodes.Remove(unit.ID);
-			}
-		}
-
-
-		private void contextMenu_Popup(object sender, System.EventArgs e)
-		{
-			TreeNode node = treeView.SelectedNode;
-
-			if (node!=null && node.Tag is Unit)
-			{
-				foreach(MenuItem item in contextMenu.MenuItems)
-				{
-					item.Visible = true;
-				}
-			}
-			else
-			{
-				foreach(MenuItem item in contextMenu.MenuItems)
-				{
-					item.Visible = false;
-				}
-			}
-		}
-
-		private void treeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
-		{
-			if (e.Button == MouseButtons.Right)
+			if (obj is ICostedWarFoundryObject)
 			{
-				TreeNode tn = treeView.GetNodeAt(e.X, e.Y);
-
-				if (tn!=null)
-				{
-					treeView.SelectedNode = tn;
-				}
-				else
-				{
-					treeView.SelectedNode = null;
-				}
-			}
-		}
-
-		private void miDelete_Click(object sender, System.EventArgs e)
-		{
-			DeleteUnit();
-		}
-
-		private void DeleteUnit()
-		{
-
-			TreeNode selected = treeView.SelectedNode;
-
-			if (selected.Tag != null && selected.Tag is Unit)
-			{
-				Unit unit = (Unit) selected.Tag;
-				commandStack.Execute(new RemoveUnitCommand(unit));
-			}
-		}
-
-		private void miEdit_Click(object sender, System.EventArgs e)
-		{	
-			EditUnit();
-		}
-
-		private void treeView_DoubleClick(object sender, System.EventArgs e)
-		{
-			EditUnit();			
-		}
-
-		private void EditUnit()
-		{
-			TreeNode selected = treeView.SelectedNode;
-			object tagData = selected.Tag;
-
-			if (tagData is Unit)
-			{
-				Unit unit = (Unit) tagData;
-				MdiParent.OpenUnitDialog(unit);
-			}
-		}
-
-		private void UpdateUnitName(WarFoundryObject obj, string oldValue, string newValue)
+				nodes[obj.ID].Text = CreateNodeName((ICostedWarFoundryObject)obj);
+			}
+		}
+
+		private TreeNode CreateTreeNode(Unit unit)
 		{
-			if (obj is Unit)
-			{
-				Unit unit = (Unit)obj;
-				TreeNode node = nodes[unit.ID];
-				
-				if (node!=null)
-				{
-					node.Text = unit.Name;
-				}
-			}
-		}
-
-		private void UpdateArmyName(WarFoundryObject obj, string oldValue, string newValue)
-		{
-			if (obj is Army)
-			{
-				Army army = (Army)obj;
-				TreeNode node = treeView.Nodes[0];
-				
-				if (node!=null)
-				{
-					node.Text = army.Name;
-				}
-			}
-		}
-
-		private void FrmArmyTree_TreeNameChanged(WarFoundryObject obj, string oldValue, string newValue)
-		{
-			TreeNode node = nodes[obj.ID];
-
-			if (node!=null)
-			{
-				node.Text = obj.Name;
-			}
-		}
-
-		private void toolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
-		{
-			if (e.Button == bttnDelete)
-			{
-				DeleteUnit();
-			}
-			else if (e.Button == bttnEdit)
-			{
-				EditUnit();
-			}
-		}
-
-		private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
-		{
-			TreeNode node = treeView.SelectedNode;
-
-			bttnDelete.Enabled = (node != null && node.Tag is Unit);
-			bttnEdit.Enabled = bttnDelete.Enabled;
-		}
-	}
-}
+			TreeNode temp = new TreeNode(CreateNodeName(unit));
+			temp.Tag = unit;
+			unit.NameChanged+= UnitNameChangedMethod;
+			unit.PointsValueChanged += NodePointsValueChanged;
+			nodes[unit.ID] = temp;
+			return temp;
+		}
+
+		public void FrmArmyTree_ArmyChanged(Army oldArmy, Army newArmy)
+		{
+			if (oldArmy != null)
+			{
+				oldArmy.UnitAdded -= UnitAddedMethod;
+				oldArmy.UnitRemoved -= UnitRemovedMethod;
+				oldArmy.PointsValueChanged -= NodePointsValueChanged;
+			}
+
+			if (newArmy != null)
+			{
+				newArmy.UnitAdded += UnitAddedMethod;
+				newArmy.UnitRemoved += UnitRemovedMethod;
+				newArmy.PointsValueChanged += NodePointsValueChanged;
+			}
+
+			SetArmy(newArmy);
+		}
+
+		private void UnitAdded(WarFoundryObject obj)
+		{
+			if (obj is Unit)
+			{
+				Unit unit = (Unit)obj;
+				ArmyCategory cat = unit.Category;
+				TreeNode parent = nodes[cat.ID];
+				TreeNode unitNode = CreateTreeNode(unit);
+				parent.Nodes.Add(unitNode);
+				parent.Expand(); //make sure it's expanded
+			}
+		}
+
+		public new FrmMain MdiParent
+		{
+			get { return (FrmMain) base.MdiParent; }
+			set { base.MdiParent = value; }
+		}
+
+		private void UnitRemoved(WarFoundryObject obj)
+		{
+			if (obj is Unit)
+			{
+				Unit unit = (Unit)obj;
+				RemoveUnitFromTree(unit);
+			}
+		}
+
+		private void RemoveUnitFromTree(Unit unit)
+		{
+			TreeNode unitNode = nodes[unit.ID];
+			unit.NameChanged-= UnitNameChangedMethod;
+
+			if (unitNode!=null)
+			{
+				unitNode.Remove();
+				nodes.Remove(unit.ID);
+			}
+		}
+
+
+		private void contextMenu_Popup(object sender, System.EventArgs e)
+		{
+			TreeNode node = treeView.SelectedNode;
+
+			if (node!=null && node.Tag is Unit)
+			{
+				foreach(MenuItem item in contextMenu.MenuItems)
+				{
+					item.Visible = true;
+				}
+			}
+			else
+			{
+				foreach(MenuItem item in contextMenu.MenuItems)
+				{
+					item.Visible = false;
+				}
+			}
+		}
+
+		private void treeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
+		{
+			if (e.Button == MouseButtons.Right)
+			{
+				TreeNode tn = treeView.GetNodeAt(e.X, e.Y);
+
+				if (tn!=null)
+				{
+					treeView.SelectedNode = tn;
+				}
+				else
+				{
+					treeView.SelectedNode = null;
+				}
+			}
+		}
+
+		private void miDelete_Click(object sender, System.EventArgs e)
+		{
+			DeleteUnit();
+		}
+
+		private void DeleteUnit()
+		{
+
+			TreeNode selected = treeView.SelectedNode;
+
+			if (selected.Tag != null && selected.Tag is Unit)
+			{
+				Unit unit = (Unit) selected.Tag;
+				commandStack.Execute(new RemoveUnitCommand(unit));
+			}
+		}
+
+		private void miEdit_Click(object sender, System.EventArgs e)
+		{	
+			EditUnit();
+		}
+
+		private void treeView_DoubleClick(object sender, System.EventArgs e)
+		{
+			EditUnit();			
+		}
+
+		private void EditUnit()
+		{
+			TreeNode selected = treeView.SelectedNode;
+			object tagData = selected.Tag;
+
+			if (tagData is Unit)
+			{
+				Unit unit = (Unit) tagData;
+				MdiParent.OpenUnitDialog(unit);
+			}
+		}
+
+		private void UpdateUnitName(WarFoundryObject obj, string oldValue, string newValue)
+		{
+			if (obj is Unit)
+			{
+				Unit unit = (Unit)obj;
+				TreeNode node = nodes[unit.ID];
+				
+				if (node!=null)
+				{
+					node.Text = unit.Name;
+				}
+			}
+		}
+
+		private void UpdateArmyName(WarFoundryObject obj, string oldValue, string newValue)
+		{
+			if (obj is Army)
+			{
+				Army army = (Army)obj;
+				TreeNode node = treeView.Nodes[0];
+				
+				if (node!=null)
+				{
+					node.Text = army.Name;
+				}
+			}
+		}
+
+		private void FrmArmyTree_TreeNameChanged(WarFoundryObject obj, string oldValue, string newValue)
+		{
+			TreeNode node = nodes[obj.ID];
+
+			if (node!=null)
+			{
+				node.Text = obj.Name;
+			}
+		}
+
+		private void toolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
+		{
+			if (e.Button == bttnDelete)
+			{
+				DeleteUnit();
+			}
+			else if (e.Button == bttnEdit)
+			{
+				EditUnit();
+			}
+		}
+
+		private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
+		{
+			TreeNode node = treeView.SelectedNode;
+
+			bttnDelete.Enabled = (node != null && node.Tag is Unit);
+			bttnEdit.Enabled = bttnDelete.Enabled;
+		}
+	}
+}
--- a/FrmMain.cs	Sat Sep 19 16:01:43 2009 +0000
+++ b/FrmMain.cs	Sat Sep 19 19:44:45 2009 +0000
@@ -1160,9 +1160,9 @@
 			}
 			else 
 			{
-				sbPointsPanel.Text = String.Format(Translation.GetTranslation("statusPanelPoints"), CurrentArmy.PointsTotal, CurrentArmy.MaxPoints);
+				sbPointsPanel.Text = String.Format(Translation.GetTranslation("statusPanelPoints"), CurrentArmy.Points, CurrentArmy.MaxPoints);
 
-				if (CurrentArmy.PointsTotal>CurrentArmy.MaxPoints)
+				if (CurrentArmy.Points>CurrentArmy.MaxPoints)
 				{
 					sbPointsPanel.Color = Color.Red;
 				}
--- a/FrmUnit.cs	Sat Sep 19 16:01:43 2009 +0000
+++ b/FrmUnit.cs	Sat Sep 19 19:44:45 2009 +0000
@@ -84,7 +84,7 @@
 
 		private void SetPointsValueText()
 		{
-			lblPoints.Text = "(" + unit.PointsValue + " pts)";
+			lblPoints.Text = "(" + unit.Points + " pts)";
 		}
 
 		private void SetStats()
--- a/WarFoundry.exe.log4net	Sat Sep 19 16:01:43 2009 +0000
+++ b/WarFoundry.exe.log4net	Sat Sep 19 19:44:45 2009 +0000
@@ -1,16 +1,25 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- This section contains the log4net configuration settings -->
-<log4net>
-    <!-- Define some output appenders -->	
-    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
-        <layout type="log4net.Layout.PatternLayout">
-            <param name="ConversionPattern" value="%-5p [%d{HH:MM:ss}]: %C{1}.%M() - Line: %L - %m%n" />
-        </layout>
-    </appender>
-    <!-- Setup the root category, add the appenders and set the default priority -->
-    <root>
-        <level value="DEBUG" />
-        <appender-ref ref="ConsoleAppender" />
-    </root>
-</log4net>
-
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- This section contains the log4net configuration settings -->
+<log4net>
+	<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
+		<layout type="log4net.Layout.PatternLayout">
+			<param name="ConversionPattern" value="%-5p [%d{HH:MM:ss}]: %C{1}.%M() - Line: %L - %m%n" />
+		</layout>
+	</appender>
+	<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
+		<file value="logfile.txt" />
+		<appendToFile value="false" />
+		<rollingStyle value="Size" />
+		<maxSizeRollBackups value="-1" />
+		<maximumFileSize value="100MB" />
+		<layout type="log4net.Layout.PatternLayout">
+			<conversionPattern value="%-5p [%d{HH:MM:ss}]: %C{1}.%M() - Line: %L - %m%n" />
+		</layout>
+	</appender>
+	<root>
+		<level value="DEBUG" />
+		<appender-ref ref="ConsoleAppender" />
+		<appender-ref ref="RollingLogFileAppender" />
+	</root>
+</log4net>
+