From f85be6a7441d9dfb8b49d40b52a012088c636600 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 2 Mar 2013 07:57:41 -0600 Subject: [PATCH 01/17] 80% complete save-on-close feature --- apps/opencs/view/doc/operations.cpp | 2 +- apps/opencs/view/doc/view.cpp | 10 ++- apps/opencs/view/doc/view.hpp | 5 +- apps/opencs/view/doc/viewmanager.cpp | 121 ++++++++++++++++++++++++--- apps/opencs/view/doc/viewmanager.hpp | 7 +- 5 files changed, 129 insertions(+), 16 deletions(-) diff --git a/apps/opencs/view/doc/operations.cpp b/apps/opencs/view/doc/operations.cpp index 71cacbe17e..58cef13430 100644 --- a/apps/opencs/view/doc/operations.cpp +++ b/apps/opencs/view/doc/operations.cpp @@ -54,7 +54,7 @@ void CSVDoc::Operations::quitOperation (int type) mLayout->removeItem ((*iter)->getLayout()); - delete *iter; + (*iter)->deleteLater(); mOperations.erase (iter); if (oldCount > 1) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 6aafef4ed0..49dd2fc8a9 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -18,10 +18,14 @@ #include "operations.hpp" #include "subview.hpp" +#include void CSVDoc::View::closeEvent (QCloseEvent *event) { if (!mViewManager.closeRequest (this)) + { + qDebug() << "ignoring event"; event->ignore(); + } } void CSVDoc::View::setupFileMenu() @@ -117,9 +121,11 @@ void CSVDoc::View::updateActions() mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying)); } -CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews, QMainWindow *viewParent) - : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews), QMainWindow (viewParent) +CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) //, QMainWindow *viewParent) + : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), + mViewTotal (totalViews) //, QMainWindow (viewParent) { + setAttribute (Qt::WA_DeleteOnClose, true); setDockOptions (QMainWindow::AllowNestedDocks); resize (300, 300); /// \todo get default size from settings and set reasonable minimal size diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 28ab24b744..f50a0550ee 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -67,7 +67,7 @@ namespace CSVDoc public: - View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews, QMainWindow *viewParent); + View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); //, QMainWindow *viewParent); ///< The ownership of \a document is not transferred to *this. virtual ~View(); @@ -94,6 +94,8 @@ namespace CSVDoc void addSubView (const CSMWorld::UniversalId& id); + void abortOperation (int type); + private slots: void newView(); @@ -106,7 +108,6 @@ namespace CSVDoc void addGmstsSubView(); - void abortOperation (int type); }; } diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index a8faefb970..59e53dfe07 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -12,6 +12,10 @@ #include "view.hpp" +#include +#include + + void CSVDoc::ViewManager::updateIndices() { std::map > documents; @@ -31,7 +35,7 @@ void CSVDoc::ViewManager::updateIndices() } CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) -: mDocumentManager (documentManager) + : mDocumentManager (documentManager), mCloseMeOnSaveStateChange(0) { mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; @@ -59,9 +63,9 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document) this, SLOT (progress (int, int, int, int, CSMDoc::Document *))); } - QMainWindow *mainWindow = new QMainWindow; + // QMainWindow *mainWindow = new QMainWindow; - View *view = new View (*this, document, countViews (document)+1, mainWindow); + View *view = new View (*this, document, countViews (document)+1); //, mainWindow); mViews.push_back (view); @@ -90,6 +94,8 @@ bool CSVDoc::ViewManager::closeRequest (View *view) { std::vector::iterator iter = std::find (mViews.begin(), mViews.end(), view); + bool continueWithClose = true; + if (iter!=mViews.end()) { bool last = countViews (view->getDocument())<=1; @@ -97,16 +103,98 @@ bool CSVDoc::ViewManager::closeRequest (View *view) /// \todo check if save is in progress -> warn user about possible data loss /// \todo check if document has not been saved -> return false and start close dialogue - mViews.erase (iter); - view->deleteLater(); + CSMDoc::Document *document = view->getDocument(); - if (last) - mDocumentManager.removeDocument (view->getDocument()); - else - updateIndices(); + //notify user of unsaved changes and process response + if ( document->getState() & CSMDoc::State_Modified) + continueWithClose = showModifiedDocumentMessageBox (view); + + //notify user of saving in progress + if ( document->getState() & CSMDoc::State_Saving ) + continueWithClose = showSaveInProgressMessageBox (view); + + qDebug() << "Continue with close? " << continueWithClose; + + if (continueWithClose) + { + mViews.erase (iter); + + if (last) + mDocumentManager.removeDocument (document); + else + updateIndices(); + } } - return true; + return continueWithClose; +} + +bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (View* view) +{ + QMessageBox messageBox; + + messageBox.setText ("The document has been modified."); + messageBox.setInformativeText ("Do you want to save your changes?"); + messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + messageBox.setDefaultButton (QMessageBox::Save); + + bool retVal = true; + + switch (messageBox.exec()) + { + case QMessageBox::Save: + view->getDocument()->save(); + mCloseMeOnSaveStateChange = view; + retVal = false; + break; + + case QMessageBox::Discard: + break; + + case QMessageBox::Cancel: + retVal = false; + break; + + default: + break; + + } + + return retVal; +} + +bool CSVDoc::ViewManager::showSaveInProgressMessageBox (View* view) +{ + QMessageBox messageBox; + + messageBox.setText ("The document is currently being saved."); + messageBox.setInformativeText("Do you want to abort the save?"); + messageBox.setStandardButtons (QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + + bool retVal = false; + + switch (messageBox.exec()) + { + case QMessageBox::Yes: + view->abortOperation(CSMDoc::State_Saving); + // mCloseMeOnSaveStateChange = view; + retVal = false; + break; + + case QMessageBox::No: + //mCloseMeOnSaveStateChange = view; + retVal = false; + break; + + case QMessageBox::Cancel: + retVal = false; + break; + + default: + break; + } + + return retVal; } void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *document) @@ -114,6 +202,19 @@ void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *doc for (std::vector::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) if ((*iter)->getDocument()==document) (*iter)->updateDocumentState(); + + if (mPreviousDocumentState & CSMDoc::State_Saving) + qDebug() << "Last state was saving"; + else + qDebug() << "Last state was something else"; +/* + if (mCloseMeOnSaveStateChange && (mPreviousDocumentState & CSMDoc::State_Saving)) + { + mCloseMeOnSaveStateChange->close(); + mCloseMeOnSaveStateChange = 0; + } +*/ + mPreviousDocumentState = state; } void CSVDoc::ViewManager::progress (int current, int max, int type, int threads, CSMDoc::Document *document) diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 72e7a3e1a1..2517f8ccbe 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -27,12 +27,17 @@ namespace CSVDoc CSMDoc::DocumentManager& mDocumentManager; std::vector mViews; CSVWorld::CommandDelegateFactoryCollection *mDelegateFactories; + View *mCloseMeOnSaveStateChange; + int mPreviousDocumentState; // not implemented ViewManager (const ViewManager&); ViewManager& operator= (const ViewManager&); void updateIndices(); + bool showModifiedDocumentMessageBox (View* view); + bool showSaveInProgressMessageBox (View* view); + public: @@ -63,4 +68,4 @@ namespace CSVDoc } -#endif \ No newline at end of file +#endif From a2e36594c97eface26fabeee13c27e1f84ff8351 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 2 Mar 2013 09:22:44 -0600 Subject: [PATCH 02/17] Completed "abort save on close" feature --- apps/opencs/view/doc/view.cpp | 4 ++-- apps/opencs/view/doc/view.hpp | 2 +- apps/opencs/view/doc/viewmanager.cpp | 23 ++++++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 49dd2fc8a9..b4d137be2e 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -121,9 +121,9 @@ void CSVDoc::View::updateActions() mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying)); } -CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) //, QMainWindow *viewParent) +CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), - mViewTotal (totalViews) //, QMainWindow (viewParent) + mViewTotal (totalViews) { setAttribute (Qt::WA_DeleteOnClose, true); setDockOptions (QMainWindow::AllowNestedDocks); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index f50a0550ee..d436aebe76 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -67,7 +67,7 @@ namespace CSVDoc public: - View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); //, QMainWindow *viewParent); + View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); ///< The ownership of \a document is not transferred to *this. virtual ~View(); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 59e53dfe07..02407dfcde 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -171,22 +171,22 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (View* view) messageBox.setInformativeText("Do you want to abort the save?"); messageBox.setStandardButtons (QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); - bool retVal = false; + bool retVal = true; switch (messageBox.exec()) { - case QMessageBox::Yes: + case QMessageBox::Yes: //immediate shutdown + mCloseMeOnSaveStateChange = 0; view->abortOperation(CSMDoc::State_Saving); - // mCloseMeOnSaveStateChange = view; + break; + + case QMessageBox::No: //shutdown after save completes + mCloseMeOnSaveStateChange = view; retVal = false; break; - case QMessageBox::No: - //mCloseMeOnSaveStateChange = view; - retVal = false; - break; - - case QMessageBox::Cancel: + case QMessageBox::Cancel: //abort shutdown, allow save to complete + mCloseMeOnSaveStateChange = 0; retVal = false; break; @@ -207,13 +207,14 @@ void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *doc qDebug() << "Last state was saving"; else qDebug() << "Last state was something else"; -/* + + //mechanism to shutdown main window after saving operation completes if (mCloseMeOnSaveStateChange && (mPreviousDocumentState & CSMDoc::State_Saving)) { mCloseMeOnSaveStateChange->close(); mCloseMeOnSaveStateChange = 0; } -*/ + mPreviousDocumentState = state; } From bf6c855e6d829ca2f54abc380f6653cb0a5e3626 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 2 Mar 2013 12:49:26 -0600 Subject: [PATCH 03/17] Final changes to implement save-on-close features --- apps/opencs/view/doc/view.cpp | 9 +++--- apps/opencs/view/doc/viewmanager.cpp | 41 +++++++++++++++------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index fea121aa0d..0a8759fa1f 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -18,14 +18,10 @@ #include "operations.hpp" #include "subview.hpp" -#include void CSVDoc::View::closeEvent (QCloseEvent *event) { if (!mViewManager.closeRequest (this)) - { - qDebug() << "ignoring event"; event->ignore(); - } } void CSVDoc::View::setupFileMenu() @@ -43,6 +39,11 @@ void CSVDoc::View::setupFileMenu() mSave = new QAction (tr ("&Save"), this); connect (mSave, SIGNAL (triggered()), this, SLOT (save())); file->addAction (mSave); + + QAction *exit = new QAction (tr ("&Exit"), this); + connect (exit, SIGNAL (triggered()), this, SLOT (close())); + file->addAction(exit); + } void CSVDoc::View::setupEditMenu() diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 02407dfcde..a5c7910c0f 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -12,7 +12,6 @@ #include "view.hpp" -#include #include @@ -105,15 +104,13 @@ bool CSVDoc::ViewManager::closeRequest (View *view) CSMDoc::Document *document = view->getDocument(); - //notify user of unsaved changes and process response - if ( document->getState() & CSMDoc::State_Modified) - continueWithClose = showModifiedDocumentMessageBox (view); - //notify user of saving in progress if ( document->getState() & CSMDoc::State_Saving ) continueWithClose = showSaveInProgressMessageBox (view); - - qDebug() << "Continue with close? " << continueWithClose; + else + //notify user of unsaved changes and process response + if ( document->getState() & CSMDoc::State_Modified) + continueWithClose = showModifiedDocumentMessageBox (view); if (continueWithClose) { @@ -144,8 +141,13 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (View* view) { case QMessageBox::Save: view->getDocument()->save(); - mCloseMeOnSaveStateChange = view; - retVal = false; + + retVal = !(view->getDocument()->getState() & CSMDoc::State_Saving); + + if (!retVal) + mCloseMeOnSaveStateChange = view; + else + mCloseMeOnSaveStateChange = 0; break; case QMessageBox::Discard: @@ -181,8 +183,16 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (View* view) break; case QMessageBox::No: //shutdown after save completes + + //return true (continue with close) if the save operation ended before the + //user clicked "No" + retVal = !(view->getDocument()->getState() & CSMDoc::State_Saving); + + if (!retVal) mCloseMeOnSaveStateChange = view; - retVal = false; + else + mCloseMeOnSaveStateChange = 0; + break; case QMessageBox::Cancel: //abort shutdown, allow save to complete @@ -203,17 +213,10 @@ void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *doc if ((*iter)->getDocument()==document) (*iter)->updateDocumentState(); - if (mPreviousDocumentState & CSMDoc::State_Saving) - qDebug() << "Last state was saving"; - else - qDebug() << "Last state was something else"; - //mechanism to shutdown main window after saving operation completes if (mCloseMeOnSaveStateChange && (mPreviousDocumentState & CSMDoc::State_Saving)) - { - mCloseMeOnSaveStateChange->close(); - mCloseMeOnSaveStateChange = 0; - } + if (mCloseMeOnSaveStateChange->close()) + mCloseMeOnSaveStateChange = 0; mPreviousDocumentState = state; } From eb90bd71badf66f7368f2c936c3b844ab7b3076a Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 2 Mar 2013 21:34:55 -0600 Subject: [PATCH 04/17] Fixed triggering confirmation messages boxes when more than one view is open. --- apps/opencs/view/doc/viewmanager.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index a5c7910c0f..63dd18291c 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -62,9 +62,7 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document) this, SLOT (progress (int, int, int, int, CSMDoc::Document *))); } - // QMainWindow *mainWindow = new QMainWindow; - - View *view = new View (*this, document, countViews (document)+1); //, mainWindow); + View *view = new View (*this, document, countViews (document)+1); mViews.push_back (view); @@ -104,18 +102,21 @@ bool CSVDoc::ViewManager::closeRequest (View *view) CSMDoc::Document *document = view->getDocument(); - //notify user of saving in progress - if ( document->getState() & CSMDoc::State_Saving ) - continueWithClose = showSaveInProgressMessageBox (view); - else - //notify user of unsaved changes and process response - if ( document->getState() & CSMDoc::State_Modified) - continueWithClose = showModifiedDocumentMessageBox (view); + if (last) + { + //notify user of saving in progress + if ( (document->getState() & CSMDoc::State_Saving) ) + continueWithClose = showSaveInProgressMessageBox (view); + else + //notify user of unsaved changes and process response + if ( document->getState() & CSMDoc::State_Modified) + continueWithClose = showModifiedDocumentMessageBox (view); + } + + mViews.erase (iter); if (continueWithClose) { - mViews.erase (iter); - if (last) mDocumentManager.removeDocument (document); else From 6911868f2af56b48f2884e65092e0bbb52e14f56 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 3 Mar 2013 15:58:26 -0600 Subject: [PATCH 05/17] File->close and File->exit menu items added. Exit uses closeAllWindows() to ensure ViewManager::closeRequest is called on the last open window. Exit will close all open windows but the last one in cases of active save operation or modified file. --- apps/opencs/editor.cpp | 4 +++- apps/opencs/view/doc/view.cpp | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index e2df365a29..98b67142a5 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -58,5 +58,7 @@ int CS::Editor::run() { mStartup.show(); + QApplication::setQuitOnLastWindowClosed (true); + return QApplication::exec(); -} \ No newline at end of file +} diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 0a8759fa1f..78eba78801 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../../model/doc/document.hpp" @@ -40,10 +41,15 @@ void CSVDoc::View::setupFileMenu() connect (mSave, SIGNAL (triggered()), this, SLOT (save())); file->addAction (mSave); + QAction *close = new QAction (tr ("&Close"), this); + connect (close, SIGNAL (triggered()), this, SLOT (close())); + file->addAction(close); + QAction *exit = new QAction (tr ("&Exit"), this); - connect (exit, SIGNAL (triggered()), this, SLOT (close())); + connect (exit, SIGNAL (triggered()), QApplication::instance(), SLOT (closeAllWindows())); file->addAction(exit); + } void CSVDoc::View::setupEditMenu() From 03c7f181125e05ebf8a46818f9e616db9a267db7 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Wed, 6 Mar 2013 06:41:33 -0600 Subject: [PATCH 06/17] Fixes for save-on-close message boxes --- apps/opencs/CMakeLists.txt | 1 - apps/opencs/model/doc/document.cpp | 7 +- apps/opencs/view/doc/view.cpp | 19 ++-- apps/opencs/view/doc/view.hpp | 10 +- apps/opencs/view/doc/viewmanager.cpp | 156 ++++++++++++++++++--------- apps/opencs/view/doc/viewmanager.hpp | 17 ++- 6 files changed, 141 insertions(+), 69 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index d5d389a141..0446d921ff 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -1,4 +1,3 @@ - set (OPENCS_SRC main.cpp) opencs_units (. editor) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index b361577bec..2cdd1f5383 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -287,11 +287,13 @@ void CSMDoc::Document::abortOperation (int type) } } + void CSMDoc::Document::modificationStateChanged (bool clean) { emit stateChanged (getState(), this); } + void CSMDoc::Document::operationDone (int type) { emit stateChanged (getState(), this); @@ -305,9 +307,12 @@ void CSMDoc::Document::saving() if (mSaveCount>15) { + //clear the stack before resetting the save state + //to avoid emitting incorrect states + mUndoStack.setClean(); + mSaveCount = 0; mSaveTimer.stop(); - mUndoStack.setClean(); emit stateChanged (getState(), this); } } diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 78eba78801..29aa471fdf 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -46,10 +46,10 @@ void CSVDoc::View::setupFileMenu() file->addAction(close); QAction *exit = new QAction (tr ("&Exit"), this); - connect (exit, SIGNAL (triggered()), QApplication::instance(), SLOT (closeAllWindows())); + connect (exit, SIGNAL (triggered()), this, SLOT (exitApplication())); + connect (this, SIGNAL (closeAllViews(View *)), &mViewManager, SLOT (closeAllViews(View *))); + file->addAction(exit); - - } void CSVDoc::View::setupEditMenu() @@ -132,13 +132,11 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews) { - setAttribute (Qt::WA_DeleteOnClose, true); setDockOptions (QMainWindow::AllowNestedDocks); resize (300, 300); /// \todo get default size from settings and set reasonable minimal size - mSubViewWindow = new QMainWindow(); - setCentralWidget (mSubViewWindow); + setCentralWidget (&mSubViewWindow); mOperations = new Operations; addDockWidget (Qt::BottomDockWidgetArea, mOperations); @@ -213,7 +211,7 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id) /// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis) SubView *view = mSubViewFactory.makeSubView (id, *mDocument); - mSubViewWindow->addDockWidget (Qt::TopDockWidgetArea, view); + mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view); connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this, SLOT (addSubView (const CSMWorld::UniversalId&))); @@ -252,7 +250,12 @@ void CSVDoc::View::abortOperation (int type) updateActions(); } -QDockWidget *CSVDoc::View::getOperations() const +CSVDoc::Operations *CSVDoc::View::getOperations() const { return mOperations; } + +void CSVDoc::View::exitApplication() +{ + emit closeAllViews (this); +} diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index d436aebe76..d6b6ad4601 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -41,7 +41,8 @@ namespace CSVDoc std::vector mEditingActions; Operations *mOperations; SubViewFactoryManager mSubViewFactory; - QMainWindow* mSubViewWindow; + QMainWindow mSubViewWindow; + // not implemented View (const View&); @@ -68,6 +69,7 @@ namespace CSVDoc public: View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); + ///< The ownership of \a document is not transferred to *this. virtual ~View(); @@ -82,7 +84,7 @@ namespace CSVDoc void updateProgress (int current, int max, int type, int threads); - QDockWidget *getOperations() const; + Operations *getOperations() const; signals: @@ -90,6 +92,8 @@ namespace CSVDoc void loadDocumentRequest(); + void closeAllViews (View *); + public slots: void addSubView (const CSMWorld::UniversalId& id); @@ -108,6 +112,8 @@ namespace CSVDoc void addGmstsSubView(); + void exitApplication(); + }; } diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 63dd18291c..9bb96167d9 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -13,7 +13,7 @@ #include "view.hpp" #include - +#include void CSVDoc::ViewManager::updateIndices() { @@ -34,7 +34,7 @@ void CSVDoc::ViewManager::updateIndices() } CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) - : mDocumentManager (documentManager), mCloseMeOnSaveStateChange(0) + : mDocumentManager (documentManager), mCloseMeOnSaveStateChange(0), mUserWarned(false) { mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; @@ -46,6 +46,7 @@ CSVDoc::ViewManager::~ViewManager() { delete mDelegateFactories; + //not needed due to deletion in ViewManager::closeRequest? for (std::vector::iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) delete *iter; } @@ -64,6 +65,7 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document) View *view = new View (*this, document, countViews (document)+1); + mViews.push_back (view); view->show(); @@ -106,17 +108,18 @@ bool CSVDoc::ViewManager::closeRequest (View *view) { //notify user of saving in progress if ( (document->getState() & CSMDoc::State_Saving) ) - continueWithClose = showSaveInProgressMessageBox (view); - else - //notify user of unsaved changes and process response - if ( document->getState() & CSMDoc::State_Modified) - continueWithClose = showModifiedDocumentMessageBox (view); - } + continueWithClose = showSaveInProgressMessageBox (iter); - mViews.erase (iter); + //notify user of unsaved changes and process response + else if ( document->getState() & CSMDoc::State_Modified) + continueWithClose = showModifiedDocumentMessageBox (iter); + } if (continueWithClose) { + (*iter)->deleteLater(); + mViews.erase (iter); + if (last) mDocumentManager.removeDocument (document); else @@ -127,7 +130,7 @@ bool CSVDoc::ViewManager::closeRequest (View *view) return continueWithClose; } -bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (View* view) +bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (std::vector::iterator viewIter) { QMessageBox messageBox; @@ -138,23 +141,32 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (View* view) bool retVal = true; - switch (messageBox.exec()) + connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close())); + connect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + mUserWarned = true; + + int response = messageBox.exec(); + + mUserWarned = false; + + switch (response) { case QMessageBox::Save: - view->getDocument()->save(); - retVal = !(view->getDocument()->getState() & CSMDoc::State_Saving); - - if (!retVal) - mCloseMeOnSaveStateChange = view; - else - mCloseMeOnSaveStateChange = 0; + (*viewIter)->getDocument()->save(); + mCloseMeOnSaveStateChange = viewIter; + retVal = false; break; case QMessageBox::Discard: + + disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); break; case QMessageBox::Cancel: + + //disconnect to prevent unintended view closures + disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); retVal = false; break; @@ -166,43 +178,55 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (View* view) return retVal; } -bool CSVDoc::ViewManager::showSaveInProgressMessageBox (View* view) +bool CSVDoc::ViewManager::showSaveInProgressMessageBox (std::vector::iterator viewIter) { QMessageBox messageBox; messageBox.setText ("The document is currently being saved."); - messageBox.setInformativeText("Do you want to abort the save?"); - messageBox.setStandardButtons (QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + messageBox.setInformativeText("Do you want to close now and abort saving, or wait until saving has completed?"); + + QPushButton* waitButton = messageBox.addButton (tr("Wait"), QMessageBox::YesRole); + QPushButton* closeButton = messageBox.addButton (tr("Close Now"), QMessageBox::RejectRole); + QPushButton* cancelButton = messageBox.addButton (tr("Cancel"), QMessageBox::NoRole); + + messageBox.setDefaultButton (waitButton); bool retVal = true; - switch (messageBox.exec()) + //Connections shut down message box if operation ends before user makes a decision. + connect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close())); + + //set / clear the user warned flag to indicate whether or not the message box is currently active. + mUserWarned = true; + + messageBox.exec(); + + mUserWarned = false; + + //if closed by the warning handler, defaults to the RejectRole button (closeButton) + if (messageBox.clickedButton() == waitButton) { - case QMessageBox::Yes: //immediate shutdown - mCloseMeOnSaveStateChange = 0; - view->abortOperation(CSMDoc::State_Saving); - break; + //save the View iterator for shutdown after the save operation ends + mCloseMeOnSaveStateChange = viewIter; + retVal = false; + } - case QMessageBox::No: //shutdown after save completes + else if (messageBox.clickedButton() == closeButton) + { + //disconnect to avoid segmentation fault + disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + (*viewIter)->abortOperation(CSMDoc::State_Saving); + mCloseMeOnSaveStateChange = mViews.end(); + } - //return true (continue with close) if the save operation ended before the - //user clicked "No" - retVal = !(view->getDocument()->getState() & CSMDoc::State_Saving); - - if (!retVal) - mCloseMeOnSaveStateChange = view; - else - mCloseMeOnSaveStateChange = 0; - - break; - - case QMessageBox::Cancel: //abort shutdown, allow save to complete - mCloseMeOnSaveStateChange = 0; - retVal = false; - break; - - default: - break; + else if (messageBox.clickedButton() == cancelButton) + { + //abort shutdown, allow save to complete + //disconnection to prevent unintended view closures + mCloseMeOnSaveStateChange = mViews.end(); + disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + retVal = false; } return retVal; @@ -213,13 +237,6 @@ void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *doc for (std::vector::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) if ((*iter)->getDocument()==document) (*iter)->updateDocumentState(); - - //mechanism to shutdown main window after saving operation completes - if (mCloseMeOnSaveStateChange && (mPreviousDocumentState & CSMDoc::State_Saving)) - if (mCloseMeOnSaveStateChange->close()) - mCloseMeOnSaveStateChange = 0; - - mPreviousDocumentState = state; } void CSVDoc::ViewManager::progress (int current, int max, int type, int threads, CSMDoc::Document *document) @@ -228,3 +245,38 @@ void CSVDoc::ViewManager::progress (int current, int max, int type, int threads, if ((*iter)->getDocument()==document) (*iter)->updateProgress (current, max, type, threads); } + +void CSVDoc::ViewManager::onCloseWarningHandler (int state, CSMDoc::Document *document) +{ + if ( !(state & CSMDoc::State_Saving) ) + { + //if the user is being warned (message box is active), shut down the message box, + //as there is no save operation currently running + if ( mUserWarned ) + emit closeMessageBox(); + + //otherwise, the user has closed the message box before the save operation ended. + //close the view + else if (mCloseMeOnSaveStateChange!=mViews.end()) + { + (*mCloseMeOnSaveStateChange)->close(); + mCloseMeOnSaveStateChange = mViews.end(); + } + } +} + +void CSVDoc::ViewManager::closeAllViews (View *lastView) +{ + //forces document views to close in an orderly manner + // the last view closed is the view from which the "Exit" action was triggered + while (mViews.size() > 1) + { + std::vector::iterator iter = mViews.begin(); + + if ((*iter) != lastView) + (*iter)->close(); + else (*(++iter))->close(); + } + + lastView->close(); +} diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 2517f8ccbe..92df13785f 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -27,17 +27,16 @@ namespace CSVDoc CSMDoc::DocumentManager& mDocumentManager; std::vector mViews; CSVWorld::CommandDelegateFactoryCollection *mDelegateFactories; - View *mCloseMeOnSaveStateChange; - int mPreviousDocumentState; + std::vector::iterator mCloseMeOnSaveStateChange; + bool mUserWarned; // not implemented ViewManager (const ViewManager&); ViewManager& operator= (const ViewManager&); void updateIndices(); - bool showModifiedDocumentMessageBox (View* view); - bool showSaveInProgressMessageBox (View* view); - + bool showModifiedDocumentMessageBox (std::vector::iterator view); + bool showSaveInProgressMessageBox (std::vector::iterator view); public: @@ -59,11 +58,19 @@ namespace CSVDoc void loadDocumentRequest(); + void closeMessageBox(); + + public slots: + + void closeAllViews (View *lastView); + private slots: void documentStateChanged (int state, CSMDoc::Document *document); void progress (int current, int max, int type, int threads, CSMDoc::Document *document); + + void onCloseWarningHandler(int state, CSMDoc::Document* document); }; } From ce91ef36ead190d6e038f75feee31b2ce1f9db56 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 10 Mar 2013 07:49:43 -0500 Subject: [PATCH 07/17] Fix for warnings on close, leaves all views open until a decision is made --- apps/opencs/view/doc/view.cpp | 8 +------ apps/opencs/view/doc/view.hpp | 2 -- apps/opencs/view/doc/viewmanager.cpp | 31 ++++++---------------------- apps/opencs/view/doc/viewmanager.hpp | 4 ---- 4 files changed, 7 insertions(+), 38 deletions(-) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 29aa471fdf..51d4a5135c 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -46,8 +46,7 @@ void CSVDoc::View::setupFileMenu() file->addAction(close); QAction *exit = new QAction (tr ("&Exit"), this); - connect (exit, SIGNAL (triggered()), this, SLOT (exitApplication())); - connect (this, SIGNAL (closeAllViews(View *)), &mViewManager, SLOT (closeAllViews(View *))); + connect (exit, SIGNAL (triggered()), QApplication::instance(), SLOT (closeAllWindows())); file->addAction(exit); } @@ -254,8 +253,3 @@ CSVDoc::Operations *CSVDoc::View::getOperations() const { return mOperations; } - -void CSVDoc::View::exitApplication() -{ - emit closeAllViews (this); -} diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index d6b6ad4601..92c57fe9ec 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -112,8 +112,6 @@ namespace CSVDoc void addGmstsSubView(); - void exitApplication(); - }; } diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index eb9744c11c..5614aeda44 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -108,16 +108,13 @@ bool CSVDoc::ViewManager::closeRequest (View *view) CSMDoc::Document *document = view->getDocument(); - if (last) - { - //notify user of saving in progress - if ( (document->getState() & CSMDoc::State_Saving) ) - continueWithClose = showSaveInProgressMessageBox (iter); + //notify user of saving in progress + if ( (document->getState() & CSMDoc::State_Saving) ) + continueWithClose = showSaveInProgressMessageBox (iter); - //notify user of unsaved changes and process response - else if ( document->getState() & CSMDoc::State_Modified) - continueWithClose = showModifiedDocumentMessageBox (iter); - } + //notify user of unsaved changes and process response + else if ( document->getState() & CSMDoc::State_Modified) + continueWithClose = showModifiedDocumentMessageBox (iter); if (continueWithClose) { @@ -268,19 +265,3 @@ void CSVDoc::ViewManager::onCloseWarningHandler (int state, CSMDoc::Document *do } } } - -void CSVDoc::ViewManager::closeAllViews (View *lastView) -{ - //forces document views to close in an orderly manner - // the last view closed is the view from which the "Exit" action was triggered - while (mViews.size() > 1) - { - std::vector::iterator iter = mViews.begin(); - - if ((*iter) != lastView) - (*iter)->close(); - else (*(++iter))->close(); - } - - lastView->close(); -} diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 92df13785f..82a8b57330 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -60,10 +60,6 @@ namespace CSVDoc void closeMessageBox(); - public slots: - - void closeAllViews (View *lastView); - private slots: void documentStateChanged (int state, CSMDoc::Document *document); From 96b62940b399e4f88fb9c415d923a8506e3581af Mon Sep 17 00:00:00 2001 From: graffy76 Date: Mon, 11 Mar 2013 06:38:27 -0500 Subject: [PATCH 08/17] Fixes docked subviews becoming tabbed and application closure when closing one of several views. --- apps/opencs/view/doc/view.cpp | 4 +++- apps/opencs/view/doc/viewmanager.cpp | 22 +++++++++++++--------- apps/opencs/view/doc/viewmanager.hpp | 4 +++- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 51d4a5135c..dfbd92a609 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -131,10 +131,12 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews) { - setDockOptions (QMainWindow::AllowNestedDocks); + // setDockOptions (QMainWindow::AllowNestedDocks); resize (300, 300); /// \todo get default size from settings and set reasonable minimal size + mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks); + setCentralWidget (&mSubViewWindow); mOperations = new Operations; diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 5614aeda44..83ace49387 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -14,6 +14,8 @@ #include #include +#include +#include void CSVDoc::ViewManager::updateIndices() { @@ -44,6 +46,8 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType, new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float)); + connect (this, SIGNAL (exitApplication()), QApplication::instance(), SLOT (closeAllWindows())); + } CSVDoc::ViewManager::~ViewManager() @@ -143,7 +147,7 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (std::vector::i bool retVal = true; connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close())); - connect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + connect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); mUserWarned = true; int response = messageBox.exec(); @@ -161,13 +165,13 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (std::vector::i case QMessageBox::Discard: - disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); break; case QMessageBox::Cancel: //disconnect to prevent unintended view closures - disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); retVal = false; break; @@ -195,7 +199,7 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (std::vector::ite bool retVal = true; //Connections shut down message box if operation ends before user makes a decision. - connect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + connect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close())); //set / clear the user warned flag to indicate whether or not the message box is currently active. @@ -216,7 +220,7 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (std::vector::ite else if (messageBox.clickedButton() == closeButton) { //disconnect to avoid segmentation fault - disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); (*viewIter)->abortOperation(CSMDoc::State_Saving); mCloseMeOnSaveStateChange = mViews.end(); } @@ -226,7 +230,7 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (std::vector::ite //abort shutdown, allow save to complete //disconnection to prevent unintended view closures mCloseMeOnSaveStateChange = mViews.end(); - disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onCloseWarningHandler(int, CSMDoc::Document *))); + disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); retVal = false; } @@ -247,7 +251,7 @@ void CSVDoc::ViewManager::progress (int current, int max, int type, int threads, (*iter)->updateProgress (current, max, type, threads); } -void CSVDoc::ViewManager::onCloseWarningHandler (int state, CSMDoc::Document *document) +void CSVDoc::ViewManager::onExitWarningHandler (int state, CSMDoc::Document *document) { if ( !(state & CSMDoc::State_Saving) ) { @@ -257,10 +261,10 @@ void CSVDoc::ViewManager::onCloseWarningHandler (int state, CSMDoc::Document *do emit closeMessageBox(); //otherwise, the user has closed the message box before the save operation ended. - //close the view + //exit the application else if (mCloseMeOnSaveStateChange!=mViews.end()) { - (*mCloseMeOnSaveStateChange)->close(); + emit exitApplication(); mCloseMeOnSaveStateChange = mViews.end(); } } diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 82a8b57330..b77e5f5758 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -60,13 +60,15 @@ namespace CSVDoc void closeMessageBox(); + void exitApplication(); + private slots: void documentStateChanged (int state, CSMDoc::Document *document); void progress (int current, int max, int type, int threads, CSMDoc::Document *document); - void onCloseWarningHandler(int state, CSMDoc::Document* document); + void onExitWarningHandler(int state, CSMDoc::Document* document); }; } From 64d517dd796a5f07406f909ee25fca81008c920e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 11 Mar 2013 14:42:49 +0100 Subject: [PATCH 09/17] removed unused file type information from esm component --- apps/esmtool/esmtool.cpp | 4 ---- components/esm/esmcommon.hpp | 4 ++-- components/esm/esmreader.cpp | 24 ------------------------ components/esm/esmreader.hpp | 3 --- components/esm/esmwriter.cpp | 16 +++------------- components/esm/esmwriter.hpp | 4 +--- 6 files changed, 6 insertions(+), 49 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 3c9476d7a2..b243917be9 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -23,7 +23,6 @@ struct ESMData std::string author; std::string description; int version; - int type; ESM::ESMReader::MasterList masters; std::deque mRecords; @@ -284,8 +283,6 @@ int load(Arguments& info) info.data.author = esm.getAuthor(); info.data.description = esm.getDesc(); info.data.masters = esm.getMasters(); - info.data.version = esm.getVer(); - info.data.type = esm.getType(); if (!quiet) { @@ -430,7 +427,6 @@ int clone(Arguments& info) esm.setAuthor(info.data.author); esm.setDescription(info.data.description); esm.setVersion(info.data.version); - esm.setType(info.data.type); for (ESM::ESMReader::MasterList::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it) esm.addMaster(it->name, it->size); diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index 335d123378..f5ddf62802 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -41,7 +41,7 @@ union NAME_T { char name[LEN]; int32_t val; - + bool operator==(const char *str) const { for(int i=0; i mBuffer; - SaveData mSaveData; MasterList mMasters; std::vector *mGlobalReaderList; ToUTF8::Utf8Encoder* mEncoder; diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index b9dd5b57b6..faceeeaa6f 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -17,16 +17,6 @@ void ESMWriter::setVersion(int ver) m_header.version = ver; } -int ESMWriter::getType() -{ - return m_header.type; -} - -void ESMWriter::setType(int type) -{ - m_header.type = type; -} - void ESMWriter::setAuthor(const std::string& auth) { strncpy((char*)&m_header.author, auth.c_str(), 32); @@ -86,7 +76,7 @@ void ESMWriter::close() void ESMWriter::startRecord(const std::string& name, uint32_t flags) { m_recordCount++; - + writeName(name); RecordData rec; rec.name = name; @@ -109,7 +99,7 @@ void ESMWriter::startSubRecord(const std::string& name) rec.size = 0; writeT(0); // Size goes here m_records.push_back(rec); - + assert(m_records.back().size == 0); } @@ -118,7 +108,7 @@ void ESMWriter::endRecord(const std::string& name) RecordData rec = m_records.back(); assert(rec.name == name); m_records.pop_back(); - + m_stream->seekp(rec.position); count = false; diff --git a/components/esm/esmwriter.hpp b/components/esm/esmwriter.hpp index 94e173b4ce..f488cce3e1 100644 --- a/components/esm/esmwriter.hpp +++ b/components/esm/esmwriter.hpp @@ -22,8 +22,6 @@ class ESMWriter public: int getVersion(); void setVersion(int ver); - int getType(); - void setType(int type); void setEncoder(ToUTF8::Utf8Encoder *encoding); // Write strings as UTF-8? void setAuthor(const std::string& author); void setDescription(const std::string& desc); @@ -80,7 +78,7 @@ public: { write((char*)&data, size); } - + void startRecord(const std::string& name, uint32_t flags); void startSubRecord(const std::string& name); void endRecord(const std::string& name); From 2e1a1fd11a4cd0583c2c507eb1aaa203444dbd13 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 11 Mar 2013 16:30:47 +0100 Subject: [PATCH 10/17] removing some remains of the removed GMST fixing feature --- apps/esmtool/esmtool.cpp | 3 +-- components/esm/esmcommon.hpp | 11 ----------- components/esm/esmreader.cpp | 12 ------------ components/esm/esmreader.hpp | 2 -- 4 files changed, 1 insertion(+), 27 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index b243917be9..8d060cbd22 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -288,8 +288,7 @@ int load(Arguments& info) { std::cout << "Author: " << esm.getAuthor() << std::endl << "Description: " << esm.getDesc() << std::endl - << "File format version: " << esm.getFVer() << std::endl - << "Special flag: " << esm.getSpecial() << std::endl; + << "File format version: " << esm.getFVer() << std::endl; ESM::ESMReader::MasterList m = esm.getMasters(); if (!m.empty()) { diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index f5ddf62802..af83ad816a 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -21,17 +21,6 @@ enum FileType FT_ESS = 32 // Savegame }; -// Used to mark special files. The original ESM files are given -// special treatment in a few places, most noticably in loading and -// filtering out "dirtly" GMST entries correctly. -enum SpecialFile - { - SF_Other, - SF_Morrowind, - SF_Tribunal, - SF_Bloodmoon - }; - /* A structure used for holding fixed-length strings. In the case of LEN=4, it can be more efficient to match the string as a 32 bit number, therefore the struct is implemented as a union with an int. diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index edd047d92d..98c598eb9a 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -51,18 +51,6 @@ void ESMReader::openRaw(Ogre::DataStreamPtr _esm, const std::string &name) mEsm = _esm; mCtx.filename = name; mCtx.leftFile = mEsm->size(); - - // Flag certain files for special treatment, based on the file - // name. - const char *cstr = mCtx.filename.c_str(); - if (iends(cstr, "Morrowind.esm")) - mSpf = SF_Morrowind; - else if (iends(cstr, "Tribunal.esm")) - mSpf = SF_Tribunal; - else if (iends(cstr, "Bloodmoon.esm")) - mSpf = SF_Bloodmoon; - else - mSpf = SF_Other; } void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name) diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index 94bf0f3d33..dd7809fb3c 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -38,7 +38,6 @@ public: int getVer() const { return mCtx.header.version; } float getFVer() const { if(mCtx.header.version == VER_12) return 1.2; else return 1.3; } - int getSpecial() const { return mSpf; } const std::string getAuthor() const { return mCtx.header.author.toString(); } const std::string getDesc() const { return mCtx.header.desc.toString(); } const MasterList &getMasters() const { return mMasters; } @@ -261,7 +260,6 @@ private: ESM_Context mCtx; // Special file signifier (see SpecialFile enum above) - int mSpf; // Buffer for ESM strings std::vector mBuffer; From b085c4f7492dcfad922e4ed8260142d0bef64d67 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 11 Mar 2013 16:53:42 +0100 Subject: [PATCH 11/17] removing more leftovers --- components/esm/esmcommon.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index af83ad816a..a8dfcf0bf7 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -14,13 +14,6 @@ enum Version VER_13 = 0x3fa66666 }; -enum FileType - { - FT_ESP = 0, // Plugin - FT_ESM = 1, // Master - FT_ESS = 32 // Savegame - }; - /* A structure used for holding fixed-length strings. In the case of LEN=4, it can be more efficient to match the string as a 32 bit number, therefore the struct is implemented as a union with an int. From 9e68a420ae5dc10e6e12ecf40ce8c99c600e33d5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 12 Mar 2013 08:15:20 +0100 Subject: [PATCH 12/17] restructuring tes3 record structs --- apps/esmtool/esmtool.cpp | 6 +-- apps/openmw/mwworld/esmstore.cpp | 5 +- components/esm/esmcommon.hpp | 52 ++++++++++++------- components/esm/esmreader.cpp | 7 +-- components/esm/esmreader.hpp | 21 +++----- components/esm/esmwriter.cpp | 20 +++---- components/esm/esmwriter.hpp | 3 +- components/esm/loadcell.cpp | 4 +- .../fileorderlist/model/datafilesmodel.cpp | 12 ++--- 9 files changed, 69 insertions(+), 61 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 8d060cbd22..5cc1b6bcbb 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -23,7 +23,7 @@ struct ESMData std::string author; std::string description; int version; - ESM::ESMReader::MasterList masters; + std::vector masters; std::deque mRecords; std::map > mCellRefs; @@ -289,7 +289,7 @@ int load(Arguments& info) std::cout << "Author: " << esm.getAuthor() << std::endl << "Description: " << esm.getDesc() << std::endl << "File format version: " << esm.getFVer() << std::endl; - ESM::ESMReader::MasterList m = esm.getMasters(); + std::vector m = esm.getMasters(); if (!m.empty()) { std::cout << "Masters:" << std::endl; @@ -427,7 +427,7 @@ int clone(Arguments& info) esm.setDescription(info.data.description); esm.setVersion(info.data.version); - for (ESM::ESMReader::MasterList::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it) + for (std::vector::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it) esm.addMaster(it->name, it->size); std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary); diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 257676076c..09a39ff8b1 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -27,14 +27,15 @@ void ESMStore::load(ESM::ESMReader &esm) ESM::Dialogue *dialogue = 0; + /// \todo Move this to somewhere else. ESMReader? // Cache parent esX files by tracking their indices in the global list of // all files/readers used by the engine. This will greaty accelerate // refnumber mangling, as required for handling moved references. int index = ~0; - const ESM::ESMReader::MasterList &masters = esm.getMasters(); + const std::vector &masters = esm.getMasters(); std::vector *allPlugins = esm.getGlobalReaderList(); for (size_t j = 0; j < masters.size(); j++) { - ESM::MasterData &mast = const_cast(masters[j]); + ESM::Header::MasterData &mast = const_cast(masters[j]); std::string fname = mast.name; for (int i = 0; i < esm.getIndex(); i++) { const std::string &candidate = allPlugins->at(i).getContext().filename; diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index a8dfcf0bf7..cbdd05a49a 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -2,6 +2,8 @@ #define OPENMW_ESM_COMMON_H #include +#include +#include #include #include @@ -43,6 +45,8 @@ union NAME_T bool operator!=(int v) const { return v != val; } std::string toString() const { return std::string(name, strnlen(name, LEN)); } + + void assign (const std::string& value) { std::strncpy (name, value.c_str(), LEN); } }; typedef NAME_T<4> NAME; @@ -53,27 +57,37 @@ typedef NAME_T<256> NAME256; #pragma pack(push) #pragma pack(1) /// File header data for all ES files -struct HEDRstruct +struct Header { - /* File format version. This is actually a float, the supported - versions are 1.2 and 1.3. These correspond to: - 1.2 = 0x3f99999a and 1.3 = 0x3fa66666 - */ - int version; - int type; // 0=esp, 1=esm, 32=ess (unused) - NAME32 author; // Author's name - NAME256 desc; // File description - int records; // Number of records? Not used. -}; + struct Data + { + /* File format version. This is actually a float, the supported + versions are 1.2 and 1.3. These correspond to: + 1.2 = 0x3f99999a and 1.3 = 0x3fa66666 + */ + int version; + int type; // 0=esp, 1=esm, 32=ess (unused) + NAME32 author; // Author's name + NAME256 desc; // File description + int records; // Number of records? Not used. + }; -// Defines another files (esm or esp) that this file depends upon. -struct MasterData -{ - std::string name; - uint64_t size; - int index; // Position of the parent file in the global list of loaded files -}; + // Defines another files (esm or esp) that this file depends upon. + struct MasterData + { + std::string name; + uint64_t size; + int index; // Position of the parent file in the global list of loaded files + }; + Data mData; + std::vector mMaster; +}; +#pragma pack(pop) + + +#pragma pack(push) +#pragma pack(1) // Data that is only present in save game files struct SaveData { @@ -95,7 +109,7 @@ struct ESM_Context uint32_t leftRec, leftSub; size_t leftFile; NAME recName, subName; - HEDRstruct header; + Header::Data header; // When working with multiple esX files, we will generate lists of all files that // actually contribute to a specific cell. Therefore, we need to store the index // of the file belonging to this contest. See CellStore::(list/load)refs for details. diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index 98c598eb9a..70ab0caa38 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -63,16 +63,17 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name) getRecHeader(); // Get the header - getHNT(mCtx.header, "HEDR", 300); + getHNT (mHeader.mData, "HEDR", 300); + mCtx.header = mHeader.mData; // Some mods abuse the header.version field for the version of the mod instead of the version of the file format, so we can only ignore it. while (isNextSub("MAST")) { - MasterData m; + Header::MasterData m; m.name = getHString(); m.size = getHNLong("DATA"); - mMasters.push_back(m); + mHeader.mMaster.push_back(m); } } diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index dd7809fb3c..6850c7a148 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -22,25 +22,17 @@ public: ESMReader(void); - /************************************************************************* - * - * Public type definitions - * - *************************************************************************/ - - typedef std::vector MasterList; - /************************************************************************* * * Information retrieval * *************************************************************************/ - int getVer() const { return mCtx.header.version; } - float getFVer() const { if(mCtx.header.version == VER_12) return 1.2; else return 1.3; } - const std::string getAuthor() const { return mCtx.header.author.toString(); } - const std::string getDesc() const { return mCtx.header.desc.toString(); } - const MasterList &getMasters() const { return mMasters; } + int getVer() const { return mHeader.mData.version; } + float getFVer() const { if(mHeader.mData.version == VER_12) return 1.2; else return 1.3; } + const std::string getAuthor() const { return mHeader.mData.author.toString(); } + const std::string getDesc() const { return mHeader.mData.desc.toString(); } + const std::vector &getMasters() const { return mHeader.mMaster; } const NAME &retSubName() const { return mCtx.subName; } uint32_t getSubSize() const { return mCtx.leftSub; } @@ -264,7 +256,8 @@ private: // Buffer for ESM strings std::vector mBuffer; - MasterList mMasters; + Header mHeader; + std::vector *mGlobalReaderList; ToUTF8::Utf8Encoder* mEncoder; }; diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index faceeeaa6f..6a3bfa9bdf 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -1,6 +1,5 @@ #include "esmwriter.hpp" #include -#include bool count = true; @@ -9,30 +8,30 @@ namespace ESM int ESMWriter::getVersion() { - return m_header.version; + return mHeader.mData.version; } void ESMWriter::setVersion(int ver) { - m_header.version = ver; + mHeader.mData.version = ver; } void ESMWriter::setAuthor(const std::string& auth) { - strncpy((char*)&m_header.author, auth.c_str(), 32); + mHeader.mData.author.assign (auth); } void ESMWriter::setDescription(const std::string& desc) { - strncpy((char*)&m_header.desc, desc.c_str(), 256); + mHeader.mData.desc.assign (desc); } void ESMWriter::addMaster(const std::string& name, uint64_t size) { - MasterData d; + Header::MasterData d; d.name = name; d.size = size; - m_masters.push_back(d); + mHeader.mMaster.push_back(d); } void ESMWriter::save(const std::string& file) @@ -48,11 +47,12 @@ void ESMWriter::save(std::ostream& file) startRecord("TES3", 0); - m_header.records = 0; - writeHNT("HEDR", m_header, 300); + mHeader.mData.records = 0; + writeHNT("HEDR", mHeader.mData, 300); m_headerPos = m_stream->tellp() - (std::streampos)4; - for (std::list::iterator it = m_masters.begin(); it != m_masters.end(); ++it) + for (std::vector::iterator it = mHeader.mMaster.begin(); + it != mHeader.mMaster.end(); ++it) { writeHNCString("MAST", it->name); writeHNT("DATA", it->size); diff --git a/components/esm/esmwriter.hpp b/components/esm/esmwriter.hpp index f488cce3e1..e8ff27577a 100644 --- a/components/esm/esmwriter.hpp +++ b/components/esm/esmwriter.hpp @@ -88,14 +88,13 @@ public: void write(const char* data, size_t size); private: - std::list m_masters; std::list m_records; std::ostream* m_stream; std::streampos m_headerPos; ToUTF8::Utf8Encoder* m_encoder; int m_recordCount; - HEDRstruct m_header; + Header mHeader; }; } diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index 76a48e5ec4..da60f76af8 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -245,7 +245,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref) // If the most significant 8 bits are used, then this reference already exists. // In this case, do not spawn a new reference, but overwrite the old one. ref.mRefnum &= 0x00ffffff; // delete old plugin ID - const ESM::ESMReader::MasterList &masters = esm.getMasters(); + const std::vector &masters = esm.getMasters(); global = masters[local-1].index + 1; ref.mRefnum |= global << 24; // insert global plugin ID } @@ -348,7 +348,7 @@ bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref) int local = (mref.mRefnum & 0xff000000) >> 24; size_t global = esm.getIndex() + 1; mref.mRefnum &= 0x00ffffff; // delete old plugin ID - const ESM::ESMReader::MasterList &masters = esm.getMasters(); + const std::vector &masters = esm.getMasters(); global = masters[local-1].index + 1; mref.mRefnum |= global << 24; // insert global plugin ID diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index b33e2e12ab..71a320190c 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -157,7 +157,7 @@ Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const if (!file) return Qt::NoItemFlags; - if (canBeChecked(file)) { + if (canBeChecked(file)) { if (index.column() == 0) { return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; } else { @@ -226,7 +226,7 @@ bool lessThanEsmFile(const EsmFile *e1, const EsmFile *e2) return true; if (!e1->fileName().endsWith(".esm") && e2->fileName().endsWith(".esm")) return false; - + return e1->fileName().toLower() < e2->fileName().toLower(); } @@ -281,7 +281,7 @@ void DataFilesModel::addFiles(const QString &path) fileReader.setEncoder(&encoder); fileReader.open(dir.absoluteFilePath(path).toStdString()); - ESM::ESMReader::MasterList mlist = fileReader.getMasters(); + std::vector mlist = fileReader.getMasters(); QStringList masters; for (unsigned int i = 0; i < mlist.size(); ++i) { @@ -369,10 +369,10 @@ QStringList DataFilesModel::checkedItems() QStringList DataFilesModel::checkedItemsPaths() { QStringList list; - + QList::ConstIterator it; QList::ConstIterator itEnd = mFiles.constEnd(); - + int i = 0; for (it = mFiles.constBegin(); it != itEnd; ++it) { EsmFile *file = item(i); @@ -381,7 +381,7 @@ QStringList DataFilesModel::checkedItemsPaths() if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file)) list << file->path(); } - + return list; } From 731ac6a16084e86fef90bff7ca8a676eb652a279 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 12 Mar 2013 08:30:51 +0100 Subject: [PATCH 13/17] removed redundant copy of Header::Data --- components/esm/esmcommon.hpp | 1 - components/esm/esmreader.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index cbdd05a49a..42fdc1211b 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -109,7 +109,6 @@ struct ESM_Context uint32_t leftRec, leftSub; size_t leftFile; NAME recName, subName; - Header::Data header; // When working with multiple esX files, we will generate lists of all files that // actually contribute to a specific cell. Therefore, we need to store the index // of the file belonging to this contest. See CellStore::(list/load)refs for details. diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index 70ab0caa38..ea2bf76945 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -64,7 +64,6 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name) // Get the header getHNT (mHeader.mData, "HEDR", 300); - mCtx.header = mHeader.mData; // Some mods abuse the header.version field for the version of the mod instead of the version of the file format, so we can only ignore it. From 16570ce87b021596e24b281b4e12c66f455e7896 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 12 Mar 2013 09:16:03 +0100 Subject: [PATCH 14/17] moved header record struct to separate file --- components/CMakeLists.txt | 2 +- components/esm/esmcommon.hpp | 33 ----------------------- components/esm/esmreader.cpp | 13 +-------- components/esm/esmreader.hpp | 4 ++- components/esm/esmwriter.cpp | 18 +++---------- components/esm/esmwriter.hpp | 7 ++--- components/esm/loadtes3.cpp | 40 +++++++++++++++++++++++++++ components/esm/loadtes3.hpp | 52 ++++++++++++++++++++++++++++++++++++ 8 files changed, 105 insertions(+), 64 deletions(-) create mode 100644 components/esm/loadtes3.cpp create mode 100644 components/esm/loadtes3.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 38625fb529..f7b97056cb 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -39,7 +39,7 @@ add_component_dir (esm loadclas loadclot loadcont loadcrea loadcrec loaddial loaddoor loadench loadfact loadglob loadgmst loadinfo loadingr loadland loadlevlist loadligh loadlocks loadltex loadmgef loadmisc loadnpcc loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat - loadweap records aipackage effectlist spelllist variant variantimp + loadweap records aipackage effectlist spelllist variant variantimp loadtes3 ) add_component_dir (misc diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index 42fdc1211b..6f51c767ec 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -2,7 +2,6 @@ #define OPENMW_ESM_COMMON_H #include -#include #include #include @@ -54,38 +53,6 @@ typedef NAME_T<32> NAME32; typedef NAME_T<64> NAME64; typedef NAME_T<256> NAME256; -#pragma pack(push) -#pragma pack(1) -/// File header data for all ES files -struct Header -{ - struct Data - { - /* File format version. This is actually a float, the supported - versions are 1.2 and 1.3. These correspond to: - 1.2 = 0x3f99999a and 1.3 = 0x3fa66666 - */ - int version; - int type; // 0=esp, 1=esm, 32=ess (unused) - NAME32 author; // Author's name - NAME256 desc; // File description - int records; // Number of records? Not used. - }; - - // Defines another files (esm or esp) that this file depends upon. - struct MasterData - { - std::string name; - uint64_t size; - int index; // Position of the parent file in the global list of loaded files - }; - - Data mData; - std::vector mMaster; -}; -#pragma pack(pop) - - #pragma pack(push) #pragma pack(1) // Data that is only present in save game files diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index ea2bf76945..979088b801 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -62,18 +62,7 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name) getRecHeader(); - // Get the header - getHNT (mHeader.mData, "HEDR", 300); - - // Some mods abuse the header.version field for the version of the mod instead of the version of the file format, so we can only ignore it. - - while (isNextSub("MAST")) - { - Header::MasterData m; - m.name = getHString(); - m.size = getHNLong("DATA"); - mHeader.mMaster.push_back(m); - } + mHeader.load (*this); } void ESMReader::open(const std::string &file) diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index 6850c7a148..e377470eeb 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -12,7 +12,9 @@ #include #include + #include "esmcommon.hpp" +#include "loadtes3.hpp" namespace ESM { @@ -20,7 +22,7 @@ class ESMReader { public: - ESMReader(void); + ESMReader(); /************************************************************************* * diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index 6a3bfa9bdf..edb681f329 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -1,5 +1,8 @@ #include "esmwriter.hpp" + +#include #include +#include bool count = true; @@ -47,26 +50,13 @@ void ESMWriter::save(std::ostream& file) startRecord("TES3", 0); - mHeader.mData.records = 0; - writeHNT("HEDR", mHeader.mData, 300); - m_headerPos = m_stream->tellp() - (std::streampos)4; - - for (std::vector::iterator it = mHeader.mMaster.begin(); - it != mHeader.mMaster.end(); ++it) - { - writeHNCString("MAST", it->name); - writeHNT("DATA", it->size); - } + mHeader.save (*this); endRecord("TES3"); } void ESMWriter::close() { - std::cout << "Writing amount of saved records (" << m_recordCount - 1 << ")" << std::endl; - m_stream->seekp(m_headerPos); - writeT(m_recordCount-1); - m_stream->seekp(0, std::ios::end); m_stream->flush(); if (!m_records.empty()) diff --git a/components/esm/esmwriter.hpp b/components/esm/esmwriter.hpp index e8ff27577a..b0e9329d4b 100644 --- a/components/esm/esmwriter.hpp +++ b/components/esm/esmwriter.hpp @@ -1,12 +1,13 @@ #ifndef OPENMW_ESM_WRITER_H #define OPENMW_ESM_WRITER_H -#include +#include #include -#include + +#include #include "esmcommon.hpp" -#include +#include "loadtes3.hpp" namespace ESM { diff --git a/components/esm/loadtes3.cpp b/components/esm/loadtes3.cpp new file mode 100644 index 0000000000..64f1446f18 --- /dev/null +++ b/components/esm/loadtes3.cpp @@ -0,0 +1,40 @@ + +#include "loadtes3.hpp" + +#include "esmcommon.hpp" +#include "esmreader.hpp" +#include "esmwriter.hpp" + +void ESM::Header::blank() +{ + mData.version = ESM::VER_13; + mData.type = 0; + mData.author.assign (""); + mData.desc.assign (""); + mData.records = 0; +} + +void ESM::Header::load (ESMReader &esm) +{ + esm.getHNT (mData, "HEDR", 300); + + while (esm.isNextSub ("MAST")) + { + MasterData m; + m.name = esm.getHString(); + m.size = esm.getHNLong ("DATA"); + mMaster.push_back (m); + } +} + +void ESM::Header::save (ESMWriter &esm) +{ + esm.writeHNT ("HEDR", mData, 300); + + for (std::vector::iterator iter = mMaster.begin(); + iter != mMaster.end(); ++iter) + { + esm.writeHNCString ("MAST", iter->name); + esm.writeHNT ("DATA", iter->size); + } +} \ No newline at end of file diff --git a/components/esm/loadtes3.hpp b/components/esm/loadtes3.hpp new file mode 100644 index 0000000000..c0b1e3af77 --- /dev/null +++ b/components/esm/loadtes3.hpp @@ -0,0 +1,52 @@ +#ifndef COMPONENT_ESM_TES3_H +#define COMPONENT_ESM_TES3_H + +#include + +#include "esmcommon.hpp" + +namespace ESM +{ + class ESMReader; + class ESMWriter; + +#pragma pack(push) +#pragma pack(1) + + /// \brief File header record + struct Header + { + struct Data + { + /* File format version. This is actually a float, the supported + versions are 1.2 and 1.3. These correspond to: + 1.2 = 0x3f99999a and 1.3 = 0x3fa66666 + */ + int version; + int type; // 0=esp, 1=esm, 32=ess (unused) + NAME32 author; // Author's name + NAME256 desc; // File description + int records; // Number of records? Not used. + }; + + // Defines another files (esm or esp) that this file depends upon. + struct MasterData + { + std::string name; + uint64_t size; + int index; // Position of the parent file in the global list of loaded files + }; + + Data mData; + std::vector mMaster; + + void blank(); + + void load (ESMReader &esm); + void save (ESMWriter &esm); + }; +#pragma pack(pop) + +} + +#endif \ No newline at end of file From 50abb221625625ae6b448b65ccf74626f3f61437 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 12 Mar 2013 06:28:13 -0500 Subject: [PATCH 15/17] Fix to allow application closing from multiple views and a single view. --- apps/opencs/model/doc/document.cpp | 7 +- apps/opencs/model/doc/document.hpp | 3 +- apps/opencs/view/doc/view.cpp | 10 ++- apps/opencs/view/doc/view.hpp | 6 +- apps/opencs/view/doc/viewmanager.cpp | 89 ++++++++++--------- apps/opencs/view/doc/viewmanager.hpp | 11 ++- .../fileorderlist/model/datafilesmodel.cpp | 2 +- 7 files changed, 76 insertions(+), 52 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 3d8f961121..af34aeedf4 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2,7 +2,7 @@ #include "document.hpp" #include - +#include void CSMDoc::Document::load (const std::vector::const_iterator& begin, const std::vector::const_iterator& end, bool lastAsModified) { @@ -237,6 +237,11 @@ CSMDoc::Document::Document (const std::vector& files, b connect (&mSaveTimer, SIGNAL(timeout()), this, SLOT (saving())); } +CSMDoc::Document::~Document() +{ + qDebug() << "document destroyed"; +} + QUndoStack& CSMDoc::Document::getUndoStack() { return mUndoStack; diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index a7b198689e..94d5fe85cc 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -63,6 +63,7 @@ namespace CSMDoc public: Document (const std::vector& files, bool new_); + ~Document(); QUndoStack& getUndoStack(); @@ -105,4 +106,4 @@ namespace CSMDoc }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index dfbd92a609..995d3ca2e2 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -46,7 +46,8 @@ void CSVDoc::View::setupFileMenu() file->addAction(close); QAction *exit = new QAction (tr ("&Exit"), this); - connect (exit, SIGNAL (triggered()), QApplication::instance(), SLOT (closeAllWindows())); + connect (exit, SIGNAL (triggered()), this, SLOT (exit())); + connect (this, SIGNAL(exitApplicationRequest(CSVDoc::View *)), &mViewManager, SLOT(exitApplication(CSVDoc::View *))); file->addAction(exit); } @@ -131,8 +132,6 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews) { - // setDockOptions (QMainWindow::AllowNestedDocks); - resize (300, 300); /// \todo get default size from settings and set reasonable minimal size mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks); @@ -255,3 +254,8 @@ CSVDoc::Operations *CSVDoc::View::getOperations() const { return mOperations; } + +void CSVDoc::View::exit() +{ + emit exitApplicationRequest (this); +} diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 92c57fe9ec..e91a4d4a80 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -66,6 +66,8 @@ namespace CSVDoc void updateActions(); + void exitApplication(); + public: View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); @@ -92,7 +94,7 @@ namespace CSVDoc void loadDocumentRequest(); - void closeAllViews (View *); + void exitApplicationRequest (CSVDoc::View *view); public slots: @@ -106,6 +108,8 @@ namespace CSVDoc void save(); + void exit(); + void verify(); void addGlobalsSubView(); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 83ace49387..527e3b2044 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -36,7 +36,7 @@ void CSVDoc::ViewManager::updateIndices() } CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) - : mDocumentManager (documentManager), mCloseMeOnSaveStateChange(0), mUserWarned(false) + : mDocumentManager (documentManager), mExitOnSaveStateChange(false), mUserWarned(false) { mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; @@ -45,16 +45,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType, new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float)); - - connect (this, SIGNAL (exitApplication()), QApplication::instance(), SLOT (closeAllWindows())); - } CSVDoc::ViewManager::~ViewManager() { delete mDelegateFactories; - //not needed due to deletion in ViewManager::closeRequest? for (std::vector::iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) delete *iter; } @@ -112,32 +108,40 @@ bool CSVDoc::ViewManager::closeRequest (View *view) CSMDoc::Document *document = view->getDocument(); - //notify user of saving in progress - if ( (document->getState() & CSMDoc::State_Saving) ) - continueWithClose = showSaveInProgressMessageBox (iter); - - //notify user of unsaved changes and process response - else if ( document->getState() & CSMDoc::State_Modified) - continueWithClose = showModifiedDocumentMessageBox (iter); - - if (continueWithClose) + if (last) + continueWithClose = notifySaveOnClose (view); + else { (*iter)->deleteLater(); mViews.erase (iter); - if (last) - mDocumentManager.removeDocument (document); - else - updateIndices(); + updateIndices(); } } return continueWithClose; } -bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (std::vector::iterator viewIter) +bool CSVDoc::ViewManager::notifySaveOnClose (CSVDoc::View *view) +{ + bool result = true; + CSMDoc::Document *document = view->getDocument(); + + //notify user of saving in progress + if ( (document->getState() & CSMDoc::State_Saving) ) + result = showSaveInProgressMessageBox (view); + + //notify user of unsaved changes and process response + else if ( document->getState() & CSMDoc::State_Modified) + result = showModifiedDocumentMessageBox (view); + + return result; +} + +bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view) { QMessageBox messageBox; + CSMDoc::Document *document = view->getDocument(); messageBox.setText ("The document has been modified."); messageBox.setInformativeText ("Do you want to save your changes?"); @@ -147,31 +151,31 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (std::vector::i bool retVal = true; connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close())); - connect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); + + connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); + mUserWarned = true; - int response = messageBox.exec(); - mUserWarned = false; switch (response) { case QMessageBox::Save: - (*viewIter)->getDocument()->save(); - mCloseMeOnSaveStateChange = viewIter; + document->save(); + mExitOnSaveStateChange = true; retVal = false; break; case QMessageBox::Discard: - disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); + disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); break; case QMessageBox::Cancel: //disconnect to prevent unintended view closures - disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); + disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); retVal = false; break; @@ -183,9 +187,10 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (std::vector::i return retVal; } -bool CSVDoc::ViewManager::showSaveInProgressMessageBox (std::vector::iterator viewIter) +bool CSVDoc::ViewManager::showSaveInProgressMessageBox (CSVDoc::View *view) { QMessageBox messageBox; + CSMDoc::Document *document = view->getDocument(); messageBox.setText ("The document is currently being saved."); messageBox.setInformativeText("Do you want to close now and abort saving, or wait until saving has completed?"); @@ -199,38 +204,37 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (std::vector::ite bool retVal = true; //Connections shut down message box if operation ends before user makes a decision. - connect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); + connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close())); //set / clear the user warned flag to indicate whether or not the message box is currently active. mUserWarned = true; - messageBox.exec(); - mUserWarned = false; //if closed by the warning handler, defaults to the RejectRole button (closeButton) if (messageBox.clickedButton() == waitButton) { //save the View iterator for shutdown after the save operation ends - mCloseMeOnSaveStateChange = viewIter; + mExitOnSaveStateChange = true; retVal = false; } else if (messageBox.clickedButton() == closeButton) { //disconnect to avoid segmentation fault - disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); - (*viewIter)->abortOperation(CSMDoc::State_Saving); - mCloseMeOnSaveStateChange = mViews.end(); + disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); + + view->abortOperation(CSMDoc::State_Saving); + mExitOnSaveStateChange = true; } else if (messageBox.clickedButton() == cancelButton) { //abort shutdown, allow save to complete //disconnection to prevent unintended view closures - mCloseMeOnSaveStateChange = mViews.end(); - disconnect ((*viewIter)->getDocument(), SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); + mExitOnSaveStateChange = false; + disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); retVal = false; } @@ -262,10 +266,13 @@ void CSVDoc::ViewManager::onExitWarningHandler (int state, CSMDoc::Document *doc //otherwise, the user has closed the message box before the save operation ended. //exit the application - else if (mCloseMeOnSaveStateChange!=mViews.end()) - { - emit exitApplication(); - mCloseMeOnSaveStateChange = mViews.end(); - } + else if (mExitOnSaveStateChange) + QApplication::instance()->exit(); } } + +void CSVDoc::ViewManager::exitApplication (CSVDoc::View *view) +{ + if (notifySaveOnClose (view)) + QApplication::instance()->exit(); +} diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index b77e5f5758..90f23eaa11 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -27,7 +27,7 @@ namespace CSVDoc CSMDoc::DocumentManager& mDocumentManager; std::vector mViews; CSVWorld::CommandDelegateFactoryCollection *mDelegateFactories; - std::vector::iterator mCloseMeOnSaveStateChange; + bool mExitOnSaveStateChange; bool mUserWarned; // not implemented @@ -35,8 +35,9 @@ namespace CSVDoc ViewManager& operator= (const ViewManager&); void updateIndices(); - bool showModifiedDocumentMessageBox (std::vector::iterator view); - bool showSaveInProgressMessageBox (std::vector::iterator view); + bool notifySaveOnClose (View *view = 0); + bool showModifiedDocumentMessageBox (View *view); + bool showSaveInProgressMessageBox (View *view); public: @@ -60,7 +61,9 @@ namespace CSVDoc void closeMessageBox(); - void exitApplication(); + public slots: + + void exitApplication (CSVDoc::View *view); private slots: diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index b33e2e12ab..25286e2f85 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -1,6 +1,6 @@ -#include #include #include +#include #include From 75bd30844db2ce8a5e3d1e1e9ea9b12f0bc5854a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 12 Mar 2013 14:33:35 +0100 Subject: [PATCH 16/17] added optional format sub-record to tes3 record --- apps/esmtool/esmtool.cpp | 1 + components/esm/esmreader.cpp | 7 ++++++- components/esm/esmreader.hpp | 1 + components/esm/esmwriter.cpp | 10 ++++++++++ components/esm/esmwriter.hpp | 2 ++ components/esm/loadtes3.cpp | 13 +++++++++++++ components/esm/loadtes3.hpp | 3 +++ 7 files changed, 36 insertions(+), 1 deletion(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 5cc1b6bcbb..20c01af259 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -426,6 +426,7 @@ int clone(Arguments& info) esm.setAuthor(info.data.author); esm.setDescription(info.data.description); esm.setVersion(info.data.version); + esm.setRecordCount (recordCount); for (std::vector::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it) esm.addMaster(it->name, it->size); diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index 979088b801..580e576d05 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -15,11 +15,16 @@ ESM_Context ESMReader::getContext() return mCtx; } -ESMReader::ESMReader(void): +ESMReader::ESMReader(): mBuffer(50*1024) { } +int ESMReader::getFormat() const +{ + return mHeader.mFormat; +} + void ESMReader::restoreContext(const ESM_Context &rc) { // Reopen the file if necessary diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index e377470eeb..f805998e43 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -35,6 +35,7 @@ public: const std::string getAuthor() const { return mHeader.mData.author.toString(); } const std::string getDesc() const { return mHeader.mData.desc.toString(); } const std::vector &getMasters() const { return mHeader.mMaster; } + int getFormat() const; const NAME &retSubName() const { return mCtx.subName; } uint32_t getSubSize() const { return mCtx.leftSub; } diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index edb681f329..3ea6bd350a 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -29,6 +29,16 @@ void ESMWriter::setDescription(const std::string& desc) mHeader.mData.desc.assign (desc); } +void ESMWriter::setRecordCount (int count) +{ + mHeader.mData.records = count; +} + +void ESMWriter::setFormat (int format) +{ + mHeader.mFormat = format; +} + void ESMWriter::addMaster(const std::string& name, uint64_t size) { Header::MasterData d; diff --git a/components/esm/esmwriter.hpp b/components/esm/esmwriter.hpp index b0e9329d4b..be3ae33abe 100644 --- a/components/esm/esmwriter.hpp +++ b/components/esm/esmwriter.hpp @@ -26,6 +26,8 @@ public: void setEncoder(ToUTF8::Utf8Encoder *encoding); // Write strings as UTF-8? void setAuthor(const std::string& author); void setDescription(const std::string& desc); + void setRecordCount (int count); + void setFormat (int format); void addMaster(const std::string& name, uint64_t size); diff --git a/components/esm/loadtes3.cpp b/components/esm/loadtes3.cpp index 64f1446f18..74d578ba7d 100644 --- a/components/esm/loadtes3.cpp +++ b/components/esm/loadtes3.cpp @@ -12,12 +12,22 @@ void ESM::Header::blank() mData.author.assign (""); mData.desc.assign (""); mData.records = 0; + mFormat = CurrentFormat; } void ESM::Header::load (ESMReader &esm) { esm.getHNT (mData, "HEDR", 300); + if (esm.isNextSub ("FORM")) + { + esm.getHT (mFormat); + if (mFormat<0) + esm.fail ("invalid format code"); + } + else + mFormat = 0; + while (esm.isNextSub ("MAST")) { MasterData m; @@ -31,6 +41,9 @@ void ESM::Header::save (ESMWriter &esm) { esm.writeHNT ("HEDR", mData, 300); + if (mFormat>0) + esm.writeHNT ("FORM", mFormat); + for (std::vector::iterator iter = mMaster.begin(); iter != mMaster.end(); ++iter) { diff --git a/components/esm/loadtes3.hpp b/components/esm/loadtes3.hpp index c0b1e3af77..b73a4c31e4 100644 --- a/components/esm/loadtes3.hpp +++ b/components/esm/loadtes3.hpp @@ -16,6 +16,8 @@ namespace ESM /// \brief File header record struct Header { + static const int CurrentFormat = 0; // most recent known format + struct Data { /* File format version. This is actually a float, the supported @@ -38,6 +40,7 @@ namespace ESM }; Data mData; + int mFormat; std::vector mMaster; void blank(); From 10fad47a8129837973e0e3d88cf94f15626c58c0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 12 Mar 2013 14:51:16 +0100 Subject: [PATCH 17/17] some cleanup --- apps/opencs/model/doc/document.cpp | 4 +--- apps/opencs/view/doc/viewmanager.cpp | 5 ----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index af34aeedf4..7a88335c89 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -238,9 +238,7 @@ CSMDoc::Document::Document (const std::vector& files, b } CSMDoc::Document::~Document() -{ - qDebug() << "document destroyed"; -} +{} QUndoStack& CSMDoc::Document::getUndoStack() { diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 527e3b2044..33300f67a7 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -103,11 +103,6 @@ bool CSVDoc::ViewManager::closeRequest (View *view) { bool last = countViews (view->getDocument())<=1; - /// \todo check if save is in progress -> warn user about possible data loss - /// \todo check if document has not been saved -> return false and start close dialogue - - CSMDoc::Document *document = view->getDocument(); - if (last) continueWithClose = notifySaveOnClose (view); else