New library VPropertyExplorer.

--HG--
branch : feature
This commit is contained in:
dismine 2014-08-26 18:06:14 +03:00
parent b61b705303
commit 3ccd408718
60 changed files with 5094 additions and 11 deletions

View File

@ -620,29 +620,36 @@ INSTALLS += \
for(_translation_name, TRANSLATIONS) {
_translation_name_qm = $$section(_translation_name,".", 0, 0).qm
system($$shell_path($$[QT_INSTALL_BINS]/lrelease) $$shell_path($$PWD/$$_translation_name) -qm $$shell_path($$PWD/$$_translation_name_qm))
system($$shell_path($$[QT_INSTALL_BINS]/lrelease) $$shell_path($${PWD}/$$_translation_name) -qm $$shell_path($${PWD}/$$_translation_name_qm))
}
}
for(DIR, INSTALL_TRANSLATIONS) {
#add these absolute paths to a variable which
#ends up as 'mkcommands = path1 path2 path3 ...'
tr_path += $$PWD/$$DIR
tr_path += $${PWD}/$$DIR
}
copyToDestdir($$tr_path, $$shell_path($$OUT_PWD/$$DESTDIR/translations))
copyToDestdir($$tr_path, $$shell_path($${OUT_PWD}/$$DESTDIR/translations))
for(DIR, INSTALL_STANDARD_MEASHUREMENTS) {
#add these absolute paths to a variable which
#ends up as 'mkcommands = path1 path2 path3 ...'
st_path += $$PWD/$$DIR
st_path += $${PWD}/$$DIR
}
copyToDestdir($$st_path, $$shell_path($$OUT_PWD/$$DESTDIR/tables/standard))
copyToDestdir($$st_path, $$shell_path($${OUT_PWD}/$$DESTDIR/tables/standard))
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libs/qmuparser/bin -lqmuparser2
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libs/qmuparser/bin -lqmuparser2
else:unix: LIBS += -L$$OUT_PWD/../libs/qmuparser/bin -lqmuparser
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../libs/qmuparser/$${DESTDIR} -lqmuparser2
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../libs/qmuparser/$${DESTDIR} -lqmuparser2
else:unix: LIBS += -L$${OUT_PWD}/../libs/qmuparser/$${DESTDIR} -lqmuparser
INCLUDEPATH += $$PWD/../libs/qmuparser
DEPENDPATH += $$PWD/../libs/qmuparser
INCLUDEPATH += $${PWD}/../libs/qmuparser
DEPENDPATH += $${PWD}/../libs/qmuparser
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../libs/vpropertyexplorer/$${DESTDIR} -lvpropertyexplorer
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../libs/vpropertyexplorer/$${DESTDIR} -lvpropertyexplorer
else:unix: LIBS += -L$${OUT_PWD}/../libs/vpropertyexplorer/$${DESTDIR} -lvpropertyexplorer
INCLUDEPATH += $${PWD}/../libs/vpropertyexplorer
DEPENDPATH += $${PWD}/../libs/vpropertyexplorer

View File

@ -1,3 +1,4 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = qmuparser
SUBDIRS = qmuparser \
vpropertyexplorer

View File

@ -0,0 +1,113 @@
#include "vvector3dproperty.h"
using namespace VPE;
#include "vproperty_p.h"
#include "../vnumberproperty.h"
#include <QStringList>
QVector3DProperty::QVector3DProperty(const QString& name)
: VProperty(name, QVariant::String) // todo: QVariant::Vector3D??
{
QVariant tmpFloat(0); tmpFloat.convert(QVariant::Double);
VDoubleProperty* tmpX = new VDoubleProperty("X"); addChild(tmpX); tmpX->setUpdateBehaviour(true, false);
VDoubleProperty* tmpY = new VDoubleProperty("Y"); addChild(tmpY); tmpY->setUpdateBehaviour(true, false);
VDoubleProperty* tmpZ = new VDoubleProperty("Z"); addChild(tmpZ); tmpZ->setUpdateBehaviour(true, false);
setVector(Vector3D());
}
//! Get the data how it should be displayed
QVariant QVector3DProperty::data (int column, int role) const
{
if(column == DPC_Data && Qt::DisplayRole == role)
{
Vector3D tmpVect = getVector();
return QString("(%1, %2, %3)").arg(QString::number(tmpVect.X),
QString::number(tmpVect.Y),
QString::number(tmpVect.Z));
}
else
return VProperty::data(column, role);
}
//! Returns item flags
Qt::ItemFlags QVector3DProperty::flags(int column) const
{
if(column == DPC_Name || column == DPC_Data)
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
else
return Qt::NoItemFlags;
}
//! Returns the Vector3d
Vector3D QVector3DProperty::getVector() const
{
Vector3D tmpVect;
if(d_ptr->Children.count() < 3)
return tmpVect;
tmpVect.X = d_ptr->Children.at(0)->getValue().toFloat();
tmpVect.Y = d_ptr->Children.at(1)->getValue().toFloat();
tmpVect.Z = d_ptr->Children.at(2)->getValue().toFloat();
return tmpVect;
}
//! Sets the Vector3d
void QVector3DProperty::setVector(const Vector3D &vect)
{
setVector(vect.X, vect.Y, vect.Z);
}
void QVector3DProperty::setVector(float x, float y, float z)
{
if(d_ptr->Children.count() < 3)
return;
QVariant tmpX(x); tmpX.convert(QVariant::Double);
QVariant tmpY(y); tmpY.convert(QVariant::Double);
QVariant tmpZ(z); tmpZ.convert(QVariant::Double);
d_ptr->Children.at(0)->setValue(tmpX);
d_ptr->Children.at(1)->setValue(tmpY);
d_ptr->Children.at(2)->setValue(tmpZ);
}
QString QVector3DProperty::type() const
{
return "vector3d";
}
VProperty* QVector3DProperty::clone(bool include_children, VProperty* container) const
{
if(!container) {
container = new QVector3DProperty(getName());
if(!include_children) {
QList<VProperty*> tmpChildren = container->getChildren();
foreach(VProperty* tmpChild, tmpChildren) {
container->removeChild(tmpChild);
delete tmpChild;
}
}
}
return VProperty::clone(false, container); // Child
}
void QVector3DProperty::setValue(const QVariant &value)
{
QStringList tmpStrings = value.toString().split(",");
if(tmpStrings.count() == 3) {
setVector(tmpStrings[0].toDouble(), tmpStrings[1].toDouble(), tmpStrings[2].toDouble());
}
}
QVariant QVector3DProperty::getValue() const
{
Vector3D tmpVect = getVector();
return QString("%1,%2,%3").arg(QString::number(tmpVect.X), QString::number(tmpVect.Y), QString::number(tmpVect.Z));
}

View File

@ -0,0 +1,78 @@
#ifndef VVECTOR3DPROPERTY_H
#define VVECTOR3DPROPERTY_H
#include "vpropertyexplorer_global.h"
#include "vproperty.h"
namespace VPE{
struct VPROPERTYEXPLORERSHARED_EXPORT Vector3D
{
public:
Vector3D()
{
X = Y = Z = 0;
}
Vector3D(const Vector3D& other)
{
X = other.X;
Y = other.Y;
Z = other.Z;
}
~Vector3D() {}
float X, Y, Z;
};
/*
}
Q_DECLARE_METATYPE(QPE::Vector3D) // todo
namespace QPE{*/
class VPROPERTYEXPLORERSHARED_EXPORT QVector3DProperty : public VProperty
{
public:
QVector3DProperty(const QString& name);
virtual ~QVector3DProperty() {}
//! Get the data how it should be displayed
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const;
//! Returns item flags
Qt::ItemFlags flags(int column = DPC_Name) const;
//! Returns the Vector3d
virtual Vector3D getVector() const;
//! Sets the Vector3d
virtual void setVector(const Vector3D& vect);
//! Sets the Vector3d
virtual void setVector(float x, float y, float z);
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const;
//! Sets the value of the property
virtual void setValue(const QVariant& value);
//! Returns the value of the property as a QVariant
virtual QVariant getValue() const;
};
}
#endif // VVECTOR3DPROPERTY_H

View File

@ -0,0 +1,67 @@
#include "vboolproperty.h"
#include <QCheckBox>
#include <QApplication>
#include <QStyle>
#include <QSizePolicy>
#include <QObject>
#include <QSpinBox>
#include "vproperty_p.h"
using namespace VPE;
QVariant VBoolProperty::TrueText;
QVariant VBoolProperty::FalseText;
VBoolProperty::VBoolProperty(const QString& name) :
VProperty(name, QVariant::Bool)
{
d_ptr->VariantValue.setValue(false);
d_ptr->VariantValue.convert(QVariant::Bool);
// I'm not sure, how Qt handles the translations...
if(TrueText.isNull()) TrueText = QObject::tr("True");
if(TrueText.isNull()) FalseText = QObject::tr("False");
}
//! Get the data how it should be displayed
QVariant VBoolProperty::data (int column, int role) const
{
if(column == DPC_Data && (Qt::DisplayRole == role || Qt::EditRole == role))
return d_ptr->VariantValue.toBool() ? TrueText : FalseText;
if(column == DPC_Data && Qt::CheckStateRole == role)
return d_ptr->VariantValue.toBool() ? Qt::Checked : Qt::Unchecked;
else
return VProperty::data(column, role);
}
bool VBoolProperty::setData(const QVariant &data, int role)
{
if(Qt::CheckStateRole == role)
{
d_ptr->VariantValue = (Qt::Checked == static_cast<Qt::CheckState>(data.toInt())); return true;
}
return false;
}
//! Returns item flags
Qt::ItemFlags VBoolProperty::flags(int column) const
{
if(column == DPC_Data)
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
else
return VProperty::flags(column);
}
QString VBoolProperty::type() const
{
return "bool";
}
VProperty *VBoolProperty::clone(bool include_children, VProperty *container) const
{
return VProperty::clone(include_children, container ? container : new VBoolProperty(getName()));
}

View File

@ -0,0 +1,49 @@
#ifndef VBOOLPROPERTY_H
#define VBOOLPROPERTY_H
#include "vproperty.h"
namespace VPE{
//! The VBoolProperty can take two states: True or False.
class VPROPERTYEXPLORERSHARED_EXPORT VBoolProperty : public VProperty
{
public:
//! Default constructor
VBoolProperty(const QString& name);
//! Destructor
~VBoolProperty() {}
//! Get the data how it should be displayed
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const;
//! This is used by the model to set the data
//! \param data The data to set
//! \param role The role. Default is Qt::EditRole
//! \return Returns true, if the data was changed, false if not.
virtual bool setData (const QVariant& data, int role = Qt::EditRole);
//! Returns item flags
virtual Qt::ItemFlags flags(int column = DPC_Name) const;
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const;
protected:
//! The (translatable) text displayed when the property is set to true (default: "True")
static QVariant TrueText;
//! The (translatable) text displayed when the property is set to false (default: "False")
static QVariant FalseText;
};
}
#endif // VBOOLPROPERTY_H

View File

@ -0,0 +1,68 @@
#include "vcolorproperty.h"
#include "vcolorpropertyeditor.h"
#include "vproperty_p.h"
using namespace VPE;
QColorProperty::QColorProperty(const QString &name) :
VProperty(name, QVariant::Color)
{
}
//! Get the data how it should be displayed
QVariant QColorProperty::data (int column, int role) const
{
if(column == DPC_Data && (Qt::DisplayRole == role))
return VColorPropertyEditor::getColorString(d_ptr->VariantValue.value<QColor>());
else if(Qt::EditRole == role)
return QVariant();
else if(column == DPC_Data && (Qt::DecorationRole == role))
return VColorPropertyEditor::getColorPixmap(d_ptr->VariantValue.value<QColor>());
else
return VProperty::data(column, role);
}
//! Returns an editor widget, or NULL if it doesn't supply one
QWidget* QColorProperty::createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate)
{
Q_UNUSED(options);
Q_UNUSED(delegate);
VColorPropertyEditor* tmpWidget = new VColorPropertyEditor(parent);
tmpWidget->setColor(d_ptr->VariantValue.value<QColor>());
return tmpWidget;
}
//! Sets the property's data to the editor (returns false, if the standard delegate should do that)
bool QColorProperty::setEditorData(QWidget* editor)
{
VColorPropertyEditor* tmpWidget = qobject_cast<VColorPropertyEditor*>(editor);
if(tmpWidget)
tmpWidget->setColor(d_ptr->VariantValue.value<QColor>());
else
return false;
return true;
}
//! Gets the data from the widget
QVariant QColorProperty::getEditorData(QWidget* editor) const
{
VColorPropertyEditor* tmpWidget = qobject_cast<VColorPropertyEditor*>(editor);
if(tmpWidget)
return tmpWidget->getColor();
return QVariant();
}
QString QColorProperty::type() const
{
return "color";
}
VProperty *QColorProperty::clone(bool include_children, VProperty *container) const
{
return VProperty::clone(include_children, container ? container : new QColorProperty(getName()));
}

View File

@ -0,0 +1,44 @@
#ifndef VCOLORPROPERTY_H
#define VCOLORPROPERTY_H
#include "vpropertyexplorer_global.h"
#include "vproperty.h"
namespace VPE {
class VPROPERTYEXPLORERSHARED_EXPORT QColorProperty : public VProperty
{
public:
QColorProperty(const QString &name);
//! Get the data how it should be displayed
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const;
//! Returns an editor widget, or NULL if it doesn't supply one
//! \param parent The widget to which the editor will be added as a child
//! \options Render options
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots.
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate);
//! Sets the property's data to the editor (returns false, if the standard delegate should do that)
virtual bool setEditorData(QWidget* editor);
//! Gets the data from the widget
virtual QVariant getEditorData(QWidget* editor) const;
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const;
};
}
#endif // VCOLORPROPERTY_H

View File

@ -0,0 +1,115 @@
#include "vcolorpropertyeditor.h"
#include <QHBoxLayout>
#include <QFileDialog>
#include <QKeyEvent>
#include <QApplication>
#include <QColorDialog>
#include "vproperty.h"
using namespace VPE;
VColorPropertyEditor::VColorPropertyEditor(QWidget *parent) :
QWidget(parent)
{
setAutoFillBackground(true);
// Create the tool button
ToolButton = new QToolButton(this);
ToolButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
ToolButton->setText(tr("..."));
ToolButton->setFixedWidth(20);
ToolButton->installEventFilter(this);
setFocusProxy(ToolButton); // Make the ToolButton the focus proxy
setFocusPolicy(ToolButton->focusPolicy());
connect(ToolButton, SIGNAL(clicked()), this, SLOT(onToolButtonClicked()));
// Create the text label
TextLabel = new QLabel(this);
TextLabel->setText(getColorString(Color));
// Create the label for the pixmap
ColorLabel = new QLabel(this);
ColorLabel->setPixmap(getColorPixmap(Color));
// Spacer (this is needed for proper display of the label and button)
Spacer = new QSpacerItem(1, 0, QSizePolicy::Expanding, QSizePolicy::Ignored);
// The layout (a horizontal layout)
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setSpacing(3);
layout->setMargin(0);
layout->addWidget(ColorLabel);
layout->addWidget(TextLabel);
layout->addItem(Spacer);
layout->addWidget(ToolButton);
//TextLabel->hide();
//ColorLabel->hide(); // for now, we just use the standard display and only add the button
}
void VColorPropertyEditor::setColor(const QColor& color_)
{
if (Color != color_)
{
Color = color_;
ColorLabel->setPixmap(getColorPixmap(Color));
TextLabel->setText(getColorString(Color));
}
}
QPixmap VColorPropertyEditor::getColorPixmap(const QColor& color, unsigned int size)
{
QImage tmpImgage(size, size, QImage::Format_ARGB32_Premultiplied);
tmpImgage.fill(static_cast<unsigned int>(color.rgb()));
return QPixmap::fromImage(tmpImgage);
// todo: support alpha channel
}
QString VColorPropertyEditor::getColorString(const QColor& color)
{
return QApplication::translate("QtPropertyExplorer", "[%1, %2, %3] (%4)", "Colors as string")
.arg(QString::number(color.red()))
.arg(QString::number(color.green()))
.arg(QString::number(color.blue()))
.arg(QString::number(color.alpha()));
}
void VColorPropertyEditor::onToolButtonClicked()
{
bool ok = false;
QRgb oldRgba = Color.rgba();
QRgb newRgba = QColorDialog::getRgba(oldRgba, &ok, this);
if (ok && newRgba != oldRgba) {
setColor(QColor::fromRgba(newRgba));
emit dataChangedByUser(Color, this);
UserChangeEvent *event = new UserChangeEvent();
QCoreApplication::postEvent ( this, event );
}
}
bool VColorPropertyEditor::eventFilter(QObject *obj, QEvent *ev)
{
if(obj == ToolButton && (ev->type() == QEvent::KeyPress || ev->type() == QEvent::KeyPress))
{
// Ignore the event, so that eventually the delegate gets the event.
ev->ignore();
return true;
}
return QWidget::eventFilter(obj, ev);
}
VColorPropertyEditor::~VColorPropertyEditor()
{
//
}
QColor VColorPropertyEditor::getColor()
{
return Color;
}

View File

