mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 06:39:40 +00:00
Add ability to touch records, LAND records in particular
This commit is contained in:
parent
9e41f1340a
commit
1d480015b4
13 changed files with 149 additions and 6 deletions
|
@ -125,6 +125,10 @@ namespace CSMWorld
|
||||||
const std::string& destination,
|
const std::string& destination,
|
||||||
const UniversalId::Type type);
|
const UniversalId::Type type);
|
||||||
|
|
||||||
|
virtual bool touchRecord(const std::string& id);
|
||||||
|
///< Change the state of a record from base to modified, if it is not already.
|
||||||
|
/// \return True if the record was changed.
|
||||||
|
|
||||||
virtual int searchId (const std::string& id) const;
|
virtual int searchId (const std::string& id) const;
|
||||||
////< Search record with \a id.
|
////< Search record with \a id.
|
||||||
/// \return index of record (if found) or -1 (not found)
|
/// \return index of record (if found) or -1 (not found)
|
||||||
|
@ -235,6 +239,25 @@ namespace CSMWorld
|
||||||
insertRecord(copy, getAppendIndex(destination, type));
|
insertRecord(copy, getAppendIndex(destination, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
|
bool Collection<ESXRecordT, IdAccessorT>::touchRecord(const std::string& id)
|
||||||
|
{
|
||||||
|
int index = getIndex(id);
|
||||||
|
Record<ESXRecordT>& record = mRecords.at(index);
|
||||||
|
if (record.isDeleted())
|
||||||
|
{
|
||||||
|
throw std::runtime_error("attempt to touch deleted record");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!record.isModified() && !record.isDeleted() && !record.isErased())
|
||||||
|
{
|
||||||
|
record.setModified(record.get());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
Collection<ESXRecordT, IdAccessorT>::Collection()
|
Collection<ESXRecordT, IdAccessorT>::Collection()
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -78,6 +78,8 @@ namespace CSMWorld
|
||||||
const std::string& destination,
|
const std::string& destination,
|
||||||
const UniversalId::Type type) = 0;
|
const UniversalId::Type type) = 0;
|
||||||
|
|
||||||
|
virtual bool touchRecord(const std::string& id) = 0;
|
||||||
|
|
||||||
virtual const RecordBase& getRecord (const std::string& id) const = 0;
|
virtual const RecordBase& getRecord (const std::string& id) const = 0;
|
||||||
|
|
||||||
virtual const RecordBase& getRecord (int index) const = 0;
|
virtual const RecordBase& getRecord (int index) const = 0;
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace CSMWorld
|
||||||
inline QVariant StringIdColumn<LandTexture>::get(const Record<LandTexture>& record) const
|
inline QVariant StringIdColumn<LandTexture>::get(const Record<LandTexture>& record) const
|
||||||
{
|
{
|
||||||
const LandTexture& ltex = record.get();
|
const LandTexture& ltex = record.get();
|
||||||
return QString::fromUtf8(std::string('L' + std::to_string(ltex.mPluginIndex) + '#' + std::to_string(ltex.mIndex)).c_str());
|
return QString(LandTexture::createUniqueRecordId(ltex.mPluginIndex, ltex.mIndex).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
|
|
|
@ -15,6 +15,31 @@
|
||||||
#include "nestedtablewrapper.hpp"
|
#include "nestedtablewrapper.hpp"
|
||||||
#include "pathgrid.hpp"
|
#include "pathgrid.hpp"
|
||||||
|
|
||||||
|
CSMWorld::TouchCommand::TouchCommand(IdTable& table, const std::string& id, QUndoCommand* parent)
|
||||||
|
: QUndoCommand(parent)
|
||||||
|
, mTable(table)
|
||||||
|
, mId(id)
|
||||||
|
, mOld(nullptr)
|
||||||
|
, mChanged(false)
|
||||||
|
{
|
||||||
|
setText(("Touch " + mId).c_str());
|
||||||
|
mOld.reset(mTable.getRecord(mId).clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::TouchCommand::redo()
|
||||||
|
{
|
||||||
|
mChanged = mTable.touchRecord(mId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::TouchCommand::undo()
|
||||||
|
{
|
||||||
|
if (mChanged)
|
||||||
|
{
|
||||||
|
mTable.setRecord(mId, *mOld);
|
||||||
|
mChanged = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
|
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
|
||||||
const QVariant& new_, QUndoCommand* parent)
|
const QVariant& new_, QUndoCommand* parent)
|
||||||
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false), mOldRecordState(CSMWorld::RecordBase::State_BaseOnly)
|
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false), mOldRecordState(CSMWorld::RecordBase::State_BaseOnly)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
@ -24,6 +25,24 @@ namespace CSMWorld
|
||||||
struct RecordBase;
|
struct RecordBase;
|
||||||
struct NestedTableWrapperBase;
|
struct NestedTableWrapperBase;
|
||||||
|
|
||||||
|
class TouchCommand : public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
TouchCommand(IdTable& model, const std::string& id, QUndoCommand* parent=nullptr);
|
||||||
|
|
||||||
|
virtual void redo();
|
||||||
|
virtual void undo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
IdTable& mTable;
|
||||||
|
std::string mId;
|
||||||
|
std::unique_ptr<RecordBase> mOld;
|
||||||
|
|
||||||
|
bool mChanged;
|
||||||
|
};
|
||||||
|
|
||||||
class ModifyCommand : public QUndoCommand
|
class ModifyCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
QAbstractItemModel *mModel;
|
QAbstractItemModel *mModel;
|
||||||
|
|
|
@ -544,7 +544,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
|
||||||
addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart);
|
addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart);
|
||||||
addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen);
|
addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen);
|
||||||
addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect);
|
addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect);
|
||||||
addModel (new IdTable (&mLand), UniversalId::Type_Land);
|
addModel (new IdTable (&mLand, IdTable::Feature_AllowTouch), UniversalId::Type_Land);
|
||||||
addModel (new LandTextureIdTable (&mLandTextures), UniversalId::Type_LandTexture);
|
addModel (new LandTextureIdTable (&mLandTextures), UniversalId::Type_LandTexture);
|
||||||
addModel (new IdTree (&mPathgrids, &mPathgrids), UniversalId::Type_Pathgrid);
|
addModel (new IdTree (&mPathgrids, &mPathgrids), UniversalId::Type_Pathgrid);
|
||||||
addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript);
|
addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript);
|
||||||
|
|
|
@ -179,6 +179,26 @@ void CSMWorld::IdTable::cloneRecord(const std::string& origin,
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::IdTable::touchRecord(const std::string& id)
|
||||||
|
{
|
||||||
|
bool changed = mIdCollection->touchRecord(id);
|
||||||
|
|
||||||
|
int row = mIdCollection->getIndex(id);
|
||||||
|
int column = mIdCollection->searchColumnIndex(Columns::ColumnId_RecordType);
|
||||||
|
if (changed && column != -1)
|
||||||
|
{
|
||||||
|
QModelIndex modelIndex = index(row, column);
|
||||||
|
emit dataChanged(modelIndex, modelIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSMWorld::IdTable::getId(int row) const
|
||||||
|
{
|
||||||
|
return mIdCollection->getId(row);
|
||||||
|
}
|
||||||
|
|
||||||
///This method can return only indexes to the top level table cells
|
///This method can return only indexes to the top level table cells
|
||||||
QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) const
|
QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,6 +61,11 @@ namespace CSMWorld
|
||||||
const std::string& destination,
|
const std::string& destination,
|
||||||
UniversalId::Type type = UniversalId::Type_None);
|
UniversalId::Type type = UniversalId::Type_None);
|
||||||
|
|
||||||
|
bool touchRecord(const std::string& id);
|
||||||
|
///< Will change the record state to modified, if it is not already.
|
||||||
|
|
||||||
|
std::string getId(int row) const;
|
||||||
|
|
||||||
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
|
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||||
|
|
||||||
void setRecord (const std::string& id, const RecordBase& record,
|
void setRecord (const std::string& id, const RecordBase& record,
|
||||||
|
|
|
@ -32,7 +32,9 @@ namespace CSMWorld
|
||||||
Feature_Preview = 8,
|
Feature_Preview = 8,
|
||||||
|
|
||||||
/// Table can not be modified through ordinary means.
|
/// Table can not be modified through ordinary means.
|
||||||
Feature_Constant = 16
|
Feature_Constant = 16,
|
||||||
|
|
||||||
|
Feature_AllowTouch = 32
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -61,7 +63,7 @@ namespace CSMWorld
|
||||||
virtual bool isDeleted (const std::string& id) const = 0;
|
virtual bool isDeleted (const std::string& id) const = 0;
|
||||||
|
|
||||||
virtual int getColumnId (int column) const = 0;
|
virtual int getColumnId (int column) const = 0;
|
||||||
|
|
||||||
unsigned int getFeatures() const;
|
unsigned int getFeatures() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -813,6 +813,12 @@ void CSMWorld::RefIdCollection::cloneRecord(const std::string& origin,
|
||||||
mData.insertRecord(*newRecord, type, destination);
|
mData.insertRecord(*newRecord, type, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::RefIdCollection::touchRecord(const std::string& id)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("RefIdCollection::touchRecord is unimplemented");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMWorld::RefIdCollection::appendRecord (const RecordBase& record,
|
void CSMWorld::RefIdCollection::appendRecord (const RecordBase& record,
|
||||||
UniversalId::Type type)
|
UniversalId::Type type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,8 @@ namespace CSMWorld
|
||||||
const std::string& destination,
|
const std::string& destination,
|
||||||
const UniversalId::Type type);
|
const UniversalId::Type type);
|
||||||
|
|
||||||
|
virtual bool touchRecord(const std::string& id);
|
||||||
|
|
||||||
virtual void appendBlankRecord (const std::string& id, UniversalId::Type type);
|
virtual void appendBlankRecord (const std::string& id, UniversalId::Type type);
|
||||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,9 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
menu.addAction(mCloneAction);
|
menu.addAction(mCloneAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mTouchAction)
|
||||||
|
menu.addAction (mTouchAction);
|
||||||
|
|
||||||
if (mCreateAction)
|
if (mCreateAction)
|
||||||
menu.addAction (mCreateAction);
|
menu.addAction (mCreateAction);
|
||||||
|
|
||||||
|
@ -226,8 +229,8 @@ void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event)
|
||||||
|
|
||||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||||
bool createAndDelete, bool sorting, CSMDoc::Document& document)
|
bool createAndDelete, bool sorting, CSMDoc::Document& document)
|
||||||
: DragRecordTable(document), mCreateAction (0),
|
: DragRecordTable(document), mCreateAction (nullptr), mCloneAction(nullptr), mTouchAction(nullptr),
|
||||||
mCloneAction(0), mRecordStatusDisplay (0), mJumpToAddedRecord(false), mUnselectAfterJump(false)
|
mRecordStatusDisplay (0), mJumpToAddedRecord(false), mUnselectAfterJump(false)
|
||||||
{
|
{
|
||||||
mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id));
|
mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id));
|
||||||
|
|
||||||
|
@ -302,6 +305,15 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||||
cloneShortcut->associateAction(mCloneAction);
|
cloneShortcut->associateAction(mCloneAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_AllowTouch)
|
||||||
|
{
|
||||||
|
mTouchAction = new QAction(tr("Touch Record"), this);
|
||||||
|
connect(mTouchAction, SIGNAL(triggered()), this, SLOT(touchRecord()));
|
||||||
|
addAction(mTouchAction);
|
||||||
|
CSMPrefs::Shortcut* touchShortcut = new CSMPrefs::Shortcut("table-touch", this);
|
||||||
|
touchShortcut->associateAction(mTouchAction);
|
||||||
|
}
|
||||||
|
|
||||||
mRevertAction = new QAction (tr ("Revert Record"), this);
|
mRevertAction = new QAction (tr ("Revert Record"), this);
|
||||||
connect (mRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeRevert()));
|
connect (mRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeRevert()));
|
||||||
addAction (mRevertAction);
|
addAction (mRevertAction);
|
||||||
|
@ -442,6 +454,30 @@ void CSVWorld::Table::cloneRecord()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::Table::touchRecord()
|
||||||
|
{
|
||||||
|
if (!mEditLock && mModel->getFeatures() & CSMWorld::IdTableBase::Feature_AllowTouch)
|
||||||
|
{
|
||||||
|
if (CSMWorld::IdTable* table = dynamic_cast<CSMWorld::IdTable*>(mModel))
|
||||||
|
{
|
||||||
|
QUndoCommand* touchRecords = new QUndoCommand();
|
||||||
|
touchRecords->setText("Touch records");
|
||||||
|
|
||||||
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
for (auto it = selectedRows.begin(); it != selectedRows.end(); ++it)
|
||||||
|
{
|
||||||
|
QModelIndex index = mProxyModel->mapToSource(mProxyModel->index(it->row(),0));
|
||||||
|
std::string id = table->getId(index.row());
|
||||||
|
|
||||||
|
// command is a child of touchRecords
|
||||||
|
QUndoCommand* command = new CSMWorld::TouchCommand(*table, id, touchRecords);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDocument.getUndoStack().push(touchRecords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSVWorld::Table::moveUpRecord()
|
void CSVWorld::Table::moveUpRecord()
|
||||||
{
|
{
|
||||||
if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
|
if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace CSVWorld
|
||||||
QAction *mEditAction;
|
QAction *mEditAction;
|
||||||
QAction *mCreateAction;
|
QAction *mCreateAction;
|
||||||
QAction *mCloneAction;
|
QAction *mCloneAction;
|
||||||
|
QAction *mTouchAction;
|
||||||
QAction *mRevertAction;
|
QAction *mRevertAction;
|
||||||
QAction *mDeleteAction;
|
QAction *mDeleteAction;
|
||||||
QAction *mMoveUpAction;
|
QAction *mMoveUpAction;
|
||||||
|
@ -129,6 +130,8 @@ namespace CSVWorld
|
||||||
|
|
||||||
void cloneRecord();
|
void cloneRecord();
|
||||||
|
|
||||||
|
void touchRecord();
|
||||||
|
|
||||||
void moveUpRecord();
|
void moveUpRecord();
|
||||||
|
|
||||||
void moveDownRecord();
|
void moveDownRecord();
|
||||||
|
|
Loading…
Reference in a new issue