changeset 69:3b4a646b4054

Re #60: Add UI to add/remove/edit weapons in GTK * Fix errors in replace dialog (move UI setup to just before we show) Also: * Fix missing refresh of army tree on equipment/points value change
author IBBoard <dev@ibboard.co.uk>
date Sat, 06 Nov 2010 11:44:26 +0000
parents 7028e24b67ec
children 4b82515586ac
files FrmMainWindow.cs UIControl/AbstractBaseEquipmentUIControl.cs UIControl/ReplaceEquipmentUIControl.cs gtk-gui/IBBoard.WarFoundry.GTK.Widgets.UnitDisplayWidget.cs gtk-gui/IBBoard.WarFoundry.GUI.GTK.FrmAddEquipment.cs gtk-gui/IBBoard.WarFoundry.GUI.GTK.FrmEditEquipment.cs
diffstat 6 files changed, 151 insertions(+), 154 deletions(-) [+]
line diff
     1.1 --- a/FrmMainWindow.cs	Wed Nov 03 21:02:54 2010 +0000
     1.2 +++ b/FrmMainWindow.cs	Sat Nov 06 11:44:26 2010 +0000
     1.3 @@ -35,23 +35,18 @@
     1.4  	{
     1.5  		private static readonly string AppTitle = "WarFoundry";
     1.6  		private const int CATEGORY_BUTTON_SEPARATOR_INDEX = 6;
     1.7 -
     1.8  		private Preferences preferences;
     1.9  		private ILog logger = LogManager.GetLogger(typeof(FrmMainWindow));
    1.10 -
    1.11  		private CommandStack commandStack;
    1.12  		private Dictionary<ToolButton, Category> categoryMap = new Dictionary<ToolButton, Category>();
    1.13  		private Dictionary<WFObjects.Unit, UnitDisplayWidget> unitToWidgetMap = new Dictionary<WFObjects.Unit,UnitDisplayWidget>();
    1.14 -
    1.15  		private ObjectAddDelegate UnitAddedMethod;
    1.16  		private ObjectRemoveDelegate UnitRemovedMethod;
    1.17  		private DoubleValChangedDelegate PointsValueChangedMethod;
    1.18  		private FailedUnitRequirementDelegate FailedUnitRequirementMethod;
    1.19  		private StringValChangedDelegate UnitNameChangedMethod;
    1.20 -
    1.21  		private GameSystem system;
    1.22  		private string loadedArmyPath;
    1.23 -
    1.24  		private MenuToolButton undoMenuButton, redoMenuButton;
    1.25  
    1.26  		public static void Main(string[] args)
    1.27 @@ -65,7 +60,7 @@
    1.28  				Application.Run();
    1.29  				LogManager.GetLogger(typeof(FrmMainWindow)).Debug("Application ended");
    1.30  			}
    1.31 -			catch(Exception ex)
    1.32 +			catch (Exception ex)
    1.33  			{
    1.34  				HandleUnhandledException(ex);
    1.35  			}
    1.36 @@ -82,7 +77,7 @@
    1.37  			}
    1.38  			else
    1.39  			{
    1.40 -				ex = new Exception("GLib returned unexpected exception object type "+obj.GetType());
    1.41 +				ex = new Exception("GLib returned unexpected exception object type " + obj.GetType());
    1.42  			}
    1.43  			
    1.44  			HandleUnhandledException(ex);
    1.45 @@ -104,7 +99,7 @@
    1.46  			
    1.47  			if (ex != null)
    1.48  			{
    1.49 -				message  = "Caused by: " + ex.GetType().FullName + Environment.NewLine + ex.StackTrace + Environment.NewLine ;
    1.50 +				message = "Caused by: " + ex.GetType().FullName + Environment.NewLine + ex.StackTrace + Environment.NewLine ;
    1.51  			}
    1.52  			
    1.53  			return message;
    1.54 @@ -130,15 +125,15 @@
    1.55  			undoMenuButton.TooltipText = "Undo";
    1.56  			undoMenuButton.Clicked += undoTBButtonActivated;
    1.57  			toolbar.Insert(undoMenuButton, CATEGORY_BUTTON_SEPARATOR_INDEX);
    1.58 -			toolbar.Remove(toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX-1]);
    1.59 -			toolbar.Remove(toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX-2]);
    1.60 +			toolbar.Remove(toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX - 1]);
    1.61 +			toolbar.Remove(toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX - 2]);
    1.62  			toolbar.ShowAll();
    1.63  
    1.64  			Title = AppTitle;
    1.65 -			TreeViewColumn mainColumn = new TreeViewColumn ();
    1.66 +			TreeViewColumn mainColumn = new TreeViewColumn();
    1.67  			mainColumn.Title = "Army Categories";
    1.68 -			CellRendererText mainCell = new CellRendererText ();
    1.69 -			mainColumn.PackStart (mainCell, true);
    1.70 +			CellRendererText mainCell = new CellRendererText();
    1.71 +			mainColumn.PackStart(mainCell, true);
    1.72  			treeUnits.AppendColumn(mainColumn);
    1.73  			mainColumn.SetCellDataFunc(mainCell, new TreeCellDataFunc(RenderCategoryTreeObjectName));
    1.74  			treeUnits.Model = new TreeStore(typeof(WarFoundryObject));
    1.75 @@ -161,10 +156,10 @@
    1.76  
    1.77  			logger.Debug("Initialising");
    1.78  			commandStack = new CommandStack();
    1.79 -			commandStack.CommandStackUpdated+=new MethodInvoker(commandStack_CommandStackUpdated);
    1.80 -			WarFoundryCore.GameSystemChanged+= new GameSystemChangedDelegate(OnGameSystemChanged);
    1.81 -			WarFoundryCore.ArmyChanged+= new ArmyChangedDelegate(OnArmyChanged);
    1.82 -			Destroyed+= new EventHandler(OnWindowDestroyed);
    1.83 +			commandStack.CommandStackUpdated += new MethodInvoker(commandStack_CommandStackUpdated);
    1.84 +			WarFoundryCore.GameSystemChanged += new GameSystemChangedDelegate(OnGameSystemChanged);
    1.85 +			WarFoundryCore.ArmyChanged += new ArmyChangedDelegate(OnArmyChanged);
    1.86 +			Destroyed += new EventHandler(OnWindowDestroyed);
    1.87  			//TODO: Translate and subscribe to other events
    1.88  			UnitAddedMethod = new ObjectAddDelegate(OnUnitAdded);
    1.89  			UnitRemovedMethod = new ObjectRemoveDelegate(OnUnitRemoved);
    1.90 @@ -201,10 +196,14 @@
    1.91  							WarFoundryCore.CurrentArmy = (Army)loadedObject;
    1.92  							logger.InfoFormat("Loaded army from {0}", file.FullName);
    1.93  						}
    1.94 -						else if (loadedObject is GameSystem)
    1.95 +						else
    1.96  						{
    1.97 -							WarFoundryCore.CurrentGameSystem = (GameSystem)loadedObject;
    1.98 -							logger.InfoFormat("Loaded game system from {0}", file.FullName);
    1.99 +							if (loadedObject is GameSystem)
   1.100 +							{
   1.101 +								WarFoundryCore.CurrentGameSystem = (GameSystem)loadedObject;
   1.102 +								logger.InfoFormat("Loaded game system from {0}", file.FullName);
   1.103 +							}
   1.104 +
   1.105  						}
   1.106  					}
   1.107  				}
   1.108 @@ -218,12 +217,12 @@
   1.109  			{
   1.110  				string gameSystemID = Preferences.GetStringProperty("currSystem");
   1.111  
   1.112 -				if (gameSystemID!=null && !"".Equals(gameSystemID))
   1.113 +				if (gameSystemID != null && !"".Equals(gameSystemID))
   1.114  				{
   1.115  					logger.Debug("Attempting to load current game system from properties");
   1.116  					GameSystem sys = WarFoundryLoader.GetDefault().GetGameSystem(gameSystemID);
   1.117  
   1.118 -					if (sys!=null)
   1.119 +					if (sys != null)
   1.120  					{
   1.121  						WarFoundryCore.CurrentGameSystem = sys;
   1.122  						logger.InfoFormat("Loaded game system {0} from properties", gameSystemID);
   1.123 @@ -232,9 +231,9 @@
   1.124  			}
   1.125  		}
   1.126  
   1.127 -		private void FileLoadingFinished (List<FileLoadFailure> failures)
   1.128 +		private void FileLoadingFinished(List<FileLoadFailure> failures)
   1.129  		{
   1.130 -			foreach(FileLoadFailure failure in failures)
   1.131 +			foreach (FileLoadFailure failure in failures)
   1.132  			{
   1.133  				logger.Warn("Failed to load " + failure.FailedFile.FullName + ": " + failure.Message);
   1.134  			}
   1.135 @@ -260,11 +259,15 @@
   1.136  
   1.137  				(cell as CellRendererText).Text = name;
   1.138  			}
   1.139 -			else if (o is WFObjects.Unit)
   1.140 +			else
   1.141  			{
   1.142 -				WFObjects.Unit u = (WFObjects.Unit)o;
   1.143 -				string name = Translation.GetTranslation("unitTreeCatName", "{0} - {1}pts", u.Name, u.Points);
   1.144 -				(cell as CellRendererText).Text = name;
   1.145 +				if (o is WFObjects.Unit)
   1.146 +				{
   1.147 +					WFObjects.Unit u = (WFObjects.Unit)o;
   1.148 +					string name = Translation.GetTranslation("unitTreeCatName", "{0} - {1}pts", u.Name, u.Points);
   1.149 +					(cell as CellRendererText).Text = name;
   1.150 +				}
   1.151 +
   1.152  			}
   1.153  		}
   1.154  
   1.155 @@ -277,24 +280,31 @@
   1.156  		private void OnUnitNameChanged(WarFoundryObject val, string oldValue, string newValue)
   1.157  		{
   1.158  			WFObjects.Unit unit = (WFObjects.Unit)val;
   1.159 +			logger.DebugFormat("Unit name changed for {0} - now called {1}", unit.ID, unit.Name);
   1.160  			UnitDisplayWidget widget;
   1.161  			unitToWidgetMap.TryGetValue(unit, out widget);
   1.162 -			logger.DebugFormat("Unit name changed for {0} - now called {1}", unit.ID, unit.Name);
   1.163 +			
   1.164 +			if (widget != null)
   1.165 +			{
   1.166 +				unitsNotebook.SetTabLabel(widget, NotebookUtil.CreateNotebookTabLabelWithClose(unitsNotebook, widget, unit.Name));
   1.167 +			}
   1.168 +			
   1.169  			treeUnits.QueueDraw();
   1.170 -
   1.171 -			if (widget!=null)
   1.172 -			{
   1.173 -				unitsNotebook.SetTabLabel(widget, NotebookUtil.CreateNotebookTabLabelWithClose(unitsNotebook, widget, newValue));
   1.174 -			}
   1.175  		}
   1.176  
   1.177  		private void OnUnitAdded(WarFoundryObject val)
   1.178  		{
   1.179  			WFObjects.Unit unit = (WFObjects.Unit)val;
   1.180 -			unit.NameChanged+= UnitNameChangedMethod;
   1.181 +			unit.NameChanged += UnitNameChangedMethod;
   1.182 +			unit.PointsValueChanged += HandleUnitPointsValueChanged;
   1.183  			AddUnitToTree(unit);
   1.184  		}
   1.185  
   1.186 +		private void HandleUnitPointsValueChanged(WarFoundryObject obj, double oldValue, double newValue)
   1.187 +		{			
   1.188 +			treeUnits.QueueDraw();
   1.189 +		}
   1.190 +
   1.191  		private void AddUnitToTree(WFObjects.Unit unit)
   1.192  		{
   1.193  			TreeStore model = (TreeStore)treeUnits.Model;
   1.194 @@ -323,7 +333,7 @@
   1.195  		private void OnUnitRemoved(WarFoundryObject obj)
   1.196  		{
   1.197  			WFObjects.Unit unit = (WFObjects.Unit)obj;
   1.198 -			unit.NameChanged-= UnitNameChangedMethod;
   1.199 +			unit.NameChanged -= UnitNameChangedMethod;
   1.200  			RemoveUnitFromTree(unit);
   1.201  			RemoveUnitTab(unit);
   1.202  		}
   1.203 @@ -402,9 +412,9 @@
   1.204  			get { return WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(Constants.ExecutablePath, factoryType); }
   1.205  		}*/
   1.206  
   1.207 -		protected void OnDeleteEvent (object sender, DeleteEventArgs a)
   1.208 +		protected void OnDeleteEvent(object sender, DeleteEventArgs a)
   1.209  		{
   1.210 -			Application.Quit ();
   1.211 +			Application.Quit();
   1.212  			a.RetVal = true;
   1.213  		}
   1.214  
   1.215 @@ -476,17 +486,21 @@
   1.216  
   1.217  		private void SetAppTitle()
   1.218  		{
   1.219 -			if (WarFoundryCore.CurrentArmy!=null)
   1.220 +			if (WarFoundryCore.CurrentArmy != null)
   1.221  			{
   1.222  				Title = AppTitle + " - " + WarFoundryCore.CurrentGameSystem.Name + " - " + WarFoundryCore.CurrentArmy.Name;
   1.223  			}
   1.224 -			else if (WarFoundryCore.CurrentGameSystem!=null)
   1.225 -			{
   1.226 -				Title = AppTitle + " - " + WarFoundryCore.CurrentGameSystem.Name;
   1.227 -			}
   1.228  			else
   1.229  			{
   1.230 -				Title = AppTitle;
   1.231 +				if (WarFoundryCore.CurrentGameSystem != null)
   1.232 +				{
   1.233 +					Title = AppTitle + " - " + WarFoundryCore.CurrentGameSystem.Name;
   1.234 +				}
   1.235 +				else
   1.236 +				{
   1.237 +					Title = AppTitle;
   1.238 +				}
   1.239 +
   1.240  			}
   1.241  		}
   1.242  
   1.243 @@ -496,7 +510,7 @@
   1.244  			SetAppTitle();
   1.245  			RemoveCategoryButtons();
   1.246  
   1.247 -			if (system!=null)
   1.248 +			if (system != null)
   1.249  			{
   1.250  				AddCategoryButtons(system.Categories);
   1.251  			}
   1.252 @@ -564,7 +578,7 @@
   1.253  			store.Clear();
   1.254  			TreeIter iter;
   1.255  
   1.256 -			if (army!=null)
   1.257 +			if (army != null)
   1.258  			{
   1.259  				logger.Debug("Loading in categories to tree");
   1.260  
   1.261 @@ -596,7 +610,7 @@
   1.262  		private void SetCategoryButtonsSensitive(bool state)
   1.263  		{
   1.264  			int toolbarButtonCount = toolbar.Children.Length - 1;
   1.265 -			logger.Debug("Last button index: "+toolbarButtonCount);
   1.266 +			logger.Debug("Last button index: " + toolbarButtonCount);
   1.267  
   1.268  			for (int i = toolbarButtonCount; i > CATEGORY_BUTTON_SEPARATOR_INDEX; i--)
   1.269  			{
   1.270 @@ -619,7 +633,7 @@
   1.271  
   1.272  		private void AddCategoryButtons(Category[] cats)
   1.273  		{
   1.274 -			if (cats!=null && cats.Length > 0)
   1.275 +			if (cats != null && cats.Length > 0)
   1.276  			{
   1.277  				logger.DebugFormat("Toolbar button count: {0}. Adding {1} categories.", toolbar.Children.Length, cats.Length);
   1.278  
   1.279 @@ -627,15 +641,15 @@
   1.280  				{
   1.281  					ToolButton button = new ToolButton("gtk-add");
   1.282  					button.Label = cat.Name;
   1.283 -					button.TooltipText = "Add unit from "+cat.Name;
   1.284 +					button.TooltipText = "Add unit from " + cat.Name;
   1.285  					//TODO: See if we can associate data in some way, the same as we can with SWF. For now we just use the map.
   1.286  					categoryMap.Add(button, cat);
   1.287 -					button.Clicked+= new System.EventHandler(OnAddUnitActivated);
   1.288 +					button.Clicked += new System.EventHandler(OnAddUnitActivated);
   1.289  					toolbar.Insert(button, -1);
   1.290  				}
   1.291  			}
   1.292  
   1.293 -			toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX].Visible = cats!=null && cats.Length>0;
   1.294 +			toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX].Visible = cats != null && cats.Length > 0;
   1.295  
   1.296  			toolbar.ShowAll();
   1.297  		}
   1.298 @@ -825,7 +839,7 @@
   1.299  		{
   1.300  			bool success = false;
   1.301  
   1.302 -			if (loadedArmyPath!=null)
   1.303 +			if (loadedArmyPath != null)
   1.304  			{
   1.305  				success = SaveArmyToPath(WarFoundryCore.CurrentArmy, loadedArmyPath);
   1.306  			}
   1.307 @@ -858,7 +872,7 @@
   1.308  		{
   1.309  			bool success = false;
   1.310  			
   1.311 -			if (filePath!=null)
   1.312 +			if (filePath != null)
   1.313  			{
   1.314  				if (WarFoundrySaver.GetSaver().Save(WarFoundryCore.CurrentArmy, filePath))
   1.315  				{
   1.316 @@ -870,7 +884,7 @@
   1.317  				}
   1.318  				else
   1.319  				{
   1.320 -					MessageDialog dialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, "Failed to save file to "+filePath);
   1.321 +					MessageDialog dialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, "Failed to save file to " + filePath);
   1.322  					dialog.Title = "Army save failed";
   1.323  					dialog.Run();
   1.324  					dialog.Hide();
   1.325 @@ -902,15 +916,19 @@
   1.326  						//If they cancel the save as then assume they don't want to close
   1.327  						canClose = SaveCurrentArmyOrSaveAs();
   1.328  					}
   1.329 -					else if (dr == ResponseType.No)
   1.330 -					{
   1.331 -						//They don't care about their changes
   1.332 -						canClose = true;
   1.333 -					}
   1.334  					else
   1.335  					{
   1.336 +						if (dr == ResponseType.No)
   1.337 +						{
   1.338 +						//They don't care about their changes
   1.339 +							canClose = true;
   1.340 +						}
   1.341 +						else
   1.342 +						{
   1.343  						//Assume cancel or close with the X button
   1.344 -						canClose = false;
   1.345 +							canClose = false;
   1.346 +						}
   1.347 +
   1.348  					}
   1.349  				}
   1.350  				else
   1.351 @@ -959,27 +977,27 @@
   1.352  			newArmy.Destroy();
   1.353  		}
   1.354  
   1.355 -		protected virtual void undoTBButtonActivated (object sender, System.EventArgs e)
   1.356 +		protected virtual void undoTBButtonActivated(object sender, System.EventArgs e)
   1.357  		{
   1.358  			CommandStack.Undo();
   1.359  		}
   1.360  
   1.361 -		protected virtual void redoTBButtonActivated (object sender, System.EventArgs e)
   1.362 +		protected virtual void redoTBButtonActivated(object sender, System.EventArgs e)
   1.363  		{
   1.364  			CommandStack.Redo();
   1.365  		}
   1.366  
   1.367 -		protected virtual void saveTBButtonActivated (object sender, System.EventArgs e)
   1.368 +		protected virtual void saveTBButtonActivated(object sender, System.EventArgs e)
   1.369  		{
   1.370  			SaveCurrentArmyOrSaveAs();
   1.371  		}
   1.372  
   1.373 -		protected virtual void openTBButtonActivated (object sender, System.EventArgs e)
   1.374 +		protected virtual void openTBButtonActivated(object sender, System.EventArgs e)
   1.375  		{
   1.376  			OpenArmy();
   1.377  		}
   1.378  
   1.379 -		protected virtual void newTBButtonActivated (object sender, System.EventArgs e)
   1.380 +		protected virtual void newTBButtonActivated(object sender, System.EventArgs e)
   1.381  		{
   1.382  			CreateNewArmy();
   1.383  		}
   1.384 @@ -1018,7 +1036,7 @@
   1.385  			}
   1.386  		}
   1.387  
   1.388 -		protected virtual void OnMiExportAsBasicHtmlActivated (object sender, System.EventArgs e)
   1.389 +		protected virtual void OnMiExportAsBasicHtmlActivated(object sender, System.EventArgs e)
   1.390  		{
   1.391  			FileChooserDialog fileDialog = new FileChooserDialog("Export army", this, FileChooserAction.Save, "Cancel", ResponseType.Cancel, "Export", ResponseType.Accept);
   1.392  			FileFilter filter = new FileFilter();
   1.393 @@ -1044,7 +1062,7 @@
   1.394  			}
   1.395  		}
   1.396  
   1.397 -		protected virtual void OnTreeUnitsPopupMenu (object o, Gtk.PopupMenuArgs args)
   1.398 +		protected virtual void OnTreeUnitsPopupMenu(object o, Gtk.PopupMenuArgs args)
   1.399  		{
   1.400  			object selectedItem = TreeUtils.GetSelectedItem(treeUnits);
   1.401  
   1.402 @@ -1053,7 +1071,7 @@
   1.403  				Menu menu = new Menu();
   1.404  				ImageMenuItem delete = new ImageMenuItem("Remove unit");
   1.405  				delete.Image = new Gtk.Image(Stock.Delete, IconSize.Menu);
   1.406 -				delete.Activated+= new EventHandler(OnUnitDelete);
   1.407 +				delete.Activated += new EventHandler(OnUnitDelete);
   1.408  				delete.Data["unit"] = selectedItem;
   1.409  				menu.Append(delete);
   1.410  				menu.ShowAll();
   1.411 @@ -1068,6 +1086,7 @@
   1.412  		}
   1.413  
   1.414  		[GLib.ConnectBefore]
   1.415 +
   1.416  		protected virtual void UnitTreeButtonPressed(object o, Gtk.ButtonPressEventArgs args)
   1.417  		{
   1.418  			TreePath path;
     2.1 --- a/UIControl/AbstractBaseEquipmentUIControl.cs	Wed Nov 03 21:02:54 2010 +0000
     2.2 +++ b/UIControl/AbstractBaseEquipmentUIControl.cs	Sat Nov 06 11:44:26 2010 +0000
     2.3 @@ -1,12 +1,14 @@
     2.4  //  This file (AbstractBaseEquipmentUIControl.cs) is a part of the IBBoard.WarFoundry.GUI.GTK project and is copyright 2010 IBBoard
     2.5  // 
     2.6  //  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.
     2.7 +
     2.8  using System;
     2.9  using IBBoard.Commands;
    2.10  using IBBoard.WarFoundry.API.Objects;
    2.11  using IBBoard.WarFoundry.GUI.GTK.UIControl.Interfaces;
    2.12  using IBBoard.Lang;
    2.13  using IBBoard.WarFoundry.API.Util;
    2.14 +
    2.15  namespace IBBoard.WarFoundry.GUI.GTK.UIControl
    2.16  {
    2.17  	public abstract class AbstractBaseEquipmentUIControl<UI_TYPE> where UI_TYPE : IBaseEquipmentUI
    2.18 @@ -24,7 +26,6 @@
    2.19  		{
    2.20  			this.unit = unit;
    2.21  			this.commandStack = commandStack;
    2.22 -			SetupUI();
    2.23  		}
    2.24  
    2.25  		private void SetupUI()
    2.26 @@ -43,11 +44,13 @@
    2.27  		/// <returns>
    2.28  		/// the UI component to display to the user
    2.29  		/// </returns>
    2.30 +
    2.31  		protected abstract UI_TYPE CreateEquipmentUI();
    2.32  		
    2.33  		/// <summary>
    2.34  		/// Completes any additional user interface setup.
    2.35  		/// </summary>
    2.36 +
    2.37  		protected virtual void CompleteUISetup()
    2.38  		{
    2.39  			//Do nothing
    2.40 @@ -61,6 +64,7 @@
    2.41  		/// <summary>
    2.42  		/// Sets the unit equipment values on the UI
    2.43  		/// </summary>
    2.44 +
    2.45  		protected void SetUnitEquipmentValues()
    2.46  		{
    2.47  			ui.SetOkayEnabledState(HasNonZeroEquipmentAmount());
    2.48 @@ -71,7 +75,6 @@
    2.49  				equipmentAmount = ui.EquipmentPercentageAmount;
    2.50  				SetEquipmentAmountsFromPercentage(equipmentAmount);
    2.51  			}
    2.52 -
    2.53  			else
    2.54  			{
    2.55  				int equipmentIntAmount = ui.EquipmentNumericAmount;
    2.56 @@ -89,15 +92,17 @@
    2.57  				//				MessageBox.Show(ParentForm, percentageTooLarge, percentageTooLargeTitle);
    2.58  				equipAmount = maxPercentage;
    2.59  			}
    2.60 +			else
    2.61 +			{
    2.62 +				if (equipAmount < minPercentage)
    2.63 +				{
    2.64 +					string percentageTooSmall = Translation.GetTranslation("equipPercentageTooSmall", "the current percentage ({0}%) was smaller than the minimum for the equipment item ({1}%) - the minimum value will be used instead", equipAmount, minPercentage);
    2.65 +					string percentageTooSmallTitle = Translation.GetTranslation("equipPercentageTooSmallTitle", "equipment percentage too small");
    2.66 +				//				MessageBox.Show(ParentForm, percentageTooSmall, percentageTooSmallTitle);
    2.67 +					equipAmount = minPercentage;
    2.68 +				}
    2.69  
    2.70 -			else if (equipAmount < minPercentage)
    2.71 -			{
    2.72 -				string percentageTooSmall = Translation.GetTranslation("equipPercentageTooSmall", "the current percentage ({0}%) was smaller than the minimum for the equipment item ({1}%) - the minimum value will be used instead", equipAmount, minPercentage);
    2.73 -				string percentageTooSmallTitle = Translation.GetTranslation("equipPercentageTooSmallTitle", "equipment percentage too small");
    2.74 -				//				MessageBox.Show(ParentForm, percentageTooSmall, percentageTooSmallTitle);
    2.75 -				equipAmount = minPercentage;
    2.76 -			}
    2.77 -			
    2.78 +			}			
    2.79  			ui.EquipmentNumericAmount = CalculateNumericValueFromPercentage(equipAmount);
    2.80  			ui.EquipmentPercentageAmount = equipAmount;
    2.81  		}
    2.82 @@ -117,15 +122,17 @@
    2.83  				//MessageBox.Show(ParentForm, amountTooLarge, amountTooLargeTitle);
    2.84  				equipAmount = maxNumber;
    2.85  			}
    2.86 +			else
    2.87 +			{
    2.88 +				if (equipAmount < minNumber)
    2.89 +				{
    2.90 +					string amountTooSmall = Translation.GetTranslation("equipNumberTooSmall", "the current amount ({0}) was smaller than the minimum for the equipment item ({1}) - the minimum value will be used instead", equipAmount, minNumber);
    2.91 +					string amountTooSmallTitle = Translation.GetTranslation("equipNumberTooSmallTitle", "equipment amount too small");
    2.92 +				//MessageBox.Show(ParentForm, amountTooSmall, amountTooSmallTitle);
    2.93 +					equipAmount = minNumber;
    2.94 +				}
    2.95  
    2.96 -			else if (equipAmount < minNumber)
    2.97 -			{
    2.98 -				string amountTooSmall = Translation.GetTranslation("equipNumberTooSmall", "the current amount ({0}) was smaller than the minimum for the equipment item ({1}) - the minimum value will be used instead", equipAmount, minNumber);
    2.99 -				string amountTooSmallTitle = Translation.GetTranslation("equipNumberTooSmallTitle", "equipment amount too small");
   2.100 -				//MessageBox.Show(ParentForm, amountTooSmall, amountTooSmallTitle);
   2.101 -				equipAmount = minNumber;
   2.102 -			}
   2.103 -			
   2.104 +			}			
   2.105  			ui.EquipmentPercentageAmount = CalcualtePercentageValueFromNumber(equipAmount);
   2.106  			ui.EquipmentNumericAmount = equipAmount;
   2.107  		}
   2.108 @@ -174,8 +181,6 @@
   2.109  			{
   2.110  				nonZero = (ui.EquipmentPercentageAmount > 0);
   2.111  			}
   2.112 -
   2.113 -			
   2.114  			else
   2.115  			{
   2.116  				nonZero = (ui.EquipmentNumericAmount > 0);
   2.117 @@ -191,6 +196,7 @@
   2.118  		
   2.119  		public void Show()
   2.120  		{			
   2.121 +			SetupUI();
   2.122  			bool okayed = ui.ShowControl();
   2.123  			
   2.124  			if (okayed)
   2.125 @@ -204,6 +210,7 @@
   2.126  		/// <summary>
   2.127  		/// Does the processing required for the control when the "OK" button was clicked
   2.128  		/// </summary>
   2.129 +
   2.130  		protected abstract void DoProcessing();
   2.131  	}
   2.132  }
     3.1 --- a/UIControl/ReplaceEquipmentUIControl.cs	Wed Nov 03 21:02:54 2010 +0000
     3.2 +++ b/UIControl/ReplaceEquipmentUIControl.cs	Sat Nov 06 11:44:26 2010 +0000
     3.3 @@ -33,8 +33,8 @@
     3.4  			string[] mutexGroups = origItem.MutexGroups;
     3.5  			UnitEquipmentItem[] mutexItems = unitType.GetEquipmentItemsByExclusionGroups(mutexGroups);
     3.6  			UnitEquipmentItem[] currentEquipment = unit.GetEquipment();
     3.7 -			UnitEquipmentItem[] items = Arrays.Subtract(mutexItems, currentEquipment);
     3.8 -			ui.SetUnitEquipmentItems(items);
     3.9 +			UnitEquipmentItem[] allowedItems = Arrays.Subtract(mutexItems, currentEquipment);
    3.10 +			ui.SetUnitEquipmentItems(allowedItems);
    3.11  			ui.UnitEquipmentItemChoiceChanged += HandleUiUnitEquipmentItemChoiceChanged;
    3.12  		}
    3.13  
     4.1 --- a/gtk-gui/IBBoard.WarFoundry.GTK.Widgets.UnitDisplayWidget.cs	Wed Nov 03 21:02:54 2010 +0000
     4.2 +++ b/gtk-gui/IBBoard.WarFoundry.GTK.Widgets.UnitDisplayWidget.cs	Sat Nov 06 11:44:26 2010 +0000
     4.3 @@ -5,45 +5,26 @@
     4.4  	public partial class UnitDisplayWidget
     4.5  	{
     4.6  		private global::Gtk.VBox vbox1;
     4.7 -
     4.8 -		private global::Gtk.HBox hbox1;
     4.9 -
    4.10 -		private global::Gtk.Entry unitName;
    4.11 -
    4.12 -		private global::Gtk.SpinButton unitSize;
    4.13 -
    4.14 -		private global::Gtk.ScrolledWindow GtkScrolledWindow;
    4.15 -
    4.16 -		private global::Gtk.NodeView unitStats;
    4.17 -
    4.18 -		private global::Gtk.HSeparator hseparator1;
    4.19 -
    4.20 -		private global::Gtk.HBox hbox2;
    4.21 -
    4.22 -		private global::Gtk.Table table1;
    4.23 -
    4.24 -		private global::Gtk.Label equipmentLabel;
    4.25 -
    4.26 -		private global::Gtk.ScrolledWindow GtkScrolledWindow2;
    4.27 -
    4.28 -		private global::Gtk.NodeView equipmentList;
    4.29 -
    4.30 -		private global::Gtk.ScrolledWindow GtkScrolledWindow3;
    4.31 -
    4.32 -		private global::Gtk.TextView notesView;
    4.33 -
    4.34 -		private global::Gtk.Label lblNotes;
    4.35 -
    4.36 -		private global::Gtk.VBox vbox3;
    4.37 -
    4.38 -		private global::Gtk.Button bttnAddEquipment;
    4.39 -
    4.40 -		private global::Gtk.Button bttnEditEquipment;
    4.41 -
    4.42 -		private global::Gtk.Button bttnReplaceEquipment;
    4.43 -
    4.44 -		private global::Gtk.Button bttnRemoveEquipment;
    4.45 -
    4.46 +				private global::Gtk.HBox hbox1;
    4.47 +				private global::Gtk.Entry unitName;
    4.48 +				private global::Gtk.SpinButton unitSize;
    4.49 +				private global::Gtk.ScrolledWindow GtkScrolledWindow;
    4.50 +				private global::Gtk.NodeView unitStats;
    4.51 +				private global::Gtk.HSeparator hseparator1;
    4.52 +				private global::Gtk.HBox hbox2;
    4.53 +				private global::Gtk.Table table1;
    4.54 +				private global::Gtk.Label equipmentLabel;
    4.55 +				private global::Gtk.ScrolledWindow GtkScrolledWindow2;
    4.56 +				private global::Gtk.NodeView equipmentList;
    4.57 +				private global::Gtk.ScrolledWindow GtkScrolledWindow3;
    4.58 +				private global::Gtk.TextView notesView;
    4.59 +				private global::Gtk.Label lblNotes;
    4.60 +				private global::Gtk.VBox vbox3;
    4.61 +				private global::Gtk.Button bttnAddEquipment;
    4.62 +				private global::Gtk.Button bttnEditEquipment;
    4.63 +				private global::Gtk.Button bttnReplaceEquipment;
    4.64 +				private global::Gtk.Button bttnRemoveEquipment;
    4.65 +		
    4.66  		protected virtual void Build()
    4.67  		{
    4.68  			global::Stetic.Gui.Initialize(this);
    4.69 @@ -240,6 +221,7 @@
    4.70  			this.unitSize.KeyPressEvent += new global::Gtk.KeyPressEventHandler(this.OnUnitSizeKeyPress);
    4.71  			this.bttnAddEquipment.Clicked += new global::System.EventHandler(this.OnBttnAddEquipmentClicked);
    4.72  			this.bttnEditEquipment.Clicked += new global::System.EventHandler(this.HandleEditButtonClicked);
    4.73 +			this.bttnReplaceEquipment.Clicked += new global::System.EventHandler(this.HandleReplaceButtonClicked);
    4.74  			this.bttnRemoveEquipment.Clicked += new global::System.EventHandler(this.HandleRemoveButtonActivated);
    4.75  		}
    4.76  	}
     5.1 --- a/gtk-gui/IBBoard.WarFoundry.GUI.GTK.FrmAddEquipment.cs	Wed Nov 03 21:02:54 2010 +0000
     5.2 +++ b/gtk-gui/IBBoard.WarFoundry.GUI.GTK.FrmAddEquipment.cs	Sat Nov 06 11:44:26 2010 +0000
     5.3 @@ -120,6 +120,7 @@
     5.4  			this.rbEquipAll = new global::Gtk.RadioButton("");
     5.5  			this.rbEquipAll.CanFocus = true;
     5.6  			this.rbEquipAll.Name = "rbEquipAll";
     5.7 +			this.rbEquipAll.Active = true;
     5.8  			this.rbEquipAll.DrawIndicator = true;
     5.9  			this.rbEquipAll.UseUnderline = true;
    5.10  			this.rbEquipAll.Group = new global::GLib.SList(global::System.IntPtr.Zero);
     6.1 --- a/gtk-gui/IBBoard.WarFoundry.GUI.GTK.FrmEditEquipment.cs	Wed Nov 03 21:02:54 2010 +0000
     6.2 +++ b/gtk-gui/IBBoard.WarFoundry.GUI.GTK.FrmEditEquipment.cs	Sat Nov 06 11:44:26 2010 +0000
     6.3 @@ -5,31 +5,19 @@
     6.4  	public partial class FrmEditEquipment
     6.5  	{
     6.6  		private global::Gtk.Table table1;
     6.7 -
     6.8 -		private global::Gtk.HBox hbox2;
     6.9 -
    6.10 -		private global::Gtk.Table table2;
    6.11 -
    6.12 -		private global::Gtk.Label lblEquipAll;
    6.13 -
    6.14 -		private global::Gtk.Label lblPercent;
    6.15 -
    6.16 -		private global::Gtk.SpinButton numericAmount;
    6.17 -
    6.18 -		private global::Gtk.SpinButton percentageAmount;
    6.19 -
    6.20 -		private global::Gtk.RadioButton rbEquipAll;
    6.21 -
    6.22 -		private global::Gtk.RadioButton rbEquipNumeric;
    6.23 -
    6.24 -		private global::Gtk.RadioButton rbEquipPercent;
    6.25 -
    6.26 -		private global::Gtk.Label lblEquipAmount;
    6.27 -
    6.28 -		private global::Gtk.Button buttonCancel;
    6.29 -
    6.30 -		private global::Gtk.Button buttonOk;
    6.31 -
    6.32 +				private global::Gtk.HBox hbox2;
    6.33 +				private global::Gtk.Table table2;
    6.34 +				private global::Gtk.Label lblEquipAll;
    6.35 +				private global::Gtk.Label lblPercent;
    6.36 +				private global::Gtk.SpinButton numericAmount;
    6.37 +				private global::Gtk.SpinButton percentageAmount;
    6.38 +				private global::Gtk.RadioButton rbEquipAll;
    6.39 +				private global::Gtk.RadioButton rbEquipNumeric;
    6.40 +				private global::Gtk.RadioButton rbEquipPercent;
    6.41 +				private global::Gtk.Label lblEquipAmount;
    6.42 +				private global::Gtk.Button buttonCancel;
    6.43 +				private global::Gtk.Button buttonOk;
    6.44 +		
    6.45  		protected virtual void Build()
    6.46  		{
    6.47  			global::Stetic.Gui.Initialize(this);