@ -0,0 +1,67 @@
#ifndef VCOLORPROPERTYEDITOR_H
#define VCOLORPROPERTYEDITOR_H
#include "vpropertyexplorer_global.h"
#include <QWidget>
#include <QToolButton>
#include <QLineEdit>
#include <QLabel>
#include <QSpacerItem>
namespace VPE{
class VPROPERTYEXPLORERSHARED_EXPORT VColorPropertyEditor : public QWidget
{
Q_OBJECT
public:
//! Constructor taking a widget as parent
VColorPropertyEditor(QWidget *parent);
//! Destructor
virtual ~VColorPropertyEditor();
//! Returns the color currently set
QColor getColor();
//! A little helper function generating an image to represent a color
//! \param color The color to fill the image with
//! \size The size of the generated pixmap
//! \return Returns a QPixmap
static QPixmap getColorPixmap(const QColor& color, unsigned int size = 16);
//! A helper function to convert a color into a string.
//! \param color The color to fill the image with
//! \return The color as string, usually in the format [RRR, GGG, BBB] (AAA)
static QString getColorString(const QColor& color);
//! Needed for proper event handling
bool eventFilter(QObject *obj, QEvent *ev);
signals:
//! This is emitted, when the user changes the color
void dataChangedByUser(const QColor &getColor, VColorPropertyEditor* editor);
void dataChanged();
public slots:
//! Sets the color of the widget
void setColor(const QColor &color_);
private slots:
void onToolButtonClicked();
private:
QColor Color;
QToolButton* ToolButton;
QLineEdit* Lineedit;
QLabel* TextLabel;
QLabel* ColorLabel;
QSpacerItem* Spacer;
};
}
#endif // QFILEPROPERTYEDITOR_H

View File

@ -0,0 +1,70 @@
#include "vemptyproperty.h"
using namespace VPE;
VEmptyProperty::VEmptyProperty(const QString& name)
: VProperty(name, QVariant::Invalid)
{
}
VEmptyProperty::VEmptyProperty(VPropertyPrivate *d)
: VProperty(d)
{
}
VEmptyProperty::~VEmptyProperty()
{
//
}
//! Get the data how it should be displayed
QVariant VEmptyProperty::data (int column, int role) const
{
if(column == DPC_Data && (Qt::DisplayRole == role || Qt::EditRole == role))
return QVariant();
else if(role == Qt::BackgroundRole)
return QBrush(QColor(217,217,217));
else if(role == Qt::FontRole)
{ QFont tmpFont; tmpFont.setBold(true); return tmpFont; }
else
return VProperty::data(column, role);
}
//! Returns an editor widget, or NULL if it doesn't supply one
QWidget* VEmptyProperty::createEditor(QWidget * parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate)
{
Q_UNUSED(options);
Q_UNUSED(parent);
Q_UNUSED(delegate);
return NULL;
}
//! Gets the data from the widget
QVariant VEmptyProperty::getEditorData(QWidget* editor) const
{
Q_UNUSED(editor);
return QVariant();
}
//! Returns item flags
Qt::ItemFlags VEmptyProperty::flags(int column) const
{
Q_UNUSED(column);
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QString VEmptyProperty::type() const
{
return "empty";
}
VProperty* VEmptyProperty::clone(bool include_children, VProperty* container) const
{
return VProperty::clone(include_children, container ? container : new VEmptyProperty(getName()));
}

View File

@ -0,0 +1,48 @@
#ifndef VEMPTYPROPERTY_H
#define VEMPTYPROPERTY_H
#include "vproperty.h"
namespace VPE {
class VPROPERTYEXPLORERSHARED_EXPORT VEmptyProperty : public VProperty
{
public:
//! Standard constructor, takes a name and a parent property as argument
explicit VEmptyProperty(const QString& name);
//! Destructor
virtual ~VEmptyProperty();
//! Get the data how it should be displayed
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const;
//! Returns an editor widget, or NULL if it doesn't supply one
//! \param parent The widget to which the editor will be added as a child
//! \options Render options
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots.
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate);
//! Gets the data from the widget
virtual QVariant getEditorData(QWidget* editor) const;
//! Returns item flags
virtual Qt::ItemFlags flags(int column = DPC_Name) const;
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const;
protected:
//! Protected constructor
VEmptyProperty(VPropertyPrivate* d);
};
}
#endif // VEMPTYPROPERTY_H

View File

@ -0,0 +1,109 @@
#include "venumproperty.h"
#include "vproperty_p.h"
#include <QComboBox>
using namespace VPE;
VEnumProperty::VEnumProperty(const QString& name)
: VProperty(name, QVariant::Int)
{
d_ptr->VariantValue = 0;
d_ptr->VariantValue.convert(QVariant::Int);
}
//! Get the data how it should be displayed
QVariant VEnumProperty::data (int column, int role) const
{
if(EnumerationLiterals.empty())
return QVariant();
int tmpIndex = d_ptr->VariantValue.toInt();
if(tmpIndex < 0 || tmpIndex >= EnumerationLiterals.count())
tmpIndex = 0;
if(column == DPC_Data && Qt::DisplayRole == role)
return EnumerationLiterals.at(tmpIndex);
else if(column == DPC_Data && Qt::EditRole == role)
return tmpIndex;
else
return VProperty::data(column, role);
}
//! Returns an editor widget, or NULL if it doesn't supply one
QWidget* VEnumProperty::createEditor(QWidget * parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate)
{
Q_UNUSED(options);
Q_UNUSED(delegate);
QComboBox* tmpEditor = new QComboBox(parent);
tmpEditor->clear();
tmpEditor->addItems(EnumerationLiterals);
tmpEditor->setCurrentIndex(d_ptr->VariantValue.toInt());
return tmpEditor;
}
//! Gets the data from the widget
QVariant VEnumProperty::getEditorData(QWidget* editor) const
{
QComboBox* tmpEditor = qobject_cast<QComboBox*>(editor);
if(tmpEditor)
return tmpEditor->currentIndex();
return QVariant(0);
}
//! Sets the enumeration literals
void VEnumProperty::setLiterals(const QStringList& literals)
{
EnumerationLiterals = literals;
}
//! Get the settings. This function has to be implemented in a subclass in order to have an effect
QStringList VEnumProperty::getLiterals() const
{
return EnumerationLiterals;
}
//! Sets the value of the property
void VEnumProperty::setValue(const QVariant& value)
{
int tmpIndex = value.toInt();
if(tmpIndex < 0 || tmpIndex >= EnumerationLiterals.count())
tmpIndex = 0;
d_ptr->VariantValue.setValue(tmpIndex);
}
QString VEnumProperty::type() const
{
return "enum";
}
VProperty* VEnumProperty::clone(bool include_children, VProperty* container) const
{
return VProperty::clone(include_children, container ? container : new VEnumProperty(getName()));
}
void VEnumProperty::setSetting(const QString& key, const QVariant& value)
{
if(key == "literals")
setLiterals(value.toString().split(";;"));
}
QVariant VEnumProperty::getSetting(const QString& key) const
{
if(key == "literals")
return getLiterals().join(";;");
else
return VProperty::getSetting(key);
}
QStringList VEnumProperty::getSettingKeys() const
{
return QStringList("literals");
}

View File

@ -0,0 +1,68 @@
#ifndef VENUMPROPERTY_H
#define VENUMPROPERTY_H
#include "vproperty.h"
#include <QStringList>
namespace VPE{
class VPROPERTYEXPLORERSHARED_EXPORT VEnumProperty : public VProperty
{
public:
//! Constructor
VEnumProperty(const QString& name);
//! Destructor
~VEnumProperty() {}
//! Get the data how it should be displayed
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const;
//! Returns an editor widget, or NULL if it doesn't supply one
//! \param parent The widget to which the editor will be added as a child
//! \options Render options
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots.
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate);
//! Gets the data from the widget
virtual QVariant getEditorData(QWidget* editor) const;
//! Sets the enumeration literals
virtual void setLiterals(const QStringList &literals);
//! Get the settings. This function has to be implemented in a subclass in order to have an effect
virtual QStringList getLiterals() const;
//! Sets the value of the property
virtual void setValue(const QVariant& value);
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = nullptr) const;
//! Sets the settings. Available settings:
//!
//! key: "literals" - value: "item1;;item2;;item3"
virtual void setSetting(const QString& key, const QVariant& value);
//! Get the settings. This function has to be implemented in a subclass in order to have an effect
virtual QVariant getSetting(const QString& key) const;
//! Returns the list of keys of the property's settings
virtual QStringList getSettingKeys() const;
protected:
//! The list of possible options to choose frome
QStringList EnumerationLiterals;
// No use of d-pointer in this case, because it is unlikely this will change. If it does, we can still add other members by reimplementing the VPropertyPrivate class without touching this header file.
};
}
#endif // VENUMPROPERTY_H

View File

@ -0,0 +1,136 @@
#include "vfileproperty.h"
#include <QFileInfo>
#include <QAbstractItemDelegate>
#include "vfilepropertyeditor.h"
#include "vfileproperty_p.h"
using namespace VPE;
VFileProperty::VFileProperty(const QString& name)
: VProperty(new VFilePropertyPrivate(name, QVariant::String))
{
}
VFileProperty::~VFileProperty()
{
//
}
void VFileProperty::setFileFilters(const QString& filefilters)
{
static_cast<VFilePropertyPrivate*>(d_ptr)->FileFilters = filefilters;
}
QString VFileProperty::getFileFilters() const
{
return static_cast<VFilePropertyPrivate*>(d_ptr)->FileFilters;
}
void VFileProperty::setFile(const QString& file)
{
d_ptr->VariantValue.setValue(file);
}
QString VFileProperty::getFile() const
{
return d_ptr->VariantValue.toString();
}
QVariant VFileProperty::data (int column, int role) const
{
if(column == DPC_Data && (Qt::DisplayRole == role || Qt::EditRole == role))
{
QFileInfo tmpFile(d_ptr->VariantValue.toString());
return tmpFile.fileName();
}
else
return VProperty::data(column, role);
}
QWidget* VFileProperty::createEditor(QWidget * parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate)
{
Q_UNUSED(options);
VFileEditWidget* tmpWidget = new VFileEditWidget(parent);
if(delegate)
VFileEditWidget::connect(tmpWidget, SIGNAL(commitData(QWidget*)), delegate, SIGNAL(commitData(QWidget*)));
tmpWidget->setFilter(static_cast<VFilePropertyPrivate*>(d_ptr)->FileFilters); // todo: parse this string
tmpWidget->setFile(d_ptr->VariantValue.toString());
tmpWidget->setDirectory(static_cast<VFilePropertyPrivate*>(d_ptr)->Directory);
return tmpWidget;
}
bool VFileProperty::setEditorData(QWidget* editor)
{
VFileEditWidget* tmpWidget = qobject_cast<VFileEditWidget*>(editor);
if(tmpWidget)
tmpWidget->setFile(d_ptr->VariantValue.toString());
else
return false;
return true;
}
QVariant VFileProperty::getEditorData(QWidget* editor) const
{
VFileEditWidget* tmpWidget = qobject_cast<VFileEditWidget*>(editor);
if(tmpWidget)
return tmpWidget->getFile();
return QVariant();
}
void VFileProperty::setSetting(const QString& key, const QVariant& value)
{
if(key == "FileFilters")
setFileFilters(value.toString());
else if(key == "Directory")
setDirectory(value.toBool());
}
QVariant VFileProperty::getSetting(const QString& key) const
{
if(key == "FileFilters")
return getFileFilters();
else if(key == "Directory")
return isDirectory();
else
return VProperty::getSetting(key);
}
QStringList VFileProperty::getSettingKeys() const
{
return QStringList("FileFilters") << "Directory";
}
QString VFileProperty::type() const
{
return "file";
}
VProperty* VFileProperty::clone(bool include_children, VProperty* container) const
{
return VProperty::clone(include_children, container ? container : new VFileProperty(getName()));
}
bool VFileProperty::isDirectory() const
{
return static_cast<VFilePropertyPrivate*>(d_ptr)->Directory;
}
void VFileProperty::setDirectory(bool is_directory)
{
static_cast<VFilePropertyPrivate*>(d_ptr)->Directory = is_directory;
}

View File

@ -0,0 +1,76 @@
#ifndef VFILEPROPERTY_H
#define VFILEPROPERTY_H
#include "vpropertyexplorer_global.h"
#include "vproperty.h"
#include <QPointer>
namespace VPE {
class VPROPERTYEXPLORERSHARED_EXPORT VFileProperty : public VProperty
{
public:
VFileProperty(const QString &name);
//! The destructor
~VFileProperty();
//! Sets the file filters. The file filters have to be like the ones passed a QFileOpenDialog.
virtual void setFileFilters(const QString& filefilters);
//! Returns the current file filters as a string
virtual QString getFileFilters() const;
//! Set file
virtual void setFile(const QString& file);
//! Get file
virtual QString getFile() const;
//! Get the data how it should be displayed
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const;
//! Returns an editor widget, or NULL if it doesn't supply one
//! \param parent The widget to which the editor will be added as a child
//! \options Render options
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots.
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate);
//! Sets the property's data to the editor (returns false, if the standard delegate should do that)
virtual bool setEditorData(QWidget* editor);
//! Gets the data from the widget
virtual QVariant getEditorData(QWidget* editor) const;
//! Sets the settings. Available settings:
//!
//! key: "FileFilters" - value: File filters in the same format the QFileDialog expects it
virtual void setSetting(const QString& key, const QVariant& value);
//! Get the settings. This function has to be implemented in a subclass in order to have an effect
virtual QVariant getSetting(const QString& key) const;
//! Returns the list of keys of the property's settings
virtual QStringList getSettingKeys() const;
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = nullptr) const;
//! Returns whether this is a file (false) or a directory (true)
virtual bool isDirectory() const;
//! Sets whether this is a file (false) or a directory (true)
virtual void setDirectory(bool is_directory);
};
}
#endif // VFILEPROPERTY_H

View File

@ -0,0 +1,204 @@
#include "vfilepropertyeditor.h"
#include "vfileproperty.h"
#include <QHBoxLayout>
#include <QFileDialog>
#include <QKeyEvent>
#include <QUrl>
using namespace VPE;
VFileEditWidget::VFileEditWidget(QWidget *parent, bool is_directory)
: QWidget(parent), Directory(is_directory)
{
// Create the tool button,ToolButton = new QToolButton(this);
ToolButton = new QToolButton(this);
ToolButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
ToolButton->setText(tr("..."));
ToolButton->setFixedWidth(20);
ToolButton->installEventFilter(this);
setFocusProxy(ToolButton); // Make the ToolButton the focus proxy
setFocusPolicy(ToolButton->focusPolicy());
connect(ToolButton, SIGNAL(clicked()), this, SLOT(onToolButtonClicked()));
// Create the line edit widget
FileLineEdit = new QLineEdit(this);
FileLineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
FileLineEdit->setText(CurrentFilePath);
FileLineEdit->installEventFilter(this);
// The layout (a horizontal layout)
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setSpacing(0);
layout->setMargin(0);
layout->addWidget(FileLineEdit);
layout->addWidget(ToolButton);
// Accept drops
setAcceptDrops(true);
}
VFileEditWidget::~VFileEditWidget()
{
// nothing needs to be done here
}
void VFileEditWidget::setFile(const QString &value, bool emit_signal)
{
if (CurrentFilePath != value)
{
CurrentFilePath = value;
FileLineEdit->setText(CurrentFilePath);
if(emit_signal)
{
emit dataChangedByUser(CurrentFilePath, this);
emit commitData(this);
}
}
}
void VFileEditWidget::setFilter(const QString &dialog_filter, const QStringList& filter_list)
{
FileDialogFilter = dialog_filter;
FilterList = filter_list;
}
void VFileEditWidget::setDirectory(bool dir)
{
Directory = dir;
}
QString VFileEditWidget::getFile()
{
return CurrentFilePath;
}
void VFileEditWidget::onToolButtonClicked()
{
QString filepath = (Directory ? QFileDialog::getExistingDirectory(0, tr("Directory"), CurrentFilePath) : QFileDialog::getOpenFileName(0, tr("Open File"), CurrentFilePath, FileDialogFilter));
if (!filepath.isNull())
setFile(filepath, true);
}
bool VFileEditWidget::eventFilter(QObject *obj, QEvent *ev)
{
if(ev->type() == QEvent::DragEnter || ev->type() == QEvent::Drop)
{
ev->ignore();
if(ev->type() == QEvent::DragEnter)
dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
else if(ev->type() == QEvent::Drop)
dropEvent(static_cast<QDropEvent*>(ev));
if(ev->isAccepted())
return true;
else
return QWidget::eventFilter(obj, ev);
}
else if(obj == ToolButton && (ev->type() == QEvent::KeyPress || ev->type() == QEvent::KeyPress))
{
// Ignore the event, so that eventually the delegate gets the event.
ev->ignore();
return true;
}
else if(obj == FileLineEdit)
{
if(ev->type() == QEvent::FocusOut)
{
setFile(FileLineEdit->text(), true);
// We don't return true here because we still want the line edit to catch the event as well
}
}
// forward the signal to the parent class
return QWidget::eventFilter(obj, ev);
}
bool VFileEditWidget::isDirectory()
{
return Directory;
}
void VFileEditWidget::dragEnterEvent(QDragEnterEvent* event)
{
QString tmpFileName;
if(checkMimeData(event->mimeData(), tmpFileName))
{
event->accept();
event->acceptProposedAction();
}
}
void VFileEditWidget::dragMoveEvent(QDragMoveEvent* event)
{
event->acceptProposedAction();
}
void VFileEditWidget::dragLeaveEvent(QDragLeaveEvent* event)
{
event->accept();
}
void VFileEditWidget::dropEvent(QDropEvent* event)
{
QString tmpFileName;
if(checkMimeData(event->mimeData(), tmpFileName))
{
setFile(tmpFileName);
emit dataChangedByUser(getFile(), this);
emit commitData(this);
event->accept();
event->acceptProposedAction();
}
}
bool VFileEditWidget::checkMimeData(const QMimeData* data, QString& file) const
{
if (data->hasUrls())
{
QList<QUrl> tmpUrlList = data->urls();
QFileInfo tmpFileInfo;
foreach(QUrl tmpUrl, tmpUrlList)
if(QFile::exists(tmpUrl.toLocalFile()))
{ tmpFileInfo = QFileInfo(tmpUrl.toLocalFile()); break; }
if(checkFileFilter(tmpFileInfo.fileName()))
{
file = tmpFileInfo.absoluteFilePath();
return true;
}
}
return false;
}
bool VFileEditWidget::checkFileFilter(const QString& file) const
{
if(FilterList.isEmpty())
return true;
QFileInfo tmpFileInfo(file);
if((Directory && !tmpFileInfo.isDir()) || (!Directory && !tmpFileInfo.isFile()))
return false;
foreach(QString tmpFilter, FilterList)
{
QRegExp tmpRegExpFilter(tmpFilter, Qt::CaseInsensitive, QRegExp::Wildcard);
if(tmpRegExpFilter.exactMatch(file))
return true;
}
return false;
}

