view MainWindow.cs @ 10:3d0c9cf1b924

Fixes #243: Create "New Army" dialog in Qt# app * Make dialog not show in task bar (add parent to constructor) * Add methods to retrieve values Re #242: Create Qt# UI for WarFoundry * Copy lots of implementation from the WinForms app to get some core army loading working (looks like we need to investigate refactoring commonality)
author IBBoard <dev@ibboard.co.uk>
date Tue, 02 Feb 2010 20:56:39 +0000
parents bbf40d66dfe4
children 72bcf6457227
line wrap: on
line source

// This file (MainWindow.cs) is a part of the IBBoard.WarFoundry.API 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.Collections.Generic;
using Qyoto;
using log4net;
using IBBoard.Commands;
using IBBoard.IO;
using IBBoard.WarFoundry.API;
using IBBoard.WarFoundry.API.Factories;
using IBBoard.WarFoundry.API.Objects;
using IBBoard.WarFoundry.API.Savers;

namespace IBBoard.WarFoundry.GUI.QtSharp
{
	public class MainWindow : QMainWindow
	{
		private static readonly string AppTitle = "WarFoundry";
		
		private Ui_MainWindowLayout layout;
		private readonly ILog log = LogManager.GetLogger(typeof(MainWindow));
		private string loadedFilePath;
		private CommandStack commandStack;
		private QFileDialog saveArmyDialog;
		
		public MainWindow ()
		{
			layout = new Ui_MainWindowLayout();
			layout.SetupUi(this);
			WindowIcon = new QIcon("icons/App.png");
			saveArmyDialog = new QFileDialog(this);
			saveArmyDialog.acceptMode = QFileDialog.AcceptMode.AcceptSave;
			SetUpActionIcons();
			ConnectMenuActions();
			SetUpToolbar();
			layout.unitTabs.Clear();
			WarFoundryCore.ArmyChanged+= HandleWarFoundryCoreArmyChanged;
			CommandStack.CommandStackUpdated+= HandleCommandStackCommandStackUpdated;
		}
		
		private void SetUpActionIcons()
		{
			layout.actionCreateArmy.icon = new QIcon("icons/ui/filenew.png");
			layout.actionOpenArmy.icon = new QIcon("icons/ui/fileopen.png");
			layout.actionSaveArmy.icon = new QIcon("icons/ui/filesave.png");
			layout.actionSaveArmyAs.icon = new QIcon("icons/ui/filesaveas.png");
			layout.menuExportArmyAs.icon = new QIcon("icons/ui/export.png");
			layout.actionCloseArmy.icon = new QIcon("icons/ui/window-close.png");
			layout.actionExit.icon = new QIcon("icons/ui/exit.png");
			layout.actionUndo.icon = new QIcon("icons/ui/edit-undo.png");
			layout.actionRedo.icon = new QIcon("icons/ui/edit-redo.png");
			layout.actionAbout.icon = new QIcon("icons/ui/help-about.png");
		}
		
		private void ConnectMenuActions()
		{
			QObject.Connect(layout.actionCreateArmy, SIGNAL("triggered()"), CreateNewArmy);
			QObject.Connect(layout.actionUndo, SIGNAL("triggered()"), UndoAction);
			QObject.Connect(layout.actionRedo, SIGNAL("triggered()"), RedoAction);
		}
		
		private void CreateNewArmy()
		{
			NewArmyDialog dialog = new NewArmyDialog(this);
			int result = dialog.Exec ();
			
			if (result == (int)QDialog.DialogCode.Accepted)
			{
				try
				{
					CurrentArmy = new Army(dialog.GetSelectedRace(), dialog.GetArmyName(), dialog.GetArmySize());
				}
				catch (RequiredDataMissingException ex)
				{
					log.Error("Required data missing from race file", ex);
					QMessageBox.Warning(this, "Invalid race file data", "the race file for the requested data could not be loaded as it did not contain some required data");
				}
				catch (InvalidFileException ex)
				{
					log.Error("Race file was invalid", ex);
					QMessageBox.Warning(this, ex.Message,  "invalid race file");
				}
			}
		}
		
		private void SetUpToolbar()
		{
			List<QAction> actions = new List<QAction>(){
				layout.actionCreateArmy,
				layout.actionOpenArmy,
				layout.actionSaveArmy};
			layout.toolBar.AddActions(actions);
			layout.toolBar.AddSeparator();
			layout.toolBar.AddAction(layout.actionUndo);
			layout.toolBar.AddAction(layout.actionRedo);
			layout.toolBar.AddSeparator();
		}		

		private void HandleWarFoundryCoreArmyChanged (Army oldValue, Army newValue)
		{
			CommandStack.Reset();
			loadedFilePath = null;
			layout.actionSaveArmy.Enabled = false;
			SetPointsPanelText();
			SetAppTitle();
		}

		private void SetPointsPanelText ()
		{
			//TODO: implement panel and points panel
		}

		
		private void SetAppTitle()
		{
			string str = AppTitle;

			if (CurrentGameSystem!=null)
			{
				str+= " - " + CurrentGameSystem.Name;
			
				if (CurrentArmy!=null)
				{
					str+= " - " + CurrentArmy.Name;
				}
			}

			this.WindowTitle = str;
		}
		
