mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 06:15:32 +00:00
create project file when saving content file
This commit is contained in:
parent
96fd1c35bf
commit
5779f799ab
15 changed files with 113 additions and 44 deletions
|
@ -10,7 +10,8 @@
|
|||
#include "model/world/data.hpp"
|
||||
|
||||
|
||||
CS::Editor::Editor() : mViewManager (mDocumentManager)
|
||||
CS::Editor::Editor()
|
||||
: mDocumentManager (mCfgMgr.getUserPath() / "projects"), mViewManager (mDocumentManager)
|
||||
{
|
||||
mIpcServerName = "org.openmw.OpenCS";
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace CS
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
CSMSettings::UserSettings mUserSettings;
|
||||
CSMDoc::DocumentManager mDocumentManager;
|
||||
CSVDoc::ViewManager mViewManager;
|
||||
|
@ -34,7 +35,6 @@ namespace CS
|
|||
CSVSettings::UserSettingsDialog mSettings;
|
||||
CSVDoc::FileDialog mFileDialog;
|
||||
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
boost::filesystem::path mLocal;
|
||||
|
||||
void setupDataFiles();
|
||||
|
|
|
@ -2140,8 +2140,9 @@ void CSMDoc::Document::createBase()
|
|||
}
|
||||
|
||||
CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files,
|
||||
const boost::filesystem::path& savePath, bool new_)
|
||||
: mSavePath (savePath), mContentFiles (files), mTools (mData), mSaving (*this)
|
||||
const boost::filesystem::path& savePath, bool new_,
|
||||
const boost::filesystem::path& projectPath)
|
||||
: mSavePath (savePath), mContentFiles (files), mTools (mData), mSaving (*this, projectPath)
|
||||
{
|
||||
if (files.empty())
|
||||
throw std::runtime_error ("Empty content file sequence");
|
||||
|
|
|
@ -65,7 +65,10 @@ namespace CSMDoc
|
|||
public:
|
||||
|
||||
Document (const std::vector<boost::filesystem::path>& files,
|
||||
const boost::filesystem::path& savePath, bool new_);
|
||||
const boost::filesystem::path& savePath, bool new_,
|
||||
const boost::filesystem::path& projectPath);
|
||||
///< \param projectPath Location of file that can be used to store additional data for
|
||||
/// this project.
|
||||
|
||||
~Document();
|
||||
|
||||
|
|
|
@ -4,9 +4,16 @@
|
|||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "document.hpp"
|
||||
|
||||
CSMDoc::DocumentManager::DocumentManager() {}
|
||||
CSMDoc::DocumentManager::DocumentManager (const boost::filesystem::path& projectPath)
|
||||
: mProjectPath (projectPath)
|
||||
{
|
||||
if (!boost::filesystem::is_directory (mProjectPath))
|
||||
boost::filesystem::create_directories (mProjectPath);
|
||||
}
|
||||
|
||||
CSMDoc::DocumentManager::~DocumentManager()
|
||||
{
|
||||
|
@ -17,7 +24,11 @@ CSMDoc::DocumentManager::~DocumentManager()
|
|||
CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
||||
bool new_)
|
||||
{
|
||||
Document *document = new Document (files, savePath, new_);
|
||||
boost::filesystem::path projectFile (mProjectPath);
|
||||
|
||||
projectFile /= savePath.filename().string() + ".project";
|
||||
|
||||
Document *document = new Document (files, savePath, new_, projectFile);
|
||||
|
||||
mDocuments.push_back (document);
|
||||
|
||||
|
|
|
@ -13,13 +13,15 @@ namespace CSMDoc
|
|||
class DocumentManager
|
||||
{
|
||||
std::vector<Document *> mDocuments;
|
||||
boost::filesystem::path mProjectPath;
|
||||
|
||||
DocumentManager (const DocumentManager&);
|
||||
DocumentManager& operator= (const DocumentManager&);
|
||||
|
||||
public:
|
||||
|
||||
DocumentManager();
|
||||
DocumentManager (const boost::filesystem::path& projectPath);
|
||||
///< \param projectPath Directory where additional per-project data will be stored.
|
||||
|
||||
~DocumentManager();
|
||||
|
||||
|
|
|
@ -8,12 +8,20 @@
|
|||
#include "savingstages.hpp"
|
||||
#include "document.hpp"
|
||||
|
||||
CSMDoc::Saving::Saving (Document& document)
|
||||
: Operation (State_Saving, true, true), mDocument (document), mState (*this)
|
||||
CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& projectPath)
|
||||
: Operation (State_Saving, true, true), mDocument (document), mState (*this, projectPath)
|
||||
{
|
||||
appendStage (new OpenSaveStage (mDocument, mState));
|
||||
// save project file
|
||||
appendStage (new OpenSaveStage (mDocument, mState, true));
|
||||
|
||||
appendStage (new WriteHeaderStage (mDocument, mState));
|
||||
appendStage (new WriteHeaderStage (mDocument, mState, true));
|
||||
|
||||
appendStage (new CloseSaveStage (mState));
|
||||
|
||||
// save content file
|
||||
appendStage (new OpenSaveStage (mDocument, mState, false));
|
||||
|
||||
appendStage (new WriteHeaderStage (mDocument, mState, false));
|
||||
|
||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Global> >
|
||||
(mDocument.getData().getGlobals(), mState));
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef CSM_DOC_SAVING_H
|
||||
#define CSM_DOC_SAVING_H
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include "operation.hpp"
|
||||
#include "savingstate.hpp"
|
||||
|
||||
|
@ -17,7 +19,7 @@ namespace CSMDoc
|
|||
|
||||
public:
|
||||
|
||||
Saving (Document& document);
|
||||
Saving (Document& document, const boost::filesystem::path& projectPath);
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#include "document.hpp"
|
||||
#include "savingstate.hpp"
|
||||
|
||||
CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state)
|
||||
: mDocument (document), mState (state)
|
||||
CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state, bool projectFile)
|
||||
: mDocument (document), mState (state), mProjectFile (projectFile)
|
||||
{}
|
||||
|
||||
int CSMDoc::OpenSaveStage::setup()
|
||||
|
@ -21,17 +21,17 @@ int CSMDoc::OpenSaveStage::setup()
|
|||
|
||||
void CSMDoc::OpenSaveStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
mState.start (mDocument);
|
||||
mState.start (mDocument, mProjectFile);
|
||||
|
||||
mState.getStream().open (mState.getTmpPath().string().c_str());
|
||||
mState.getStream().open ((mProjectFile ? mState.getPath() : mState.getTmpPath()).string().c_str());
|
||||
|
||||
if (!mState.getStream().is_open())
|
||||
throw std::runtime_error ("failed to open stream for saving");
|
||||
}
|
||||
|
||||
|
||||
CSMDoc::WriteHeaderStage::WriteHeaderStage (Document& document, SavingState& state)
|
||||
: mDocument (document), mState (state)
|
||||
CSMDoc::WriteHeaderStage::WriteHeaderStage (Document& document, SavingState& state, bool simple)
|
||||
: mDocument (document), mState (state), mSimple (simple)
|
||||
{}
|
||||
|
||||
int CSMDoc::WriteHeaderStage::setup()
|
||||
|
@ -43,26 +43,38 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector<std::string>& mes
|
|||
{
|
||||
mState.getWriter().setVersion();
|
||||
|
||||
mState.getWriter().clearMaster();
|
||||
|
||||
mState.getWriter().setFormat (0);
|
||||
|
||||
mState.getWriter().setAuthor (mDocument.getData().getAuthor());
|
||||
mState.getWriter().setDescription (mDocument.getData().getDescription());
|
||||
mState.getWriter().setRecordCount (
|
||||
mDocument.getData().count (CSMWorld::RecordBase::State_Modified) +
|
||||
mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) +
|
||||
mDocument.getData().count (CSMWorld::RecordBase::State_Deleted));
|
||||
|
||||
/// \todo refine dependency list (at least remove redundant dependencies)
|
||||
std::vector<boost::filesystem::path> dependencies = mDocument.getContentFiles();
|
||||
std::vector<boost::filesystem::path>::const_iterator end (--dependencies.end());
|
||||
|
||||
for (std::vector<boost::filesystem::path>::const_iterator iter (dependencies.begin());
|
||||
iter!=end; ++iter)
|
||||
if (mSimple)
|
||||
{
|
||||
std::string name = iter->filename().string();
|
||||
uint64_t size = boost::filesystem::file_size (*iter);
|
||||
mState.getWriter().setAuthor ("");
|
||||
mState.getWriter().setDescription ("");
|
||||
mState.getWriter().setRecordCount (0);
|
||||
|
||||
mState.getWriter().addMaster (name, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
mState.getWriter().setAuthor (mDocument.getData().getAuthor());
|
||||
mState.getWriter().setDescription (mDocument.getData().getDescription());
|
||||
mState.getWriter().setRecordCount (
|
||||
mDocument.getData().count (CSMWorld::RecordBase::State_Modified) +
|
||||
mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) +
|
||||
mDocument.getData().count (CSMWorld::RecordBase::State_Deleted));
|
||||
|
||||
/// \todo refine dependency list (at least remove redundant dependencies)
|
||||
std::vector<boost::filesystem::path> dependencies = mDocument.getContentFiles();
|
||||
std::vector<boost::filesystem::path>::const_iterator end (--dependencies.end());
|
||||
|
||||
for (std::vector<boost::filesystem::path>::const_iterator iter (dependencies.begin());
|
||||
iter!=end; ++iter)
|
||||
{
|
||||
std::string name = iter->filename().string();
|
||||
uint64_t size = boost::filesystem::file_size (*iter);
|
||||
|
||||
mState.getWriter().addMaster (name, size);
|
||||
}
|
||||
}
|
||||
|
||||
mState.getWriter().save (mState.getStream());
|
||||
|
@ -121,7 +133,7 @@ void CSMDoc::FinalSavingStage::perform (int stage, std::vector<std::string>& mes
|
|||
if (boost::filesystem::exists (mState.getTmpPath()))
|
||||
boost::filesystem::remove (mState.getTmpPath());
|
||||
}
|
||||
else
|
||||
else if (!mState.isProjectFile())
|
||||
{
|
||||
if (boost::filesystem::exists (mState.getPath()))
|
||||
boost::filesystem::remove (mState.getPath());
|
||||
|
|
|
@ -16,10 +16,12 @@ namespace CSMDoc
|
|||
{
|
||||
Document& mDocument;
|
||||
SavingState& mState;
|
||||
bool mProjectFile;
|
||||
|
||||
public:
|
||||
|
||||
OpenSaveStage (Document& document, SavingState& state);
|
||||
OpenSaveStage (Document& document, SavingState& state, bool projectFile);
|
||||
///< \param projectFile Saving the project file instead of the content file.
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
@ -32,10 +34,12 @@ namespace CSMDoc
|
|||
{
|
||||
Document& mDocument;
|
||||
SavingState& mState;
|
||||
bool mSimple;
|
||||
|
||||
public:
|
||||
|
||||
WriteHeaderStage (Document& document, SavingState& state);
|
||||
WriteHeaderStage (Document& document, SavingState& state, bool simple);
|
||||
///< \param simple Simplified header (used for project files).
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
#include "operation.hpp"
|
||||
#include "document.hpp"
|
||||
|
||||
CSMDoc::SavingState::SavingState (Operation& operation)
|
||||
CSMDoc::SavingState::SavingState (Operation& operation, const boost::filesystem::path& projectPath)
|
||||
: mOperation (operation),
|
||||
/// \todo set encoding properly, once config implementation has been fixed.
|
||||
mEncoder (ToUTF8::calculateEncoding ("win1252"))
|
||||
mEncoder (ToUTF8::calculateEncoding ("win1252")),
|
||||
mProjectPath (projectPath), mProjectFile (false)
|
||||
{
|
||||
mWriter.setEncoder (&mEncoder);
|
||||
}
|
||||
|
@ -17,14 +18,19 @@ bool CSMDoc::SavingState::hasError() const
|
|||
return mOperation.hasError();
|
||||
}
|
||||
|
||||
void CSMDoc::SavingState::start (Document& document)
|
||||
void CSMDoc::SavingState::start (Document& document, bool project)
|
||||
{
|
||||
mProjectFile = project;
|
||||
|
||||
if (mStream.is_open())
|
||||
mStream.close();
|
||||
|
||||
mStream.clear();
|
||||
|
||||
mPath = document.getSavePath();
|
||||
if (project)
|
||||
mPath = mProjectPath;
|
||||
else
|
||||
mPath = document.getSavePath();
|
||||
|
||||
boost::filesystem::path file (mPath.filename().string() + ".tmp");
|
||||
|
||||
|
@ -51,4 +57,9 @@ std::ofstream& CSMDoc::SavingState::getStream()
|
|||
ESM::ESMWriter& CSMDoc::SavingState::getWriter()
|
||||
{
|
||||
return mWriter;
|
||||
}
|
||||
|
||||
bool CSMDoc::SavingState::isProjectFile() const
|
||||
{
|
||||
return mProjectFile;
|
||||
}
|
|
@ -20,14 +20,17 @@ namespace CSMDoc
|
|||
ToUTF8::Utf8Encoder mEncoder;
|
||||
std::ofstream mStream;
|
||||
ESM::ESMWriter mWriter;
|
||||
boost::filesystem::path mProjectPath;
|
||||
bool mProjectFile;
|
||||
|
||||
public:
|
||||
|
||||
SavingState (Operation& operation);
|
||||
SavingState (Operation& operation, const boost::filesystem::path& projectPath);
|
||||
|
||||
bool hasError() const;
|
||||
|
||||
void start (Document& document);
|
||||
void start (Document& document, bool project);
|
||||
///< \param project Save project file instead of content file.
|
||||
|
||||
const boost::filesystem::path& getPath() const;
|
||||
|
||||
|
@ -36,6 +39,9 @@ namespace CSMDoc
|
|||
std::ofstream& getStream();
|
||||
|
||||
ESM::ESMWriter& getWriter();
|
||||
|
||||
bool isProjectFile() const;
|
||||
///< Currently saving project file? (instead of content file)
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@ namespace ESM
|
|||
mHeader.mFormat = format;
|
||||
}
|
||||
|
||||
void ESMWriter::clearMaster()
|
||||
{
|
||||
mHeader.mMaster.clear();
|
||||
}
|
||||
|
||||
void ESMWriter::addMaster(const std::string& name, uint64_t size)
|
||||
{
|
||||
Header::MasterData d;
|
||||
|
|
|
@ -32,6 +32,8 @@ class ESMWriter
|
|||
void setRecordCount (int count);
|
||||
void setFormat (int format);
|
||||
|
||||
void clearMaster();
|
||||
|
||||
void addMaster(const std::string& name, uint64_t size);
|
||||
|
||||
void save(const std::string& file);
|
||||
|
|
|
@ -14,6 +14,7 @@ void ESM::Header::blank()
|
|||
mData.desc.assign ("");
|
||||
mData.records = 0;
|
||||
mFormat = CurrentFormat;
|
||||
mMaster.clear();
|
||||
}
|
||||
|
||||
void ESM::Header::load (ESMReader &esm)
|
||||
|
|
Loading…
Reference in a new issue