View File

@ -0,0 +1,89 @@
#ifndef VFILEPROPERTYEDITOR_H
#define VFILEPROPERTYEDITOR_H
#include "vpropertyexplorer_global.h"
#include <QWidget>
#include <QToolButton>
#include <QLineEdit>
#include <QMimeData>
namespace VPE{
class VPROPERTYEXPLORERSHARED_EXPORT VFileEditWidget : public QWidget
{
Q_OBJECT
public:
VFileEditWidget(QWidget* parent, bool is_directory = false);
virtual ~VFileEditWidget();
//! This function returns the file currently set to this editor
QString getFile();
//! Needed for proper event handling
bool eventFilter(QObject* obj, QEvent* ev);
//! Returns the directory/file setting
//! \return True, if a directory dialog is being shown, false if a file dialog
bool isDirectory();
signals:
//! This signal is emitted when the user changed the curret file.
//! Actions triggering this signal are either using the file dialog
//! to select a new file or changing the file path in the line edit.
void dataChangedByUser(const QString &getFile, VFileEditWidget* editor);
//! This signal is emitted whenever dataChangedByUser() gets emmitted
//! and is connected to the delegate's commitData() signal
void commitData(QWidget* editor);
public slots:
//! Sets the current file, does not check if it is valid
//! \param file The new filepath the widget should show
//! \emit_signal If true, this will emit the dataChangedByUser()-signal (if file differs from the current file)
void setFile(const QString &getFile, bool emit_signal = false);
//! Sets a filter for the file field
//! \param dialog_filter The filter used for the File Dialog
//! \param filter_list The list of file endings. The filters are being checked using regular expressions
void setFilter(const QString& dialog_filter = QString(), const QStringList& filter_list = QStringList());
//! Sets whether the property stores a directory or a file
void setDirectory(bool dir);
private slots:
//! This slot gets activated, when the "..." button gets clicked
void onToolButtonClicked();
protected:
void dragEnterEvent(QDragEnterEvent* event);
void dragMoveEvent(QDragMoveEvent* event);
void dragLeaveEvent(QDragLeaveEvent* event);
void dropEvent(QDropEvent* event);
//! This function checks the mime data, if it is compatible with the filters
virtual bool checkMimeData(const QMimeData* data, QString& getFile) const;
//! This checks, if a file is compatible with the filters
virtual bool checkFileFilter(const QString& getFile) const;
QString CurrentFilePath;
QToolButton* ToolButton;
QLineEdit* FileLineEdit;
QString FileDialogFilter;
QStringList FilterList;
//! Specifies whether it is being looked for a directory (true) or a file (false, default)
bool Directory;
};
}
#endif // VFILEPROPERTYEDITOR_H

View File

@ -0,0 +1,183 @@
#include "vnumberproperty.h"
#include <QDoubleSpinBox>
#include <QSpinBox>
#include <QSizePolicy>
#include "vproperty_p.h"
using namespace VPE;
const int VIntegerProperty::StandardMin = -1000000;
const int VIntegerProperty::StandardMax = 1000000;
VIntegerProperty::VIntegerProperty(const QString& name, const QMap<QString, QVariant>& settings)
: VProperty(name, QVariant::Int), Min(StandardMin), Max(StandardMax)
{
VProperty::setSettings(settings);
d_ptr->VariantValue.setValue(0);
d_ptr->VariantValue.convert(QVariant::Int);
}
VIntegerProperty::VIntegerProperty(const QString &name)
: VProperty(name), Min(StandardMin), Max(StandardMax)
{
d_ptr->VariantValue.setValue(0);
d_ptr->VariantValue.convert(QVariant::Int);
}
//! Returns an editor widget, or NULL if it doesn't supply one
QWidget* VIntegerProperty::createEditor(QWidget * parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate)
{
Q_UNUSED(options);
Q_UNUSED(delegate);
QSpinBox* tmpEditor = new QSpinBox(parent);
tmpEditor->setMinimum(Min);
tmpEditor->setMaximum(Max);
tmpEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
tmpEditor->setValue(d_ptr->VariantValue.toInt());
return tmpEditor;
}
//! Gets the data from the widget
QVariant VIntegerProperty::getEditorData(QWidget* editor) const
{
QSpinBox* tmpEditor = qobject_cast<QSpinBox*>(editor);
if(tmpEditor)
return tmpEditor->value();
return QVariant(0);
}
void VIntegerProperty::setSettings(int minimum, int maxiumum)
{
Min = minimum;
Max = maxiumum;
}
void VIntegerProperty::setSetting(const QString& key, const QVariant& value)
{
if(key == "Min")
setSettings(value.toInt(), Max);
else if(key == "Max")
setSettings(Min, value.toInt());
}
QVariant VIntegerProperty::getSetting(const QString& key) const
{
if(key == "Min")
return Min;
if(key == "Max")
return Max;
else
return VProperty::getSetting(key);
}
QStringList VIntegerProperty::getSettingKeys() const
{
return (QStringList("Min") << "Max");
}
QString VIntegerProperty::type() const
{
return "integer";
}
VProperty* VIntegerProperty::clone(bool include_children, VProperty* container) const
{
return VProperty::clone(include_children, container ? container : new VIntegerProperty(getName()));
}
const double VDoubleProperty::StandardPrecision = 5;
VDoubleProperty::VDoubleProperty(const QString& name, const QMap<QString, QVariant>& settings)
: VIntegerProperty(name), Precision(StandardPrecision)
{
VProperty::setSettings(settings);
d_ptr->VariantValue.setValue(0);
d_ptr->VariantValue.convert(QVariant::Double);
d_ptr->PropertyVariantType = QVariant::Double;
}
VDoubleProperty::VDoubleProperty(const QString &name)
: VIntegerProperty(name), Precision(StandardPrecision)
{
d_ptr->VariantValue.setValue(0);
d_ptr->VariantValue.convert(QVariant::Double);
d_ptr->PropertyVariantType = QVariant::Double;
}
//! Returns an editor widget, or NULL if it doesn't supply one
QWidget* VDoubleProperty::createEditor(QWidget * parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate)
{
Q_UNUSED(options);
Q_UNUSED(delegate);
QDoubleSpinBox* tmpEditor = new QDoubleSpinBox(parent);
tmpEditor->setMinimum(Min);
tmpEditor->setMaximum(Max);
tmpEditor->setDecimals(Precision);
tmpEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
tmpEditor->setValue(d_ptr->VariantValue.toDouble());
return tmpEditor;
}
//! Gets the data from the widget
QVariant VDoubleProperty::getEditorData(QWidget* editor) const
{
QDoubleSpinBox* tmpEditor = qobject_cast<QDoubleSpinBox*>(editor);
if(tmpEditor)
return tmpEditor->value();
return QVariant(0);
}
void VDoubleProperty::setSettings(double minimum, double maxiumum, int precision)
{
VIntegerProperty::setSettings(minimum, maxiumum);
Precision = precision;
}
void VDoubleProperty::setSetting(const QString& key, const QVariant& value)
{
if(key == "Min")
setSettings(value.toDouble(), Max, Precision);
else if(key == "Max")
setSettings(Min, value.toDouble(), Precision);
else if(key == "Precision")
setSettings(Min, Max, value.toDouble());
}
QVariant VDoubleProperty::getSetting(const QString& key) const
{
if(key == "Min")
return Min;
if(key == "Max")
return Max;
if(key == "Precision")
return Precision;
else
return VProperty::getSetting(key);
}
QStringList VDoubleProperty::getSettingKeys() const
{
return (QStringList("Min") << "Max" << "Precision");
}
QString VDoubleProperty::type() const
{
return "double";
}
VProperty* VDoubleProperty::clone(bool include_children, VProperty* container) const
{
return VIntegerProperty::clone(include_children, container ? container : new VDoubleProperty(getName()));
}

View File

@ -0,0 +1,115 @@
#ifndef VNUMBERPROPERTY_H
#define VNUMBERPROPERTY_H
#include "vpropertyexplorer_global.h"
#include "vproperty.h"
namespace VPE {
//! Class for holding an integer property
class VPROPERTYEXPLORERSHARED_EXPORT VIntegerProperty : public VProperty
{
public:
VIntegerProperty(const QString& name, const QMap<QString, QVariant>& settings);
VIntegerProperty(const QString& name);
//! Returns an editor widget, or NULL if it doesn't supply one
//! \param parent The widget to which the editor will be added as a child
//! \options Render options
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots.
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate);
//! Gets the data from the widget
virtual QVariant getEditorData(QWidget* editor) const;
//! Sets the settings of a basic integer property
//! \param minimum The minimum value
//! \param maxiumum The maximum value
virtual void setSettings(int minimum, int maxiumum);
//! Sets the settings. Available settings:
//!
//! key: "Min" - value: Minimum number as integer
//! key: "Max" - value: Maximum number as integer
virtual void setSetting(const QString& key, const QVariant& value);
//! Get the settings. This function has to be implemented in a subclass in order to have an effect
virtual QVariant getSetting(const QString& key) const;
//! Returns the list of keys of the property's settings
virtual QStringList getSettingKeys() const;
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const;
protected:
int Min, Max;
static const int StandardMin;// = -1000000;
static const int StandardMax;// = 1000000;
};
//! Class for holding a double property
class VPROPERTYEXPLORERSHARED_EXPORT VDoubleProperty : public VIntegerProperty
{
public:
VDoubleProperty(const QString& name, const QMap<QString, QVariant>& settings);
VDoubleProperty(const QString& name);
//! Returns an editor widget, or NULL if it doesn't supply one
//! \param parent The widget to which the editor will be added as a child
//! \options Render options
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots.
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate);
//! Gets the data from the widget
virtual QVariant getEditorData(QWidget* editor) const;
//! Sets the settings of a double property
//! \param minimum The minimum value
//! \param maxiumum The maximum value
//! \param precision The number of decimal places
virtual void setSettings(double minimum, double maxiumum, int precision);
//! Sets the settings. Available settings:
//!
//! key: "Min" - value: Minimum number as integer
//! key: "Max" - value: Maximum number as integer
virtual void setSetting(const QString& key, const QVariant& value);
//! Get the settings. This function has to be implemented in a subclass in order to have an effect
virtual QVariant getSetting(const QString& key) const;
//! Returns the list of keys of the property's settings
virtual QStringList getSettingKeys() const;
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const;
protected:
//! Number of decimals after the decimal point
int Precision;
const static double StandardPrecision;// = 5;
};
}
#endif // VNUMBERPROPERTY_H

View File

@ -0,0 +1,84 @@
#include "vshortcutproperty.h"
#include <QFileInfo>
#include <QAbstractItemDelegate>
#include "vshortcutpropertyeditor.h"
#include "vproperty_p.h"
using namespace VPE;
VShortcutProperty::VShortcutProperty(const QString& name)
: VProperty(name, QVariant::String)
{
}
VShortcutProperty::~VShortcutProperty()
{
//
}
QVariant VShortcutProperty::data (int column, int role) const
{
if(column == DPC_Data && (Qt::DisplayRole == role || Qt::EditRole == role))
{
return d_ptr->VariantValue;
}
else
return VProperty::data(column, role);
}
QWidget* VShortcutProperty::createEditor(QWidget * parent, const QStyleOptionViewItem& options,
const QAbstractItemDelegate* delegate)
{
Q_UNUSED(options);
VShortcutEditWidget* tmpWidget = new VShortcutEditWidget(parent);
if(delegate)
VShortcutEditWidget::connect(tmpWidget, SIGNAL(commitData(QWidget*)), delegate, SIGNAL(commitData(QWidget*)));
return tmpWidget;
return nullptr;
}
bool VShortcutProperty::setEditorData(QWidget* editor)
{
VShortcutEditWidget* tmpWidget = qobject_cast<VShortcutEditWidget*>(editor);
if(tmpWidget)
tmpWidget->setShortcut(d_ptr->VariantValue.toString(), false);
else
return false;
return true;
}
QVariant VShortcutProperty::getEditorData(QWidget* editor) const
{
VShortcutEditWidget* tmpWidget = qobject_cast<VShortcutEditWidget*>(editor);
if(tmpWidget)
return tmpWidget->getShortcutAsString();
return QVariant();
}
QString VShortcutProperty::type() const
{
return "shortcut";
}
VProperty* VShortcutProperty::clone(bool include_children, VProperty* container) const
{
return VProperty::clone(include_children, container ? container : new VShortcutProperty(getName()));
}
void VShortcutProperty::setValue(const QVariant &value)
{
VProperty::setValue(QKeySequence::fromString(value.toString()).toString());
}

View File

@ -0,0 +1,49 @@
#ifndef VSHORTCUTROPERTY_H
#define VSHORTCUTROPERTY_H
#include "vpropertyexplorer_global.h"
#include "vproperty.h"
namespace VPE {
//! This property can be used to handle key shortcuts
class VPROPERTYEXPLORERSHARED_EXPORT VShortcutProperty : public VProperty
{
public:
VShortcutProperty(const QString &name);
//! The destructor
~VShortcutProperty();
//! Get the data how it should be displayed
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const;
//! Returns an editor widget, or NULL if it doesn't supply one
//! \param parent The widget to which the editor will be added as a child
//! \options Render options
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots.
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options,
const QAbstractItemDelegate* delegate);
//! Sets the property's data to the editor (returns false, if the standard delegate should do that)
virtual bool setEditorData(QWidget* editor);
//! Gets the data from the widget
virtual QVariant getEditorData(QWidget* editor) const;
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = NULL) const;
//! Sets the value of the property
virtual void setValue(const QVariant& value);
};
}
#endif // VFILEPROPERTY_H

View File

@ -0,0 +1,86 @@
#include "vshortcutpropertyeditor.h"
#include <QHBoxLayout>
#include <QKeyEvent>
using namespace VPE;
VShortcutEditWidget::VShortcutEditWidget(QWidget *parent)
: QWidget(parent)
{
// Create the line edit widget
LineEdit = new QLineEdit(this);
LineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
LineEdit->clear();
LineEdit->installEventFilter(this);
setFocusProxy(LineEdit);
connect(LineEdit, SIGNAL(textEdited(QString)), this, SLOT(onTextEdited(QString)));
// The layout (a horizontal layout)
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setSpacing(0);
layout->setMargin(0);
layout->addWidget(LineEdit);
}
VShortcutEditWidget::~VShortcutEditWidget()
{
// nothing needs to be done here
}
bool VShortcutEditWidget::eventFilter(QObject *obj, QEvent *event)
{
if (obj == LineEdit) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
int keys = keyEvent->key();
if(keys != Qt::Key_Shift &&
keys != Qt::Key_Control &&
keys != Qt::Key_Meta &&
keys != Qt::Key_AltGr &&
keys != Qt::Key_Alt)
{
keys += keyEvent->modifiers();
setShortcut(QKeySequence(keys), true);
return true;
}
}
}
return QWidget::eventFilter(obj, event);
}
QString VShortcutEditWidget::getShortcutAsString()
{
return CurrentKeySequence.toString();
}
QKeySequence VShortcutEditWidget::getShortcut()
{
return CurrentKeySequence;
}
void VShortcutEditWidget::setShortcut(const QString &shortcut, bool emit_signal)
{
setShortcut(QKeySequence::fromString(shortcut), emit_signal);
}
void VShortcutEditWidget::setShortcut(const QKeySequence &shortcut, bool emit_signal)
{
if(shortcut != CurrentKeySequence) {
CurrentKeySequence = shortcut;
LineEdit->setText(CurrentKeySequence.toString());
if(emit_signal)
emit dataChangedByUser(CurrentKeySequence, this);
}
}
void VShortcutEditWidget::onTextEdited(const QString &text)
{
setShortcut(text, true);
}

View File

