Support for undo/redo on array resize
This commit is contained in:
parent
cc054cf571
commit
f6f36f4f2e
|
@ -23,6 +23,19 @@ TIDString IProperty::IDString(bool FullPath) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CPropertyStruct ************
|
// ************ CPropertyStruct ************
|
||||||
|
void CPropertyStruct::Copy(const IProperty *pkProp)
|
||||||
|
{
|
||||||
|
const CPropertyStruct *pkSource = static_cast<const CPropertyStruct*>(pkProp);
|
||||||
|
|
||||||
|
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
|
||||||
|
delete *it;
|
||||||
|
|
||||||
|
mProperties.resize(pkSource->mProperties.size());
|
||||||
|
|
||||||
|
for (u32 iSub = 0; iSub < mProperties.size(); iSub++)
|
||||||
|
mProperties[iSub] = pkSource->mProperties[iSub]->Clone(this);
|
||||||
|
}
|
||||||
|
|
||||||
IProperty* CPropertyStruct::PropertyByIndex(u32 index) const
|
IProperty* CPropertyStruct::PropertyByIndex(u32 index) const
|
||||||
{
|
{
|
||||||
return mProperties[index];
|
return mProperties[index];
|
||||||
|
|
|
@ -41,8 +41,11 @@ public:
|
||||||
virtual EPropertyType Type() const = 0;
|
virtual EPropertyType Type() const = 0;
|
||||||
virtual TString ToString() const { return ""; }
|
virtual TString ToString() const { return ""; }
|
||||||
virtual IPropertyValue* RawValue() { return nullptr; }
|
virtual IPropertyValue* RawValue() { return nullptr; }
|
||||||
|
virtual void Copy(const IProperty *pkProp) = 0;
|
||||||
|
virtual IProperty* Clone(CPropertyStruct *pParent = 0) const = 0;
|
||||||
|
|
||||||
inline CPropertyStruct* Parent() const { return mpParent; }
|
inline CPropertyStruct* Parent() const { return mpParent; }
|
||||||
|
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
|
||||||
|
|
||||||
// These functions can't be in the header to avoid circular includes with IPropertyTemplate.h
|
// These functions can't be in the header to avoid circular includes with IPropertyTemplate.h
|
||||||
IPropertyTemplate* Template() const;
|
IPropertyTemplate* Template() const;
|
||||||
|
@ -71,6 +74,21 @@ public:
|
||||||
virtual TString ToString() const { return mValue.ToString(); }
|
virtual TString ToString() const { return mValue.ToString(); }
|
||||||
virtual IPropertyValue* RawValue() { return &mValue; }
|
virtual IPropertyValue* RawValue() { return &mValue; }
|
||||||
|
|
||||||
|
virtual void Copy(const IProperty *pkProp)
|
||||||
|
{
|
||||||
|
const TTypedProperty *pkCast = static_cast<const TTypedProperty*>(pkProp);
|
||||||
|
mValue.Set(pkCast->mValue.Get());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual TTypedProperty* Clone(CPropertyStruct *pParent) const
|
||||||
|
{
|
||||||
|
if (!pParent) pParent = mpParent;
|
||||||
|
|
||||||
|
TTypedProperty *pOut = new TTypedProperty(mpTemplate, pParent);
|
||||||
|
pOut->Copy(this);
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
||||||
inline PropType Get() const { return mValue.Get(); }
|
inline PropType Get() const { return mValue.Get(); }
|
||||||
inline void Set(PropType v) { mValue.Set(v); }
|
inline void Set(PropType v) { mValue.Set(v); }
|
||||||
};
|
};
|
||||||
|
@ -107,6 +125,16 @@ public:
|
||||||
|
|
||||||
EPropertyType Type() const { return eStructProperty; }
|
EPropertyType Type() const { return eStructProperty; }
|
||||||
|
|
||||||
|
virtual void Copy(const IProperty *pkProp);
|
||||||
|
|
||||||
|
virtual IProperty* Clone(CPropertyStruct *pParent) const
|
||||||
|
{
|
||||||
|
if (!pParent) pParent = mpParent;
|
||||||
|
CPropertyStruct *pOut = new CPropertyStruct(mpTemplate, pParent);
|
||||||
|
pOut->Copy(this);
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
||||||
// Inline
|
// Inline
|
||||||
inline u32 Count() const { return mProperties.size(); }
|
inline u32 Count() const { return mProperties.size(); }
|
||||||
inline void AddSubProperty(IProperty *pProp) { mProperties.push_back(pProp); }
|
inline void AddSubProperty(IProperty *pProp) { mProperties.push_back(pProp); }
|
||||||
|
@ -134,6 +162,14 @@ public:
|
||||||
|
|
||||||
EPropertyType Type() const { return eArrayProperty; }
|
EPropertyType Type() const { return eArrayProperty; }
|
||||||
|
|
||||||
|
virtual IProperty* Clone(CPropertyStruct *pParent) const
|
||||||
|
{
|
||||||
|
if (!pParent) pParent = mpParent;
|
||||||
|
CArrayProperty *pOut = new CArrayProperty(mpTemplate, pParent);
|
||||||
|
pOut->Copy(this);
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
||||||
// Inline
|
// Inline
|
||||||
inline void Reserve(u32 amount) { mProperties.reserve(amount); }
|
inline void Reserve(u32 amount) { mProperties.reserve(amount); }
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,9 @@ HEADERS += \
|
||||||
PropertyEdit/CPropertyRelay.h \
|
PropertyEdit/CPropertyRelay.h \
|
||||||
WorldEditor/CInstancesProxyModel.h \
|
WorldEditor/CInstancesProxyModel.h \
|
||||||
WorldEditor/CInstancesModel.h \
|
WorldEditor/CInstancesModel.h \
|
||||||
Undo/CEditScriptPropertyCommand.h
|
Undo/CEditScriptPropertyCommand.h \
|
||||||
|
Undo/CResizeScriptArrayCommand.h \
|
||||||
|
Undo/CBasicPropertyCommand.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -186,7 +188,9 @@ SOURCES += \
|
||||||
PropertyEdit/CPropertyDelegate.cpp \
|
PropertyEdit/CPropertyDelegate.cpp \
|
||||||
PropertyEdit/CPropertyView.cpp \
|
PropertyEdit/CPropertyView.cpp \
|
||||||
WorldEditor/CInstancesModel.cpp \
|
WorldEditor/CInstancesModel.cpp \
|
||||||
Undo/CEditScriptPropertyCommand.cpp
|
Undo/CEditScriptPropertyCommand.cpp \
|
||||||
|
Undo/CResizeScriptArrayCommand.cpp \
|
||||||
|
Undo/CBasicPropertyCommand.cpp
|
||||||
|
|
||||||
# UI Files
|
# UI Files
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Editor/UICommon.h"
|
#include "Editor/UICommon.h"
|
||||||
#include "Editor/Undo/CEditScriptPropertyCommand.h"
|
#include "Editor/Undo/CEditScriptPropertyCommand.h"
|
||||||
|
#include "Editor/Undo/CResizeScriptArrayCommand.h"
|
||||||
#include "Editor/Widgets/WColorPicker.h"
|
#include "Editor/Widgets/WColorPicker.h"
|
||||||
#include "Editor/Widgets/WDraggableSpinBox.h"
|
#include "Editor/Widgets/WDraggableSpinBox.h"
|
||||||
#include "Editor/Widgets/WIntegralSpinBox.h"
|
#include "Editor/Widgets/WIntegralSpinBox.h"
|
||||||
|
@ -351,7 +352,8 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
||||||
|
|
||||||
if (pProp)
|
if (pProp)
|
||||||
{
|
{
|
||||||
pOldValue = pProp->RawValue()->Clone();
|
IPropertyValue *pRawValue = pProp->RawValue();
|
||||||
|
pOldValue = pRawValue ? pRawValue->Clone() : nullptr;
|
||||||
|
|
||||||
switch (pProp->Type())
|
switch (pProp->Type())
|
||||||
{
|
{
|
||||||
|
@ -430,8 +432,14 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
||||||
case eArrayProperty:
|
case eArrayProperty:
|
||||||
{
|
{
|
||||||
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
||||||
|
CArrayProperty *pArray = static_cast<CArrayProperty*>(pProp);
|
||||||
u32 NewCount = pSpinBox->value();
|
u32 NewCount = pSpinBox->value();
|
||||||
mpModel->ResizeArray(rkIndex, NewCount);
|
|
||||||
|
if (pArray->Count() != NewCount)
|
||||||
|
{
|
||||||
|
CResizeScriptArrayCommand *pCmd = new CResizeScriptArrayCommand(mpModel, rkIndex, NewCount);
|
||||||
|
mpEditor->UndoStack()->push(pCmd);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +450,9 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
||||||
else if (rkIndex.internalId() & 0x1)
|
else if (rkIndex.internalId() & 0x1)
|
||||||
{
|
{
|
||||||
pProp = mpModel->PropertyForIndex(rkIndex, true);
|
pProp = mpModel->PropertyForIndex(rkIndex, true);
|
||||||
pOldValue = pProp->RawValue()->Clone();
|
|
||||||
|
IPropertyValue *pOldValue = pProp->RawValue();
|
||||||
|
pOldValue = pOldValue ? pOldValue->Clone() : nullptr;
|
||||||
|
|
||||||
if (pProp->Type() == eCharacterProperty)
|
if (pProp->Type() == eCharacterProperty)
|
||||||
SetCharacterModelData(pEditor, rkIndex);
|
SetCharacterModelData(pEditor, rkIndex);
|
||||||
|
@ -490,7 +500,7 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pProp)
|
if (pProp && pOldValue)
|
||||||
{
|
{
|
||||||
// Check for edit in progress
|
// Check for edit in progress
|
||||||
bool Matches = pOldValue->Matches(pProp->RawValue());
|
bool Matches = pOldValue->Matches(pProp->RawValue());
|
||||||
|
|
|
@ -409,29 +409,35 @@ void CPropertyModel::NotifyPropertyModified(const QModelIndex& rkIndex)
|
||||||
emit PropertyModified(rkIndex);
|
emit PropertyModified(rkIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPropertyModel::ResizeArray(const QModelIndex& rkIndex, u32 NewSize)
|
void CPropertyModel::ArrayAboutToBeResized(const QModelIndex& rkIndex, u32 NewSize)
|
||||||
{
|
{
|
||||||
QModelIndex Index = index(rkIndex.row(), 0, rkIndex.parent());
|
QModelIndex Index = rkIndex.sibling(rkIndex.row(), 0);
|
||||||
CArrayProperty *pArray = static_cast<CArrayProperty*>(PropertyForIndex(rkIndex, false));
|
CArrayProperty *pArray = static_cast<CArrayProperty*>(PropertyForIndex(Index, false));
|
||||||
|
|
||||||
if (pArray && pArray->Type() == eArrayProperty)
|
if (pArray && pArray->Type() == eArrayProperty)
|
||||||
{
|
{
|
||||||
u32 OldSize = pArray->Count();
|
u32 OldSize = pArray->Count();
|
||||||
|
|
||||||
if (OldSize != NewSize)
|
if (NewSize != OldSize)
|
||||||
{
|
{
|
||||||
if (OldSize < NewSize)
|
if (NewSize > OldSize)
|
||||||
{
|
|
||||||
beginInsertRows(Index, OldSize, NewSize - 1);
|
beginInsertRows(Index, OldSize, NewSize - 1);
|
||||||
pArray->Resize(NewSize);
|
|
||||||
endInsertRows();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
beginRemoveRows(Index, NewSize, OldSize - 1);
|
beginRemoveRows(Index, NewSize, OldSize - 1);
|
||||||
pArray->Resize(NewSize);
|
|
||||||
endRemoveRows();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPropertyModel::ArrayResized(const QModelIndex& rkIndex, u32 OldSize)
|
||||||
|
{
|
||||||
|
CArrayProperty *pArray = static_cast<CArrayProperty*>(PropertyForIndex(rkIndex, false));
|
||||||
|
u32 NewSize = pArray->Count();
|
||||||
|
|
||||||
|
if (NewSize != OldSize)
|
||||||
|
{
|
||||||
|
if (pArray->Count() > OldSize)
|
||||||
|
endInsertRows();
|
||||||
|
else
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,8 +24,9 @@ public:
|
||||||
Qt::ItemFlags flags(const QModelIndex& rkIndex) const;
|
Qt::ItemFlags flags(const QModelIndex& rkIndex) const;
|
||||||
|
|
||||||
void NotifyPropertyModified(const QModelIndex& rkIndex);
|
void NotifyPropertyModified(const QModelIndex& rkIndex);
|
||||||
|
void ArrayAboutToBeResized(const QModelIndex& rkIndex, u32 NewSize);
|
||||||
|
void ArrayResized(const QModelIndex& rkIndex, u32 OldSize);
|
||||||
void ResizeArray(const QModelIndex& rkIndex, u32 NewSize);
|
void ResizeArray(const QModelIndex& rkIndex, u32 NewSize);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void PropertyModified(const QModelIndex& rkIndex);
|
void PropertyModified(const QModelIndex& rkIndex);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
#include "CBasicPropertyCommand.h"
|
||||||
|
#include <Core/Resource/Script/IPropertyTemplate.h>
|
||||||
|
|
||||||
|
CBasicPropertyCommand::CBasicPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex)
|
||||||
|
: QUndoCommand("Edit Property")
|
||||||
|
, mpModel(pModel)
|
||||||
|
, mpProperty(pModel->PropertyForIndex(rkIndex, true))
|
||||||
|
, mpTemplate(mpProperty->Template())
|
||||||
|
, mIndex(rkIndex)
|
||||||
|
, mIsInArray(false)
|
||||||
|
{
|
||||||
|
// Check for array
|
||||||
|
IProperty *pProp = mpProperty;
|
||||||
|
IProperty *pParent = mpProperty->Parent();
|
||||||
|
|
||||||
|
while (pParent)
|
||||||
|
{
|
||||||
|
if (pParent->Type() == eArrayProperty)
|
||||||
|
{
|
||||||
|
mIsInArray = true;
|
||||||
|
|
||||||
|
// Find array index
|
||||||
|
CArrayProperty *pArray = static_cast<CArrayProperty*>(pParent);
|
||||||
|
|
||||||
|
for (u32 iSub = 0; iSub < pArray->Count(); iSub++)
|
||||||
|
{
|
||||||
|
if (pArray->PropertyByIndex(iSub) == pProp)
|
||||||
|
{
|
||||||
|
mArrayIndices << iSub;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pProp = pParent;
|
||||||
|
pParent = pParent->Parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBasicPropertyCommand::UpdateArraySubProperty()
|
||||||
|
{
|
||||||
|
// If an array has been sized down and then back up, then we might have an index to an invalid property.
|
||||||
|
// Since we can't assume our index is still valid, we'll use the template and the model to find the corresponding property.
|
||||||
|
IPropertyTemplate *pTemp = mpTemplate;
|
||||||
|
CStructTemplate *pParent = mpTemplate->Parent();
|
||||||
|
|
||||||
|
QVector<u32> SubIndices;
|
||||||
|
int IndexIndex = 0;
|
||||||
|
|
||||||
|
if (mIndex.internalId() & 0x1)
|
||||||
|
SubIndices << mIndex.row();
|
||||||
|
|
||||||
|
while (pParent)
|
||||||
|
{
|
||||||
|
if (pParent->Type() != eArrayProperty || static_cast<CArrayTemplate*>(pParent)->Count() > 1)
|
||||||
|
{
|
||||||
|
for (u32 iSub = 0; iSub < pParent->Count(); iSub++)
|
||||||
|
{
|
||||||
|
if (pParent->PropertyByIndex(iSub) == pTemp)
|
||||||
|
{
|
||||||
|
SubIndices << iSub;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pParent->Type() == eArrayProperty)
|
||||||
|
{
|
||||||
|
SubIndices << mArrayIndices[IndexIndex];
|
||||||
|
IndexIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTemp = pParent;
|
||||||
|
pParent = pParent->Parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find corresponding index
|
||||||
|
QModelIndex Index = QModelIndex();
|
||||||
|
|
||||||
|
for (int iSub = SubIndices.size() - 1; iSub >= 0; iSub--)
|
||||||
|
Index = mpModel->index(SubIndices[iSub], 0, Index);
|
||||||
|
|
||||||
|
Index = Index.sibling(Index.row(), 1);
|
||||||
|
|
||||||
|
// Get property
|
||||||
|
mpProperty = mpModel->PropertyForIndex(Index, true);
|
||||||
|
mIndex = Index;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef CBASICPROPERTYCOMMAND_H
|
||||||
|
#define CBASICPROPERTYCOMMAND_H
|
||||||
|
|
||||||
|
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||||
|
#include <QUndoCommand>
|
||||||
|
|
||||||
|
class CBasicPropertyCommand : public QUndoCommand
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
CPropertyModel *mpModel;
|
||||||
|
IProperty *mpProperty;
|
||||||
|
IPropertyTemplate *mpTemplate;
|
||||||
|
QModelIndex mIndex;
|
||||||
|
|
||||||
|
bool mIsInArray;
|
||||||
|
QVector<u32> mArrayIndices;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CBasicPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex);
|
||||||
|
virtual void UpdateArraySubProperty();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CBASICPROPERTYCOMMAND_H
|
|
@ -2,12 +2,9 @@
|
||||||
#include "EUndoCommand.h"
|
#include "EUndoCommand.h"
|
||||||
|
|
||||||
CEditScriptPropertyCommand::CEditScriptPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, IPropertyValue *pOldValue, bool IsDone)
|
CEditScriptPropertyCommand::CEditScriptPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, IPropertyValue *pOldValue, bool IsDone)
|
||||||
: QUndoCommand("Edit Property")
|
: CBasicPropertyCommand(pModel, rkIndex)
|
||||||
, mpModel(pModel)
|
|
||||||
, mIndex(rkIndex)
|
|
||||||
, mCommandEnded(IsDone)
|
, mCommandEnded(IsDone)
|
||||||
{
|
{
|
||||||
mpProperty = pModel->PropertyForIndex(rkIndex, true);
|
|
||||||
mpOldValue = pOldValue;
|
mpOldValue = pOldValue;
|
||||||
mpNewValue = mpProperty->RawValue()->Clone();
|
mpNewValue = mpProperty->RawValue()->Clone();
|
||||||
}
|
}
|
||||||
|
@ -42,12 +39,14 @@ bool CEditScriptPropertyCommand::mergeWith(const QUndoCommand *pkOther)
|
||||||
|
|
||||||
void CEditScriptPropertyCommand::undo()
|
void CEditScriptPropertyCommand::undo()
|
||||||
{
|
{
|
||||||
|
if (mIsInArray) UpdateArraySubProperty();
|
||||||
mpProperty->RawValue()->Copy(mpOldValue);
|
mpProperty->RawValue()->Copy(mpOldValue);
|
||||||
mpModel->NotifyPropertyModified(mIndex);
|
mpModel->NotifyPropertyModified(mIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEditScriptPropertyCommand::redo()
|
void CEditScriptPropertyCommand::redo()
|
||||||
{
|
{
|
||||||
|
if (mIsInArray) UpdateArraySubProperty();
|
||||||
mpProperty->RawValue()->Copy(mpNewValue);
|
mpProperty->RawValue()->Copy(mpNewValue);
|
||||||
mpModel->NotifyPropertyModified(mIndex);
|
mpModel->NotifyPropertyModified(mIndex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
#ifndef CEDITSCRIPTPROPERTYCOMMAND_H
|
#ifndef CEDITSCRIPTPROPERTYCOMMAND_H
|
||||||
#define CEDITSCRIPTPROPERTYCOMMAND_H
|
#define CEDITSCRIPTPROPERTYCOMMAND_H
|
||||||
|
|
||||||
#include "Editor/PropertyEdit/CPropertyDelegate.h"
|
#include "CBasicPropertyCommand.h"
|
||||||
|
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
|
|
||||||
class CEditScriptPropertyCommand : public QUndoCommand
|
class CEditScriptPropertyCommand : public CBasicPropertyCommand
|
||||||
{
|
{
|
||||||
CPropertyModel *mpModel;
|
|
||||||
IProperty *mpProperty;
|
|
||||||
QModelIndex mIndex;
|
|
||||||
|
|
||||||
IPropertyValue *mpOldValue;
|
IPropertyValue *mpOldValue;
|
||||||
IPropertyValue *mpNewValue;
|
IPropertyValue *mpNewValue;
|
||||||
bool mCommandEnded;
|
bool mCommandEnded;
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
#include "CResizeScriptArrayCommand.h"
|
||||||
|
|
||||||
|
CResizeScriptArrayCommand::CResizeScriptArrayCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, u32 NewSize)
|
||||||
|
: CBasicPropertyCommand(pModel, rkIndex)
|
||||||
|
, mpArray(static_cast<CArrayProperty*>(mpProperty))
|
||||||
|
, mOldSize(mpArray->Count())
|
||||||
|
, mNewSize(NewSize)
|
||||||
|
{
|
||||||
|
mNewSizeLarger = mNewSize > mOldSize;
|
||||||
|
|
||||||
|
if (!mNewSizeLarger)
|
||||||
|
{
|
||||||
|
for (u32 iSub = mNewSize; iSub < mOldSize; iSub++)
|
||||||
|
{
|
||||||
|
mDeletedProperties << mpArray->PropertyByIndex(iSub)->Clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CResizeScriptArrayCommand::~CResizeScriptArrayCommand()
|
||||||
|
{
|
||||||
|
foreach (IProperty *pProp, mDeletedProperties)
|
||||||
|
delete pProp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CResizeScriptArrayCommand::undo()
|
||||||
|
{
|
||||||
|
if (mNewSize != mOldSize)
|
||||||
|
{
|
||||||
|
if (mIsInArray) UpdateArraySubProperty();
|
||||||
|
|
||||||
|
mpModel->ArrayAboutToBeResized(mIndex, mOldSize);
|
||||||
|
mpArray->Resize(mOldSize);
|
||||||
|
|
||||||
|
if (!mNewSizeLarger)
|
||||||
|
{
|
||||||
|
u32 NumNewElements = mOldSize - mNewSize;
|
||||||
|
|
||||||
|
for (u32 iSub = 0; iSub < NumNewElements; iSub++)
|
||||||
|
{
|
||||||
|
u32 Idx = iSub + mNewSize;
|
||||||
|
mpArray->PropertyByIndex(Idx)->Copy(mDeletedProperties[iSub]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mpModel->ArrayResized(mIndex, mNewSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CResizeScriptArrayCommand::redo()
|
||||||
|
{
|
||||||
|
// Whether we're increasing or decreasing in size, there's no need to restore deleted properties on redo.
|
||||||
|
if (mNewSize != mOldSize)
|
||||||
|
{
|
||||||
|
if (mIsInArray) UpdateArraySubProperty();
|
||||||
|
|
||||||
|
mpModel->ArrayAboutToBeResized(mIndex, mNewSize);
|
||||||
|
mpArray->Resize(mNewSize);
|
||||||
|
mpModel->ArrayResized(mIndex, mOldSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CResizeScriptArrayCommand::UpdateArraySubProperty()
|
||||||
|
{
|
||||||
|
CArrayProperty *pOldArray = mpArray;
|
||||||
|
CBasicPropertyCommand::UpdateArraySubProperty();
|
||||||
|
mpArray = static_cast<CArrayProperty*>(mpProperty);
|
||||||
|
|
||||||
|
if (pOldArray != mpArray)
|
||||||
|
{
|
||||||
|
for (int iDel = 0; iDel < mDeletedProperties.size(); iDel++)
|
||||||
|
mDeletedProperties[iDel]->SetParent(mpArray);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef CRESIZESCRIPTARRAYCOMMAND_H
|
||||||
|
#define CRESIZESCRIPTARRAYCOMMAND_H
|
||||||
|
|
||||||
|
#include "CBasicPropertyCommand.h"
|
||||||
|
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||||
|
#include <QUndoCommand>
|
||||||
|
|
||||||
|
class CResizeScriptArrayCommand : public CBasicPropertyCommand
|
||||||
|
{
|
||||||
|
CArrayProperty *mpArray;
|
||||||
|
QVector<IProperty*> mDeletedProperties;
|
||||||
|
|
||||||
|
u32 mOldSize;
|
||||||
|
u32 mNewSize;
|
||||||
|
bool mNewSizeLarger;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CResizeScriptArrayCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, u32 NewSize);
|
||||||
|
~CResizeScriptArrayCommand();
|
||||||
|
void undo();
|
||||||
|
void redo();
|
||||||
|
virtual void UpdateArraySubProperty();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CRESIZESCRIPTARRAYCOMMAND_H
|
|
@ -10,6 +10,7 @@
|
||||||
#include "CSelectAllCommand.h"
|
#include "CSelectAllCommand.h"
|
||||||
#include "CInvertSelectionCommand.h"
|
#include "CInvertSelectionCommand.h"
|
||||||
#include "CEditScriptPropertyCommand.h"
|
#include "CEditScriptPropertyCommand.h"
|
||||||
|
#include "CResizeScriptArrayCommand.h"
|
||||||
#include "EUndoCommand.h"
|
#include "EUndoCommand.h"
|
||||||
|
|
||||||
#endif // UNDOCOMMANDS
|
#endif // UNDOCOMMANDS
|
||||||
|
|
Loading…
Reference in New Issue