view FrmArmyTree.cs @ 66:68d4f7499212

Re #176: Bug when saving recently edited army * Make save button available whether army has previously been saved or not (partly for usability and partly to try to trigger bug) Bug seems to occur when opening an army as the first action, adding a unit and saving it, but not when creating a new army as the first action, then loading an old army as the second action, then adding a unit and saving it
author IBBoard <dev@ibboard.co.uk>
date Sat, 26 Sep 2009 09:51:53 +0000
parents 4db2c1086a85
children e3488dd61a21
line wrap: on
line source

// 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.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(CreateNodeName(army), catNodes);
				root.Tag = army;
				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)
		{
			if (obj is ICostedWarFoundryObject)
			{
				nodes[obj.ID].Text = CreateNodeName((ICostedWarFoundryObject)obj);
			}
		}

		private TreeNode CreateTreeNode(Unit unit)
		{
			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;
		}
	}
}