		public CommandStack CommandStack
		{
			get 
			{
				if (commandStack == null)
				{					
					commandStack = new CommandStack();
				}

				return commandStack; 
			}
		}

		private void HandleCommandStackCommandStackUpdated ()
		{
			
		}

		private void UndoAction()
		{
			if (commandStack.CanUndo())
			{
				commandStack.Undo();
			}
		}

		private void RedoAction()
		{
			if (commandStack.CanRedo())
			{
				commandStack.Redo();
			}
		}

		private bool SaveCurrentArmy()
		{
			bool saved = false;

			string filePath = loadedFilePath;

			if (filePath == null)
			{
				filePath = PromptForArmyFilePath();
			}

			if (filePath != null)
			{
				saved = SaveCurrentArmyToFile(filePath);
			}

			return saved;
		}

		private bool SaveCurrentArmyAs()
		{
			bool saved = false;
			string filePath = PromptForArmyFilePath();

			if (filePath != null)
			{
				saved = SaveCurrentArmyToFile(filePath);
			}
			
			return saved;
		}

		private bool SaveCurrentArmyToFile(string filePath)
		{
			if (WarFoundrySaver.GetSaver().Save(CurrentArmy, filePath))
			{
				loadedFilePath = filePath;
				layout.actionSaveArmy.Enabled = false;
				CommandStack.setCleanMark();
				return true;
			}
			else
			{
				QMessageBox.Critical(this, "file save failed", "file save failed - check log for details");
				return false;
			}
		}

		private string PromptForArmyFilePath()
		{
			int result = saveArmyDialog.Exec();

			if (result == (int)QDialog.DialogCode.Accepted)
			{
				return saveArmyDialog.SelectedFiles()[0];
			}
			else
			{
				return null;
			}
		}		

		public GameSystem CurrentGameSystem
		{
			get { return WarFoundryCore.CurrentGameSystem; }
			set { WarFoundryCore.CurrentGameSystem = value; }
		}

		public Army CurrentArmy
		{
			get { return WarFoundryCore.CurrentArmy; }
			set { SetArmy(value); }
		}

		private void SetArmy(Army newArmy)
		{
			IgnoreArmy(CurrentArmy);
			CloseAllUnitWindows();

			if (newArmy == null)
			{
				SetNullArmyState();
			}
			else
			{
				WarFoundryCore.CurrentGameSystem = newArmy.GameSystem;
				ListenToArmy(newArmy);
				SetNonNullArmyState(newArmy);
			}
			
			WarFoundryCore.CurrentArmy = newArmy;
		}

		private void IgnoreArmy(Army oldArmy)
		{
			if (oldArmy != null)
			{
				oldArmy.UnitAdded -= UnitAddedMethod;
				oldArmy.UnitRemoved -= UnitRemovedMethod;
				oldArmy.PointsValueChanged -= PointsValueChangedMethod;
			}
		}
		private void UnitAddedMethod(object unitObj)
		{
			if (unitObj is Unit)
			{
				Unit unit = (Unit)unitObj;
				//TODO set error panel
				//sbErrorPanel.Text = "";
			}
		}

		private void UnitRemovedMethod(object unitObj)
		{
			if (unitObj is Unit)
			{
				Unit unit = (Unit)unitObj;
				//TODO set error panel
				//sbErrorPanel.Text = "";

				//TODO check if window is open, and close it if it is
				
			}
		}
		
		private void PointsValueChangedMethod(WarFoundryObject obj, double oldVal, double newVal)
		{
			if (obj is Army)
			{
				SetPointsPanelText();
			}
		}

		private void CloseAllUnitWindows()
		{
//			FrmUnit[] unitForms = DictionaryUtils.ToArray(unitWindows);
//
//			foreach (FrmUnit window in unitForms)
//			{
//				window.Close();
//			}
//
//			unitWindows.Clear();
		}

		private void ListenToArmy(Army newArmy)
		{
			if (newArmy != null)
			{
				newArmy.UnitAdded += UnitAddedMethod;
				newArmy.UnitRemoved += UnitRemovedMethod;
				newArmy.PointsValueChanged += PointsValueChangedMethod;
			}
		}

		private void SetNullArmyState()
		{
			layout.actionSaveArmyAs.Enabled = false;
			layout.actionCloseArmy.Enabled = false;
			layout.menuExportArmyAs.Enabled = false;
			DisableCategoryButtons();
		}

		void DisableCategoryButtons ()
		{
			//TODO handle category buttons
		}


		private void SetNonNullArmyState(Army newArmy)
		{
			SetCategoryButtons(newArmy.Race.Categories);
			EnableCategoryButtons();
			layout.actionSaveArmyAs.Enabled = true;
			layout.actionCloseArmy.Enabled = true;
			layout.menuExportArmyAs.Enabled = true;
		}

		void SetCategoryButtons (Category[] categories)
		{
			//TODO create category buttons
		}
		
		void EnableCategoryButtons ()
		{
			//TODO enable category buttons
		}
	}
}