From fa25a068a8681202a8327cde663273d9910fd838 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 15:00:41 +0200 Subject: [PATCH] basic saving (no data is written to file yet) --- apps/opencs/model/doc/saving.cpp | 3 ++ apps/opencs/model/doc/savingstages.cpp | 53 ++++++++++++++++++++++++-- apps/opencs/model/doc/savingstages.hpp | 31 +++++++++++++++ apps/opencs/model/doc/savingstate.cpp | 45 +++++++++++++++++++++- apps/opencs/model/doc/savingstate.hpp | 22 +++++++++++ 5 files changed, 149 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index dda4ad12a..5607883ad 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -8,7 +8,10 @@ CSMDoc::Saving::Saving (Document& document) : Operation (State_Saving, true, true), mDocument (document), mState (*this) { + appendStage (new OpenSaveStage (mDocument, mState)); + appendStage (new CloseSaveStage (mState)); + appendStage (new FinalSavingStage (mDocument, mState)); } \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 97facf612..078762992 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -1,11 +1,53 @@ #include "savingstages.hpp" +#include + +#include + #include #include "document.hpp" #include "savingstate.hpp" +CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state) +: mDocument (document), mState (state) +{} + +int CSMDoc::OpenSaveStage::setup() +{ + return 1; +} + +void CSMDoc::OpenSaveStage::perform (int stage, std::vector& messages) +{ + mState.start (mDocument); + + mState.getStream().open (mState.getTmpPath().string().c_str()); + + if (!mState.getStream().is_open()) + throw std::runtime_error ("failed to open stream for saving"); +} + + +CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) +: mState (state) +{} + +int CSMDoc::CloseSaveStage::setup() +{ + return 1; +} + +void CSMDoc::CloseSaveStage::perform (int stage, std::vector& messages) +{ + mState.getStream().close(); + + if (!mState.getStream()) + throw std::runtime_error ("saving failed"); +} + + CSMDoc::FinalSavingStage::FinalSavingStage (Document& document, SavingState& state) : mDocument (document), mState (state) {} @@ -19,12 +61,17 @@ void CSMDoc::FinalSavingStage::perform (int stage, std::vector& mes { if (mState.hasError()) { - /// \todo close stream - /// \todo delete tmp file + mState.getWriter().close(); + mState.getStream().close(); + + if (boost::filesystem::exists (mState.getTmpPath())) + boost::filesystem::remove (mState.getTmpPath()); } else { - /// \todo delete file, rename tmp file + boost::filesystem::remove (mState.getPath()); + boost::filesystem::rename (mState.getTmpPath(), mState.getPath()); + mDocument.getUndoStack().setClean(); } } \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 1549c9640..0b64896f7 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -8,6 +8,37 @@ namespace CSMDoc class Document; class SavingState; + class OpenSaveStage : public Stage + { + Document& mDocument; + SavingState& mState; + + public: + + OpenSaveStage (Document& document, SavingState& state); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + + class CloseSaveStage : public Stage + { + SavingState& mState; + + public: + + CloseSaveStage (SavingState& state); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + class FinalSavingStage : public Stage { Document& mDocument; diff --git a/apps/opencs/model/doc/savingstate.cpp b/apps/opencs/model/doc/savingstate.cpp index 379870859..a49a0699b 100644 --- a/apps/opencs/model/doc/savingstate.cpp +++ b/apps/opencs/model/doc/savingstate.cpp @@ -2,12 +2,53 @@ #include "savingstate.hpp" #include "operation.hpp" +#include "document.hpp" CSMDoc::SavingState::SavingState (Operation& operation) -: mOperation (operation) -{} +: mOperation (operation), + /// \todo set encoding properly, once config implementation has been fixed. + mEncoder (ToUTF8::calculateEncoding ("win1252")) +{ + mWriter.setEncoder (&mEncoder); +} bool CSMDoc::SavingState::hasError() const { return mOperation.hasError(); +} + +void CSMDoc::SavingState::start (Document& document) +{ + if (mStream.is_open()) + mStream.close(); + + mStream.clear(); + + mPath = document.getSavePath(); + + boost::filesystem::path file (mPath.filename().string() + ".tmp"); + + mTmpPath = mPath.parent_path(); + + mTmpPath /= file; +} + +const boost::filesystem::path& CSMDoc::SavingState::getPath() const +{ + return mPath; +} + +const boost::filesystem::path& CSMDoc::SavingState::getTmpPath() const +{ + return mTmpPath; +} + +std::ofstream& CSMDoc::SavingState::getStream() +{ + return mStream; +} + +ESM::ESMWriter& CSMDoc::SavingState::getWriter() +{ + return mWriter; } \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstate.hpp b/apps/opencs/model/doc/savingstate.hpp index b8b6f3878..3f42b4653 100644 --- a/apps/opencs/model/doc/savingstate.hpp +++ b/apps/opencs/model/doc/savingstate.hpp @@ -1,19 +1,41 @@ #ifndef CSM_DOC_SAVINGSTATE_H #define CSM_DOC_SAVINGSTATE_H +#include + +#include + +#include + namespace CSMDoc { class Operation; + class Document; class SavingState { Operation& mOperation; + boost::filesystem::path mPath; + boost::filesystem::path mTmpPath; + ToUTF8::Utf8Encoder mEncoder; + std::ofstream mStream; + ESM::ESMWriter mWriter; public: SavingState (Operation& operation); bool hasError() const; + + void start (Document& document); + + const boost::filesystem::path& getPath() const; + + const boost::filesystem::path& getTmpPath() const; + + std::ofstream& getStream(); + + ESM::ESMWriter& getWriter(); };