| 1 | // This file (FrmMainWindow.cs) is a part of the IBBoard.WarFoundry.GTK project and is copyright 2009 IBBoard. |
|---|
| 2 | // |
|---|
| 3 | // The file and the library/program it is in are licensed under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license. |
|---|
| 4 | |
|---|
| 5 | using System; |
|---|
| 6 | using System.IO; |
|---|
| 7 | using System.Collections.Generic; |
|---|
| 8 | using System.Configuration; |
|---|
| 9 | using Gtk; |
|---|
| 10 | using IBBoard; |
|---|
| 11 | using IBBoard.Commands; |
|---|
| 12 | using IBBoard.GtkSharp; |
|---|
| 13 | using IBBoard.IO; |
|---|
| 14 | using IBBoard.Lang; |
|---|
| 15 | using IBBoard.Logging; |
|---|
| 16 | using IBBoard.CustomMath; |
|---|
| 17 | using IBBoard.Log4Net; |
|---|
| 18 | using IBBoard.WarFoundry.API; |
|---|
| 19 | using IBBoard.WarFoundry.API.Factories; |
|---|
| 20 | using IBBoard.WarFoundry.API.Factories.Xml; |
|---|
| 21 | using IBBoard.WarFoundry.API.Objects; |
|---|
| 22 | using IBBoard.WarFoundry.API.Commands; |
|---|
| 23 | using IBBoard.WarFoundry.API.Savers; |
|---|
| 24 | using IBBoard.WarFoundry.API.Requirements; |
|---|
| 25 | using IBBoard.WarFoundry.GTK.Widgets; |
|---|
| 26 | using IBBoard.WarFoundry.Plugin.Rollcall; |
|---|
| 27 | using IBBoard.Xml; |
|---|
| 28 | using log4net; |
|---|
| 29 | |
|---|
| 30 | namespace IBBoard.WarFoundry.GTK |
|---|
| 31 | { |
|---|
| 32 | public partial class FrmMainWindow: Gtk.Window |
|---|
| 33 | { |
|---|
| 34 | private static readonly string AppTitle = "WarFoundry"; |
|---|
| 35 | private const int CATEGORY_BUTTON_SEPARATOR_INDEX = 6; |
|---|
| 36 | |
|---|
| 37 | private Preferences preferences; |
|---|
| 38 | private ILog logger = LogManager.GetLogger(typeof(FrmMainWindow)); |
|---|
| 39 | |
|---|
| 40 | private CommandStack commandStack; |
|---|
| 41 | private Dictionary<ToolButton, Category> categoryMap = new Dictionary<ToolButton, Category>(); |
|---|
| 42 | private Dictionary<IBBoard.WarFoundry.API.Objects.Unit, UnitDisplayWidget> unitToWidgetMap = new Dictionary<IBBoard.WarFoundry.API.Objects.Unit,UnitDisplayWidget>(); |
|---|
| 43 | |
|---|
| 44 | private ObjectAddDelegate UnitAddedMethod; |
|---|
| 45 | private ObjectRemoveDelegate UnitRemovedMethod; |
|---|
| 46 | private DoubleValChangedDelegate PointsValueChangedMethod; |
|---|
| 47 | private FailedUnitRequirementDelegate FailedUnitRequirementMethod; |
|---|
| 48 | private StringValChangedDelegate UnitNameChangedMethod; |
|---|
| 49 | |
|---|
| 50 | private GameSystem system; |
|---|
| 51 | private string loadedArmyPath; |
|---|
| 52 | |
|---|
| 53 | private MenuToolButton undoMenuButton, redoMenuButton; |
|---|
| 54 | |
|---|
| 55 | public static void Main (string[] args) |
|---|
| 56 | { |
|---|
| 57 | try |
|---|
| 58 | { |
|---|
| 59 | Application.Init(); |
|---|
| 60 | FrmMainWindow win = new FrmMainWindow(args); |
|---|
| 61 | win.Show(); |
|---|
| 62 | Application.Run(); |
|---|
| 63 | LogManager.GetLogger(typeof(FrmMainWindow)).Debug("Application ended"); |
|---|
| 64 | } |
|---|
| 65 | catch(Exception ex) |
|---|
| 66 | { |
|---|
| 67 | LogManager.GetLogger(typeof(FrmMainWindow)).Fatal("("+ex.GetType().Name+") "+ex.Message + Environment.NewLine + ex.StackTrace); |
|---|
| 68 | } |
|---|
| 69 | } |
|---|
| 70 | |
|---|
| 71 | public FrmMainWindow() : this(new string[0]) |
|---|
| 72 | { |
|---|
| 73 | //Do nothing extra |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | public FrmMainWindow (string[] args): base (Gtk.WindowType.Toplevel) |
|---|
| 77 | { |
|---|
| 78 | logger.Info("Opening FrmMainWindow"); |
|---|
| 79 | LogNotifierHandler.RegisterNotifierHandler(); |
|---|
| 80 | Build (); |
|---|
| 81 | //Replace the undo/redo buttons with menu versions, which Monodevelop's GUI editor doesn't currently support |
|---|
| 82 | redoMenuButton = new MenuToolButton("gtk-redo"); |
|---|
| 83 | redoMenuButton.Label = "Redo"; |
|---|
| 84 | redoMenuButton.TooltipText = "Redo"; |
|---|
| 85 | redoMenuButton.Clicked+= redoTBButtonActivated; |
|---|
| 86 | toolbar.Insert(redoMenuButton, CATEGORY_BUTTON_SEPARATOR_INDEX); |
|---|
| 87 | undoMenuButton = new MenuToolButton("gtk-undo"); |
|---|
| 88 | undoMenuButton.Label = "Undo"; |
|---|
| 89 | undoMenuButton.TooltipText = "Undo"; |
|---|
| 90 | undoMenuButton.Clicked+= undoTBButtonActivated; |
|---|
| 91 | toolbar.Insert(undoMenuButton, CATEGORY_BUTTON_SEPARATOR_INDEX); |
|---|
| 92 | toolbar.Remove(toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX-1]); |
|---|
| 93 | toolbar.Remove(toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX-2]); |
|---|
| 94 | toolbar.ShowAll(); |
|---|
| 95 | |
|---|
| 96 | Title = AppTitle; |
|---|
| 97 | TreeViewColumn mainColumn = new TreeViewColumn (); |
|---|
| 98 | mainColumn.Title = "Army Categories"; |
|---|
| 99 | CellRendererText mainCell = new CellRendererText (); |
|---|
| 100 | mainColumn.PackStart (mainCell, true); |
|---|
| 101 | treeUnits.AppendColumn(mainColumn); |
|---|
| 102 | mainColumn.SetCellDataFunc(mainCell, new TreeCellDataFunc(RenderCategoryTreeObjectName)); |
|---|
| 103 | treeUnits.Model = new TreeStore(typeof(WarFoundryObject)); |
|---|
| 104 | logger.Debug("Loading preferences"); |
|---|
| 105 | Preferences = new Preferences("WarFoundryGTK"); |
|---|
| 106 | logger.Debug("Loading translations"); |
|---|
| 107 | |
|---|
| 108 | try |
|---|
| 109 | { |
|---|
| 110 | Translation.InitialiseTranslations(Constants.ExecutablePath, Preferences["language"].ToString()); |
|---|
| 111 | } |
|---|
| 112 | catch (TranslationLoadException ex) |
|---|
| 113 | { |
|---|
| 114 | logger.Error(ex); |
|---|
| 115 | MessageDialog dialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, ex.Message); |
|---|
| 116 | dialog.Title = "Translation loading failed"; |
|---|
| 117 | dialog.Run(); |
|---|
| 118 | dialog.Destroy(); |
|---|
| 119 | } |
|---|
| 120 | |
|---|
| 121 | logger.Debug("Initialising"); |
|---|
| 122 | commandStack = new CommandStack(); |
|---|
| 123 | commandStack.CommandStackUpdated+=new MethodInvoker(commandStack_CommandStackUpdated); |
|---|
| 124 | WarFoundryCore.GameSystemChanged+= new GameSystemChangedDelegate(OnGameSystemChanged); |
|---|
| 125 | WarFoundryCore.ArmyChanged+= new ArmyChangedDelegate(OnArmyChanged); |
|---|
| 126 | Destroyed+= new EventHandler(OnWindowDestroyed); |
|---|
| 127 | //TODO: Translate and subscribe to other events |
|---|
| 128 | UnitAddedMethod = new ObjectAddDelegate(OnUnitAdded); |
|---|
| 129 | UnitRemovedMethod = new ObjectRemoveDelegate(OnUnitRemoved); |
|---|
| 130 | PointsValueChangedMethod = new DoubleValChangedDelegate(OnPointsValueChanged); |
|---|
| 131 | FailedUnitRequirementMethod = new FailedUnitRequirementDelegate(OnFailedUnitRequirement); |
|---|
| 132 | UnitNameChangedMethod = new StringValChangedDelegate(OnUnitNameChanged); |
|---|
| 133 | logger.Debug("Initialising complete - trying to load default army or system"); |
|---|
| 134 | |
|---|
| 135 | //FIXME: Temporary hack to add paths and factories |
|---|
| 136 | WarFoundryLoader.GetDefault().AddLoadDirectory(new DirectoryInfo(Constants.ExecutablePath + Constants.DirectoryString + "data")); |
|---|
| 137 | IWarFoundryFactory factory = WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(typeof(WarFoundryXmlFactory)); |
|---|
| 138 | |
|---|
| 139 | if (factory!=null && factory is WarFoundryXmlFactory) |
|---|
| 140 | { |
|---|
| 141 | WarFoundryLoader.GetDefault().RegisterFactory((WarFoundryXmlFactory)factory); |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | factory = WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(typeof(RollcallFactory)); |
|---|
| 145 | |
|---|
| 146 | if (factory!=null && factory is RollcallFactory) |
|---|
| 147 | { |
|---|
| 148 | WarFoundryLoader.GetDefault().RegisterNonNativeFactory((INonNativeWarFoundryFactory)factory); |
|---|
| 149 | } |
|---|
| 150 | |
|---|
| 151 | if (args.Length == 1) |
|---|
| 152 | { |
|---|
| 153 | logger.Debug("Attempting to load from file"); |
|---|
| 154 | FileInfo file = new FileInfo(args[0]); |
|---|
| 155 | |
|---|
| 156 | try |
|---|
| 157 | { |
|---|
| 158 | ICollection<IWarFoundryObject> objects = WarFoundryLoader.GetDefault().LoadFile(file); |
|---|
| 159 | |
|---|
| 160 | if (objects.Count == 1) |
|---|
| 161 | { |
|---|
| 162 | List<IWarFoundryObject> objectList = new List<IWarFoundryObject>(); |
|---|
| 163 | objectList.AddRange(objects); |
|---|
| 164 | IWarFoundryObject loadedObject = objectList[0]; |
|---|
| 165 | |
|---|
| 166 | if (loadedObject is Army) |
|---|
| 167 | { |
|---|
| 168 | WarFoundryCore.CurrentArmy = (Army)loadedObject; |
|---|
| 169 | logger.InfoFormat("Loaded army from {0}", file.FullName); |
|---|
| 170 | } |
|---|
| 171 | else if (loadedObject is GameSystem) |
|---|
| 172 | { |
|---|
| 173 | WarFoundryCore.CurrentGameSystem = (GameSystem)loadedObject; |
|---|
| 174 | logger.InfoFormat("Loaded game system from {0}", file.FullName); |
|---|
| 175 | } |
|---|
| 176 | } |
|---|
| 177 | } |
|---|
| 178 | catch (InvalidFileException ex) |
|---|
| 179 | { |
|---|
| 180 | //TODO: show error dialog |
|---|
| 181 | logger.Error(ex); |
|---|
| 182 | } |
|---|
| 183 | } |
|---|
| 184 | else |
|---|
| 185 | { |
|---|
| 186 | string gameSystemID = Preferences.GetStringProperty("currSystem"); |
|---|
| 187 | |
|---|
| 188 | if (gameSystemID!=null && !"".Equals(gameSystemID)) |
|---|
| 189 | { |
|---|
| 190 | logger.Debug("Attempting to load current game system from properties"); |
|---|
| 191 | GameSystem sys = WarFoundryLoader.GetDefault().GetGameSystem(gameSystemID); |
|---|
| 192 | |
|---|
| 193 | if (sys!=null) |
|---|
| 194 | { |
|---|
| 195 | WarFoundryCore.CurrentGameSystem = sys; |
|---|
| 196 | logger.InfoFormat("Loaded game system {0} from properties", gameSystemID); |
|---|
| 197 | } |
|---|
| 198 | } |
|---|
| 199 | } |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | private void RenderCategoryTreeObjectName(TreeViewColumn column, CellRenderer cell, TreeModel model, TreeIter iter) |
|---|
| 203 | { |
|---|
| 204 | object o = model.GetValue(iter, 0); |
|---|
| 205 | |
|---|
| 206 | if (o is ArmyCategory) |
|---|
| 207 | { |
|---|
| 208 | ArmyCategory c = (ArmyCategory)o; |
|---|
| 209 | string name = ""; |
|---|
| 210 | |
|---|
| 211 | if (Preferences.GetBooleanProperty("ShowCatPercentage")) |
|---|
| 212 | { |
|---|
| 213 | name = Translation.GetTranslation("categoryTreeCatName", "{0} - {1}pts", c.Name, c.PointsTotal); |
|---|
| 214 | } |
|---|
| 215 | else |
|---|
| 216 | { |
|---|
| 217 | name = Translation.GetTranslation("categoryTreeCatNamePercentage", "{0} - {1}pts ({2}%)", c.Name, c.PointsTotal, (c.ParentArmy.PointsTotal > 0 ? Math.Round((c.PointsTotal / c.ParentArmy.PointsTotal) * 100) : 0)); |
|---|
| 218 | } |
|---|
| 219 | |
|---|
| 220 | (cell as CellRendererText).Text = name; |
|---|
| 221 | } |
|---|
| 222 | else if (o is IBBoard.WarFoundry.API.Objects.Unit) |
|---|
| 223 | { |
|---|
| 224 | IBBoard.WarFoundry.API.Objects.Unit u = (IBBoard.WarFoundry.API.Objects.Unit)o; |
|---|
| 225 | string name = Translation.GetTranslation("categoryTreeCatName", "{0} - {1}pts", u.Name, u.PointsValue); |
|---|
| 226 | (cell as CellRendererText).Text = name; |
|---|
| 227 | } |
|---|
| 228 | } |
|---|
| 229 | |
|---|
| 230 | private void OnWindowDestroyed(object source, EventArgs args) |
|---|
| 231 | { |
|---|
| 232 | logger.Info("Exiting"); |
|---|
| 233 | Application.Quit(); |
|---|
| 234 | } |
|---|
| 235 | |
|---|
| 236 | private void OnUnitNameChanged(WarFoundryObject val, string oldValue, string newValue) |
|---|
| 237 | { |
|---|
| 238 | IBBoard.WarFoundry.API.Objects.Unit unit = (IBBoard.WarFoundry.API.Objects.Unit)val; |
|---|
| 239 | UnitDisplayWidget widget; |
|---|
| 240 | unitToWidgetMap.TryGetValue(unit, out widget); |
|---|
| 241 | |
|---|
| 242 | if (widget!=null) |
|---|
| 243 | { |
|---|
| 244 | unitsNotebook.SetTabLabelText(widget, newValue); |
|---|
| 245 | } |
|---|
| 246 | } |
|---|
| 247 | |
|---|
| 248 | private void OnUnitAdded(WarFoundryObject val) |
|---|
| 249 | { |
|---|
| 250 | IBBoard.WarFoundry.API.Objects.Unit unit = (IBBoard.WarFoundry.API.Objects.Unit)val; |
|---|
| 251 | unit.NameChanged+= UnitNameChangedMethod; |
|---|
| 252 | AddUnitToTree(unit); |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | private void AddUnitToTree(IBBoard.WarFoundry.API.Objects.Unit unit) |
|---|
| 256 | { |
|---|
| 257 | TreeStore model = (TreeStore)treeUnits.Model; |
|---|
| 258 | TreeIter iter; |
|---|
| 259 | model.GetIterFirst(out iter); |
|---|
| 260 | |
|---|
| 261 | do |
|---|
| 262 | { |
|---|
| 263 | object obj = model.GetValue(iter, 0); |
|---|
| 264 | |
|---|
| 265 | if (obj is ArmyCategory) |
|---|
| 266 | { |
|---|
| 267 | ArmyCategory cat = (ArmyCategory)obj; |
|---|
| 268 | |
|---|
| 269 | if (cat.Equals(unit.Category)) |
|---|
| 270 | { |
|---|
| 271 | model.AppendValues(iter, unit); |
|---|
| 272 | TreePath path = model.GetPath(iter); |
|---|
| 273 | treeUnits.ExpandToPath(path); |
|---|
| 274 | } |
|---|
| 275 | } |
|---|
| 276 | } |
|---|
| 277 | while (model.IterNext(ref iter)); |
|---|
| 278 | } |
|---|
| 279 | |
|---|
| 280 | private void OnUnitRemoved(WarFoundryObject obj) |
|---|
| 281 | { |
|---|
| 282 | IBBoard.WarFoundry.API.Objects.Unit unit = (IBBoard.WarFoundry.API.Objects.Unit)obj; |
|---|
| 283 | unit.NameChanged-= UnitNameChangedMethod; |
|---|
| 284 | RemoveUnitFromTree(unit); |
|---|
| 285 | |
|---|
| 286 | //See if unit has a tab open and close it if it does |
|---|
| 287 | } |
|---|
| 288 | |
|---|
| 289 | private void RemoveUnitFromTree(IBBoard.WarFoundry.API.Objects.Unit unit) |
|---|
| 290 | { |
|---|
| 291 | TreeStore model = (TreeStore)treeUnits.Model; |
|---|
| 292 | TreeIter iter; |
|---|
| 293 | model.GetIterFirst(out iter); |
|---|
| 294 | bool removed = false; |
|---|
| 295 | |
|---|
| 296 | do |
|---|
| 297 | { |
|---|
| 298 | object obj = model.GetValue(iter, 0); |
|---|
| 299 | |
|---|
| 300 | if (obj is ArmyCategory) |
|---|
| 301 | { |
|---|
| 302 | ArmyCategory cat = (ArmyCategory)obj; |
|---|
| 303 | |
|---|
| 304 | if (unit.Category == null || cat.Equals(unit.Category)) |
|---|
| 305 | { |
|---|
| 306 | TreeIter innerIter; |
|---|
| 307 | model.IterChildren(out innerIter, iter); |
|---|
| 308 | |
|---|
| 309 | do |
|---|
| 310 | { |
|---|
| 311 | object innerObj = model.GetValue(innerIter, 0); |
|---|
| 312 | |
|---|
| 313 | if (unit.Equals(innerObj)) |
|---|
| 314 | { |
|---|
| 315 | model.Remove(ref innerIter); |
|---|
| 316 | removed = true; |
|---|
| 317 | break; |
|---|
| 318 | } |
|---|
| 319 | } |
|---|
| 320 | while (model.IterNext(ref innerIter)); |
|---|
| 321 | |
|---|
| 322 | if (removed) |
|---|
| 323 | { |
|---|
| 324 | break; |
|---|
| 325 | } |
|---|
| 326 | } |
|---|
| 327 | } |
|---|
| 328 | } |
|---|
| 329 | while (model.IterNext(ref iter)); |
|---|
| 330 | } |
|---|
| 331 | |
|---|
| 332 | private void OnPointsValueChanged(WarFoundryObject obj, double before, double after) |
|---|
| 333 | { |
|---|
| 334 | //Set points in panel |
|---|
| 335 | } |
|---|
| 336 | |
|---|
| 337 | private void OnFailedUnitRequirement(List<FailedUnitRequirement> failedRequirement) |
|---|
| 338 | { |
|---|
| 339 | //Show error message in panel |
|---|
| 340 | } |
|---|
| 341 | |
|---|
| 342 | public Preferences Preferences |
|---|
| 343 | { |
|---|
| 344 | get { return preferences; } |
|---|
| 345 | set { preferences = value; } |
|---|
| 346 | } |
|---|
| 347 | |
|---|
| 348 | /*public AbstractNativeWarFoundryFactory Factory |
|---|
| 349 | { |
|---|
| 350 | get { return WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(Constants.ExecutablePath, factoryType); } |
|---|
| 351 | }*/ |
|---|
| 352 | |
|---|
| 353 | protected void OnDeleteEvent (object sender, DeleteEventArgs a) |
|---|
| 354 | { |
|---|
| 355 | Application.Quit (); |
|---|
| 356 | a.RetVal = true; |
|---|
| 357 | } |
|---|
| 358 | |
|---|
| 359 | protected virtual void OnExitActivated(object sender, System.EventArgs e) |
|---|
| 360 | { |
|---|
| 361 | Application.Quit(); |
|---|
| 362 | } |
|---|
| 363 | |
|---|
| 364 | protected virtual void OnChangeGameSystemActivated(object sender, System.EventArgs e) |
|---|
| 365 | { |
|---|
| 366 | ChangeCurrentGameSystem(); |
|---|
| 367 | } |
|---|
| 368 | |
|---|
| 369 | protected virtual void OnCreateArmyActivated(object sender, System.EventArgs e) |
|---|
| 370 | { |
|---|
| 371 | CreateNewArmy(); |
|---|
| 372 | } |
|---|
| 373 | |
|---|
| 374 | protected virtual void OnReloadFilesActivated(object sender, System.EventArgs e) |
|---|
| 375 | { |
|---|
| 376 | } |
|---|
| 377 | |
|---|
| 378 | protected virtual void OnSaveArmyAsActivated(object sender, System.EventArgs e) |
|---|
| 379 | { |
|---|
| 380 | SaveCurrentArmyAs(); |
|---|
| 381 | } |
|---|
| 382 | |
|---|
| 383 | protected virtual void OnCloseArmyActivated(object sender, System.EventArgs e) |
|---|
| 384 | { |
|---|
| 385 | CloseCurrentArmy(); |
|---|
| 386 | } |
|---|
| 387 | |
|---|
| 388 | protected virtual void OnOpenArmyActivated(object sender, System.EventArgs e) |
|---|
| 389 | { |
|---|
| 390 | OpenArmy(); |
|---|
| 391 | } |
|---|
| 392 | |
|---|
| 393 | protected virtual void OnSaveArmyActivated(object sender, System.EventArgs e) |
|---|
| 394 | { |
|---|
| 395 | SaveCurrentArmy(); |
|---|
| 396 | } |
|---|
| 397 | |
|---|
| 398 | protected virtual void OnAddUnitActivated(object sender, System.EventArgs e) |
|---|
| 399 | { |
|---|
| 400 | if (sender is ToolButton) |
|---|
| 401 | { |
|---|
| 402 | Category cat = null; |
|---|
| 403 | categoryMap.TryGetValue((ToolButton)sender, out cat); |
|---|
| 404 | |
|---|
| 405 | if (cat!=null) |
|---|
| 406 | { |
|---|
| 407 | logger.DebugFormat("Show FrmNewUnit for {0}", cat.Name); |
|---|
| 408 | FrmNewUnit newUnit = new FrmNewUnit(WarFoundryCore.CurrentArmy.Race, cat, WarFoundryCore.CurrentArmy); |
|---|
| 409 | ResponseType response = (ResponseType)newUnit.Run(); |
|---|
| 410 | newUnit.Hide(); |
|---|
| 411 | |
|---|
| 412 | if (response==ResponseType.Ok) |
|---|
| 413 | { |
|---|
| 414 | CreateAndAddUnitCommand cmd = new CreateAndAddUnitCommand(newUnit.SelectedUnit, WarFoundryCore.CurrentArmy); |
|---|
| 415 | commandStack.Execute(cmd); |
|---|
| 416 | } |
|---|
| 417 | |
|---|
| 418 | newUnit.Dispose(); |
|---|
| 419 | } |
|---|
| 420 | } |
|---|
| 421 | } |
|---|
| 422 | |
|---|
| 423 | public CommandStack CommandStack |
|---|
| 424 | { |
|---|
| 425 | get { return commandStack; } |
|---|
| 426 | } |
|---|
| 427 | |
|---|
| 428 | private void SetAppTitle() |
|---|
| 429 | { |
|---|
| 430 | if (WarFoundryCore.CurrentArmy!=null) |
|---|
| 431 | { |
|---|
| 432 | Title = AppTitle + " - " + WarFoundryCore.CurrentGameSystem.Name + " - " + WarFoundryCore.CurrentArmy.Name; |
|---|
| 433 | } |
|---|
| 434 | else if (WarFoundryCore.CurrentGameSystem!=null) |
|---|
| 435 | { |
|---|
| 436 | Title = AppTitle + " - " + WarFoundryCore.CurrentGameSystem.Name; |
|---|
| 437 | } |
|---|
| 438 | else |
|---|
| 439 | { |
|---|
| 440 | Title = AppTitle; |
|---|
| 441 | } |
|---|
| 442 | } |
|---|
| 443 | |
|---|
| 444 | private void OnGameSystemChanged(GameSystem oldSys, GameSystem newSys) |
|---|
| 445 | { |
|---|
| 446 | system = newSys; |
|---|
| 447 | SetAppTitle(); |
|---|
| 448 | miCreateArmy.Sensitive = system!=null; |
|---|
| 449 | newArmyButton.Sensitive = system!=null; |
|---|
| 450 | RemoveCategoryButtons(); |
|---|
| 451 | |
|---|
| 452 | if (system!=null) |
|---|
| 453 | { |
|---|
| 454 | AddCategoryButtons(system.Categories); |
|---|
| 455 | } |
|---|
| 456 | } |
|---|
| 457 | |
|---|
| 458 | private void OnArmyChanged(Army oldArmy, Army newArmy) |
|---|
| 459 | { |
|---|
| 460 | loadedArmyPath = null; |
|---|
| 461 | SetAppTitle(); |
|---|
| 462 | SetArmyTree(newArmy); |
|---|
| 463 | |
|---|
| 464 | if (oldArmy!=null) |
|---|
| 465 | { |
|---|
| 466 | oldArmy.UnitAdded-= UnitAddedMethod; |
|---|
| 467 | oldArmy.UnitRemoved-= UnitRemovedMethod; |
|---|
| 468 | oldArmy.PointsValueChanged-= PointsValueChangedMethod; |
|---|
| 469 | oldArmy.FailedRequirement-=FailedUnitRequirementMethod; |
|---|
| 470 | } |
|---|
| 471 | |
|---|
| 472 | unitToWidgetMap.Clear(); |
|---|
| 473 | |
|---|
| 474 | while (unitsNotebook.NPages > 0) |
|---|
| 475 | { |
|---|
| 476 | unitsNotebook.RemovePage(0); |
|---|
| 477 | } |
|---|
| 478 | |
|---|
| 479 | if (newArmy==null) |
|---|
| 480 | { |
|---|
| 481 | DisableCategoryButtons(); |
|---|
| 482 | } |
|---|
| 483 | else |
|---|
| 484 | { |
|---|
| 485 | newArmy.UnitAdded+= UnitAddedMethod; |
|---|
| 486 | newArmy.UnitRemoved+= UnitRemovedMethod; |
|---|
| 487 | newArmy.PointsValueChanged+= PointsValueChangedMethod; |
|---|
| 488 | newArmy.FailedRequirement+=FailedUnitRequirementMethod; |
|---|
| 489 | //TODO: Clear all buttons |
|---|
| 490 | EnableCategoryButtons(); |
|---|
| 491 | |
|---|
| 492 | if (newArmy.Race.HasCategoryOverrides()) |
|---|
| 493 | { |
|---|
| 494 | RemoveCategoryButtons(); |
|---|
| 495 | AddCategoryButtons(newArmy.Race.Categories); |
|---|
| 496 | } |
|---|
| 497 | } |
|---|
| 498 | |
|---|
| 499 | miCloseArmy.Sensitive = newArmy!=null; |
|---|
| 500 | miSaveArmyAs.Sensitive = newArmy!=null; |
|---|
| 501 | //New army has no changes, so we can't save it |
|---|
| 502 | miSaveArmy.Sensitive = false; |
|---|
| 503 | saveArmyButton.Sensitive = false; |
|---|
| 504 | |
|---|
| 505 | CommandStack.Reset(); |
|---|
| 506 | SetPointsPanelText(); |
|---|
| 507 | } |
|---|
| 508 | |
|---|
| 509 | private void SetArmyTree(Army army) |
|---|
| 510 | { |
|---|
| 511 | logger.Debug("Resetting tree"); |
|---|
| 512 | TreeStore store = (TreeStore)treeUnits.Model; |
|---|
| 513 | store.Clear(); |
|---|
| 514 | TreeIter iter; |
|---|
| 515 | |
|---|
| 516 | if (army!=null) |
|---|
| 517 | { |
|---|
| 518 | logger.Debug("Loading in categories to tree"); |
|---|
| 519 | |
|---|
| 520 | foreach (ArmyCategory cat in army.Categories) |
|---|
| 521 | { |
|---|
| 522 | logger.DebugFormat("Append category {0}", cat.Name); |
|---|
| 523 | iter = store.AppendValues(cat); |
|---|
| 524 | |
|---|
| 525 | foreach (IBBoard.WarFoundry.API.Objects.Unit unit in cat.GetUnits()) |
|---|
| 526 | { |
|---|
| 527 | store.AppendValues(iter, unit); |
|---|
| 528 | } |
|---|
| 529 | } |
|---|
| 530 | |
|---|
| 531 | logger.Debug("Finished loading tree categories"); |
|---|
| 532 | } |
|---|
| 533 | } |
|---|
| 534 | |
|---|
| 535 | private void DisableCategoryButtons() |
|---|
| 536 | { |
|---|
| 537 | SetCategoryButtonsSensitive(false); |
|---|
| 538 | } |
|---|
| 539 | |
|---|
| 540 | private void EnableCategoryButtons() |
|---|
| 541 | { |
|---|
| 542 | SetCategoryButtonsSensitive(true); |
|---|
| 543 | } |
|---|
| 544 | |
|---|
| 545 | private void SetCategoryButtonsSensitive(bool state) |
|---|
| 546 | { |
|---|
| 547 | int toolbarButtonCount = toolbar.Children.Length - 1; |
|---|
| 548 | logger.Debug("Last button index: "+toolbarButtonCount); |
|---|
| 549 | |
|---|
| 550 | for (int i = toolbarButtonCount; i > CATEGORY_BUTTON_SEPARATOR_INDEX; i--) |
|---|
| 551 | { |
|---|
| 552 | logger.DebugFormat("Setting button {0} state to {1}", i, state); |
|---|
| 553 | toolbar.Children[i].Sensitive = state; |
|---|
| 554 | } |
|---|
| 555 | } |
|---|
| 556 | |
|---|
| 557 | private void RemoveCategoryButtons() |
|---|
| 558 | { |
|---|
| 559 | int toolbarButtonCount = toolbar.Children.Length - 1; |
|---|
| 560 | |
|---|
| 561 | for (int i = toolbarButtonCount; i > CATEGORY_BUTTON_SEPARATOR_INDEX; i--) |
|---|
| 562 | { |
|---|
| 563 | toolbar.Remove(toolbar.Children[i]); |
|---|
| 564 | } |
|---|
| 565 | |
|---|
| 566 | categoryMap.Clear(); |
|---|
| 567 | } |
|---|
| 568 | |
|---|
| 569 | private void AddCategoryButtons(Category[] cats) |
|---|
| 570 | { |
|---|
| 571 | if (cats!=null && cats.Length > 0) |
|---|
| 572 | { |
|---|
| 573 | logger.DebugFormat("Toolbar button count: {0}. Adding {1} categories.", toolbar.Children.Length, cats.Length); |
|---|
| 574 | |
|---|
| 575 | foreach (Category cat in cats) |
|---|
| 576 | { |
|---|
| 577 | ToolButton button = new ToolButton("gtk-add"); |
|---|
| 578 | button.Label = cat.Name; |
|---|
| 579 | button.TooltipText = "Add unit from "+cat.Name; |
|---|
| 580 | //TODO: See if we can associate data in some way, the same as we can with SWF. For now we just use the map. |
|---|
| 581 | categoryMap.Add(button, cat); |
|---|
| 582 | button.Clicked+= new System.EventHandler(OnAddUnitActivated); |
|---|
| 583 | toolbar.Insert(button, -1); |
|---|
| 584 | } |
|---|
| 585 | } |
|---|
| 586 | |
|---|
| 587 | toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX].Visible = cats!=null && cats.Length>0; |
|---|
| 588 | |
|---|
| 589 | toolbar.ShowAll(); |
|---|
| 590 | } |
|---|
| 591 | |
|---|
| 592 | private void SetPointsPanelText() |
|---|
| 593 | { |
|---|
| 594 | //TODO: Set the points value in the status bar |
|---|
| 595 | } |
|---|
| 596 | |
|---|
| 597 | private void commandStack_CommandStackUpdated() |
|---|
| 598 | { |
|---|
| 599 | undoMenuButton.Sensitive = commandStack.CanUndo(); |
|---|
| 600 | miUndo.Sensitive = undoMenuButton.Sensitive; |
|---|
| 601 | redoMenuButton.Sensitive = commandStack.CanRedo(); |
|---|
| 602 | miRedo.Sensitive = redoMenuButton.Sensitive; |
|---|
| 603 | int redoLength = commandStack.RedoLength; |
|---|
| 604 | //TODO: Build menus for undo/redo and find way of adding tooltips |
|---|
| 605 | /*int maxRedo = Math.Min(10, redoLength); |
|---|
| 606 | MenuItem[] menuItems = null; |
|---|
| 607 | |
|---|
| 608 | if (redoLength > 0) |
|---|
| 609 | { |
|---|
| 610 | menuItems = new MenuItem[maxRedo]; |
|---|
| 611 | Command com; |
|---|
| 612 | MenuItem mi; |
|---|
| 613 | |
|---|
| 614 | for (int i = 0; i < maxRedo; i++) |
|---|
| 615 | { |
|---|
| 616 | com = commandStack.PeekRedoCommand(i+1); |
|---|
| 617 | |
|---|
| 618 | if (com == null) |
|---|
| 619 | { |
|---|
| 620 | break; |
|---|
| 621 | } |
|---|
| 622 | |
|---|
| 623 | mi = new MenuItem(com.Description); |
|---|
| 624 | mi.Click+=new EventHandler(redoMenu_Click); |
|---|
| 625 | menuItems[i] = mi; |
|---|
| 626 | } |
|---|
| 627 | } |
|---|
| 628 | |
|---|
| 629 | redoMenu.MenuItems.Clear(); |
|---|
| 630 | |
|---|
| 631 | if (menuItems!=null && menuItems[0]!=null) |
|---|
| 632 | { |
|---|
| 633 | bttnRedo.ToolTipText = menuItems[0].Text; |
|---|
| 634 | redoMenu.MenuItems.AddRange(menuItems); |
|---|
| 635 | }*/ |
|---|
| 636 | //TODO: Put above code back when we have a dropdown version of the redo button |
|---|
| 637 | if (redoLength > 0) |
|---|
| 638 | { |
|---|
| 639 | //redoMenuButton.Tooltip = CommandStack.PeekRedoCommand().Description; |
|---|
| 640 | } |
|---|
| 641 | |
|---|
| 642 | int undoLength = commandStack.UndoLength; |
|---|
| 643 | /*int maxUndo = Math.Min(10, undoLength); |
|---|
| 644 | MenuItem[] menuItemsUndo = null; |
|---|
| 645 | |
|---|
| 646 | if (undoLength > 0) |
|---|
| 647 | { |
|---|
| 648 | menuItemsUndo = new MenuItem[maxUndo]; |
|---|
| 649 | Command com; |
|---|
| 650 | MenuItem mi; |
|---|
| 651 | |
|---|
| 652 | for (int i = 0; i < maxUndo; i++) |
|---|
| 653 | { |
|---|
| 654 | com = commandStack.PeekUndoCommand(i+1); |
|---|
| 655 | |
|---|
| 656 | if (com == null) |
|---|
| 657 | { |
|---|
| 658 | break; |
|---|
| 659 | } |
|---|
| 660 | |
|---|
| 661 | mi = new MenuItem(com.UndoDescription); |
|---|
| 662 | mi.Click+=new EventHandler(undoMenu_Click); |
|---|
| 663 | menuItemsUndo[i] = mi; |
|---|
| 664 | } |
|---|
| 665 | } |
|---|
| 666 | |
|---|
| 667 | undoMenu.MenuItems.Clear(); |
|---|
| 668 | |
|---|
| 669 | if (menuItemsUndo!=null && menuItemsUndo[0]!=null) |
|---|
| 670 | { |
|---|
| 671 | bttnUndo.ToolTipText = menuItemsUndo[0].Text; |
|---|
| 672 | undoMenu.MenuItems.AddRange(menuItemsUndo); |
|---|
| 673 | }*/ |
|---|
| 674 | //TODO: Put above code back when we have a dropdown version of the undo button |
|---|
| 675 | if (undoLength > 0) |
|---|
| 676 | { |
|---|
| 677 | //undoMenuButton.Tooltip = CommandStack.PeekUndoCommand().UndoDescription; |
|---|
| 678 | } |
|---|
| 679 | |
|---|
| 680 | saveArmyButton.Sensitive = commandStack.IsDirty() && WarFoundryCore.CurrentArmy!=null && CanSave(); |
|---|
| 681 | miSaveArmy.Sensitive = commandStack.IsDirty() && WarFoundryCore.CurrentArmy!=null && CanSave(); |
|---|
| 682 | } |
|---|
| 683 | |
|---|
| 684 | private bool CanSave() |
|---|
| 685 | { |
|---|
| 686 | return loadedArmyPath!=null && WarFoundryCore.CurrentArmy!=null && WarFoundrySaver.GetSaver()!=null; |
|---|
| 687 | } |
|---|
| 688 | |
|---|
| 689 | private bool SaveCurrentArmyOrSaveAs() |
|---|
| 690 | { |
|---|
| 691 | if (CanSave()) |
|---|
| 692 | { |
|---|
| 693 | return SaveCurrentArmy(); |
|---|
| 694 | } |
|---|
| 695 | else |
|---|
| 696 | { |
|---|
| 697 | return SaveCurrentArmyAs(); |
|---|
| 698 | } |
|---|
| 699 | } |
|---|
| 700 | |
|---|
| 701 | private bool OpenArmy() |
|---|
| 702 | { |
|---|
| 703 | //TODO: Open dialog for file selection then open army |
|---|
| 704 | bool success = false; |
|---|
| 705 | loadedArmyPath = null;//TODO: Set loaded file path |
|---|
| 706 | return success; |
|---|
| 707 | } |
|---|
| 708 | |
|---|
| 709 | private bool SaveCurrentArmy() |
|---|
| 710 | { |
|---|
| 711 | bool success = false; |
|---|
| 712 | |
|---|
| 713 | if (CanSave()) |
|---|
| 714 | { |
|---|
| 715 | try |
|---|
| 716 | { |
|---|
| 717 | if (WarFoundrySaver.GetSaver().Save(WarFoundryCore.CurrentArmy, loadedArmyPath)) |
|---|
| 718 | { |
|---|
| 719 | saveArmyButton.Sensitive = false; |
|---|
| 720 | miSaveArmy.Sensitive = false; |
|---|
| 721 | CommandStack.setCleanMark(); |
|---|
| 722 | success = true; |
|---|
| 723 | } |
|---|
| 724 | } |
|---|
| 725 | catch (IOException ex) |
|---|
| 726 | { |
|---|
| 727 | logger.Error("Saving army failed", ex); |
|---|
| 728 | MessageDialog md = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, "An error occured while saving the army. Please check the logs for details on what failed"); |
|---|
| 729 | md.Show(); |
|---|
| 730 | } |
|---|
| 731 | } |
|---|
| 732 | |
|---|
| 733 | return success; |
|---|
| 734 | } |
|---|
| 735 | |
|---|
| 736 | private bool SaveCurrentArmyAs() |
|---|
| 737 | { |
|---|
| 738 | /*if (saveArmyDialog.Filter == "") |
|---|
| 739 | { |
|---|
| 740 | string savePath = UserDataPath+Constants.DirectoryString+"armies"+Constants.DirectoryString; |
|---|
| 741 | |
|---|
| 742 | if (!Directory.Exists(savePath)) |
|---|
| 743 | { |
|---|
| 744 | Directory.CreateDirectory(savePath); |
|---|
| 745 | } |
|---|
| 746 | |
|---|
| 747 | saveArmyDialog.InitialDirectory = savePath; |
|---|
| 748 | saveArmyDialog.Filter = Translation.GetTranslation("armyFileFilter")+"|*.army"; |
|---|
| 749 | saveArmyDialog.Title = Translation.GetTranslation("saveArmyDialog"); |
|---|
| 750 | } |
|---|
| 751 | |
|---|
| 752 | DialogResult dr = saveArmyDialog.ShowDialog(this); |
|---|
| 753 | |
|---|
| 754 | if (dr == DialogResult.OK) |
|---|
| 755 | { |
|---|
| 756 | if (WarFoundrySaver.GetSaver().Save(WarFoundryCore.CurrentArmy, saveArmyDialog.FileName)) |
|---|
| 757 | { |
|---|
| 758 | miSaveArmy.Enabled = false; |
|---|
| 759 | bttnSaveArmy.Enabled = false; |
|---|
| 760 | CommandStack.setCleanMark(); |
|---|
| 761 | loadedArmyPath = saveArmyDialog.FileName; |
|---|
| 762 | return true; |
|---|
| 763 | } |
|---|
| 764 | else |
|---|
| 765 | { |
|---|
| 766 | MessageBox.Show(this, Translation.GetTranslation("SaveFailed"), Translation.GetTranslation("SaveFailedTitle"), MessageBoxButtons.OK, MessageBoxIcon.Error); |
|---|
| 767 | return false; |
|---|
| 768 | } |
|---|
| 769 | } |
|---|
| 770 | else |
|---|
| 771 | { |
|---|
| 772 | return false; |
|---|
| 773 | }*/ |
|---|
| 774 | return false; |
|---|
| 775 | } |
|---|
| 776 | |
|---|
| 777 | private bool CloseCurrentArmy() |
|---|
| 778 | { |
|---|
| 779 | if (WarFoundryCore.CurrentArmy!=null) |
|---|
| 780 | { |
|---|
| 781 | bool canClose = false; |
|---|
| 782 | |
|---|
| 783 | if (CommandStack.IsDirty()) |
|---|
| 784 | { |
|---|
| 785 | MessageDialog dia = new MessageDialog(this, DialogFlags.DestroyWithParent, MessageType.Question, ButtonsType.YesNo | ButtonsType.Cancel, "The army \""+WarFoundryCore.CurrentArmy.Name+"\" has been modified.\r\nSave changes before closing army?"); |
|---|
| 786 | ResponseType dr = (ResponseType)dia.Run(); |
|---|
| 787 | |
|---|
| 788 | if (dr == ResponseType.Yes) |
|---|
| 789 | { |
|---|
| 790 | //They want to save so try to save it or prompt for save as |
|---|
| 791 | //If they cancel the save as then assume they don't want to close |
|---|
| 792 | canClose = SaveCurrentArmyOrSaveAs(); |
|---|
| 793 | } |
|---|
| 794 | else if (dr == ResponseType.No) |
|---|
| 795 | { |
|---|
| 796 | //They don't care about their changes |
|---|
| 797 | canClose = true; |
|---|
| 798 | } |
|---|
| 799 | else |
|---|
| 800 | { |
|---|
| 801 | //Assume cancel or close with the X button |
|---|
| 802 | canClose = false; |
|---|
| 803 | } |
|---|
| 804 | |
|---|
| 805 | dia.Dispose(); |
|---|
| 806 | } |
|---|
| 807 | else |
|---|
| 808 | { |
|---|
| 809 | //Nothing has changed so we can safely close |
|---|
| 810 | canClose = true; |
|---|
| 811 | } |
|---|
| 812 | |
|---|
| 813 | if (canClose) |
|---|
| 814 | { |
|---|
| 815 | //do close |
|---|
| 816 | WarFoundryCore.CurrentArmy = null; |
|---|
| 817 | return true; |
|---|
| 818 | } |
|---|
| 819 | else |
|---|
| 820 | { |
|---|
| 821 | return false; |
|---|
| 822 | } |
|---|
| 823 | } |
|---|
| 824 | else |
|---|
| 825 | { |
|---|
| 826 | //pretend we succeeded |
|---|
| 827 | return true; |
|---|
| 828 | } |
|---|
| 829 | } |
|---|
| 830 | |
|---|
| 831 | private void CreateNewArmy() |
|---|
| 832 | { |
|---|
| 833 | logger.Debug("Create new army"); |
|---|
| 834 | FrmNewArmy newArmy = new FrmNewArmy(WarFoundryCore.CurrentGameSystem); |
|---|
| 835 | ResponseType type = (ResponseType)newArmy.Run(); |
|---|
| 836 | newArmy.Hide(); |
|---|
| 837 | |
|---|
| 838 | if (type == ResponseType.Ok) |
|---|
| 839 | { |
|---|
| 840 | if (CloseCurrentArmy()) |
|---|
| 841 | { |
|---|
| 842 | WarFoundryCore.CurrentArmy = new Army(newArmy.SelectedRace, newArmy.ArmyName, newArmy.ArmySize); |
|---|
| 843 | } |
|---|
| 844 | } |
|---|
| 845 | else |
|---|
| 846 | { |
|---|
| 847 | logger.Debug("Create new army cancelled"); |
|---|
| 848 | } |
|---|
| 849 | |
|---|
| 850 | newArmy.Destroy(); |
|---|
| 851 | } |
|---|
| 852 | |
|---|
| 853 | private void ChangeCurrentGameSystem() |
|---|
| 854 | { |
|---|
| 855 | logger.Debug("Changing game system"); |
|---|
| 856 | FrmChangeGameSystem dialog = new FrmChangeGameSystem(this); |
|---|
| 857 | ResponseType type = (ResponseType)dialog.Run(); |
|---|
| 858 | dialog.Hide(); |
|---|
| 859 | |
|---|
| 860 | if (type == ResponseType.Ok) |
|---|
| 861 | { |
|---|
| 862 | WarFoundryCore.CurrentGameSystem = dialog.SelectedSystem; |
|---|
| 863 | } |
|---|
| 864 | else |
|---|
| 865 | { |
|---|
| 866 | logger.Debug("Game system change cancelled"); |
|---|
| 867 | } |
|---|
| 868 | |
|---|
| 869 | dialog.Destroy(); |
|---|
| 870 | } |
|---|
| 871 | |
|---|
| 872 | protected virtual void undoTBButtonActivated (object sender, System.EventArgs e) |
|---|
| 873 | { |
|---|
| 874 | CommandStack.Undo(); |
|---|
| 875 | } |
|---|
| 876 | |
|---|
| 877 | protected virtual void redoTBButtonActivated (object sender, System.EventArgs e) |
|---|
| 878 | { |
|---|
| 879 | CommandStack.Redo(); |
|---|
| 880 | } |
|---|
| 881 | |
|---|
| 882 | protected virtual void saveTBButtonActivated (object sender, System.EventArgs e) |
|---|
| 883 | { |
|---|
| 884 | SaveCurrentArmy(); |
|---|
| 885 | } |
|---|
| 886 | |
|---|
| 887 | protected virtual void openTBButtonActivated (object sender, System.EventArgs e) |
|---|
| 888 | { |
|---|
| 889 | OpenArmy(); |
|---|
| 890 | } |
|---|
| 891 | |
|---|
| 892 | protected virtual void newTBButtonActivated (object sender, System.EventArgs e) |
|---|
| 893 | { |
|---|
| 894 | CreateNewArmy(); |
|---|
| 895 | } |
|---|
| 896 | |
|---|
| 897 | protected virtual void ArmyRowActivated (object o, Gtk.RowActivatedArgs args) |
|---|
| 898 | { |
|---|
| 899 | TreeModel model = treeUnits.Model; |
|---|
| 900 | TreeIter iter; |
|---|
| 901 | model.GetIter(out iter, args.Path); |
|---|
| 902 | object obj = model.GetValue(iter, 0); |
|---|
| 903 | |
|---|
| 904 | if (obj is IBBoard.WarFoundry.API.Objects.Unit) |
|---|
| 905 | { |
|---|
| 906 | IBBoard.WarFoundry.API.Objects.Unit unit = (IBBoard.WarFoundry.API.Objects.Unit)obj; |
|---|
| 907 | |
|---|
| 908 | UnitDisplayWidget widget; |
|---|
| 909 | unitToWidgetMap.TryGetValue(unit, out widget); |
|---|
| 910 | |
|---|
| 911 | if (widget!=null) |
|---|
| 912 | { |
|---|
| 913 | logger.DebugFormat("Selecting existing page for "+unit.Name); |
|---|
| 914 | unitsNotebook.Page = unitsNotebook.PageNum(widget); |
|---|
| 915 | } |
|---|
| 916 | else |
|---|
| 917 | { |
|---|
| 918 | widget = new UnitDisplayWidget(unit, CommandStack); |
|---|
| 919 | logger.Debug("Adding page for "+unit.Name); |
|---|
| 920 | unitToWidgetMap[unit] = widget; |
|---|
| 921 | int pageNum = NotebookUtil.AddPageToNotebookWithCloseButton(unitsNotebook, widget, unit.Name); |
|---|
| 922 | logger.Debug("Page added at index "+pageNum); |
|---|
| 923 | unitsNotebook.ShowAll(); |
|---|
| 924 | unitsNotebook.Page = pageNum; |
|---|
| 925 | } |
|---|
| 926 | } |
|---|
| 927 | } |
|---|
| 928 | } |
|---|
| 929 | } |
|---|