Add ability to touch records, LAND records in particular

new-script-api
Kyle Cooley 7 years ago
parent 9e41f1340a
commit 1d480015b4

@ -125,6 +125,10 @@ namespace CSMWorld
const std::string& destination,
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;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
@ -235,6 +239,25 @@ namespace CSMWorld
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>
Collection<ESXRecordT, IdAccessorT>::Collection()
{}

@ -78,6 +78,8 @@ namespace CSMWorld
const std::string& destination,
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 (int index) const = 0;

@ -67,7 +67,7 @@ namespace CSMWorld
inline QVariant StringIdColumn<LandTexture>::get(const Record<LandTexture>& record) const
{
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>

@ -15,6 +15,31 @@
#include "nestedtablewrapper.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,
const QVariant& new_, QUndoCommand* parent)
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false), mOldRecordState(CSMWorld::RecordBase::State_BaseOnly)

@ -5,6 +5,7 @@
#include <string>
#include <map>
#include <memory>
#include <vector>
#include <QVariant>
@ -24,6 +25,24 @@ namespace CSMWorld
struct RecordBase;
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
{
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 (&mSoundGens), UniversalId::Type_SoundGen);
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 IdTree (&mPathgrids, &mPathgrids), UniversalId::Type_Pathgrid);
addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript);

@ -179,6 +179,26 @@ void CSMWorld::IdTable::cloneRecord(const std::string& origin,
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
QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) const
{

@ -61,6 +61,11 @@ namespace CSMWorld
const std::string& destination,
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;
void setRecord (const std::string& id, const RecordBase& record,

@ -32,7 +32,9 @@ namespace CSMWorld
Feature_Preview = 8,
/// Table can not be modified through ordinary means.
Feature_Constant = 16
Feature_Constant = 16,
Feature_AllowTouch = 32
};
private:
@ -61,7 +63,7 @@ namespace CSMWorld
virtual bool isDeleted (const std::string& id) const = 0;
virtual int getColumnId (int column) const = 0;
unsigned int getFeatures() const;
};
}

@ -813,6 +813,12 @@ void CSMWorld::RefIdCollection::cloneRecord(const std::string& origin,
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,
UniversalId::Type type)
{

@ -80,6 +80,8 @@ namespace CSMWorld
const std::string& destination,
const UniversalId::Type type);
virtual bool touchRecord(const std::string& id);
virtual void appendBlankRecord (const std::string& id, UniversalId::Type type);
///< \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);
}
if (mTouchAction)
menu.addAction (mTouchAction);
if (mCreateAction)
menu.addAction (mCreateAction);
@ -226,8 +229,8 @@ void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event)
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
bool createAndDelete, bool sorting, CSMDoc::Document& document)
: DragRecordTable(document), mCreateAction (0),
mCloneAction(0), mRecordStatusDisplay (0), mJumpToAddedRecord(false), mUnselectAfterJump(false)
: DragRecordTable(document), mCreateAction (nullptr), mCloneAction(nullptr), mTouchAction(nullptr),
mRecordStatusDisplay (0), mJumpToAddedRecord(false), mUnselectAfterJump(false)
{
mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id));
@ -302,6 +305,15 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
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);
connect (mRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeRevert()));
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()
{
if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))

@ -56,6 +56,7 @@ namespace CSVWorld
QAction *mEditAction;
QAction *mCreateAction;
QAction *mCloneAction;
QAction *mTouchAction;
QAction *mRevertAction;
QAction *mDeleteAction;
QAction *mMoveUpAction;
@ -129,6 +130,8 @@ namespace CSVWorld
void cloneRecord();
void touchRecord();
void moveUpRecord();
void moveDownRecord();

Loading…
Cancel
Save