Mercurial > repos > IBBoard.WarFoundry.GUI.QtSharp
changeset 14:61bc9b44a695
Re #242: Create Qt# UI for WarFoundry
* Add log4net logging output
* Output as "WarFoundry.exe"
* Wrap execution in try...catch to try to debug occasional crashes
* Refactor common "connect action to menu" method
Re #247: Implement menu options in Qt# app
* Implement "open" action
* Make "create" check for closing the old army
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 13 Feb 2010 11:56:14 +0000 |
parents | dbe784f0802c |
children | 03ed32fdc706 |
files | AssemblyInfo.cs IBBoard.WarFoundry.GUI.QtSharp.csproj Main.cs MainWindow.cs WarFoundry.exe.log4net |
diffstat | 5 files changed, 183 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/AssemblyInfo.cs Sat Feb 13 10:34:41 2010 +0000 +++ b/AssemblyInfo.cs Sat Feb 13 11:56:14 2010 +0000 @@ -27,3 +27,4 @@ //[assembly: AssemblyDelaySign(false)] //[assembly: AssemblyKeyFile("")] +[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "log4net", Watch = true)] \ No newline at end of file
--- a/IBBoard.WarFoundry.GUI.QtSharp.csproj Sat Feb 13 10:34:41 2010 +0000 +++ b/IBBoard.WarFoundry.GUI.QtSharp.csproj Sat Feb 13 11:56:14 2010 +0000 @@ -8,7 +8,8 @@ <ProjectGuid>{299D84D6-C84A-45CD-B709-AF536FCBA937}</ProjectGuid> <OutputType>Exe</OutputType> <RootNamespace>IBBoard.WarFoundry.GUI.QtSharp</RootNamespace> - <AssemblyName>IBBoard.WarFoundry.GUI.QtSharp</AssemblyName> + <AssemblyName>WarFoundry</AssemblyName> + <StartupObject>IBBoard.WarFoundry.GUI.QtSharp.MainClass</StartupObject> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -79,6 +80,9 @@ <None Include="lib\log4net.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> + <None Include="WarFoundry.exe.log4net"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> </ItemGroup> <ItemGroup> <Folder Include="qt-gui\" />
--- a/Main.cs Sat Feb 13 10:34:41 2010 +0000 +++ b/Main.cs Sat Feb 13 11:56:14 2010 +0000 @@ -19,14 +19,22 @@ public static void Main (string[] args) { - new QApplication (args); - - SetUpWarFoundryEnvironment (); - - MainWindow win = new MainWindow (); - win.Show (); - - QApplication.Exec (); + try + { + new QApplication (args); + + SetUpWarFoundryEnvironment (); + + MainWindow win = new MainWindow (); + win.Show (); + + QApplication.Exec (); + } + catch(Exception ex) + { + logger.Fatal(ex); + } + } private static void SetUpWarFoundryEnvironment ()
--- a/MainWindow.cs Sat Feb 13 10:34:41 2010 +0000 +++ b/MainWindow.cs Sat Feb 13 11:56:14 2010 +0000 @@ -2,11 +2,13 @@ // // 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.IO; using System.Collections.Generic; using Qyoto; using log4net; using IBBoard.Commands; using IBBoard.IO; +using IBBoard.Lang; using IBBoard.WarFoundry.API; using IBBoard.WarFoundry.API.Factories; using IBBoard.WarFoundry.API.Objects; @@ -23,6 +25,7 @@ private string loadedFilePath; private CommandStack commandStack; private QFileDialog saveArmyDialog; + private QFileDialog openArmyDialog; public MainWindow () { @@ -32,6 +35,11 @@ SetAppTitle(); saveArmyDialog = new QFileDialog(this); saveArmyDialog.acceptMode = QFileDialog.AcceptMode.AcceptSave; + saveArmyDialog.fileMode = QFileDialog.FileMode.AnyFile; + openArmyDialog = new QFileDialog(this); + openArmyDialog.acceptMode = QFileDialog.AcceptMode.AcceptOpen; + openArmyDialog.fileMode = QFileDialog.FileMode.ExistingFile; + openArmyDialog.SetNameFilter("*.army"); SetUpActionIcons(); ConnectMenuActions(); SetUpToolbar(); @@ -54,36 +62,45 @@ layout.actionAbout.icon = new QIcon("icons/ui/help-about.png"); } - private void ConnectMenuActions() + private void ConnectMenuActions () { - QObject.Connect(layout.actionCreateArmy, SIGNAL("triggered()"), CreateNewArmy); - QObject.Connect(layout.actionUndo, SIGNAL("triggered()"), UndoAction); - QObject.Connect(layout.actionRedo, SIGNAL("triggered()"), RedoAction); - QObject.Connect(layout.actionSaveArmyAs, SIGNAL("triggered()"), DoSaveCurrentArmyAs); - QObject.Connect(layout.actionSaveArmy, SIGNAL("triggered()"), DoSaveCurrentArmy); - QObject.Connect(layout.actionCloseArmy, SIGNAL("triggered()"), CloseArmy); + ConnectMenuAction (layout.actionCreateArmy, CreateNewArmy); + ConnectMenuAction (layout.actionUndo, UndoAction); + ConnectMenuAction (layout.actionRedo,RedoAction); + ConnectMenuAction (layout.actionSaveArmyAs, DoSaveCurrentArmyAs); + ConnectMenuAction (layout.actionSaveArmy, DoSaveCurrentArmy); + ConnectMenuAction (layout.actionCloseArmy, DoCloseArmy); + ConnectMenuAction (layout.actionOpenArmy, DoOpenArmy); + } + + private void ConnectMenuAction (QAction menuAction, SlotFunc method) + { + QObject.Connect(menuAction, SIGNAL("triggered()"), method); } private void CreateNewArmy() { - NewArmyDialog dialog = new NewArmyDialog(this); - int result = dialog.Exec (); - - if (result == (int)QDialog.DialogCode.Accepted) + if (CloseCurrentArmy()) { - try + NewArmyDialog dialog = new NewArmyDialog(this); + int result = dialog.Exec (); + + if (result == (int)QDialog.DialogCode.Accepted) { - 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"); + 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"); + } } } } @@ -167,6 +184,41 @@ } } + private void DoOpenArmy() + { + OpenArmy(); + } + + private bool OpenArmy() + { + log.Debug("Opening army"); + string newFilePath = PromptForFilePath (openArmyDialog); + bool openedFile = false; + + if (newFilePath != null && CloseCurrentArmy()) + { + try + { + log.DebugFormat("Opening {0}", newFilePath); + CurrentArmy = WarFoundryLoader.GetDefault().LoadArmy(new FileInfo(newFilePath)); + loadedFilePath = newFilePath; + openedFile = true; + } + catch (RequiredDataMissingException ex) + { + log.Error(ex); + QMessageBox.Critical(this, Translation.GetTranslation("InvalidArmyFileBoxTitle", "invalid army file"), ex.Message); + } + catch (InvalidFileException ex) + { + log.Error(ex); + QMessageBox.Critical(this, Translation.GetTranslation("InvalidArmyFileBoxTitle", "invalid army file"), ex.Message); + } + } + + return openedFile; + } + private void DoSaveCurrentArmy() { SaveCurrentArmy(); @@ -174,6 +226,7 @@ private bool SaveCurrentArmy() { + log.Debug("Save current army"); bool saved = false; string filePath = loadedFilePath; @@ -198,6 +251,7 @@ private bool SaveCurrentArmyAs() { + log.Debug("Saving current army as a different file"); bool saved = false; string filePath = PromptForArmyFilePath(); @@ -211,8 +265,11 @@ private bool SaveCurrentArmyToFile(string filePath) { + log.DebugFormat("Save to {0}", filePath); + if (WarFoundrySaver.GetSaver().Save(CurrentArmy, filePath)) { + log.Debug("Army saved"); loadedFilePath = filePath; layout.actionSaveArmy.Enabled = false; CommandStack.setCleanMark(); @@ -220,6 +277,7 @@ } else { + log.Debug("Save failed"); QMessageBox.Critical(this, "file save failed", "file save failed - check log for details"); return false; } @@ -227,7 +285,12 @@ private string PromptForArmyFilePath() { - int result = saveArmyDialog.Exec(); + return PromptForFilePath (saveArmyDialog); + } + + private string PromptForFilePath(QFileDialog qFileDialog) + { + int result = qFileDialog.Exec(); string path = null; if (result == (int)QDialog.DialogCode.Accepted) @@ -407,9 +470,58 @@ //TODO enable category buttons } - private void CloseArmy() + private void DoCloseArmy() + { + CloseCurrentArmy(); + } + + private bool CloseCurrentArmy() { - CurrentArmy = null; + bool closed = false; + + if (CurrentArmy!=null) + { + log.Debug("Closing "+CurrentArmy.Name); + bool canClose = false; + + if (CommandStack.IsDirty() || true) + { + log.Debug("Unsaved changes"); + string saveChanges = Translation.GetTranslation("SaveChangesQuestion", "the army \"{0}\" has been modified\r\nsave changes before closing army?", CurrentArmy.Name); + string saveChangesTitle = Translation.GetTranslation("SaveChangesTitle", "unsaved changes"); + QMessageBox.StandardButton response = QMessageBox.Question(this, saveChangesTitle, saveChanges, (uint) (QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No | QMessageBox.StandardButton.Cancel), QMessageBox.StandardButton.Cancel); + + if (response == QMessageBox.StandardButton.Yes) + { + canClose = SaveCurrentArmy(); + } + else if (response == QMessageBox.StandardButton.No) + { + log.Debug("User didn't save army"); + canClose = true; + } + //else they said cancel and we default to "canClose = false" so do nothing + } + else + { + canClose = true; + } + + if (canClose) + { + CurrentArmy = null; + closed = true; + } + } + else + { + //pretend we succeeded + closed = true; + } + + log.Debug("Army "+(closed ? "" : "not")+" closed"); + + return closed; } } } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WarFoundry.exe.log4net Sat Feb 13 11:56:14 2010 +0000 @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" ?> +<log4net> + <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> + <layout type="log4net.Layout.PatternLayout"> + <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="logs/WarFoundry.log" /> + <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> \ No newline at end of file