@ -0,0 +1,64 @@
#ifndef VSHORTCUTPROPERTYEDITOR_H
#define VSHORTCUTPROPERTYEDITOR_H
#include "vpropertyexplorer_global.h"
#include <QWidget>
#include <QToolButton>
#include <QLineEdit>
#include <QMimeData>
namespace VPE{
class VPROPERTYEXPLORERSHARED_EXPORT VShortcutEditWidget : public QWidget
{
Q_OBJECT
public:
VShortcutEditWidget(QWidget* parent);
virtual ~VShortcutEditWidget();
//! Needed for proper event handling
bool eventFilter(QObject* obj, QEvent* evenvt);
//! Returns the currently set shortcut
QString getShortcutAsString();
//! Returns the currently set shortcut
QKeySequence getShortcut();
signals:
//! This signal is emitted when the user changed the current shortcut
void dataChangedByUser(const QKeySequence& sequence, VShortcutEditWidget* editor);
//! This signal is emitted whenever dataChangedByUser() gets emmitted
//! and is connected to the delegate's commitData() signal
void commitData(QWidget* editor);
public slots:
//! Sets the shortcut
//! \param shortcut The new shortcut
//! \emit_signal If true, this will emit the dataChangedByUser()-signal
void setShortcut(const QString &shortcut, bool emit_signal);
//! Sets the shortcut
//! \param shortcut The new shortcut
//! \emit_signal If true, this will emit the dataChangedByUser()-signal
void setShortcut(const QKeySequence &shortcut, bool emit_signal);
private slots:
//! This slot is called when the user edits the line edit (e.g. by removing or pasting text using the mouse)
void onTextEdited(const QString& text);
protected:
//! The current key sequence
QKeySequence CurrentKeySequence;
//! The line to display and edit the key sequence
QLineEdit* LineEdit;
};
}
#endif // VFILEPROPERTYEDITOR_H

View File

@ -0,0 +1,46 @@
#include "vwidgetproperty.h"
#include "vwidgetproperty_p.h"
using namespace VPE;
VWidgetProperty::VWidgetProperty(const QString& name, QWidget* widget)
: VEmptyProperty(new VWidgetPropertyPrivate(name, QVariant::Invalid, widget))
{
}
VWidgetProperty::~VWidgetProperty()
{
//
}
QWidget *VWidgetProperty::getWidget() const
{
return static_cast<VWidgetPropertyPrivate*>(d_ptr)->Widget.data();
}
void VWidgetProperty::setWidget(QWidget* widget)
{
VWidgetPropertyPrivate* tmpDPtr = static_cast<VWidgetPropertyPrivate*>(d_ptr);
QWidget* tmpOldWidget = tmpDPtr->Widget.data();
if(tmpOldWidget)
tmpOldWidget->deleteLater();
tmpDPtr->Widget = widget;
}
QString VWidgetProperty::type() const
{
return "widget";
}
VProperty* VWidgetProperty::clone(bool include_children, VProperty* container) const
{
// todo: This is a tricky one to clone... don't know what would be the best way to do so... Maybe serialize the widget somehow?
return VProperty::clone(include_children, container ? container : new VWidgetProperty(getName()));
}

View File

@ -0,0 +1,42 @@
#ifndef VWIDGETROPERTY_H
#define VWIDGETROPERTY_H
#include "vpropertyexplorer_global.h"
#include "vemptyproperty.h"
#include <QPointer>
namespace VPE {
// todo: this way, this class doesn't really make sense. What we have to do is pass a widget factory instead of the actual widget!
//! This property holds a QWidget and displays it, if the view supports that. If not, it will behave like an empty property
class VPROPERTYEXPLORERSHARED_EXPORT VWidgetProperty : public VEmptyProperty
{
public:
//! Constructor
VWidgetProperty(const QString &name, QWidget* widget = nullptr);
//! The destructor
~VWidgetProperty();
//! Returns the widget held by this property
QWidget* getWidget() const;
//! Sets the widget for this property. If there is already an old one, it will be deleted.
void setWidget(QWidget* widget);
//! Returns a string containing the type of the property
virtual QString type() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = nullptr) const;
};
}
#endif // VWIDGETROPERTY_H

View File

@ -0,0 +1,26 @@
#ifndef VABSTRACTPROPERTYFACTORY_H
#define VABSTRACTPROPERTYFACTORY_H
#include "vpropertyexplorer_global.h"
#include <QObject>
namespace VPE {
class VProperty;
class VPROPERTYEXPLORERSHARED_EXPORT VAbstractPropertyFactory
{
public:
//! Empty virtual destructor
virtual ~VAbstractPropertyFactory() {}
//! Creates a new property of a certain type and assigns a name and description (otionally)
//! \param type The type of the property as string
//! \param name The property's name
//! \return Returns the created property or NULL if it couldn't be be created
virtual VProperty* createProperty(const QString& type, const QString &name) = 0;
};
}
#endif // VABSTRACTPROPERTYFACTORY_H

View File

@ -0,0 +1,30 @@
#ifndef VFILEPROPERTY_P_H
#define VFILEPROPERTY_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include "vproperty_p.h"
namespace VPE {
class VFilePropertyPrivate : public VPropertyPrivate {
public:
//! File filters
QString FileFilters;
//! Determines whether the file property is a file or a directory. Default: false
bool Directory;
//! Constructor passing name and type
VFilePropertyPrivate(const QString& name, QVariant::Type type, bool directory = false)
: VPropertyPrivate(name, type), FileFilters(), Directory(directory) {}
//! Constructor
VFilePropertyPrivate()
: VPropertyPrivate(), FileFilters(), Directory(false) {}
};
}
#endif // VFILEPROPERTY_P_H

View File

@ -0,0 +1,345 @@
#include "vproperty.h"
#include <QObject>
#include <QMetaProperty>
#include <QItemEditorFactory>
#include <QLineEdit>
#include "vproperty_p.h"
using namespace VPE;
//! Standard constructor, takes a name and a parent property as argument
VProperty::VProperty(const QString& name, QVariant::Type type)
: d_ptr(new VPropertyPrivate(name, type))
{
}
VProperty::VProperty(VPropertyPrivate *d)
: d_ptr(d)
{
}
VProperty::~VProperty()
{
setParent(nullptr);
while(!d_ptr->Children.isEmpty())
{
VProperty* tmpChild = d_ptr->Children.takeLast();
delete tmpChild;
}
delete d_ptr;
}
QString VProperty::type() const
{
return "string";
}
//! Get the data how it should be displayed
QVariant VProperty::data (int column, int role) const
{
if(column == DPC_Name && Qt::DisplayRole == role)
return QVariant(d_ptr->Name);
else if(column == DPC_Data && (Qt::DisplayRole == role || Qt::EditRole == role))
return d_ptr->VariantValue;
else if(Qt::ToolTipRole == role)
return QVariant(d_ptr->Description);
else
return QVariant();
}
bool VProperty::setData(const QVariant &data, int role)
{
bool tmpResult = false;
if(Qt::EditRole == role)
{
tmpResult = (d_ptr->VariantValue != data);
setValue(data);
}
return tmpResult;
}
bool VProperty::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const QAbstractItemDelegate *delegate) const
{
Q_UNUSED(painter);
Q_UNUSED(option);
Q_UNUSED(index);
Q_UNUSED(delegate);
return false;
}
//! Returns an editor widget, or NULL if it doesn't supply one
QWidget* VProperty::createEditor(QWidget * parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate)
{
Q_UNUSED(options);
Q_UNUSED(delegate);
QItemEditorFactory *factory = new QItemEditorFactory;
QItemEditorCreatorBase *lineCreator = new QStandardItemEditorCreator<QLineEdit>();
factory->registerEditor(QVariant::String, lineCreator);
QItemEditorFactory::setDefaultFactory(factory);
d_ptr->editor = factory->createEditor(d_ptr->PropertyVariantType, parent);
//return factory->createEditor(d_ptr->PropertyVariantType, parent);
return d_ptr->editor;
}
bool VProperty::setEditorData(QWidget* editor)
{
if(!editor)
return false;
QByteArray n = editor->metaObject()->userProperty().name();
if (!n.isEmpty()) {
editor->blockSignals(true);
editor->setProperty(n, d_ptr->VariantValue);
editor->blockSignals(false);
return true;
}
return false;
}
//! Gets the data from the widget
QVariant VProperty::getEditorData(QWidget* editor) const
{
if(!editor)
return QVariant();
QByteArray n = editor->metaObject()->userProperty().name();
if (!n.isEmpty())
return editor->property(n);
else
return QVariant();
}
//! Returns item flags
Qt::ItemFlags VProperty::flags(int column) const
{
if(column == DPC_Name)
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
else if(column == DPC_Data)
return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
else
return Qt::NoItemFlags;
}
void VProperty::setValue(const QVariant &value)
{
d_ptr->VariantValue = value;
d_ptr->VariantValue.convert(d_ptr->PropertyVariantType);
if (d_ptr->editor != nullptr)
{
setEditorData(d_ptr->editor);
}
}
QVariant VProperty::getValue() const
{
return d_ptr->VariantValue;
}
QString VProperty::serialize() const
{
return getValue().toString();
}
void VProperty::deserialize(const QString& value)
{
setValue(QVariant(value));
}
void VProperty::setName(const QString& name)
{
d_ptr->Name = name;
}
QString VProperty::getName() const
{
return d_ptr->Name;
}
void VProperty::setDescription(const QString& desc)
{
d_ptr->Description = desc;
}
QString VProperty::getDescription() const
{
return d_ptr->Description;
}
//! Returns a reference to the list of children
QList<VProperty*>& VProperty::getChildren()
{
return d_ptr->Children;
}
//! Returns a reference to the list of children
const QList<VProperty*>& VProperty::getChildren() const
{
return d_ptr->Children;
}
//! Returns the child at a certain row
VProperty* VProperty::getChild(int row) const
{
if(row >= 0 && row < getRowCount())
return d_ptr->Children.at(row);
else
return nullptr;
}
//! Gets the number of children
int VProperty::getRowCount() const
{
return d_ptr->Children.count();
}
//! Gets the parent of this property
VProperty* VProperty::getParent() const
{
return d_ptr->Parent;
}
//! Sets the parent of this property
void VProperty::setParent(VProperty* parent)
{
if(d_ptr->Parent == parent)
return;
VProperty* oldParent = d_ptr->Parent;
d_ptr->Parent = parent;
if(oldParent)
oldParent->removeChild(this);
if(d_ptr->Parent && d_ptr->Parent->getChildRow(this) == -1)
d_ptr->Parent->addChild(this);
}
int VProperty::addChild(VProperty *child)
{
if(child && child->getParent() != this)
child->setParent(this);
if(!d_ptr->Children.contains(child) && child != nullptr)
{
d_ptr->Children.push_back(child);
return d_ptr->Children.count()-1;
}
else
{
return d_ptr->Children.indexOf(child);
}
}
//! Removes a child from the children list
void VProperty::removeChild(VProperty* child)
{
d_ptr->Children.removeAll(child);
if(child && child->getParent() == this)
child->setParent(nullptr);
}
//! Returns the row the child has
int VProperty::getChildRow(VProperty* child) const
{
return d_ptr->Children.indexOf(child);
}
//! Returns whether the views have to update the parent of this property if it changes
bool VProperty::getUpdateParent() const
{
return d_ptr->UpdateParent;
}
//! Returns whether the views have to update the children of this property if it changes
bool VProperty::getUpdateChildren() const
{
return d_ptr->UpdateChildren;
}
//! Sets whether the views should update Parents or children after this property changes
void VProperty::setUpdateBehaviour(bool update_parent, bool update_children)
{
d_ptr->UpdateParent = update_parent;
d_ptr->UpdateChildren = update_children;
}
void VProperty::setSettings(const QMap<QString, QVariant>& settings)
{
QMap<QString, QVariant>::const_iterator tmpIterator = settings.constBegin();
for (; tmpIterator != settings.constEnd(); ++tmpIterator) {
setSetting(tmpIterator.key(), tmpIterator.value());
}
}
QMap<QString, QVariant> VProperty::getSettings() const
{
QMap<QString, QVariant> tmpResult;
QStringList tmpKeyList = getSettingKeys();
foreach(const QString& tmpKey, tmpKeyList)
tmpResult.insert(tmpKey, getSetting(tmpKey));
return tmpResult;
}
void VProperty::setSetting(const QString& key, const QVariant& value)
{
Q_UNUSED(key)
Q_UNUSED(value)
// Not needed in the Standard property
}
QVariant VProperty::getSetting(const QString& key) const
{
// Not needed in the Standard property
Q_UNUSED(key)
return QVariant();
}
QStringList VProperty::getSettingKeys() const
{
return QStringList();
}
VProperty* VProperty::clone(bool include_children, VProperty* container) const
{
if(!container)
container = new VProperty(getName(), d_ptr->PropertyVariantType);
container->setName(getName());
container->setDescription(getDescription());
container->setValue(getValue());
container->setSettings(getSettings());
container->setUpdateBehaviour(getUpdateParent(), getUpdateChildren());
if(include_children) {
foreach(VProperty* tmpChild, d_ptr->Children)
container->addChild(tmpChild->clone(true));
}
return container;
}

View File

@ -0,0 +1,176 @@
#ifndef VPROPERTY_H
#define VPROPERTY_H
#include "vpropertyexplorer_global.h"
#include <QVariant>
#include <QString>
#include <QSharedPointer>
#include <QStyleOptionViewItem>
#include <QAbstractItemDelegate>
#include <QEvent>
namespace VPE {
static const int MyCustomEventType = 1099;
class UserChangeEvent : public QEvent
{
public:
UserChangeEvent() : QEvent((QEvent::Type)MyCustomEventType) {}
};
class VPropertyPrivate;
class VPROPERTYEXPLORERSHARED_EXPORT VProperty
{
public:
enum DPC_DisplayColumn {
DPC_Name = 0,
DPC_Data
};
//! Standard constructor, takes a name and a parent property as argument
explicit VProperty(const QString& name, QVariant::Type type = QVariant::String);
//! Destructor
virtual ~VProperty();
//! Returns a string containing the type of the property
virtual QString type() const;
//! Get the data how it should be displayed
virtual QVariant data (int column = DPC_Name, int role = Qt::DisplayRole) const;
//! This is used by the model to set the data
//! \param data The data to set
//! \param role The role. Default is Qt::EditRole
//! \return Returns true, if the data was changed, false if not.
virtual bool setData (const QVariant& data, int role = Qt::EditRole);
//! This is called by the delegate when the property value is being drawn.
//! The standard implementation doesn't do anything.
//! If you reimplement this in a sub property, make sure to return true or the delegate will draw the item.
virtual bool paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QAbstractItemDelegate* delegate) const;
//! Returns an editor widget, or NULL if it doesn't supply one
//! \param parent The widget to which the editor will be added as a child
//! \options Render options
//! \delegate A pointer to the QAbstractItemDelegate requesting the editor. This can be used to connect signals and slots.
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& options, const QAbstractItemDelegate* delegate);
//! Sets the property's data to the editor (returns false, if the standard delegate should do that)
virtual bool setEditorData(QWidget* editor);
//! Gets the data from the widget
virtual QVariant getEditorData(QWidget* editor) const;
//! Returns item flags
virtual Qt::ItemFlags flags(int column = DPC_Name) const;
//! Sets the value of the property
virtual void setValue(const QVariant& value);
//! Returns the value of the property as a QVariant
virtual QVariant getValue() const;
//! Serializes the value to a string
virtual QString serialize() const;
//! Deserializes the value from a string
virtual void deserialize(const QString& value);
// The following functions are experimental and not yet implemented.
/*//! Returns a pointer to the data stored and handled by this property. In most cases this function shouldn't be used.
//! \return Returns a void pointer to the data. Not all properties have to support this. By default, this implementation returns a NULL pointer.
virtual void* getDataPointer();
//! Sets the data.
//! \return Returns a void pointer to the data. Not all properties have to support this. By default, this implementation returns a NULL pointer.
virtual bool setDataPointer(void* pointer);*/
//! Sets the name of the property
virtual void setName(const QString& name);
//! Gets the name of the property
virtual QString getName() const;
//! Sets the name of the property
virtual void setDescription(const QString& desc);
//! Gets the name of the property
virtual QString getDescription() const;
//! Adds a child to this property
virtual int addChild(VProperty* child);
//! Returns a reference to the list of children
virtual QList<VProperty*>& getChildren();
//! Returns a reference to the list of children
virtual const QList<VProperty*>& getChildren() const;
//! Returns the child at a certain row
virtual VProperty* getChild(int row) const;
//! Gets the number of children
virtual int getRowCount() const;
//! Gets the parent of this property
virtual VProperty* getParent() const;
//! Sets the parent of this property
virtual void setParent(VProperty* parent);
//! Removes a child from the children list, doesn't delete the child!
virtual void removeChild(VProperty* child);
//! Returns the row the child has
virtual int getChildRow(VProperty* child) const;
//! Returns whether the views have to update the parent of this property if it changes
virtual bool getUpdateParent() const;
//! Returns whether the views have to update the children of this property if it changes
virtual bool getUpdateChildren() const;
//! Sets whether the views should update Parents or children after this property changes
virtual void setUpdateBehaviour(bool update_parent, bool update_children);
//! Sets the settings by calling the overloaded setSetting(const QString& key, const QVariant& value) for each item in the map.
virtual void setSettings(const QMap<QString, QVariant>& settings);
//! Get the settings.
virtual QMap<QString, QVariant> getSettings() const;
//! Sets the settings. This function has to be implemented in a subclass in order to have an effect
virtual void setSetting(const QString& key, const QVariant& value);
//! Get the settings. This function has to be implemented in a subclass in order to have an effect
virtual QVariant getSetting(const QString& key) const;
//! Returns the list of keys of the property's settings
virtual QStringList getSettingKeys() const;
//! Clones this property
//! \param include_children Indicates whether to also clone the children
//! \param container If a property is being passed here, no new VProperty is being created but instead it is tried to fill all the data into container. This can also be used when subclassing this function.
//! \return Returns the newly created property (or container, if it was not NULL)
virtual VProperty* clone(bool include_children = true, VProperty* container = nullptr) const;
protected:
//! Protected constructor
VProperty(VPropertyPrivate* d);
//! The protected structure holding the member variables (to assure binary compatibility)
VPropertyPrivate* d_ptr;
private:
// Provide access functions for the d_ptr
Q_DECLARE_PRIVATE(VProperty)
};
}
#endif // VPROPERTY_H

