mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-05 17:45:34 +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 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…
Reference in a new issue