# HG changeset patch # User IBBoard # Date 1266062174 0 # Node ID 61bc9b44a695b383980d21ab3e0f26d5c5bbe2ff # Parent dbe784f0802cbbfd85d6f0dec6dcc92a1c2d11fe 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 diff -r dbe784f0802c -r 61bc9b44a695 AssemblyInfo.cs --- 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 diff -r dbe784f0802c -r 61bc9b44a695 IBBoard.WarFoundry.GUI.QtSharp.csproj --- 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 @@ {299D84D6-C84A-45CD-B709-AF536FCBA937} Exe IBBoard.WarFoundry.GUI.QtSharp - IBBoard.WarFoundry.GUI.QtSharp + WarFoundry + IBBoard.WarFoundry.GUI.QtSharp.MainClass true @@ -79,6 +80,9 @@ PreserveNewest + + PreserveNewest + diff -r dbe784f0802c -r 61bc9b44a695 Main.cs --- 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 () diff -r dbe784f0802c -r 61bc9b44a695 MainWindow.cs --- 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 diff -r dbe784f0802c -r 61bc9b44a695 WarFoundry.exe.log4net --- /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 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file