View File

@ -0,0 +1,61 @@
#ifndef VPROPERTY_P_H
#define VPROPERTY_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include <QVariant>
#include <QString>
#include "vproperty.h"
namespace VPE {
class VPropertyPrivate {
public:
//! The property's value.
//! This does not have to be used by subclasses, but it makes sense in cases where QVariant supports
//! the data type. Also, this can be used as cache, so that when the data() function gets called by
//! the model, the data does not have to be converted in a QVariant every time.
QVariant VariantValue;
//! Property name
QString Name;
//! Description
QString Description;
//! Specifies whether the property is empty or not
bool IsEmpty;
//! Stores the property type
QVariant::Type PropertyVariantType;
//! Stores whether the views have to update the parent of this property if it changes
bool UpdateParent;
//! Stores whether the views have to update the children of this property if it changes
bool UpdateChildren;
//! The parent property
VProperty* Parent;
QWidget* editor;
//! List of child properties
QList<VProperty*> Children;
//! Constructor passing name and type
VPropertyPrivate(const QString& name, QVariant::Type type)
: VariantValue(type), Name(name), PropertyVariantType(type), UpdateParent(false), UpdateChildren(false),
Parent(nullptr), editor(nullptr)
{}
//! Constructor
VPropertyPrivate()
: VariantValue(), Name(), PropertyVariantType(QVariant::Invalid), UpdateParent(false), UpdateChildren(false),
Parent(nullptr), editor(nullptr)
{}
};
}
#endif // VPROPERTY_P_H

View File

@ -0,0 +1,100 @@
#include "vpropertydelegate.h"
#include "vproperty.h"
#include <QApplication>
#include <QStyle>
#include <QPen>
#include <QPainter>
using namespace VPE;
VPropertyDelegate::VPropertyDelegate(QObject *parent) :
QStyledItemDelegate(parent), RowHeight(0), AddRowHeight(false)
{
}
VPropertyDelegate::~VPropertyDelegate()
{
//
}
QWidget* VPropertyDelegate::createEditor (QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QWidget* tmpWidget = nullptr;
if(index.isValid())
{
VProperty* tmpProperty = reinterpret_cast<VProperty*>(index.internalPointer());
tmpWidget = tmpProperty->createEditor(parent, option, this);
}
return tmpWidget ? tmpWidget : QStyledItemDelegate::createEditor(parent, option, index);
}
//! Sets the index data to the editor
void VPropertyDelegate::setEditorData (QWidget * editor, const QModelIndex & index) const
{
bool done = false;
if(index.isValid() && editor)
{
VProperty* tmpProperty = reinterpret_cast<VProperty*>(index.internalPointer());
done = tmpProperty->setEditorData(editor);
}
if(!done)
QStyledItemDelegate::setEditorData(editor, index);
}
//! Updates the index data
void VPropertyDelegate::setModelData (QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
{
QVariant tmpData;
if(index.isValid() && editor)
{
VProperty* tmpProperty = reinterpret_cast<VProperty*>(index.internalPointer());
tmpData = tmpProperty->getEditorData(editor);
}
if(tmpData.isNull())
QStyledItemDelegate::setModelData(editor, model, index);
else
model->setData(index, tmpData);
}
QSize VPropertyDelegate::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QSize tmpStandardSizeHint = QStyledItemDelegate::sizeHint(option, index);
tmpStandardSizeHint.setHeight(tmpStandardSizeHint.height() + 1);
if(RowHeight > 0)
return QSize(tmpStandardSizeHint.width(), AddRowHeight ? tmpStandardSizeHint.height() + RowHeight : RowHeight);
else
return tmpStandardSizeHint;
}
void VPropertyDelegate::setRowHeight(int height, bool add_to_standard)
{
RowHeight = height;
AddRowHeight = add_to_standard;
}
void VPropertyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
bool done = false;
if(index.isValid() && index.column() == 1)
done = reinterpret_cast<VProperty*>(index.internalPointer())->paint(painter, option, index, this);
if(!done)
QStyledItemDelegate::paint(painter, option, index);
QColor tmpPenColor = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &option));
QPen tmpOldPen = painter->pen();
painter->setPen(QPen(tmpPenColor));
painter->drawLine(option.rect.right(), option.rect.y(), option.rect.right(), option.rect.bottom());
painter->drawLine(option.rect.x(), option.rect.bottom(), option.rect.right(), option.rect.bottom());
painter->setPen(tmpOldPen);
}

View File

@ -0,0 +1,44 @@
#ifndef VPROPERTYDELEGATE_H
#define VPROPERTYDELEGATE_H
#include "vpropertyexplorer_global.h"
#include <QStyledItemDelegate>
namespace VPE {
class VPROPERTYEXPLORERSHARED_EXPORT VPropertyDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit VPropertyDelegate(QObject *parent = 0);
virtual ~VPropertyDelegate();
//! Creates the editor widget
virtual QWidget* createEditor (QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
//! Sets the index data to the editor
virtual void setEditorData (QWidget * editor, const QModelIndex & index) const;
//! Updates the index data
virtual void setModelData (QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
//! Returns the size hint
virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const;
//! Sets the row height. Set this to 0 and the standard will be taken
void setRowHeight(int height = 0, bool add_to_standard = false);
//! Renders the delegate using the given painter and style option for the item specified by index.
virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
protected:
int RowHeight;
bool AddRowHeight;
};
}
#endif // VPROPERTYDELEGATE_H

View File

@ -0,0 +1,34 @@
/************************************************************************
**
** @file vpropertyexplorer.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 26 8, 2014
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2014 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vpropertyexplorer.h"
Vpropertyexplorer::Vpropertyexplorer()
{
}

View File

@ -0,0 +1,41 @@
/************************************************************************
**
** @file vpropertyexplorer.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 26 8, 2014
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2014 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPROPERTYEXPLORER_H
#define VPROPERTYEXPLORER_H
#include "vpropertyexplorer_global.h"
class VPROPERTYEXPLORERSHARED_EXPORT Vpropertyexplorer
{
public:
Vpropertyexplorer();
};
#endif // VPROPERTYEXPLORER_H

View File

@ -0,0 +1,80 @@
#-------------------------------------------------
#
# Project created by QtCreator 2014-08-26T14:18:08
#
#-------------------------------------------------
QT += widgets
QT -= gui
TARGET = vpropertyexplorer
TEMPLATE = lib
CONFIG += c++11
DEFINES += VPROPERTYEXPLORER_LIBRARY
SOURCES += vpropertyexplorer.cpp \
vproperty.cpp \
vpropertydelegate.cpp \
vpropertyfactorymanager.cpp \
vpropertyformview.cpp \
vpropertyformwidget.cpp \
vpropertymodel.cpp \
vpropertyset.cpp \
vpropertytreeview.cpp \
vserializedproperty.cpp \
vstandardpropertyFactory.cpp \
plugins/vwidgetproperty.cpp \
plugins/vemptyproperty.cpp \
plugins/vboolproperty.cpp \
plugins/vshortcutproperty.cpp \
plugins/vcolorproperty.cpp \
plugins/vshortcutpropertyeditor.cpp \
plugins/venumproperty.cpp \
plugins/vfileproperty.cpp \
plugins/vcolorpropertyeditor.cpp \
plugins/vfilepropertyeditor.cpp \
plugins/vnumberproperty.cpp \
plugins/Vector3d/vvector3dproperty.cpp
HEADERS += vpropertyexplorer.h\
vpropertyexplorer_global.h \
vpropertyfactorymanager_p.h \
vpropertytreeview_p.h \
vpropertyset_p.h \
vabstractpropertyfactory.h \
vfileproperty_p.h \
vwidgetproperty_p.h \
vpropertymodel_p.h \
vstandardpropertyfactory.h \
vpropertyformview_p.h \
vpropertytreeview.h \
vpropertyformwidget_p.h \
vpropertydelegate.h \
vproperty_p.h \
vpropertyformwidget.h \
vpropertyformview.h \
vpropertyset.h \
vpropertymodel.h \
vproperty.h \
plugins/vwidgetproperty.h \
plugins/vcolorproperty.h \
plugins/vboolproperty.h \
plugins/vcolorpropertyeditor.h \
plugins/vshortcutpropertyeditor.h \
plugins/vemptyproperty.h \
plugins/vshortcutproperty.h \
plugins/venumproperty.h \
plugins/vfilepropertyeditor.h \
plugins/vfileproperty.h \
plugins/vnumberproperty.h \
plugins/Vector3d/vvector3dproperty.h \
vpropertyfactorymanager.h \
vserializedproperty.h
unix {
target.path = /usr/lib
INSTALLS += target
}

View File

@ -0,0 +1,40 @@
/************************************************************************
**
** @file vpropertyexplorer_global.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 26 8, 2014
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2014 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPROPERTYEXPLORER_GLOBAL_H
#define VPROPERTYEXPLORER_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(VPROPERTYEXPLORER_LIBRARY)
# define VPROPERTYEXPLORERSHARED_EXPORT Q_DECL_EXPORT
#else
# define VPROPERTYEXPLORERSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // VPROPERTYEXPLORER_GLOBAL_H

View File

@ -0,0 +1,109 @@
#include "vpropertyfactorymanager.h"
#include "vpropertyfactorymanager_p.h"
#include "vstandardpropertyfactory.h"
#include "vproperty.h"
using namespace VPE;
VPropertyFactoryManager* VPropertyFactoryManager::DefaultManager = NULL;
VPropertyFactoryManager::VPropertyFactoryManager(QObject *parent)
: QObject(parent), d_ptr(new VPropertyFactoryManagerPrivate())
{
}
VPropertyFactoryManager::~VPropertyFactoryManager()
{
// Delete all factories
QList<VAbstractPropertyFactory*> tmpFactories = d_ptr->Factories.values();
while(!tmpFactories.isEmpty()) {
VAbstractPropertyFactory* tmpFactory = tmpFactories.takeLast();
tmpFactories.removeAll(tmpFactory);
delete tmpFactory;
}
delete d_ptr;
if(this == DefaultManager)
DefaultManager = NULL;
}
void VPropertyFactoryManager::registerFactory(const QString& type, VAbstractPropertyFactory* factory)
{
if(type.isEmpty())
return;
// Remove old factory
unregisterFactory(getFactory(type), type, true);
// Register new one
d_ptr->Factories[type] = factory;
}
void VPropertyFactoryManager::unregisterFactory(VAbstractPropertyFactory* factory, const QString& type, bool delete_if_unused)
{
if(!factory)
return;
if(!type.isEmpty()) {
// Remove all occurances
QString tmpKey;
do {
tmpKey = d_ptr->Factories.key(factory, QString());
if(!tmpKey.isEmpty()) d_ptr->Factories.remove(tmpKey);
} while(!tmpKey.isEmpty());
} else {
// Only remove one type
if(d_ptr->Factories.value(type, NULL) == factory)
d_ptr->Factories.remove(type);
}
if(delete_if_unused && !isRegistered(factory))
delete factory;
}
bool VPropertyFactoryManager::isRegistered(VAbstractPropertyFactory* factory)
{
return (!d_ptr->Factories.key(factory, QString()).isEmpty());
}
VAbstractPropertyFactory* VPropertyFactoryManager::getFactory(const QString& type)
{
return d_ptr->Factories.value(type, NULL);
}
VProperty* VPropertyFactoryManager::createProperty(const QString& type, const QString& name, const QString& description, const QString &default_value)
{
VAbstractPropertyFactory* tmpFactory = getFactory(type);
VProperty* tmpResult = NULL;
if(tmpFactory) {
tmpResult = tmpFactory->createProperty(type, name);
if(tmpResult) {
tmpResult->setDescription(description);
if(!default_value.isEmpty())
tmpResult->deserialize(default_value);
}
}
return tmpResult;
}
VPropertyFactoryManager *VPropertyFactoryManager::getDefaultManager()
{
if(!DefaultManager) {
DefaultManager = new VPropertyFactoryManager();
/*VStandardPropertyFactory* tmpStandardProp = */new VStandardPropertyFactory(DefaultManager);
}
return DefaultManager;
}
QStringList VPropertyFactoryManager::getSupportedTypes()
{
return d_ptr->Factories.keys();
}

View File

@ -0,0 +1,67 @@
#ifndef VPROPERTYFACTORYMANAGER_H
#define VPROPERTYFACTORYMANAGER_H
#include "vpropertyexplorer_global.h"
#include <QObject>
namespace VPE {
class VAbstractPropertyFactory;
class VPropertyFactoryManagerPrivate;
class VProperty;
class VPROPERTYEXPLORERSHARED_EXPORT VPropertyFactoryManager : public QObject
{
Q_OBJECT
public:
//! Constructor
VPropertyFactoryManager(QObject* parent = nullptr);
//! Destructor
virtual ~VPropertyFactoryManager();
//! Register a factory to the factory manager
//! Note that the manager takes ownership of the factory, so don't delete it.
//! You can unregister a factory using unregisterFactory()
void registerFactory(const QString& type, VAbstractPropertyFactory* factory);
//! Removes a factory from the manager.
//! \param factory The factory to unregister
//! \param type The type from which to remove the factory. If this is empty, all the types the factory is registered for are being removed
//! \param delete_if_unused Determines whether the factory should be deleted, if it not used anymore by this manager. Default: true. Otherwise, if the factory is unused by this manager, ownership is being passed on.
void unregisterFactory(VAbstractPropertyFactory* factory, const QString& type = QString(),
bool delete_if_unused = true);
//! Returns whether a factory is registered (and thus owned) by this factory manager
bool isRegistered(VAbstractPropertyFactory* factory);
//! Returns a pointer to a factory registered for a certain type
//! \param type The type to return the factory for
//! \return Returns NULL, if there is none registered for this type
VAbstractPropertyFactory* getFactory(const QString& type);
//! Creates a new property of a certain type and assigns a name and description (otionally)
//! \param type The type of the property as string
//! \param name The name of the property
//! \param description The property's description. Optional.
//! \param default_value The properties initial value as string. Optional.
//! \return Returns the created property or NULL if it couldn't be be created
VProperty* createProperty(const QString& type, const QString& name, const QString& description = QString(),
const QString& default_value = QString());
//! Returns the default manager.
static VPropertyFactoryManager* getDefaultManager();
//! Returns a list of all supported property types
QStringList getSupportedTypes();
protected:
VPropertyFactoryManagerPrivate* d_ptr;
//! The default manager
static VPropertyFactoryManager* DefaultManager;
};
}
#endif // VPROPERTYFACTORYMANAGER_H

View File

@ -0,0 +1,21 @@
#ifndef VPROPERTYFACTORYMANAGER_P_H
#define VPROPERTYFACTORYMANAGER_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include <QMap>
#include <QString>
namespace VPE {
class VAbstractPropertyFactory;
class VPropertyFactoryManagerPrivate {
public:
QMap<QString, VAbstractPropertyFactory*> Factories;
};
}
#endif // VPROPERTYFACTORYMANAGER_P_H

View File

@ -0,0 +1,180 @@
#include "vpropertyformview.h"
#include "vpropertymodel.h"
#include "vpropertyset.h"
#include <QFormLayout>
#include <QGroupBox>
#include <QShowEvent>
#include "vpropertyformview_p.h"
using namespace VPE;
VPropertyFormView::VPropertyFormView(QWidget* parent)
: VPropertyFormWidget(new VPropertyFormViewPrivate(), parent)
{
//
}
VPropertyFormView::VPropertyFormView(VPropertyModel* model, QWidget *parent)
: VPropertyFormWidget(new VPropertyFormViewPrivate(), parent)
{
setModel(model);
}
VPropertyFormView::VPropertyFormView(VPropertySet* property_set, QWidget *parent)
: VPropertyFormWidget(new VPropertyFormViewPrivate(), parent)
{
setPropertySet(property_set);
}
VPropertyFormView::~VPropertyFormView()
{
// Nothing to do
}
void VPropertyFormView::build()
{
VPropertyFormWidget::build();
// Go through all sub widgets and connect
connectPropertyFormWidget(this);
}
void VPropertyFormView::setModel(VPropertyModel *model)
{
// Remove old model or set
removeModelAndSet();
// Set model
static_cast<VPropertyFormViewPrivate*>(d_ptr)->Model = model;
if(model) {
// Set the property list
if(model->getPropertySet())
d_ptr->Properties = model->getPropertySet()->getRootProperties();
// Connect signals // todo: more signals neccesary!!!
connect(model, SIGNAL(destroyed()), this, SLOT(modelDestroyed()));
connect(model, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this, SLOT(rowsInserted(QModelIndex,int,int)));
connect(model, SIGNAL(modelReset()), this, SLOT(modelReset()));
connect(model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(rowsRemoved(QModelIndex,int,int)));
}
// Build the widget
updatePropertyList();
}
void VPropertyFormView::setPropertySet(VPropertySet* property_set)
{
// Remove old model or set
removeModelAndSet();
// Set property set
static_cast<VPropertyFormViewPrivate*>(d_ptr)->PropertySet = property_set;
if(property_set) {
// Set the property list
d_ptr->Properties = property_set->getRootProperties();
}
// Build the widget
updatePropertyList();
}
void VPropertyFormView::rowsRemoved(const QModelIndex &parent, int start, int end)
{
// todo: Only rebuild the neccessary parts
Q_UNUSED(parent)
Q_UNUSED(start)
Q_UNUSED(end)
updatePropertyList();
}
void VPropertyFormView::rowsInserted(const QModelIndex &parent, int start, int end)
{
// todo: Only rebuild the neccessary parts
Q_UNUSED(parent)
Q_UNUSED(start)
Q_UNUSED(end)
updatePropertyList();
}
void VPropertyFormView::modelReset()
{
updatePropertyList();
}
void VPropertyFormView::modelDestroyed()
{
removeModelAndSet();
updatePropertyList();
}
void VPropertyFormView::dataChanged(const QModelIndex &top_left, const QModelIndex &bottom_right)
{
if(static_cast<VPropertyFormViewPrivate*>(d_ptr)->IgnoreDataChangedSignal)
return;
// todo: handle data changes
}
void VPropertyFormView::dataSubmitted(VProperty *property)
{
VPropertyModel* tmpModel = static_cast<VPropertyFormViewPrivate*>(d_ptr)->Model;
if(tmpModel && d_ptr->UpdateEditors) {
static_cast<VPropertyFormViewPrivate*>(d_ptr)->IgnoreDataChangedSignal = true;
//tmpModel->onDataChangedByModel(property);
tmpModel->showDataChangedByEditor(property);
static_cast<VPropertyFormViewPrivate*>(d_ptr)->IgnoreDataChangedSignal = false;
}
}
void VPropertyFormView::showEvent(QShowEvent *event)
{
Q_UNUSED(event)
if(static_cast<VPropertyFormViewPrivate*>(d_ptr)->NeedsRebuild)
build();
static_cast<VPropertyFormViewPrivate*>(d_ptr)->NeedsRebuild = false;
}
void VPropertyFormView::updatePropertyList()
{
VPropertyModel* tmpModel = static_cast<VPropertyFormViewPrivate*>(d_ptr)->Model;
VPropertySet* tmpSet = static_cast<VPropertyFormViewPrivate*>(d_ptr)->PropertySet;
if(tmpModel && tmpModel->getPropertySet())
d_ptr->Properties = tmpModel->getPropertySet()->getRootProperties();
else if(tmpSet)
d_ptr->Properties = tmpSet->getRootProperties();
else
d_ptr->Properties.clear();
if(isVisible())
build();
else
static_cast<VPropertyFormViewPrivate*>(d_ptr)->NeedsRebuild = true;
}
void VPropertyFormView::removeModelAndSet()
{
if(static_cast<VPropertyFormViewPrivate*>(d_ptr)->Model) {
disconnect(static_cast<VPropertyFormViewPrivate*>(d_ptr)->Model, 0, this, 0);
static_cast<VPropertyFormViewPrivate*>(d_ptr)->Model = nullptr;
}
static_cast<VPropertyFormViewPrivate*>(d_ptr)->NeedsRebuild = true;
d_ptr->Properties.clear();
static_cast<VPropertyFormViewPrivate*>(d_ptr)->PropertySet = nullptr;
}
void VPropertyFormView::connectPropertyFormWidget(VPropertyFormWidget *widget)
{
if(!widget)
return;
connect(widget, SIGNAL(propertyDataSubmitted(VProperty*)), this, SLOT(dataSubmitted(VProperty*)));
QList<VPropertyFormWidget*> tmpList = widget->getChildPropertyFormWidgets();
foreach(VPropertyFormWidget* tmpEditorWidget, tmpList) {
connectPropertyFormWidget(tmpEditorWidget);
}
}

View File

@ -0,0 +1,81 @@
#ifndef VPROPERTYFORMVIEW_H
#define VPROPERTYFORMVIEW_H
#include "vpropertyexplorer_global.h"
#include <QPointer>
#include "vpropertyformwidget.h"
namespace VPE {
class VProperty;
class VPropertyModel;
class VPropertySet;
//! This class populates a form layout with the properties in a model
class VPROPERTYEXPLORERSHARED_EXPORT VPropertyFormView : public VPropertyFormWidget
{
Q_OBJECT
public:
//! Constructor
explicit VPropertyFormView(QWidget *parent = 0);
//! Constructor
explicit VPropertyFormView(VPropertyModel* model, QWidget *parent = 0);
//! Constructor
explicit VPropertyFormView(VPropertySet* property_set, QWidget *parent = 0);
//! Destructor
virtual ~VPropertyFormView();
public slots:
//! Rebuilds the whole form
virtual void build();
//! Set the source model. Leads to the rebuild of the form
//! \param model The model to use
void setModel(VPropertyModel* model);
//! Set the property set to use. Note that if using a property set directly, adding and removing properties to the property set leads to undifined behaviour for the property set misses notification signals.
//! \param model The property set to use
void setPropertySet(VPropertySet* property_set);
//! Called when a row gets removed in the model
void rowsRemoved(const QModelIndex& parent, int start, int end);
//! Called when a new row is being inserted into the model
void rowsInserted(const QModelIndex& parent, int start, int end);
//! Called when the model is being reset
void modelReset();
private slots:
//! Called, when the model gets destroyed
void modelDestroyed();
//! Called when data in the model gets changed
void dataChanged(const QModelIndex& top_left, const QModelIndex& bottom_right);
//! Updates the model when data was submitted by the view
void dataSubmitted(VProperty* property);
protected:
void showEvent(QShowEvent* event);
//! Rebuilds the widegt only if it is visible
void updatePropertyList();
//! Removes the model and property set if they were set
void removeModelAndSet();
//! Function to handle newly created VPropertyWidgets
virtual void connectPropertyFormWidget(VPropertyFormWidget* widget);
};
} // Namespace VPE
#endif // VPROPERTYFORMVIEW_H

View File

@ -0,0 +1,40 @@
#ifndef VPROPERTYFORMVIEW_P_H
#define VPROPERTYFORMVIEW_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include "vpropertyformwidget_p.h"
namespace VPE {
class VPropertyModel;
class VPropertySet;
class VPropertyFormViewPrivate : public VPropertyFormWidgetPrivate
{
public:
//! The current property model
VPropertyModel* Model;
//! The currently used property set
VPropertySet* PropertySet;
//! Determines whether the widget needs to be rebuild
bool NeedsRebuild;
//! Helper variable
bool IgnoreDataChangedSignal;
VPropertyFormViewPrivate()
: VPropertyFormWidgetPrivate(), Model(NULL), PropertySet(NULL), NeedsRebuild(false) {}
VPropertyFormViewPrivate(VPropertyModel* prop_model)
: VPropertyFormWidgetPrivate(), Model(prop_model), PropertySet(NULL), NeedsRebuild(false) {}
VPropertyFormViewPrivate(VPropertySet* prop_set)
: VPropertyFormWidgetPrivate(), Model(NULL), PropertySet(prop_set), NeedsRebuild(false) {}
};
}
#endif // VPROPERTYFORMVIEW_P_H

View File

@ -0,0 +1,223 @@
#include "vpropertyformwidget.h"
#include <QFormLayout>
#include "vpropertyformwidget_p.h"
#include "plugins/vwidgetproperty.h"
#include <QEvent>
#include <QKeyEvent>
#include "vproperty.h"
using namespace VPE;
VPropertyFormWidget::VPropertyFormWidget(const QString &title, const QString &description, const QList<VProperty*>& properties, QWidget *parent)
: QGroupBox(title, parent), d_ptr(new VPropertyFormWidgetPrivate(properties))
{
build();
setToolTip(description);
setWhatsThis(description);
}
VPropertyFormWidget::VPropertyFormWidget(VProperty *parent_property, QWidget *parent)
: QGroupBox(parent), d_ptr(new VPropertyFormWidgetPrivate())
{
if(parent_property) {
d_ptr->Properties = parent_property->getChildren();
build();
setTitle(parent_property->getName());
setToolTip(parent_property->getDescription());
setWhatsThis(parent_property->getDescription());
}
}
VPropertyFormWidget::VPropertyFormWidget(VPropertyFormWidgetPrivate *d_pointer, QWidget *parent, const QString &title, const QString &description)
: QGroupBox(title, parent), d_ptr(d_pointer)
{
build();
setToolTip(description);
setWhatsThis(description);
}
VPropertyFormWidget::~VPropertyFormWidget()
{
delete d_ptr;
}
void VPropertyFormWidget::build()
{
// Clear the old content, delete old widgets
d_ptr->EditorWidgets.clear();
if(layout()) {
QLayoutItem *child;
while (layout()->count() > 0 && (child = layout()->takeAt(0)) != 0) {
if(child->widget())
delete child->widget();
delete child;
}
delete layout();
}
// Create new content
if(d_ptr->Properties.isEmpty()) return; //... only if there are properties
QFormLayout* tmpFormLayout = new QFormLayout(this);
setLayout(tmpFormLayout);
for(int i = 0; i < d_ptr->Properties.count(); ++i) {
// Get the current property
VProperty* tmpProperty = d_ptr->Properties.value(i, nullptr);
if(!tmpProperty) continue;
if(tmpProperty->getRowCount() > 0) {
// Child properties, the property itself is not being added
VPropertyFormWidget* tmpNewFormWidget = new VPropertyFormWidget(tmpProperty, this);
tmpFormLayout->addRow(tmpNewFormWidget);
d_ptr->EditorWidgets.append(VPropertyFormWidgetPrivate::SEditorWidget(tmpNewFormWidget));
tmpNewFormWidget->setCommitBehaviour(d_ptr->UpdateEditors);
} else if(tmpProperty->type() == "widget") {
VWidgetProperty* tmpWidgetProperty = static_cast<VWidgetProperty*>(tmpProperty);
tmpFormLayout->addRow(tmpWidgetProperty->getWidget());
d_ptr->EditorWidgets.append(VPropertyFormWidgetPrivate::SEditorWidget(tmpWidgetProperty->getWidget()));
} else {
// Add property (no child properties)
// Create the editor (if it doesn't work, create empty widget)
QWidget* tmpEditor = tmpProperty->createEditor(this, QStyleOptionViewItem(), nullptr);
if(!tmpEditor)
tmpEditor = new QWidget(this);
// set tooltip and whats this
tmpEditor->setToolTip(tmpProperty->getDescription());
tmpEditor->setWhatsThis(tmpProperty->getDescription());
// Install event filter
tmpEditor->installEventFilter(this);
// Set the editor data
tmpProperty->setEditorData(tmpEditor);
// add new row
tmpFormLayout->addRow(tmpProperty->getName(), tmpEditor);
d_ptr->EditorWidgets.append(VPropertyFormWidgetPrivate::SEditorWidget(tmpEditor));
}
}
}
void VPropertyFormWidget::commitData()
{
for(int i = 0; i < d_ptr->Properties.count(); ++i)
commitData(i);
}
void VPropertyFormWidget::loadData()
{
for(int i = 0; i < d_ptr->Properties.count(); ++i)
loadData(i);
}
void VPropertyFormWidget::commitData(int row)
{
if(row < 0 || row >= d_ptr->EditorWidgets.count() || row >= d_ptr->Properties.count()) return;
VPropertyFormWidgetPrivate::SEditorWidget& tmpEditorWidget = d_ptr->EditorWidgets[row];
VProperty* tmpProperty = d_ptr->Properties[row];
if(tmpEditorWidget.FormWidget)
tmpEditorWidget.FormWidget->commitData();
else if(tmpEditorWidget.Editor && tmpProperty) {
QVariant newValue = tmpProperty->getEditorData(tmpEditorWidget.Editor);
QVariant oldValue = tmpProperty->data(VProperty::DPC_Data);
if (oldValue != newValue)
{
tmpProperty->setValue(tmpProperty->getEditorData(tmpEditorWidget.Editor));
emit propertyDataSubmitted(tmpProperty);
}
}
}
void VPropertyFormWidget::loadData(int row)
{
if(row < 0 || row >= d_ptr->EditorWidgets.count() || row >= d_ptr->Properties.count()) return;
VPropertyFormWidgetPrivate::SEditorWidget& tmpEditorWidget = d_ptr->EditorWidgets[row];
VProperty* tmpProperty = d_ptr->Properties[row];
if(tmpEditorWidget.FormWidget)
tmpEditorWidget.FormWidget->loadData();
else if(tmpEditorWidget.Editor && tmpProperty) {
tmpProperty->setEditorData(tmpEditorWidget.Editor);
}
}
void VPropertyFormWidget::setCommitBehaviour(bool auto_commit)
{
d_ptr->UpdateEditors = auto_commit;
QList<VPropertyFormWidget*> tmpChildFormWidgets = getChildPropertyFormWidgets();
foreach(VPropertyFormWidget* tmpChild, tmpChildFormWidgets) {
if(tmpChild)
tmpChild->setCommitBehaviour(auto_commit);
}
}
QList<VPropertyFormWidget *> VPropertyFormWidget::getChildPropertyFormWidgets() const
{
QList<VPropertyFormWidget *> tmpResult;
foreach(const VPropertyFormWidgetPrivate::SEditorWidget& tmpEditorWidget, d_ptr->EditorWidgets) {
if(tmpEditorWidget.FormWidget)
tmpResult.append(tmpEditorWidget.FormWidget);
}
return tmpResult;
}
bool VPropertyFormWidget::eventFilter(QObject *object, QEvent *event)
{
if(!d_ptr->UpdateEditors)
return false;
QWidget* editor = qobject_cast<QWidget*>(object);
if (!editor)
return false;
if (event->type() == QEvent::KeyPress) {
switch (static_cast<QKeyEvent *>(event)->key()) {
case Qt::Key_Tab:
case Qt::Key_Backtab:
case Qt::Key_Enter:
case Qt::Key_Return:
case Qt::Key_Escape:
commitData(editor);
event->accept();
return true;
default:
return false;
}
} else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
commitData(editor);
return false;
} else if (event->type() == QEvent::ShortcutOverride) {
if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
commitData(editor);
event->accept();
return true;
}
} else if (event->type() == MyCustomEventType) {
commitData(editor);
event->accept();
return true;
}
// Default:
return false;
}
void VPropertyFormWidget::commitData(QWidget *editor)
{
if(!editor)
return;
for(int i = 0; i < d_ptr->EditorWidgets.count(); ++i) {
VPropertyFormWidgetPrivate::SEditorWidget& tmpEditorWidget = d_ptr->EditorWidgets[i];
if(tmpEditorWidget.Editor == editor)
commitData(i);
}
}

View File

@ -0,0 +1,73 @@
#ifndef VPROPERTYFORMWIDGET_H
#define VPROPERTYFORMWIDGET_H
#include <QGroupBox>
#include <QLabel>
#include "vproperty.h"
namespace VPE {
class VPropertyFormWidgetPrivate;
class VPropertySet;
//! Class that displays the sub properties of a property using a form layout
class VPROPERTYEXPLORERSHARED_EXPORT VPropertyFormWidget : public QGroupBox
{
Q_OBJECT
public:
//! Constructor
VPropertyFormWidget(const QString& title, const QString& description, const QList<VProperty*>& properties, QWidget* parent);
//! Constructor
VPropertyFormWidget(VProperty* parent_property, QWidget* parent);
//! Destructor
~VPropertyFormWidget();
//! Returns a list of all child property form widgets (note that indirect children will not be in the list)
QList<VPropertyFormWidget*> getChildPropertyFormWidgets() const;
public slots:
//! Rebuilds the whole form
virtual void build();
//! Reads the data from the editors and commits it to the properties
void commitData();
//! Refills the editors with the propertie's data
void loadData();
//! Reads the data from row'th editor and commits it to the property
void commitData(int row);
//! Reads the data from row'th property
void loadData(int row);
//! Sets the update behaviour
//! \param auto_commit If set to true, whenever an event like focusOut is triggered on an editor, the data will be submitted to the property.
void setCommitBehaviour(bool auto_commit = true);
signals:
//! Emitted whenever a property data changes
void propertyDataSubmitted(VProperty* property);
protected:
//! Protected Constructor
VPropertyFormWidget(VPropertyFormWidgetPrivate* d_pointer, QWidget* parent, const QString &title = QString(),
const QString &description = QString());
//! The protected data
VPropertyFormWidgetPrivate* d_ptr;
//! Event filter for the editor widgets
bool eventFilter(QObject *object, QEvent *event);
//! Commits data of an editor
void commitData(QWidget* editor);
};
} // Namespace VPE
#endif // VPROPERTYFORMWIDGET_H

View File

@ -0,0 +1,44 @@
#ifndef VPROPERTYFORMWIDGET_P_H
#define VPROPERTYFORMWIDGET_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include <QList>
#include "vproperty.h"
namespace VPE {
class VPropertyFormWidgetPrivate {
public:
//! Stores either another VPropertyFormWidget (then Editor is null) or an editor widget (then FormWidget is null)
struct SEditorWidget {
SEditorWidget() : FormWidget(nullptr), Editor(nullptr) {}
SEditorWidget(VPropertyFormWidget* form_widget) : FormWidget(form_widget), Editor(nullptr) {}
SEditorWidget(QWidget* editor_widget) : FormWidget(nullptr), Editor(editor_widget) {}
VPropertyFormWidget* FormWidget;
QWidget* Editor;
};
//! The root property to use
QList<VProperty*> Properties;
//! Binds the properties to their editors
QList<SEditorWidget> EditorWidgets;
//! Determines the behaviour of the editors. If this is true, when a focus out event etc. happens, the data will be submitted to the VProperty. If false, you will have to call commitData() yourself.
bool UpdateEditors;
//! Default constructor
VPropertyFormWidgetPrivate()
: UpdateEditors(true)
{}
//! Constructor
VPropertyFormWidgetPrivate(const QList<VProperty*>& properties)
: Properties(properties), UpdateEditors(true) {}
};
}
#endif // VPROPERTYFORMWIDGET_P_H

View File

@ -0,0 +1,290 @@
#include "vpropertymodel.h"
#include <QBrush>
#include "vpropertyset.h"
using namespace VPE;
#include "vpropertymodel_p.h"
VPropertyModel::VPropertyModel(VPropertyModelPrivate *d, QObject *parent)
: QAbstractItemModel(parent), d_ptr(d)
{
}
VPropertyModel::VPropertyModel(QObject * parent) :
QAbstractItemModel(parent), d_ptr(new VPropertyModelPrivate())
{
}
VPropertyModel::~VPropertyModel()
{
if(d_ptr->Properties)
delete d_ptr->Properties;
delete d_ptr;
}
//! Adds the property to the model and attaches it to the parentid
bool VPropertyModel::addProperty(VProperty* property, const QString& id, const QString &parentid, bool emitsignals)
{
if(!property)
return false;
if(!d_ptr->Properties) // If not existant, create property set
d_ptr->Properties = new VPropertySet();
if(emitsignals) {
VProperty* tmpParent = getProperty(parentid);
int tmpRow = tmpParent != nullptr ? tmpParent->getRowCount() : d_ptr->Properties->getRootPropertyCount();
beginInsertRows((tmpParent != nullptr ? getIndexFromProperty(tmpParent) : QModelIndex()), tmpRow, tmpRow);
}
d_ptr->Properties->addProperty(property, id, parentid);
if(emitsignals)
endInsertRows();
return true;
}
//! Creates a property and adds it to the model
VProperty* VPropertyModel::createProperty(const QString& id, const QString& name, const QString& parentid, const QVariant& data)
{
VProperty* tmpProp = new VProperty(name);
tmpProp->setValue(data);
if(tmpProp && addProperty(tmpProp, id, parentid))
return tmpProp;
else
return nullptr;
}
//! Gets a property by it's ID
VProperty* VPropertyModel::getProperty(const QString& id)
{
return d_ptr->Properties != nullptr ? d_ptr->Properties->getProperty(id) : nullptr;
}
//! Returns the model index at row/column
QModelIndex VPropertyModel::index(int row, int column, const QModelIndex& parent) const
{
if (d_ptr->Properties == nullptr || (parent.isValid() && parent.column() > 1))
return QModelIndex();
if(parent.isValid()) {
// Get the parent index
VProperty* parentItem = getProperty(parent);
if(parentItem) {
VProperty* childItem = parentItem->getChild(row);
if (childItem)
return createIndex(row, column, childItem);
}
} else if(row >= 0 && row < d_ptr->Properties->count()) {
return createIndex(row, column, d_ptr->Properties->getRootProperty(row));
}
return QModelIndex();
}
//! Returns the parent of one model index
QModelIndex VPropertyModel::parent ( const QModelIndex & index ) const
{
if (!index.isValid())
return QModelIndex();
VProperty* childItem = getProperty(index);
if(childItem) {
VProperty* parentItem = childItem->getParent();
if(parentItem) {
VProperty* grandParentItem = parentItem->getParent();
int parents_row = grandParentItem != nullptr ? grandParentItem->getChildRow(parentItem) : d_ptr->Properties->getRootProperties().indexOf(parentItem);
if(parents_row >= 0)
return createIndex(parents_row, 0, parentItem);
}
}
return QModelIndex();
}
//! Returns the item flags for the given index
Qt::ItemFlags VPropertyModel::flags (const QModelIndex& index) const
{
VProperty* tmpProperty = getProperty(index);
if(!tmpProperty)
return Qt::NoItemFlags;
else
return tmpProperty->flags(index.column());
}
//! Sets the role data for the item at index to value
bool VPropertyModel::setData (const QModelIndex& index, const QVariant& value, int role)
{
VProperty* tmpProperty = getProperty(index);
if(index.column() == 1 && tmpProperty) {
bool tmpHasChanged = tmpProperty->setData(value, role);
if(tmpProperty->getUpdateParent() && tmpHasChanged) { // If neccessary, update the parent as well
QModelIndex tmpParentIndex = parent(index);
emit dataChanged(tmpParentIndex, tmpParentIndex);
}
if(tmpHasChanged)
emit onDataChangedByEditor(tmpProperty);
}
return true;
}
//! Returns the data of an model index
QVariant VPropertyModel::data ( const QModelIndex & index, int role ) const
{
VProperty* tmpProperty = getProperty(index);
if(!tmpProperty)
return QVariant();
else
return tmpProperty->data(index.column(), role);
}
QVariant VPropertyModel::headerData (int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal && role == Qt::DisplayRole) {
// Header data
if (section == 0) return d_ptr->HeadlineProperty;
else if (section == 1) return d_ptr->HeadlineValue;
}
else if(role == Qt::DisplayRole)
return QVariant(section);
return QVariant();
}
//! Returns the number of rows
int VPropertyModel::rowCount ( const QModelIndex & parent ) const
{
if(parent.isValid()) {
VProperty* tmpParent = getProperty(parent);
if(tmpParent)
return tmpParent->getRowCount();
}
// Return the root property count
if(d_ptr->Properties)
return d_ptr->Properties->getRootPropertyCount();
return 0;
}
//! Returns the number of columns
int VPropertyModel::columnCount ( const QModelIndex & parent) const
{
Q_UNUSED(parent);
return 2;
}
//! Gets a property by its ModelIndex
VProperty* VPropertyModel::getProperty(const QModelIndex &index) const
{
if (index.isValid()) {
VProperty* prop = static_cast<VProperty*>(index.internalPointer());
if (prop)
return prop;
}
return nullptr;
}
QString VPropertyModel::getPropertyID(VProperty *prop) const
{
return d_ptr->Properties != nullptr ? d_ptr->Properties->getPropertyID(prop) : QString();
}
QModelIndex VPropertyModel::getIndexFromProperty(VProperty* property, int column) const
{
if (!property || column > columnCount() || column < 0)
return QModelIndex();
VProperty* parentItem = property->getParent();
int row = 0;
if(parentItem) {
row = parentItem->getChildRow(property);
}
return createIndex(row, column, property);
}
void VPropertyModel::onDataChangedByModel(VProperty* property)
{
QModelIndex tmpIndex = getIndexFromProperty(property, 1);
if(tmpIndex.isValid())
{
emit dataChanged(tmpIndex, tmpIndex);
}
}
void VPropertyModel::showDataChangedByEditor(VProperty *property)
{
emit onDataChangedByEditor(property);
}
const VPropertySet *VPropertyModel::getPropertySet() const
{
return d_ptr->Properties;
}
void VPropertyModel::clear(bool emit_signals)
{
setPropertySet(nullptr, emit_signals);
}
VPropertySet *VPropertyModel::takePropertySet(VPropertySet *new_property_set, bool emit_signals)
{
VPropertySet* tmpOldPropertySet = d_ptr->Properties;
if(emit_signals) emit beginResetModel();
d_ptr->Properties = new_property_set;
if(emit_signals) emit endResetModel();
return tmpOldPropertySet;
}
void VPropertyModel::setPropertySet(VPropertySet *property_set, bool emit_signals)
{
VPropertySet* tmpOldPropertySet = takePropertySet(property_set, emit_signals);
if(tmpOldPropertySet)
delete tmpOldPropertySet;
}
VProperty *VPropertyModel::takeProperty(const QString &id)
{
QModelIndex tmpIndex = getIndexFromProperty(getProperty(id));
if(d_ptr->Properties && tmpIndex.isValid()) {
beginRemoveRows(tmpIndex.parent(), tmpIndex.row(), tmpIndex.row());
VProperty* tmpProp = d_ptr->Properties->takeProperty(id);
endRemoveRows();
return tmpProp;
}
return nullptr;
}
void VPropertyModel::removeProperty(const QString &id)
{
QModelIndex tmpIndex = getIndexFromProperty(getProperty(id));
if(d_ptr->Properties && tmpIndex.isValid()) {
beginRemoveRows(tmpIndex.parent(), tmpIndex.row(), tmpIndex.row());
d_ptr->Properties->removeProperty(id);
endRemoveRows();
}
}

View File

@ -0,0 +1,142 @@
#ifndef VPROPERTYMODEL_H
#define VPROPERTYMODEL_H
#include "vpropertyexplorer_global.h"
#include <QAbstractItemModel>
#include <QMap>
#include <QString>
#include "vproperty.h"
namespace VPE {
class VPropertyModelPrivate;
class VPropertySet;
//! \brief This is the base model for managing all the properties
//! and passing them to the view.
//!
//! When you create your own "proxy models", this is the place to
//! start: just subclass VPropertyModel and extend the new class.
//! Have a look at existing examples of proxies.
//!
//! <strong>Note that in this context, the term "proxy model" does not refer
//! to VProxyModel as that is another concept.</strong>
//! The idea behind "proxy models" in the QtPropertyExplorer framework
//! is to provide an convenient interface which takes data as your
//! application (or a third-party-library) provides it, and converts this
//! data to VProperty-objects, manage them and produce output for the views.
//!
//! In most cases, you will not need to rewrite the basic functions of
//! QAbstractItemModel, as VPropertyModel provides standard implementations
//! to work with. Thus, instead of subclassing VPropertyModel, it is also
//! possible to use VPropertyModel directly (as it is not an abstract class).
//! This might be more convenient in some cases.
class VPROPERTYEXPLORERSHARED_EXPORT VPropertyModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit VPropertyModel(QObject * parent = 0);
virtual ~VPropertyModel();
//! Adds the property to the model and attaches it to the parentid
//! \param emitsignals If this is set to false, this function will not call beginInsertRows() and endInsertRows(), so it has to be called from a subclass
virtual bool addProperty(VProperty* property, const QString& id, const QString& parentid = QString(),
bool emitsignals = true);
//! Creates a property and adds it to the model
virtual VProperty* createProperty(const QString& id, const QString& name, const QString& parentid = QString(),
const QVariant& data = QVariant());
//! Gets a property by it's ID
virtual VProperty* getProperty(const QString& id);
//! Returns the item flags for the given index
virtual Qt::ItemFlags flags (const QModelIndex& index) const;
//! Sets the role data for the item at index to value
virtual bool setData (const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
//! Returns the model index at row/column
virtual QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex() ) const;
//! Returns the parent of one model index
virtual QModelIndex parent (const QModelIndex& index) const;
//! Returns the data of an model index
virtual QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const;
//! Returns the data for the given role and section in the header with the specified orientation.
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
//! Returns the number of rows
virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
//! Returns the number of columns
virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
//! Gets a property by its ModelIndex
//! \param index The modelIndex of the property.
//! \return Returns the property with the given index, or NULL if none such property exists
virtual VProperty* getProperty(const QModelIndex &index) const;
//! Returns the ID of the property within the model
//! The concept of property IDs is, that the object that manages the properties
//! and not the properties themselves handle the IDs.
//! \param property
//! \return Returns the ID under which the property is stored within the model
virtual QString getPropertyID(VProperty* prop) const;
//! Returns a const pointer to the property set managed by this model. If you want to manipulate the property set, either use the methods provided by the model or use takePropertySet() and setPropertySet().
//! \return A constant pointer to the property set or NULL if there currently is none.
virtual const VPropertySet* getPropertySet() const;
//! Clears the model, deletes the property set managed by this model.
//! \param emit_signals Default: true. Set this to false if you want to prevent the model from emmiting the reset model signals
virtual void clear(bool emit_signals = true);
//! Removes the current property set and returns it. If new_property_set is set, the old one will be replaced by the new one
//! \param new_property_set The new property set to replace the old one with. Default: NULL
//! \param emit_signals Default: true. Set this to false if you want to prevent the model from emmiting the reset model signals
//! \return A constant pointer to the property set or NULL if there currently is none.
virtual VPropertySet* takePropertySet(VPropertySet* new_property_set = nullptr, bool emit_signals = true);
//! Sets a new property set. The model will take ownership of the property set. The old property set will be deleted.
//! \param property_set The new property set. Setting this to NULL has the same effect as calling clear.
//! \param emit_signals Default: true. Set this to false if you want to prevent the model from emmiting the reset model signals
//! \return A constant pointer to the property set or NULL if there currently is none.
virtual void setPropertySet(VPropertySet* property_set, bool emit_signals = true);
//! Removes a property from the model and returns it
virtual VProperty* takeProperty(const QString& id);
//! Removes a property from the model and deletes it
virtual void removeProperty(const QString& id);
signals:
//! This signal is being emitted, when the setData method is being called
void onDataChangedByEditor(VProperty* property);
public slots:
//! This function causes the views to update the property
void onDataChangedByModel(VProperty* property);
void showDataChangedByEditor(VProperty* property);
protected:
//! Gets a property by its ModelIndex
virtual QModelIndex getIndexFromProperty(VProperty* property, int column = 0) const;
//! Protected constructor passing the private object
VPropertyModel(VPropertyModelPrivate* d, QObject* parent = 0);
//! The model data
VPropertyModelPrivate* d_ptr;
};
}
#endif // VPROPERTYMODEL_H

View File

@ -0,0 +1,40 @@
#ifndef VPROPERTYMODEL_P_H
#define VPROPERTYMODEL_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include <QMap>
#include <QString>
#include <QObject>
namespace VPE {
class VProperty;
class VPropertySet;
class VPropertyModelPrivate {
public:
//! The property set holding the properties
VPropertySet* Properties;
//! The header data for the property name column
QString HeadlineProperty;
//! The header data for the value column
QString HeadlineValue;
//! Constructor
VPropertyModelPrivate()
: Properties(nullptr)
{
//: The text that appears in the first column header
HeadlineProperty = QObject::tr("Property");
//: The text that appears in the second column header
HeadlineValue = QObject::tr("Value");
}
};
}
#endif // VPROPERTYMODEL_P_H

View File

@ -0,0 +1,211 @@
#include "vpropertyset.h"
using namespace VPE;
#include "vpropertyset_p.h"
VPropertySet::VPropertySet()
: d_ptr(new VPropertySetPrivate())
{
}
VPropertySet::~VPropertySet()
{
// Delete all the properties
clear(true);
delete d_ptr;
}
bool VPropertySet::addProperty(VProperty *property, const QString &id, const QString &parentid)
{
// Check if the property to add is not a null pointer
if(!property)
return false;
VProperty* tmpParent = parentid.isEmpty() ? NULL : getProperty(parentid);
return addProperty(property, id, tmpParent);
}
bool VPropertySet::addProperty(VProperty *property, const QString &id, VProperty *parent_property)
{
// Check if the property to add is not a null pointer
if(!property)
return false;
QString tmpOldID = getPropertyID(property);
if(!tmpOldID.isEmpty())
d_ptr->Properties.remove(tmpOldID);
if(parent_property)
parent_property->addChild(property);
else {
d_ptr->RootProperties.append(property);
if(property->getParent())
property->getParent()->removeChild(property);
}
if(!id.isEmpty())
d_ptr->Properties.insert(id, property);
return true;
}
bool VPropertySet::hasProperty(VProperty *property) const
{
if(!property)
return false;
return hasProperty(property, NULL);
}
VProperty *VPropertySet::getProperty(const QString &id) const
{
return d_ptr->Properties.value(id, NULL);
}
VProperty *VPropertySet::takeProperty(const QString &id)
{
VProperty* tmpProp = getProperty(id);
removeProperty(tmpProp, false);
// Return the property
return tmpProp;
}
void VPropertySet::removeProperty(const QString &id)
{
VProperty* tmpProp = takeProperty(id);
if(tmpProp)
delete tmpProp;
}
void VPropertySet::removeProperty(VProperty* prop, bool delete_property)
{
// Remove all the children
removePropertyFromSet(prop);
// Remove from parent and optionally delete
if(prop) {
prop->setParent(NULL);
if(delete_property)
delete prop;
}
}
int VPropertySet::count() const
{
return d_ptr->Properties.count();
}
void VPropertySet::clear(bool delete_properties)
{
d_ptr->Properties.clear();
while(!d_ptr->RootProperties.isEmpty()) {
VProperty* tmpProp = d_ptr->RootProperties.takeLast();
if(tmpProp != NULL && delete_properties) {
delete tmpProp;
}
}
}
QString VPropertySet::getPropertyID(const VProperty *prop, bool look_for_parent_id) const
{
QString tmpResult;
const VProperty* tmpCurrentProp = prop;
while(tmpCurrentProp && (look_for_parent_id || prop == tmpCurrentProp) && tmpResult.isEmpty()) {
// todo: The following code doesn't work, because .key() doesn't accept a const VProperty* pointer ...
//tmpResult = d_ptr->Properties.key(tmpCurrentProp, QString());
// ... which is why we need the code below
for (QMap<QString, VProperty*>::const_iterator i = d_ptr->Properties.constBegin(); i != d_ptr->Properties.constEnd(); ++i) {
if(tmpCurrentProp == (*i))
return i.key();
}
tmpCurrentProp = tmpCurrentProp->getParent();
}
return tmpResult;
}
const QMap<QString, VProperty *> &VPropertySet::getPropertiesMap() const
{
return d_ptr->Properties;
}
const QList<VProperty *> &VPropertySet::getRootProperties() const
{
return d_ptr->RootProperties;
}
VProperty *VPropertySet::getRootProperty(int row) const
{
return d_ptr->RootProperties.value(row, NULL);
}
int VPropertySet::getRootPropertyCount() const
{
return d_ptr->RootProperties.count();
}
VPropertySet* VPropertySet::clone() const
{
VPropertySet* tmpResult = new VPropertySet();
foreach(VProperty* tmpProperty, d_ptr->RootProperties)
cloneProperty(tmpProperty, NULL, tmpResult);
return tmpResult;
}
bool VPropertySet::hasProperty(VProperty *property, VProperty *parent) const
{
if(!property)
return false;
const QList<VProperty*>& tmpChildrenList = (parent != NULL ? parent->getChildren() : d_ptr->RootProperties);
foreach(VProperty* tmpProp, tmpChildrenList) {
if(!tmpProp)
continue;
else if(tmpProp == property || hasProperty(property, tmpProp))
return true;
}
return false;
}
void VPropertySet::cloneProperty(VProperty* property_to_clone, VProperty *parent_property, VPropertySet *output_set) const
{
if(!output_set || !property_to_clone || !hasProperty(property_to_clone))
return;
QString tmpID = getPropertyID(property_to_clone, false);
VProperty* tmpNewProperty = property_to_clone->clone(false); // We want to clone the children ourselves (because of the IDs)
output_set->addProperty(tmpNewProperty, tmpID, parent_property);
for(int i = 0; i < property_to_clone->getRowCount(); ++i)
cloneProperty(property_to_clone->getChild(i), tmpNewProperty, output_set);
}
void VPropertySet::removePropertyFromSet(VProperty *prop)
{
// Remove all the children
foreach(VProperty* tmpChild, prop->getChildren())
removeProperty(tmpChild);
QList<QString> tmpKeys = d_ptr->Properties.keys(prop);
foreach(const QString& tmpID, tmpKeys)
d_ptr->Properties.remove(tmpID);
// Remove from list
d_ptr->RootProperties.removeAll(prop);
}

View File

@ -0,0 +1,111 @@
#ifndef VPROPERTYSET_H
#define VPROPERTYSET_H
#include "vpropertyexplorer_global.h"
#include <QMap>
#include <QString>
#include "vproperty.h"
namespace VPE {
// Forward declaration
class VPropertySetPrivate;
// todo: better description
//! \brief VPropertySet is a simple class for managing a set of properties.
//! If you don't need all the Model-functionality, chose this class
//! over VPropertyModel.
//!
//!
class VPROPERTYEXPLORERSHARED_EXPORT VPropertySet
{
public:
//! Default constructor, creating an empty property set
explicit VPropertySet();
//! Destructor
virtual ~VPropertySet();
//! Adds the property to the model and attaches it to the parentid. Note that if the property has a parent which is not part of this set, it will be removed from that parent.
//! \param property The property to add
//! \param id The property ID. If id is empty, the property will not be accessable by it's id but still be added. If the property was filed under another ID before, that will no longer be valid.
//! \param parentid The property's ID to which to add the property as child. Pass empty string to add it to the root properties.
virtual bool addProperty(VProperty* property, const QString& id, const QString& parentid);
//! Adds the property to the model and attaches it to the parent property.
//! \param property The property to add
//! \param id The property ID. If id is empty, the property will not be accessable by it's id but still be added. If the property was filed under another ID before, that will no longer be valid.
//! \param parentid The property to which to add the property as child. Pass NULL to add it to the root properties.
virtual bool addProperty(VProperty* property, const QString& id, VProperty* parent_property = nullptr);
//! Checks whether a property belongs to this set and returns the result
//! \param property The property to check for
//! \return True, if the property is part of this set, false otherwise
virtual bool hasProperty(VProperty* property) const;
//! Gets a property by it's ID
virtual VProperty* getProperty(const QString& id) const;
//! Removes a property from the set and returns it
virtual VProperty* takeProperty(const QString& id);
//! Removes a property from the set and deletes it
virtual void removeProperty(const QString& id);
//! Removes a property from the set and deletes it optionally
virtual void removeProperty(VProperty* prop, bool delete_property = true);
//! Returns the number of properties with in ID that are directly accessable by getProperty()
virtual int count() const;
//! Clears the set and (optionally) deletes all properties
//! \param delete_properties Set this to false, if you don't want the properties to get deleted.
virtual void clear(bool delete_properties = true);
//! Returns the ID of the property within the set
//! The concept of property IDs is, that the object that manages the properties
//! and not the properties themselves handle the IDs.
//! \param prop The property of which to get the ID.
//! \param look_for_parent_id If this is TRUE and the property has no ID, all the parent properties are checked.
//! \return Returns the ID under which the property is stored within the set
virtual QString getPropertyID(const VProperty* prop, bool look_for_parent_id = true) const;
//! Returns a const reference to the map of properties
const QMap<QString, VProperty*>& getPropertiesMap() const;
//! Returns a const reference to the list of root properties
const QList<VProperty*>& getRootProperties() const;
//! Returns the root property in a certain row
//! \param row The root row in which to look for the root property
VProperty* getRootProperty(int row) const;
//! Returns the number of independent properties
int getRootPropertyCount() const;
//! Clones the property set
VPropertySet* clone() const;
protected:
//! Checks whether a property belongs to this set and returns the result
//! \param property The property to check for
//! \param parent The parent property from which to start checking all the children
//! \return True, if the property is part of this set, false otherwise
virtual bool hasProperty(VProperty* property, VProperty* parent) const;
//! Clones a property into another property set
void cloneProperty(VProperty* property_to_clone, VProperty* parent_property, VPropertySet* output_set) const;
//! Recursivly removes a property's child properties from the set, but not from the parent
virtual void removePropertyFromSet(VProperty* prop);
//! The data
VPropertySetPrivate* d_ptr;
};
}
#endif // VPROPERTYMODEL_H

View File

@ -0,0 +1,29 @@
#ifndef VPROPERTYSET_P_H
#define VPROPERTYSET_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include <QMap>
#include <QString>
namespace VPE {
class VProperty;
class VPropertySetPrivate {
public:
//! Property map (ID, Property)
QMap<QString, VProperty*> Properties; // All the Properties managed by this model are being stored in this map for quick access
//! List containing the root properties
QList<VProperty*> RootProperties;
//! Constructor
VPropertySetPrivate()
{
}
};
}
#endif // VPROPERTYMODEL_P_H

View File

@ -0,0 +1,57 @@
#include "vpropertytreeview.h"
#include "vpropertydelegate.h"
#include "vpropertymodel.h"
#include "vpropertytreeview_p.h"
using namespace VPE;
VPropertyTreeView::VPropertyTreeView(QWidget *parent)
: QTreeView(parent), d_ptr(new VPropertyTreeViewPrivate())
{
init();
}
VPropertyTreeView::VPropertyTreeView(VPropertyModel *model, QWidget *parent)
: QTreeView(parent), d_ptr(new VPropertyTreeViewPrivate())
{
init();
if(model)
setModel(model);
}
VPropertyTreeView::VPropertyTreeView(VPropertyTreeViewPrivate *d, bool init_, QWidget *parent)
: QTreeView(parent), d_ptr(d)
{
if(init_)
init();
}
VPropertyTreeView::~VPropertyTreeView()
{
delete d_ptr;
}
void VPropertyTreeView::setRowHeight(int height, bool add_to_standard)
{
d_ptr->PropertyDelegate->setRowHeight(height, add_to_standard);
}
void VPropertyTreeView::init()
{
setAlternatingRowColors(true);
setUniformRowHeights(true);
d_ptr->PropertyDelegate = new VPropertyDelegate(this);
setItemDelegate(d_ptr->PropertyDelegate);
setSelectionMode(QTreeView::SingleSelection);
setSelectionBehavior(QTreeView::SelectRows);
setRootIsDecorated(true);
setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);
}

View File

@ -0,0 +1,45 @@
#ifndef VPROPERTYTREEVIEW_H
#define VPROPERTYTREEVIEW_H
#include <QTreeView>
#include "vpropertyexplorer_global.h"
namespace VPE {
class VPropertyTreeViewPrivate;
class VPROPERTYEXPLORERSHARED_EXPORT VPropertyDelegate;
class VPROPERTYEXPLORERSHARED_EXPORT VPropertyModel;
class VPROPERTYEXPLORERSHARED_EXPORT VPropertyTreeView : public QTreeView
{
Q_OBJECT
public:
//! Default constructor
explicit VPropertyTreeView(QWidget *parent = 0);
//! The destructor, taking a model and setting it to the tree view
//! \param The model to set as model for this tree view
VPropertyTreeView(VPropertyModel* model, QWidget *parent = 0);
//! Destructor
virtual ~VPropertyTreeView();
//! Sets the height for each row. Set this to 0 in order to let the standard delegate decide
void setRowHeight(int height = 0, bool add_to_standard = false);
protected:
//! This method is called by the constructors to initialize the view
virtual void init();
//! protected constructor
explicit VPropertyTreeView(VPropertyTreeViewPrivate* d, bool init_, QWidget *parent = 0);
//! The protected data
VPropertyTreeViewPrivate* d_ptr;
};
}
#endif // VPROPERTYTREEVIEWEEVIEW_H

View File

@ -0,0 +1,30 @@
#ifndef VPROPERTYTREEVIEW_P_H
#define VPROPERTYTREEVIEW_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include <QMap>
#include <QString>
namespace VPE {
class VPropertyDelegate;
class VPropertyTreeViewPrivate
{
public:
//! Property Delegate
VPropertyDelegate* PropertyDelegate;
//! Constructor
VPropertyTreeViewPrivate(VPropertyDelegate* delegate)
: PropertyDelegate(delegate) {}
//! Constructor
VPropertyTreeViewPrivate()
: PropertyDelegate(nullptr) {}
};
}
#endif // VPROPERTYTREEVIEW_P_H

View File

@ -0,0 +1,49 @@
#include "vserializedproperty.h"
using namespace VPE;
VSerializedProperty::VSerializedProperty()
: ID(), Type(), Value()
{
}
/*! Creates a new VSerializedProperty from an existing property
*/
VSerializedProperty::VSerializedProperty(const VProperty* property, const VPropertySet* set)
: ID(), Type(property ? property->type() : QString()), Value(property ? property->getValue() : QVariant())
{
if(set) {
ID = set->getPropertyID(property);
initChildren(property, set);
}
}
VSerializedProperty::VSerializedProperty(const VProperty *property, const QString &id, const VPropertySet *set)
: ID(id), Type(property ? property->type() : QString()), Value(property ? property->getValue() : QVariant())
{
initChildren(property, set);
}
VSerializedProperty::VSerializedProperty(const QString &id, const QString &type, const QVariant &value)
: ID(id), Type(type), Value(value)
{
}
VPE::VSerializedProperty::~VSerializedProperty()
{
//
}
void VSerializedProperty::initChildren(const VProperty *property, const VPropertySet *set)
{
if(property && set) {
const QList<VProperty*>& tmpChildren = property->getChildren();
foreach(const VProperty* tmpChild, tmpChildren) {
QString tmpChildID = set->getPropertyID(property);
Children.append(VSerializedProperty(tmpChild, tmpChildID, set));
}
}
}

View File

@ -0,0 +1,52 @@
#ifndef VSERIALIZEDPROPERTY_H
#define VSERIALIZEDPROPERTY_H
#include "vpropertyexplorer_global.h"
#include <QString>
#include <QList>
#include <QVariant>
#include "vproperty.h"
#include "vpropertyset.h"
namespace VPE {
class VPROPERTYEXPLORERSHARED_EXPORT VSerializedProperty
{
public:
//! Constructor
VSerializedProperty();
//! Constructor
VSerializedProperty(const VProperty* property, const VPropertySet* set);
//! Constructor
VSerializedProperty(const VProperty* property, const QString& id, const VPropertySet* set);
//! Constructor
VSerializedProperty(const QString& id, const QString& type, const QVariant& value);
//! Destructor
~VSerializedProperty();
//! The property type
QString ID;
//! The property type
QString Type;
//! The serialized value of the property
QVariant Value;
//! List of child properties
QList<VSerializedProperty> Children;
private:
void initChildren(const VProperty* property, const VPropertySet* set);
};
}
#endif // VSERIALIZEDPROPERTY_H

View File

@ -0,0 +1,66 @@
#include "vstandardpropertyfactory.h"
#include "vpropertyfactorymanager.h"
// Supported Properties
#include "vproperty.h"
#include "plugins/vboolproperty.h"
#include "plugins/vcolorproperty.h"
#include "plugins/vemptyproperty.h"
#include "plugins/venumproperty.h"
#include "plugins/vfileproperty.h"
#include "plugins/vnumberproperty.h"
#include "plugins/vshortcutproperty.h"
#include "plugins/Vector3d/vvector3dproperty.h"
using namespace VPE;
VStandardPropertyFactory::VStandardPropertyFactory()
: VAbstractPropertyFactory()
{
}
VStandardPropertyFactory::VStandardPropertyFactory(VPropertyFactoryManager *manager)
: VAbstractPropertyFactory()
{
if(manager) {
manager->registerFactory("string", this);
manager->registerFactory("bool", this);
manager->registerFactory("color", this);
manager->registerFactory("empty", this);
manager->registerFactory("enum", this);
manager->registerFactory("file", this);
manager->registerFactory("integer", this);
manager->registerFactory("double", this);
manager->registerFactory("shortcut", this);
manager->registerFactory("vector3d", this);
}
}
VProperty *VStandardPropertyFactory::createProperty(const QString &type, const QString &name)
{
if(type == QString("string")) {
return new VProperty(name);
} else if(type == QString("bool")) {
return new VBoolProperty(name);
} else if(type == QString("color")) {
return new QColorProperty(name);
} else if(type == QString("empty")) {
return new VEmptyProperty(name);
} else if(type == QString("enum")) {
return new VEnumProperty(name);
} else if(type == QString("file")) {
return new VFileProperty(name);
} else if(type == QString("integer")) {
return new VIntegerProperty(name);
} else if(type == QString("double")) {
return new VDoubleProperty(name);
} else if(type == QString("shortcut")) {
return new VShortcutProperty(name);
} else if(type == QString("vector3d")) {
return new QVector3DProperty(name);
}
else
return nullptr;
}

View File

@ -0,0 +1,33 @@
#ifndef VASTANDARDPROPERTYFACTORY_H
#define VASTANDARDPROPERTYFACTORY_H
#include "vpropertyexplorer_global.h"
#include "vabstractpropertyfactory.h"
namespace VPE {
class VProperty;
class VPropertyFactoryManager;
//! The standard property factory is able to create all the properties that are included in QtPropertyExplorer
//! by default.
class VPROPERTYEXPLORERSHARED_EXPORT VStandardPropertyFactory : public VAbstractPropertyFactory
{
public:
//! Constructor
VStandardPropertyFactory();
//! Constructor
//! \param manager Registers this factory at the manager for all it's types
VStandardPropertyFactory(VPropertyFactoryManager* manager);
//! Creates a new property of a certain type and assigns a name and description (otionally)
//! \param type The type of the property as string
//! \return Returns the created property or NULL if it couldn't be be created
virtual VProperty* createProperty(const QString& type, const QString &name);
};
}
#endif // VASTANDARDPROPERTYFACTORY_H

View File

@ -0,0 +1,35 @@
#ifndef VWIDGETPROPERTY_P_H
#define VWIDGETPROPERTY_P_H
// ONLY INCLUDE THIS IN .CPP FILES
#include "vproperty_p.h"
#include <QPointer>
#include <QWidget>
namespace VPE {
class VWidgetPropertyPrivate : public VPropertyPrivate {
public:
//! The widget to show
QPointer<QWidget> Widget;
//! Constructor passing name and type
VWidgetPropertyPrivate(const QString& name, QVariant::Type type, QWidget* widget = nullptr)
: VPropertyPrivate(name, type), Widget(widget) {}
//! Constructor
VWidgetPropertyPrivate()
: VPropertyPrivate(), Widget(nullptr) {}
//! Destructor
~VWidgetPropertyPrivate() {
if(Widget)
Widget->deleteLater();
}
};
}
#endif // VWIDGETPROPERTY_P_H