forked from mirror/openmw-tes3mp
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"
|
#include "model/world/data.hpp"
|
||||||
|
|
||||||
|
|
||||||
CS::Editor::Editor() : mViewManager (mDocumentManager)
|
CS::Editor::Editor()
|
||||||
|
: mDocumentManager (mCfgMgr.getUserPath() / "projects"), mViewManager (mDocumentManager)
|
||||||
{
|
{
|
||||||
mIpcServerName = "org.openmw.OpenCS";
|
mIpcServerName = "org.openmw.OpenCS";
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace CS
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Files::ConfigurationManager mCfgMgr;
|
||||||
CSMSettings::UserSettings mUserSettings;
|
CSMSettings::UserSettings mUserSettings;
|
||||||
CSMDoc::DocumentManager mDocumentManager;
|
CSMDoc::DocumentManager mDocumentManager;
|
||||||
CSVDoc::ViewManager mViewManager;
|
CSVDoc::ViewManager mViewManager;
|
||||||
|
@ -34,7 +35,6 @@ namespace CS
|
||||||
CSVSettings::UserSettingsDialog mSettings;
|
CSVSettings::UserSettingsDialog mSettings;
|
||||||
CSVDoc::FileDialog mFileDialog;
|
CSVDoc::FileDialog mFileDialog;
|
||||||
|
|
||||||
Files::ConfigurationManager mCfgMgr;
|
|
||||||
boost::filesystem::path mLocal;
|
boost::filesystem::path mLocal;
|
||||||
|
|
||||||
void setupDataFiles();
|
void setupDataFiles();
|
||||||
|
|
|
@ -2140,8 +2140,9 @@ void CSMDoc::Document::createBase()
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files,
|
CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files,
|
||||||
const boost::filesystem::path& savePath, bool new_)
|
const boost::filesystem::path& savePath, bool new_,
|
||||||
: mSavePath (savePath), mContentFiles (files), mTools (mData), mSaving (*this)
|
const boost::filesystem::path& projectPath)
|
||||||
|
: mSavePath (savePath), mContentFiles (files), mTools (mData), mSaving (*this, projectPath)
|
||||||
{
|
{
|
||||||
if (files.empty())
|
if (files.empty())
|
||||||
throw std::runtime_error ("Empty content file sequence");
|
throw std::runtime_error ("Empty content file sequence");
|
||||||
|
|
|
@ -65,7 +65,10 @@ namespace CSMDoc
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Document (const std::vector<boost::filesystem::path>& files,
|
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();
|
~Document();
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,16 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include "document.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()
|
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,
|
CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
||||||
bool new_)
|
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);
|
mDocuments.push_back (document);
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,15 @@ namespace CSMDoc
|
||||||
class DocumentManager
|
class DocumentManager
|
||||||
{
|
{
|
||||||
std::vector<Document *> mDocuments;
|
std::vector<Document *> mDocuments;
|
||||||
|
boost::filesystem::path mProjectPath;
|
||||||
|
|
||||||
DocumentManager (const DocumentManager&);
|
DocumentManager (const DocumentManager&);
|
||||||
DocumentManager& operator= (const DocumentManager&);
|
DocumentManager& operator= (const DocumentManager&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DocumentManager();
|
DocumentManager (const boost::filesystem::path& projectPath);
|
||||||
|
///< \param projectPath Directory where additional per-project data will be stored.
|
||||||
|
|
||||||
~DocumentManager();
|
~DocumentManager();
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,20 @@
|
||||||
#include "savingstages.hpp"
|
#include "savingstages.hpp"
|
||||||
#include "document.hpp"
|
#include "document.hpp"
|
||||||
|
|
||||||
CSMDoc::Saving::Saving (Document& document)
|
CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& projectPath)
|
||||||
: Operation (State_Saving, true, true), mDocument (document), mState (*this)
|
: 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> >
|
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Global> >
|
||||||
(mDocument.getData().getGlobals(), mState));
|
(mDocument.getData().getGlobals(), mState));
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef CSM_DOC_SAVING_H
|
#ifndef CSM_DOC_SAVING_H
|
||||||
#define CSM_DOC_SAVING_H
|
#define CSM_DOC_SAVING_H
|
||||||
|
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
#include "operation.hpp"
|
#include "operation.hpp"
|
||||||
#include "savingstate.hpp"
|
#include "savingstate.hpp"
|
||||||
|
|
||||||
|
@ -17,7 +19,7 @@ namespace CSMDoc
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Saving (Document& document);
|
Saving (Document& document, const boost::filesystem::path& projectPath);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
#include "document.hpp"
|
#include "document.hpp"
|
||||||
#include "savingstate.hpp"
|
#include "savingstate.hpp"
|
||||||
|
|
||||||
CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state)
|
CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state, bool projectFile)
|
||||||
: mDocument (document), mState (state)
|
: mDocument (document), mState (state), mProjectFile (projectFile)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int CSMDoc::OpenSaveStage::setup()
|
int CSMDoc::OpenSaveStage::setup()
|
||||||
|
@ -21,17 +21,17 @@ int CSMDoc::OpenSaveStage::setup()
|
||||||
|
|
||||||
void CSMDoc::OpenSaveStage::perform (int stage, std::vector<std::string>& messages)
|
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())
|
if (!mState.getStream().is_open())
|
||||||
throw std::runtime_error ("failed to open stream for saving");
|
throw std::runtime_error ("failed to open stream for saving");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CSMDoc::WriteHeaderStage::WriteHeaderStage (Document& document, SavingState& state)
|
CSMDoc::WriteHeaderStage::WriteHeaderStage (Document& document, SavingState& state, bool simple)
|
||||||
: mDocument (document), mState (state)
|
: mDocument (document), mState (state), mSimple (simple)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int CSMDoc::WriteHeaderStage::setup()
|
int CSMDoc::WriteHeaderStage::setup()
|
||||||
|
@ -43,26 +43,38 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector<std::string>& mes
|
||||||
{
|
{
|
||||||
mState.getWriter().setVersion();
|
mState.getWriter().setVersion();
|
||||||
|
|
||||||
|
mState.getWriter().clearMaster();
|
||||||
|
|
||||||
mState.getWriter().setFormat (0);
|
mState.getWriter().setFormat (0);
|
||||||
|
|
||||||
mState.getWriter().setAuthor (mDocument.getData().getAuthor());
|
if (mSimple)
|
||||||
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();
|
mState.getWriter().setAuthor ("");
|
||||||
uint64_t size = boost::filesystem::file_size (*iter);
|
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());
|
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()))
|
if (boost::filesystem::exists (mState.getTmpPath()))
|
||||||
boost::filesystem::remove (mState.getTmpPath());
|
boost::filesystem::remove (mState.getTmpPath());
|
||||||
}
|
}
|
||||||
else
|
else if (!mState.isProjectFile())
|
||||||
{
|
{
|
||||||
if (boost::filesystem::exists (mState.getPath()))
|
if (boost::filesystem::exists (mState.getPath()))
|
||||||
boost::filesystem::remove (mState.getPath());
|
boost::filesystem::remove (mState.getPath());
|
||||||
|
|
|
@ -16,10 +16,12 @@ namespace CSMDoc
|
||||||
{
|
{
|
||||||
Document& mDocument;
|
Document& mDocument;
|
||||||
SavingState& mState;
|
SavingState& mState;
|
||||||
|
bool mProjectFile;
|
||||||
|
|
||||||
public:
|
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();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
@ -32,10 +34,12 @@ namespace CSMDoc
|
||||||
{
|
{
|
||||||
Document& mDocument;
|
Document& mDocument;
|
||||||
SavingState& mState;
|
SavingState& mState;
|
||||||
|
bool mSimple;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WriteHeaderStage (Document& document, SavingState& state);
|
WriteHeaderStage (Document& document, SavingState& state, bool simple);
|
||||||
|
///< \param simple Simplified header (used for project files).
|
||||||
|
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
#include "operation.hpp"
|
#include "operation.hpp"
|
||||||
#include "document.hpp"
|
#include "document.hpp"
|
||||||
|
|
||||||
CSMDoc::SavingState::SavingState (Operation& operation)
|
CSMDoc::SavingState::SavingState (Operation& operation, const boost::filesystem::path& projectPath)
|
||||||
: mOperation (operation),
|
: mOperation (operation),
|
||||||
/// \todo set encoding properly, once config implementation has been fixed.
|
/// \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);
|
mWriter.setEncoder (&mEncoder);
|
||||||
}
|
}
|
||||||
|
@ -17,14 +18,19 @@ bool CSMDoc::SavingState::hasError() const
|
||||||
return mOperation.hasError();
|
return mOperation.hasError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::SavingState::start (Document& document)
|
void CSMDoc::SavingState::start (Document& document, bool project)
|
||||||
{
|
{
|
||||||
|
mProjectFile = project;
|
||||||
|
|
||||||
if (mStream.is_open())
|
if (mStream.is_open())
|
||||||
mStream.close();
|
mStream.close();
|
||||||
|
|
||||||
mStream.clear();
|
mStream.clear();
|
||||||
|
|
||||||
mPath = document.getSavePath();
|
if (project)
|
||||||
|
mPath = mProjectPath;
|
||||||
|
else
|
||||||
|
mPath = document.getSavePath();
|
||||||
|
|
||||||
boost::filesystem::path file (mPath.filename().string() + ".tmp");
|
boost::filesystem::path file (mPath.filename().string() + ".tmp");
|
||||||
|
|
||||||
|
@ -51,4 +57,9 @@ std::ofstream& CSMDoc::SavingState::getStream()
|
||||||
ESM::ESMWriter& CSMDoc::SavingState::getWriter()
|
ESM::ESMWriter& CSMDoc::SavingState::getWriter()
|
||||||
{
|
{
|
||||||
return mWriter;
|
return mWriter;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMDoc::SavingState::isProjectFile() const
|
||||||
|
{
|
||||||
|
return mProjectFile;
|
||||||
}
|
}
|
|
@ -20,14 +20,17 @@ namespace CSMDoc
|
||||||
ToUTF8::Utf8Encoder mEncoder;
|
ToUTF8::Utf8Encoder mEncoder;
|
||||||
std::ofstream mStream;
|
std::ofstream mStream;
|
||||||
ESM::ESMWriter mWriter;
|
ESM::ESMWriter mWriter;
|
||||||
|
boost::filesystem::path mProjectPath;
|
||||||
|
bool mProjectFile;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SavingState (Operation& operation);
|
SavingState (Operation& operation, const boost::filesystem::path& projectPath);
|
||||||
|
|
||||||
bool hasError() const;
|
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;
|
const boost::filesystem::path& getPath() const;
|
||||||
|
|
||||||
|
@ -36,6 +39,9 @@ namespace CSMDoc
|
||||||
std::ofstream& getStream();
|
std::ofstream& getStream();
|
||||||
|
|
||||||
ESM::ESMWriter& getWriter();
|
ESM::ESMWriter& getWriter();
|
||||||
|
|
||||||
|
bool isProjectFile() const;
|
||||||
|
///< Currently saving project file? (instead of content file)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,11 @@ namespace ESM
|
||||||
mHeader.mFormat = format;
|
mHeader.mFormat = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ESMWriter::clearMaster()
|
||||||
|
{
|
||||||
|
mHeader.mMaster.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ESMWriter::addMaster(const std::string& name, uint64_t size)
|
void ESMWriter::addMaster(const std::string& name, uint64_t size)
|
||||||
{
|
{
|
||||||
Header::MasterData d;
|
Header::MasterData d;
|
||||||
|
|
|
@ -32,6 +32,8 @@ class ESMWriter
|
||||||
void setRecordCount (int count);
|
void setRecordCount (int count);
|
||||||
void setFormat (int format);
|
void setFormat (int format);
|
||||||
|
|
||||||
|
void clearMaster();
|
||||||
|
|
||||||
void addMaster(const std::string& name, uint64_t size);
|
void addMaster(const std::string& name, uint64_t size);
|
||||||
|
|
||||||
void save(const std::string& file);
|
void save(const std::string& file);
|
||||||
|
|
|
@ -14,6 +14,7 @@ void ESM::Header::blank()
|
||||||
mData.desc.assign ("");
|
mData.desc.assign ("");
|
||||||
mData.records = 0;
|
mData.records = 0;
|
||||||
mFormat = CurrentFormat;
|
mFormat = CurrentFormat;
|
||||||
|
mMaster.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Header::load (ESMReader &esm)
|
void ESM::Header::load (ESMReader &esm)
|
||||||
|
|
Loading…
Reference in a new issue