mirror of https://github.com/OpenMW/openmw.git
Merge branch 'mergetool'
Conflicts: apps/opencs/CMakeLists.txt apps/opencs/model/tools/tools.cpppull/757/head
commit
a445683312
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
#include "mergeoperation.hpp"
|
||||||
|
|
||||||
|
#include "../doc/state.hpp"
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
|
||||||
|
#include "mergestages.hpp"
|
||||||
|
|
||||||
|
CSMTools::MergeOperation::MergeOperation (CSMDoc::Document& document, ToUTF8::FromType encoding)
|
||||||
|
: CSMDoc::Operation (CSMDoc::State_Merging, true), mState (document)
|
||||||
|
{
|
||||||
|
appendStage (new StartMergeStage (mState));
|
||||||
|
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Global> (mState, &CSMWorld::Data::getGlobals));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::GameSetting> (mState, &CSMWorld::Data::getGmsts));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Skill> (mState, &CSMWorld::Data::getSkills));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Class> (mState, &CSMWorld::Data::getClasses));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Faction> (mState, &CSMWorld::Data::getFactions));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Race> (mState, &CSMWorld::Data::getRaces));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Sound> (mState, &CSMWorld::Data::getSounds));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Script> (mState, &CSMWorld::Data::getScripts));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Region> (mState, &CSMWorld::Data::getRegions));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::BirthSign> (mState, &CSMWorld::Data::getBirthsigns));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Spell> (mState, &CSMWorld::Data::getSpells));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Dialogue> (mState, &CSMWorld::Data::getTopics));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Dialogue> (mState, &CSMWorld::Data::getJournals));
|
||||||
|
appendStage (new MergeIdCollectionStage<CSMWorld::Cell> (mState, &CSMWorld::Data::getCells));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Filter> (mState, &CSMWorld::Data::getFilters));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::Enchantment> (mState, &CSMWorld::Data::getEnchantments));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::BodyPart> (mState, &CSMWorld::Data::getBodyParts));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::DebugProfile> (mState, &CSMWorld::Data::getDebugProfiles));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::SoundGenerator> (mState, &CSMWorld::Data::getSoundGens));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::MagicEffect> (mState, &CSMWorld::Data::getMagicEffects));
|
||||||
|
appendStage (new MergeIdCollectionStage<ESM::StartScript> (mState, &CSMWorld::Data::getStartScripts));
|
||||||
|
appendStage (new MergeIdCollectionStage<CSMWorld::Pathgrid, CSMWorld::SubCellCollection<CSMWorld::Pathgrid> > (mState, &CSMWorld::Data::getPathgrids));
|
||||||
|
appendStage (new MergeIdCollectionStage<CSMWorld::Info, CSMWorld::InfoCollection> (mState, &CSMWorld::Data::getTopicInfos));
|
||||||
|
appendStage (new MergeIdCollectionStage<CSMWorld::Info, CSMWorld::InfoCollection> (mState, &CSMWorld::Data::getJournalInfos));
|
||||||
|
appendStage (new MergeRefIdsStage (mState));
|
||||||
|
appendStage (new MergeReferencesStage (mState));
|
||||||
|
appendStage (new MergeReferencesStage (mState));
|
||||||
|
appendStage (new ListLandTexturesMergeStage (mState));
|
||||||
|
appendStage (new MergeLandTexturesStage (mState));
|
||||||
|
appendStage (new MergeLandStage (mState));
|
||||||
|
|
||||||
|
appendStage (new FinishMergedDocumentStage (mState, encoding));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::MergeOperation::setTarget (std::auto_ptr<CSMDoc::Document> document)
|
||||||
|
{
|
||||||
|
mState.mTarget = document;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::MergeOperation::operationDone()
|
||||||
|
{
|
||||||
|
CSMDoc::Operation::operationDone();
|
||||||
|
|
||||||
|
if (mState.mCompleted)
|
||||||
|
emit mergeDone (mState.mTarget.release());
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef CSM_TOOLS_MERGEOPERATION_H
|
||||||
|
#define CSM_TOOLS_MERGEOPERATION_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <components/to_utf8/to_utf8.hpp>
|
||||||
|
|
||||||
|
#include "../doc/operation.hpp"
|
||||||
|
|
||||||
|
#include "mergestate.hpp"
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
class MergeOperation : public CSMDoc::Operation
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
MergeState mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MergeOperation (CSMDoc::Document& document, ToUTF8::FromType encoding);
|
||||||
|
|
||||||
|
/// \attention Do not call this function while a merge is running.
|
||||||
|
void setTarget (std::auto_ptr<CSMDoc::Document> document);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
|
||||||
|
virtual void operationDone();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/// \attention When this signal is emitted, *this hands over the ownership of the
|
||||||
|
/// document. This signal must be handled to avoid a leak.
|
||||||
|
void mergeDone (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,258 @@
|
|||||||
|
|
||||||
|
#include "mergestages.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include "mergestate.hpp"
|
||||||
|
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
#include "../world/data.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
CSMTools::StartMergeStage::StartMergeStage (MergeState& state)
|
||||||
|
: mState (state)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMTools::StartMergeStage::setup()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::StartMergeStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
mState.mCompleted = false;
|
||||||
|
mState.mTextureIndices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMTools::FinishMergedDocumentStage::FinishMergedDocumentStage (MergeState& state, ToUTF8::FromType encoding)
|
||||||
|
: mState (state), mEncoder (encoding)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMTools::FinishMergedDocumentStage::setup()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::FinishMergedDocumentStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
// We know that the content file list contains at least two entries and that the first one
|
||||||
|
// does exist on disc (otherwise it would have been impossible to initiate a merge on that
|
||||||
|
// document).
|
||||||
|
boost::filesystem::path path = mState.mSource.getContentFiles()[0];
|
||||||
|
|
||||||
|
ESM::ESMReader reader;
|
||||||
|
reader.setEncoder (&mEncoder);
|
||||||
|
reader.open (path.string());
|
||||||
|
|
||||||
|
CSMWorld::MetaData source;
|
||||||
|
source.mId = "sys::meta";
|
||||||
|
source.load (reader);
|
||||||
|
|
||||||
|
CSMWorld::MetaData target = mState.mTarget->getData().getMetaData();
|
||||||
|
|
||||||
|
target.mAuthor = source.mAuthor;
|
||||||
|
target.mDescription = source.mDescription;
|
||||||
|
|
||||||
|
mState.mTarget->getData().setMetaData (target);
|
||||||
|
|
||||||
|
mState.mCompleted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMTools::MergeRefIdsStage::MergeRefIdsStage (MergeState& state) : mState (state) {}
|
||||||
|
|
||||||
|
int CSMTools::MergeRefIdsStage::setup()
|
||||||
|
{
|
||||||
|
return mState.mSource.getData().getReferenceables().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::MergeRefIdsStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
mState.mSource.getData().getReferenceables().copyTo (
|
||||||
|
stage, mState.mTarget->getData().getReferenceables());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMTools::MergeReferencesStage::MergeReferencesStage (MergeState& state)
|
||||||
|
: mState (state)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMTools::MergeReferencesStage::setup()
|
||||||
|
{
|
||||||
|
mIndex.clear();
|
||||||
|
return mState.mSource.getData().getReferences().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::CellRef>& record =
|
||||||
|
mState.mSource.getData().getReferences().getRecord (stage);
|
||||||
|
|
||||||
|
if (!record.isDeleted())
|
||||||
|
{
|
||||||
|
CSMWorld::CellRef ref = record.get();
|
||||||
|
|
||||||
|
ref.mOriginalCell = ref.mCell;
|
||||||
|
|
||||||
|
ref.mRefNum.mIndex = mIndex[Misc::StringUtils::lowerCase (ref.mCell)]++;
|
||||||
|
ref.mRefNum.mContentFile = 0;
|
||||||
|
|
||||||
|
CSMWorld::Record<CSMWorld::CellRef> newRecord (
|
||||||
|
CSMWorld::RecordBase::State_ModifiedOnly, 0, &ref);
|
||||||
|
|
||||||
|
mState.mTarget->getData().getReferences().appendRecord (newRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMTools::ListLandTexturesMergeStage::ListLandTexturesMergeStage (MergeState& state)
|
||||||
|
: mState (state)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMTools::ListLandTexturesMergeStage::setup()
|
||||||
|
{
|
||||||
|
return mState.mSource.getData().getLand().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::ListLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::Land>& record =
|
||||||
|
mState.mSource.getData().getLand().getRecord (stage);
|
||||||
|
|
||||||
|
if (!record.isDeleted())
|
||||||
|
{
|
||||||
|
const CSMWorld::Land& land = record.get();
|
||||||
|
|
||||||
|
// make sure record is loaded
|
||||||
|
land.loadData (ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML |
|
||||||
|
ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX | ESM::Land::DATA_WNAM);
|
||||||
|
|
||||||
|
if (const ESM::Land::LandData *data = land.getLandData (ESM::Land::DATA_VTEX))
|
||||||
|
{
|
||||||
|
// list texture indices
|
||||||
|
std::pair<uint16_t, int> key;
|
||||||
|
key.second = land.mPlugin;
|
||||||
|
|
||||||
|
for (int i=0; i<ESM::Land::LAND_NUM_TEXTURES; ++i)
|
||||||
|
{
|
||||||
|
key.first = data->mTextures[i];
|
||||||
|
|
||||||
|
mState.mTextureIndices[key] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMTools::MergeLandTexturesStage::MergeLandTexturesStage (MergeState& state)
|
||||||
|
: mState (state), mNext (mState.mTextureIndices.end())
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMTools::MergeLandTexturesStage::setup()
|
||||||
|
{
|
||||||
|
// Should use the size of mState.mTextureIndices instead, but that is not available at this
|
||||||
|
// point. Unless there are any errors in the land and land texture records this will not
|
||||||
|
// make a difference.
|
||||||
|
return mState.mSource.getData().getLandTextures().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::MergeLandTexturesStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
if (stage==0)
|
||||||
|
mNext = mState.mTextureIndices.begin();
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (mNext==mState.mTextureIndices.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mNext->second = stage+1;
|
||||||
|
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << mNext->first.first-1 << "_" << mNext->first.second;
|
||||||
|
|
||||||
|
int index = mState.mSource.getData().getLandTextures().searchId (stream.str());
|
||||||
|
|
||||||
|
if (index!=-1)
|
||||||
|
{
|
||||||
|
CSMWorld::LandTexture texture =
|
||||||
|
mState.mSource.getData().getLandTextures().getRecord (index).get();
|
||||||
|
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << mNext->second-1 << "_0";
|
||||||
|
|
||||||
|
texture.mIndex = mNext->second-1;
|
||||||
|
texture.mId = stream.str();
|
||||||
|
|
||||||
|
CSMWorld::Record<CSMWorld::LandTexture> newRecord (
|
||||||
|
CSMWorld::RecordBase::State_ModifiedOnly, 0, &texture);
|
||||||
|
|
||||||
|
mState.mTarget->getData().getLandTextures().appendRecord (newRecord);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
++mNext;
|
||||||
|
}
|
||||||
|
while (!found);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMTools::MergeLandStage::MergeLandStage (MergeState& state) : mState (state) {}
|
||||||
|
|
||||||
|
int CSMTools::MergeLandStage::setup()
|
||||||
|
{
|
||||||
|
return mState.mSource.getData().getLand().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::MergeLandStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::Land>& record =
|
||||||
|
mState.mSource.getData().getLand().getRecord (stage);
|
||||||
|
|
||||||
|
if (!record.isDeleted())
|
||||||
|
{
|
||||||
|
const CSMWorld::Land& land = record.get();
|
||||||
|
|
||||||
|
land.loadData (ESM::Land::DATA_VCLR | ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML |
|
||||||
|
ESM::Land::DATA_VTEX | ESM::Land::DATA_WNAM);
|
||||||
|
|
||||||
|
CSMWorld::Land newLand (land);
|
||||||
|
|
||||||
|
newLand.mEsm = 0; // avoid potential dangling pointer (ESMReader isn't needed anyway,
|
||||||
|
// because record is already fully loaded)
|
||||||
|
newLand.mPlugin = 0;
|
||||||
|
|
||||||
|
if (land.mDataTypes & ESM::Land::DATA_VTEX)
|
||||||
|
{
|
||||||
|
// adjust land texture references
|
||||||
|
if (ESM::Land::LandData *data = newLand.getLandData())
|
||||||
|
{
|
||||||
|
std::pair<uint16_t, int> key;
|
||||||
|
key.second = land.mPlugin;
|
||||||
|
|
||||||
|
for (int i=0; i<ESM::Land::LAND_NUM_TEXTURES; ++i)
|
||||||
|
{
|
||||||
|
key.first = data->mTextures[i];
|
||||||
|
std::map<std::pair<uint16_t, int>, int>::const_iterator iter =
|
||||||
|
mState.mTextureIndices.find (key);
|
||||||
|
|
||||||
|
if (iter!=mState.mTextureIndices.end())
|
||||||
|
data->mTextures[i] = iter->second;
|
||||||
|
else
|
||||||
|
data->mTextures[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::Record<CSMWorld::Land> newRecord (
|
||||||
|
CSMWorld::RecordBase::State_ModifiedOnly, 0, &newLand);
|
||||||
|
|
||||||
|
mState.mTarget->getData().getLand().appendRecord (newRecord);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,166 @@
|
|||||||
|
#ifndef CSM_TOOLS_MERGESTAGES_H
|
||||||
|
#define CSM_TOOLS_MERGESTAGES_H
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <components/to_utf8/to_utf8.hpp>
|
||||||
|
|
||||||
|
#include "../doc/stage.hpp"
|
||||||
|
|
||||||
|
#include "../world/data.hpp"
|
||||||
|
|
||||||
|
#include "mergestate.hpp"
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
class StartMergeStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
StartMergeStage (MergeState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
class FinishMergedDocumentStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
ToUTF8::Utf8Encoder mEncoder;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FinishMergedDocumentStage (MergeState& state, ToUTF8::FromType encoding);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename RecordType, typename Collection = CSMWorld::IdCollection<RecordType> >
|
||||||
|
class MergeIdCollectionStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
Collection& (CSMWorld::Data::*mAccessor)();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MergeIdCollectionStage (MergeState& state, Collection& (CSMWorld::Data::*accessor)());
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename RecordType, typename Collection>
|
||||||
|
MergeIdCollectionStage<RecordType, Collection>::MergeIdCollectionStage (MergeState& state, Collection& (CSMWorld::Data::*accessor)())
|
||||||
|
: mState (state), mAccessor (accessor)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename RecordType, typename Collection>
|
||||||
|
int MergeIdCollectionStage<RecordType, Collection>::setup()
|
||||||
|
{
|
||||||
|
return (mState.mSource.getData().*mAccessor)().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RecordType, typename Collection>
|
||||||
|
void MergeIdCollectionStage<RecordType, Collection>::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
const Collection& source = (mState.mSource.getData().*mAccessor)();
|
||||||
|
Collection& target = (mState.mTarget->getData().*mAccessor)();
|
||||||
|
|
||||||
|
const CSMWorld::Record<RecordType>& record = source.getRecord (stage);
|
||||||
|
|
||||||
|
if (!record.isDeleted())
|
||||||
|
target.appendRecord (CSMWorld::Record<RecordType> (CSMWorld::RecordBase::State_ModifiedOnly, 0, &record.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
class MergeRefIdsStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MergeRefIdsStage (MergeState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
class MergeReferencesStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
std::map<std::string, int> mIndex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MergeReferencesStage (MergeState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
class ListLandTexturesMergeStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ListLandTexturesMergeStage (MergeState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
class MergeLandTexturesStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
std::map<std::pair<uint16_t, int>, int>::iterator mNext;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MergeLandTexturesStage (MergeState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
class MergeLandStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MergeLandStage (MergeState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef CSM_TOOLS_MERGESTATE_H
|
||||||
|
#define CSM_TOOLS_MERGESTATE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
struct MergeState
|
||||||
|
{
|
||||||
|
std::auto_ptr<CSMDoc::Document> mTarget;
|
||||||
|
CSMDoc::Document& mSource;
|
||||||
|
bool mCompleted;
|
||||||
|
std::map<std::pair<uint16_t, int>, int> mTextureIndices; // (texture, content file) -> new texture
|
||||||
|
|
||||||
|
MergeState (CSMDoc::Document& source) : mSource (source), mCompleted (false) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,142 @@
|
|||||||
|
|
||||||
|
#include "merge.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
#include "../../model/doc/documentmanager.hpp"
|
||||||
|
|
||||||
|
#include "../doc/filewidget.hpp"
|
||||||
|
#include "../doc/adjusterwidget.hpp"
|
||||||
|
|
||||||
|
void CSVTools::Merge::keyPressEvent (QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if (event->key()==Qt::Key_Escape)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
QWidget::keyPressEvent (event);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVTools::Merge::Merge (CSMDoc::DocumentManager& documentManager, QWidget *parent)
|
||||||
|
: QWidget (parent), mDocument (0), mDocumentManager (documentManager)
|
||||||
|
{
|
||||||
|
setWindowTitle ("Merge Content Files into a new Game File");
|
||||||
|
|
||||||
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
|
setLayout (mainLayout);
|
||||||
|
|
||||||
|
QSplitter *splitter = new QSplitter (Qt::Horizontal, this);
|
||||||
|
|
||||||
|
mainLayout->addWidget (splitter, 1);
|
||||||
|
|
||||||
|
// left panel (files to be merged)
|
||||||
|
QWidget *left = new QWidget (this);
|
||||||
|
left->setContentsMargins (0, 0, 0, 0);
|
||||||
|
splitter->addWidget (left);
|
||||||
|
|
||||||
|
QVBoxLayout *leftLayout = new QVBoxLayout;
|
||||||
|
left->setLayout (leftLayout);
|
||||||
|
|
||||||
|
leftLayout->addWidget (new QLabel ("Files to be merged", this));
|
||||||
|
|
||||||
|
mFiles = new QListWidget (this);
|
||||||
|
leftLayout->addWidget (mFiles, 1);
|
||||||
|
|
||||||
|
// right panel (new game file)
|
||||||
|
QWidget *right = new QWidget (this);
|
||||||
|
right->setContentsMargins (0, 0, 0, 0);
|
||||||
|
splitter->addWidget (right);
|
||||||
|
|
||||||
|
QVBoxLayout *rightLayout = new QVBoxLayout;
|
||||||
|
rightLayout->setAlignment (Qt::AlignTop);
|
||||||
|
right->setLayout (rightLayout);
|
||||||
|
|
||||||
|
rightLayout->addWidget (new QLabel ("New game file", this));
|
||||||
|
|
||||||
|
mNewFile = new CSVDoc::FileWidget (this);
|
||||||
|
mNewFile->setType (false);
|
||||||
|
mNewFile->extensionLabelIsVisible (true);
|
||||||
|
rightLayout->addWidget (mNewFile);
|
||||||
|
|
||||||
|
mAdjuster = new CSVDoc::AdjusterWidget (this);
|
||||||
|
|
||||||
|
rightLayout->addWidget (mAdjuster);
|
||||||
|
|
||||||
|
connect (mNewFile, SIGNAL (nameChanged (const QString&, bool)),
|
||||||
|
mAdjuster, SLOT (setName (const QString&, bool)));
|
||||||
|
connect (mAdjuster, SIGNAL (stateChanged (bool)), this, SLOT (stateChanged (bool)));
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
QDialogButtonBox *buttons = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, this);
|
||||||
|
|
||||||
|
connect (buttons->button (QDialogButtonBox::Cancel), SIGNAL (clicked()), this, SLOT (cancel()));
|
||||||
|
|
||||||
|
mOkay = new QPushButton ("Merge", this);
|
||||||
|
connect (mOkay, SIGNAL (clicked()), this, SLOT (accept()));
|
||||||
|
mOkay->setDefault (true);
|
||||||
|
buttons->addButton (mOkay, QDialogButtonBox::AcceptRole);
|
||||||
|
|
||||||
|
mainLayout->addWidget (buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::Merge::configure (CSMDoc::Document *document)
|
||||||
|
{
|
||||||
|
mDocument = document;
|
||||||
|
|
||||||
|
mNewFile->setName ("");
|
||||||
|
|
||||||
|
// content files
|
||||||
|
while (mFiles->count())
|
||||||
|
delete mFiles->takeItem (0);
|
||||||
|
|
||||||
|
std::vector<boost::filesystem::path> files = document->getContentFiles();
|
||||||
|
|
||||||
|
for (std::vector<boost::filesystem::path>::const_iterator iter (files.begin());
|
||||||
|
iter!=files.end(); ++iter)
|
||||||
|
mFiles->addItem (QString::fromUtf8 (iter->filename().string().c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::Merge::setLocalData (const boost::filesystem::path& localData)
|
||||||
|
{
|
||||||
|
mAdjuster->setLocalData (localData);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMDoc::Document *CSVTools::Merge::getDocument() const
|
||||||
|
{
|
||||||
|
return mDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::Merge::cancel()
|
||||||
|
{
|
||||||
|
mDocument = 0;
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::Merge::accept()
|
||||||
|
{
|
||||||
|
if ((mDocument->getState() & CSMDoc::State_Merging)==0)
|
||||||
|
{
|
||||||
|
std::vector< boost::filesystem::path > files (1, mAdjuster->getPath());
|
||||||
|
|
||||||
|
std::auto_ptr<CSMDoc::Document> target (
|
||||||
|
mDocumentManager.makeDocument (files, files[0], true));
|
||||||
|
|
||||||
|
mDocument->runMerge (target);
|
||||||
|
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::Merge::stateChanged (bool valid)
|
||||||
|
{
|
||||||
|
mOkay->setEnabled (valid);
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef CSV_TOOLS_REPORTTABLE_H
|
||||||
|
#define CSV_TOOLS_REPORTTABLE_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
|
class QPushButton;
|
||||||
|
class QListWidget;
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
class DocumentManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVDoc
|
||||||
|
{
|
||||||
|
class FileWidget;
|
||||||
|
class AdjusterWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVTools
|
||||||
|
{
|
||||||
|
class Merge : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMDoc::Document *mDocument;
|
||||||
|
QPushButton *mOkay;
|
||||||
|
QListWidget *mFiles;
|
||||||
|
CSVDoc::FileWidget *mNewFile;
|
||||||
|
CSVDoc::AdjusterWidget *mAdjuster;
|
||||||
|
CSMDoc::DocumentManager& mDocumentManager;
|
||||||
|
|
||||||
|
void keyPressEvent (QKeyEvent *event);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Merge (CSMDoc::DocumentManager& documentManager, QWidget *parent = 0);
|
||||||
|
|
||||||
|
/// Configure dialogue for a new merge
|
||||||
|
void configure (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void setLocalData (const boost::filesystem::path& localData);
|
||||||
|
|
||||||
|
CSMDoc::Document *getDocument() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void cancel();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void accept();
|
||||||
|
|
||||||
|
void stateChanged (bool valid);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue