├── CBaseProperty.cpp ├── CBaseProperty.h ├── CBoolProperty.cpp ├── CBoolProperty.h ├── CButtonBasedEditor.cpp ├── CButtonBasedEditor.h ├── CColorProperty.cpp ├── CColorProperty.h ├── CDateProperty.cpp ├── CDateProperty.h ├── CDateTimeProperty.cpp ├── CDateTimeProperty.h ├── CDoubleProperty.cpp ├── CDoubleProperty.h ├── CFontProperty.cpp ├── CFontProperty.h ├── CIntegerProperty.cpp ├── CIntegerProperty.h ├── CListProperty.cpp ├── CListProperty.h ├── CPropertyEditor.cpp ├── CPropertyEditor.h ├── CPropertyHeader.cpp ├── CPropertyHeader.h ├── CStringProperty.cpp ├── CStringProperty.h ├── CTimeProperty.cpp ├── CTimeProperty.h ├── Icons ├── file-open.png ├── info.png └── remove.png ├── PropertyEditor.pro ├── QColorComboBox.cpp ├── QColorComboBox.h ├── README.md ├── main.cpp ├── screenshot.png ├── testwidget.cpp ├── testwidget.h ├── testwidget.qrc └── testwidget.ui /CBaseProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CBaseProperty.h" 2 | 3 | 4 | CBaseProperty::CBaseProperty(const QByteArray &id, const QString &name): 5 | QTreeWidgetItem(), 6 | m_id(id), 7 | m_name(name), 8 | m_isMarkable(false), 9 | m_editorIsPrivate(false) 10 | { 11 | setText(0, m_name); 12 | } 13 | 14 | 15 | CBaseProperty::CBaseProperty(CBaseProperty *top, const QByteArray &id, const QString &name): 16 | QTreeWidgetItem(top), 17 | m_id(id), 18 | m_name(name), 19 | m_isMarkable(false), 20 | m_editorIsPrivate(false) 21 | { 22 | setText(0, m_name); 23 | } 24 | 25 | 26 | void CBaseProperty::setMarked(bool on) 27 | { 28 | m_isMarkable = true; 29 | 30 | setCheckState(0, on ? Qt::Checked : Qt::Unchecked); 31 | } 32 | 33 | 34 | bool CBaseProperty::isMarked() const 35 | { 36 | return (checkState(0) == Qt::Checked); 37 | } 38 | 39 | 40 | bool CBaseProperty::isMarkable() const 41 | { 42 | return m_isMarkable; 43 | } 44 | 45 | 46 | void CBaseProperty::setBackground(const QBrush &bg) 47 | { 48 | QTreeWidgetItem::setBackground(0, bg); 49 | QTreeWidgetItem::setBackground(1, bg); 50 | } 51 | 52 | 53 | void CBaseProperty::setTextColor(const QColor &color) 54 | { 55 | QTreeWidgetItem::setTextColor(0, color); 56 | QTreeWidgetItem::setTextColor(1, color); 57 | } 58 | 59 | 60 | void CBaseProperty::setValue() 61 | { 62 | validateValue(); 63 | 64 | displayValue(); 65 | 66 | valueToEditor(); 67 | } 68 | 69 | 70 | void CBaseProperty::startEdit() 71 | { 72 | QWidget* editWidget = getActiveEditor(); 73 | 74 | // create if needed 75 | if (editWidget == NULL) 76 | { 77 | editWidget = createEditor(); 78 | } 79 | 80 | if (editWidget == NULL) 81 | return; 82 | 83 | // show it 84 | if (!m_editorIsPrivate || (getActiveEditor() == NULL)) 85 | { 86 | treeWidget()->setItemWidget(this, 1, editWidget); 87 | } 88 | 89 | if (m_editorIsPrivate) 90 | { 91 | editWidget->show(); 92 | } 93 | 94 | onShowEditor(editWidget); 95 | 96 | // set value and constraints to the editor 97 | valueToEditor(); 98 | 99 | // focus 100 | editWidget->setFocus(); 101 | } 102 | 103 | 104 | void CBaseProperty::finishEdit(bool cancel) 105 | { 106 | QWidget* editWidget = getActiveEditor(); 107 | if (editWidget != NULL) 108 | { 109 | if (!cancel) 110 | { 111 | valueFromEditor(); 112 | } 113 | 114 | onHideEditor(editWidget); 115 | 116 | if (m_editorIsPrivate) 117 | { 118 | editWidget->hide(); 119 | } 120 | else 121 | { 122 | treeWidget()->removeItemWidget(this, 1); 123 | } 124 | } 125 | 126 | treeWidget()->setFocus(); 127 | } 128 | 129 | 130 | // internal 131 | 132 | QWidget* CBaseProperty::getActiveEditor() 133 | { 134 | if (treeWidget() != NULL) 135 | { 136 | return treeWidget()->itemWidget(this, 1); 137 | } 138 | 139 | return NULL; 140 | } 141 | 142 | 143 | void CBaseProperty::setEditorPrivate() 144 | { 145 | m_editorIsPrivate = true; 146 | } 147 | 148 | 149 | void CBaseProperty::emitValueChanged() 150 | { 151 | if (treeWidget() != NULL) 152 | { 153 | Q_EMIT treeWidget()->itemChanged(this, 1); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /CBaseProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CBASEPROPERTY_H 2 | #define CBASEPROPERTY_H 3 | 4 | #include 5 | 6 | class CBaseProperty: public QTreeWidgetItem 7 | { 8 | public: 9 | CBaseProperty(const QByteArray& id, const QString &name); 10 | CBaseProperty(CBaseProperty* top, const QByteArray& id, const QString &name); 11 | 12 | const QByteArray& getId() const { return m_id; } 13 | const QString& getName() const { return m_name; } 14 | 15 | void setMarked(bool on = true); 16 | bool isMarked() const; 17 | bool isMarkable() const; 18 | bool checkMarked(); 19 | 20 | void setBackground(const QBrush& bg); 21 | void setTextColor(const QColor& color); 22 | 23 | // handlers to reimplement 24 | virtual void onAdded() {} 25 | virtual void onEnter() {} 26 | virtual void onLeave() { finishEdit(); } 27 | virtual void onShowEditor(QWidget* /*editWidget*/) {} 28 | virtual void onHideEditor(QWidget* /*editWidget*/) {} 29 | virtual bool onKeyPressed(QKeyEvent* /*event*/, QWidget* /*editWidget*/) { return false; } 30 | 31 | // actions to reimplement 32 | virtual QVariant getVariantValue() const = 0; 33 | virtual void setValue(); 34 | virtual void validateValue() {} 35 | virtual void displayValue() {} 36 | 37 | virtual QWidget* createEditor() const { return NULL; } 38 | virtual void valueToEditor() {} 39 | virtual void valueFromEditor() {} 40 | virtual void startEdit(); 41 | virtual void finishEdit(bool cancel = false); 42 | virtual bool isEditorWindow(QWidget* editor, QWidget* window) const { return editor == window; } 43 | 44 | protected: 45 | friend class CPropertyEditor; 46 | 47 | QWidget* getActiveEditor(); 48 | void setEditorPrivate(); 49 | 50 | void emitValueChanged(); 51 | 52 | QByteArray m_id; 53 | QString m_name; 54 | 55 | bool m_isMarkable; 56 | 57 | bool m_editorIsPrivate; 58 | }; 59 | 60 | #endif // CBASEPROPERTY_H 61 | -------------------------------------------------------------------------------- /CBoolProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CBoolProperty.h" 2 | 3 | 4 | CBoolProperty::CBoolProperty(const QByteArray &id, const QString &name, bool value, bool defaultValue): 5 | CBaseProperty(id, name), 6 | m_value(value), 7 | m_defaultValue(defaultValue) 8 | { 9 | setValue(value); 10 | } 11 | 12 | 13 | CBoolProperty::CBoolProperty(CBaseProperty *top, const QByteArray &id, const QString &name, bool value, bool defaultValue): 14 | CBaseProperty(top, id, name), 15 | m_value(value), 16 | m_defaultValue(defaultValue) 17 | { 18 | setValue(value); 19 | } 20 | 21 | 22 | void CBoolProperty::setValue(bool value) 23 | { 24 | m_value = value; 25 | 26 | CBaseProperty::setValue(); 27 | } 28 | 29 | 30 | bool CBoolProperty::getValue() const 31 | { 32 | m_value = (checkState(1) == Qt::Checked); 33 | 34 | return m_value; 35 | } 36 | 37 | 38 | QVariant CBoolProperty::getVariantValue() const 39 | { 40 | return getValue(); 41 | } 42 | 43 | 44 | void CBoolProperty::displayValue() 45 | { 46 | setCheckState(1, m_value ? Qt::Checked : Qt::Unchecked); 47 | } 48 | 49 | 50 | bool CBoolProperty::onKeyPressed(QKeyEvent *event, QWidget *) 51 | { 52 | if (event->key() == Qt::Key_Return) 53 | { 54 | setValue(!m_value); 55 | return true; 56 | } 57 | 58 | return false; 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /CBoolProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CBOOLPROPERTY_H 2 | #define CBOOLPROPERTY_H 3 | 4 | #include "CBaseProperty.h" 5 | 6 | #include 7 | 8 | 9 | class CBoolProperty : public CBaseProperty 10 | { 11 | public: 12 | CBoolProperty(const QByteArray& id, const QString &name, bool value, bool defaultValue = false); 13 | CBoolProperty(CBaseProperty *top, const QByteArray& id, const QString &name, bool value, bool defaultValue = false); 14 | 15 | void setValue(bool value); 16 | bool getValue() const; 17 | 18 | // reimp 19 | virtual QVariant getVariantValue() const; 20 | virtual void displayValue(); 21 | 22 | // handlers 23 | virtual bool onKeyPressed(QKeyEvent* /*event*/, QWidget* /*editWidget*/); 24 | 25 | protected: 26 | mutable bool m_value; 27 | bool m_defaultValue; 28 | }; 29 | 30 | #endif // CBOOLPROPERTY_H 31 | -------------------------------------------------------------------------------- /CButtonBasedEditor.cpp: -------------------------------------------------------------------------------- 1 | #include "CButtonBasedEditor.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | CButtonBasedEditor::CButtonBasedEditor(QWidget *hostedEditor, QWidget *parent) : 8 | QWidget(parent), 9 | m_hostedEditor(hostedEditor) 10 | { 11 | QHBoxLayout* hbl = new QHBoxLayout(); 12 | hbl->setContentsMargins(0,0,0,0); 13 | hbl->setSpacing(0); 14 | setLayout(hbl); 15 | 16 | hbl->addWidget(m_hostedEditor); 17 | 18 | m_button = new QToolButton(this); 19 | m_button->setText("..."); 20 | hbl->addWidget(m_button); 21 | 22 | connect(m_button, SIGNAL(clicked()), this, SLOT(onEditButtonActivated())); 23 | } 24 | 25 | 26 | CButtonBasedEditor::~CButtonBasedEditor() 27 | { 28 | layout()->removeWidget(m_hostedEditor); 29 | m_hostedEditor->setParent(NULL); 30 | m_hostedEditor->hide(); 31 | } 32 | 33 | 34 | void CButtonBasedEditor::enableButton(bool on) 35 | { 36 | m_button->setVisible(on); 37 | } 38 | 39 | 40 | bool CButtonBasedEditor::event(QEvent *e) 41 | { 42 | if (e->type() == QEvent::FocusIn) 43 | { 44 | m_hostedEditor->setFocus(); 45 | e->accept(); 46 | return true; 47 | } 48 | 49 | return QWidget::event(e); 50 | } 51 | 52 | 53 | void CButtonBasedEditor::showEvent(QShowEvent *e) 54 | { 55 | QWidget::showEvent(e); 56 | 57 | m_hostedEditor->show(); 58 | } 59 | -------------------------------------------------------------------------------- /CButtonBasedEditor.h: -------------------------------------------------------------------------------- 1 | #ifndef CBUTTONBASEDEDITOR_H 2 | #define CBUTTONBASEDEDITOR_H 3 | 4 | #include 5 | 6 | 7 | class CButtonBasedEditor : public QWidget 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit CButtonBasedEditor(QWidget* hostedEditor, QWidget *parent = 0); 12 | virtual ~CButtonBasedEditor(); 13 | 14 | public Q_SLOTS: 15 | void enableButton(bool on); 16 | 17 | protected Q_SLOTS: 18 | // reimp 19 | virtual void onEditButtonActivated() = 0; 20 | 21 | protected: 22 | virtual bool event(QEvent* e); 23 | virtual void showEvent(QShowEvent *e); 24 | 25 | QWidget* m_hostedEditor; 26 | QToolButton* m_button; 27 | }; 28 | 29 | 30 | template 31 | class TButtonBasedEditor : public CButtonBasedEditor 32 | { 33 | public: 34 | TButtonBasedEditor(EditorClass* hostedEditor, QWidget *parent = 0) 35 | : CButtonBasedEditor(hostedEditor, parent) 36 | { 37 | } 38 | 39 | protected: 40 | EditorClass* getEditor() const 41 | { 42 | return dynamic_cast(m_hostedEditor); 43 | } 44 | }; 45 | 46 | 47 | #endif // CBUTTONBASEDEDITOR_H 48 | -------------------------------------------------------------------------------- /CColorProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CColorProperty.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | CColorProperty::CColorProperty(const QByteArray& id, const QString &name, const QColor& color): 8 | CBaseProperty(id, name), 9 | m_color(color), 10 | m_listColorsOnly(false) 11 | { 12 | setColor(m_color); 13 | } 14 | 15 | 16 | CColorProperty::CColorProperty(CBaseProperty *top, const QByteArray& id, const QString &name, const QColor& color): 17 | CBaseProperty(top, id, name), 18 | m_color(color), 19 | m_listColorsOnly(false) 20 | { 21 | setColor(m_color); 22 | } 23 | 24 | 25 | void CColorProperty::setColor(const QColor &color) 26 | { 27 | m_color = color; 28 | 29 | CBaseProperty::setValue(); 30 | } 31 | 32 | 33 | const QColor &CColorProperty::getColor() const 34 | { 35 | return m_color; 36 | } 37 | 38 | 39 | void CColorProperty::setColorsList(const QStringList &colorNames) 40 | { 41 | m_colorEditor.setColorsList(colorNames); 42 | 43 | CBaseProperty::setValue(); 44 | } 45 | 46 | 47 | void CColorProperty::allowListColorsOnly(bool on) 48 | { 49 | m_listColorsOnly = on; 50 | 51 | CBaseProperty::setValue(); 52 | } 53 | 54 | 55 | QVariant CColorProperty::getVariantValue() const 56 | { 57 | return m_color; 58 | } 59 | 60 | 61 | void CColorProperty::validateValue() 62 | { 63 | if (!m_color.isValid()) 64 | { 65 | m_color = QColor(Qt::black); 66 | } 67 | 68 | if (m_listColorsOnly && m_colorEditor.count()) 69 | { 70 | if (m_colorEditor.findData(m_color) < 0) 71 | m_color = QColor(m_colorEditor.itemText(0)); 72 | } 73 | } 74 | 75 | 76 | void CColorProperty::displayValue() 77 | { 78 | if (treeWidget()) 79 | treeWidget()->blockSignals(true); 80 | 81 | QString colorNameExt = QString("HEX: %1\nRGB: %2,%3,%4") 82 | .arg(m_color.name()) 83 | .arg(m_color.red()).arg(m_color.green()).arg(m_color.blue()); 84 | 85 | setText(1, m_colorEditor.colorName(m_color)); 86 | setIcon(1, QColorComboBox::colorIcon(m_color)); 87 | setToolTip(1, colorNameExt); 88 | 89 | if (treeWidget()) 90 | treeWidget()->blockSignals(false); 91 | } 92 | 93 | 94 | QWidget *CColorProperty::createEditor() const 95 | { 96 | CColorButtonEditor* hostEditor = new CColorButtonEditor(&m_colorEditor, const_cast(this)); 97 | 98 | hostEditor->enableButton(!m_listColorsOnly); 99 | 100 | return hostEditor; 101 | } 102 | 103 | 104 | void CColorProperty::valueToEditor() 105 | { 106 | if (m_colorEditor.isVisible()) 107 | { 108 | m_colorEditor.allowListColorsOnly(m_listColorsOnly); 109 | m_colorEditor.setCurrentColor(m_color); 110 | m_colorEditor.lineEdit()->selectAll(); 111 | } 112 | } 113 | 114 | 115 | void CColorProperty::valueFromEditor() 116 | { 117 | QColor col = m_colorEditor.currentColor(); 118 | if (col.isValid() && col != m_color) 119 | { 120 | setColor(col); 121 | 122 | emitValueChanged(); 123 | } 124 | } 125 | 126 | 127 | // CColorButtonEditor 128 | 129 | CColorProperty::CColorButtonEditor::CColorButtonEditor(QColorComboBox *colorComboEditor, CColorProperty *property) 130 | : TButtonBasedEditor(colorComboEditor) 131 | { 132 | m_property = property; 133 | } 134 | 135 | 136 | void CColorProperty::CColorButtonEditor::onEditButtonActivated() 137 | { 138 | QColorDialog colorDialog(getEditor()->currentColor()); 139 | 140 | if (colorDialog.exec() == QDialog::Accepted) 141 | { 142 | getEditor()->setCurrentColor(colorDialog.selectedColor()); 143 | 144 | m_property->finishEdit(); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /CColorProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CCOLORPROPERTY_H 2 | #define CCOLORPROPERTY_H 3 | 4 | #include "CBaseProperty.h" 5 | #include "CButtonBasedEditor.h" 6 | 7 | #include "QColorComboBox.h" 8 | 9 | 10 | class CColorProperty : public CBaseProperty 11 | { 12 | public: 13 | CColorProperty(const QByteArray& id, const QString &name, const QColor& color); 14 | CColorProperty(CBaseProperty *top, const QByteArray& id, const QString &name, const QColor& color); 15 | 16 | void setColor(const QColor& color); 17 | const QColor& getColor() const; 18 | 19 | void setColorsList(const QStringList& colorNames); 20 | 21 | void allowListColorsOnly(bool on); 22 | 23 | // reimp 24 | virtual QVariant getVariantValue() const; 25 | virtual void validateValue(); 26 | virtual void displayValue(); 27 | 28 | virtual QWidget* createEditor() const; 29 | virtual void valueToEditor(); 30 | virtual void valueFromEditor(); 31 | 32 | protected: 33 | class CColorButtonEditor : public TButtonBasedEditor 34 | { 35 | public: 36 | CColorButtonEditor(QColorComboBox* colorComboEditor, CColorProperty* property); 37 | 38 | protected: 39 | virtual void onEditButtonActivated(); 40 | 41 | CColorProperty* m_property; 42 | }; 43 | 44 | mutable QColor m_color; 45 | 46 | mutable QColorComboBox m_colorEditor; 47 | bool m_listColorsOnly; 48 | }; 49 | 50 | #endif // CCOLORPROPERTY_H 51 | -------------------------------------------------------------------------------- /CDateProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CDateProperty.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | CDateProperty::CDateProperty(const QByteArray &id, const QString &name, const QDate &value, const QDate &defaultValue): 8 | CBaseProperty(id, name), 9 | m_defaultValue(defaultValue) 10 | { 11 | setDate(value); 12 | } 13 | 14 | 15 | CDateProperty::CDateProperty(CBaseProperty *top, const QByteArray &id, const QString &name, const QDate &value, const QDate &defaultValue): 16 | CBaseProperty(top, id, name), 17 | m_defaultValue(defaultValue) 18 | { 19 | setDate(value); 20 | } 21 | 22 | 23 | void CDateProperty::setDate(const QDate &value) 24 | { 25 | m_value = value; 26 | 27 | CBaseProperty::setValue(); 28 | } 29 | 30 | 31 | QDate CDateProperty::getDate() const 32 | { 33 | return m_value; 34 | } 35 | 36 | 37 | void CDateProperty::setMaximumDate(const QDate &value) 38 | { 39 | m_maxDate = value; 40 | 41 | CBaseProperty::setValue(); 42 | } 43 | 44 | 45 | QDate CDateProperty::getMaximumDate() const 46 | { 47 | return m_maxDate; 48 | } 49 | 50 | 51 | void CDateProperty::setMinimumDate(const QDate &value) 52 | { 53 | m_minDate = value; 54 | 55 | CBaseProperty::setValue(); 56 | } 57 | 58 | 59 | QDate CDateProperty::getMinimumDate() const 60 | { 61 | return m_minDate; 62 | } 63 | 64 | 65 | void CDateProperty::setDateRange(const QDate &min, const QDate &max) 66 | { 67 | m_maxDate = max; 68 | m_minDate = min; 69 | 70 | CBaseProperty::setValue(); 71 | } 72 | 73 | 74 | void CDateProperty::setDisplayFormat(const QString &format) 75 | { 76 | m_format = format; 77 | 78 | displayValue(); 79 | } 80 | 81 | 82 | QString CDateProperty::displayFormat() const 83 | { 84 | return m_format; 85 | } 86 | 87 | 88 | // reimp 89 | 90 | QVariant CDateProperty::getVariantValue() const 91 | { 92 | return m_value; 93 | } 94 | 95 | 96 | void CDateProperty::displayValue() 97 | { 98 | if (treeWidget()) 99 | treeWidget()->blockSignals(true); 100 | 101 | QString dateString = m_format.isEmpty() ? m_value.toString(): m_value.toString(m_format); 102 | 103 | setText(1, dateString); 104 | setToolTip(1, dateString); 105 | 106 | if (treeWidget()) 107 | treeWidget()->blockSignals(false); 108 | } 109 | 110 | 111 | void CDateProperty::validateValue() 112 | { 113 | if (m_maxDate.isValid() && m_value > m_maxDate) 114 | { 115 | m_value = m_maxDate; 116 | } 117 | 118 | if (m_minDate.isValid() && m_value < m_minDate) 119 | { 120 | m_value = m_minDate; 121 | } 122 | } 123 | 124 | 125 | QWidget* CDateProperty::createEditor() const 126 | { 127 | QDateEdit* dateEditor = new QDateEdit(); 128 | dateEditor->setCalendarPopup(true); 129 | 130 | return dateEditor; 131 | } 132 | 133 | 134 | void CDateProperty::valueToEditor() 135 | { 136 | QDateEdit* dateEditor = dynamic_cast(getActiveEditor()); 137 | if (dateEditor != NULL) 138 | { 139 | dateEditor->setDate(m_value); 140 | 141 | if (m_minDate.isValid()) 142 | dateEditor->setMinimumDate(m_minDate); 143 | else 144 | dateEditor->clearMinimumDate(); 145 | 146 | if (m_maxDate.isValid()) 147 | dateEditor->setMaximumDate(m_maxDate); 148 | else 149 | dateEditor->clearMaximumDate(); 150 | 151 | dateEditor->setDisplayFormat(m_format); 152 | } 153 | } 154 | 155 | 156 | void CDateProperty::valueFromEditor() 157 | { 158 | QDateEdit* dateEditor = dynamic_cast(getActiveEditor()); 159 | if (dateEditor != NULL && dateEditor->date() != m_value) 160 | { 161 | setDate(dateEditor->date()); 162 | 163 | emitValueChanged(); 164 | } 165 | } 166 | 167 | -------------------------------------------------------------------------------- /CDateProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CDATEPROPERTY_H 2 | #define CDATEPROPERTY_H 3 | 4 | #include "CBaseProperty.h" 5 | 6 | #include 7 | 8 | 9 | class CDateProperty : public CBaseProperty 10 | { 11 | public: 12 | CDateProperty(const QByteArray& id, const QString &name, const QDate& value, const QDate& defaultValue = QDate::currentDate()); 13 | CDateProperty(CBaseProperty *top, const QByteArray& id, const QString &name, const QDate& value, const QDate& defaultValue = QDate::currentDate()); 14 | 15 | void setDate(const QDate& value); 16 | QDate getDate() const; 17 | 18 | void setMaximumDate(const QDate& value); 19 | QDate getMaximumDate() const; 20 | void setMinimumDate(const QDate& value); 21 | QDate getMinimumDate() const; 22 | void setDateRange(const QDate& min, const QDate& max); 23 | 24 | void setDisplayFormat(const QString& format); 25 | QString displayFormat() const; 26 | 27 | // reimp 28 | virtual QVariant getVariantValue() const; 29 | virtual void displayValue(); 30 | virtual void validateValue(); 31 | 32 | virtual QWidget* createEditor() const; 33 | virtual void valueToEditor(); 34 | virtual void valueFromEditor(); 35 | 36 | protected: 37 | mutable QDate m_value; 38 | QDate m_defaultValue, m_maxDate, m_minDate; 39 | QString m_format; 40 | }; 41 | 42 | #endif // CDATEPROPERTY_H 43 | -------------------------------------------------------------------------------- /CDateTimeProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CDateTimeProperty.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | CDateTimeProperty::CDateTimeProperty(const QByteArray &id, const QString &name, const QDateTime &value, const QDateTime &defaultValue): 8 | CBaseProperty(id, name), 9 | m_defaultValue(defaultValue) 10 | { 11 | setDateTime(value); 12 | } 13 | 14 | 15 | CDateTimeProperty::CDateTimeProperty(CBaseProperty *top, const QByteArray &id, const QString &name, const QDateTime &value, const QDateTime &defaultValue): 16 | CBaseProperty(top, id, name), 17 | m_defaultValue(defaultValue) 18 | { 19 | setDateTime(value); 20 | } 21 | 22 | 23 | void CDateTimeProperty::setDateTime(const QDateTime &value) 24 | { 25 | m_value = value; 26 | 27 | CBaseProperty::setValue(); 28 | } 29 | 30 | 31 | QDateTime CDateTimeProperty::getDateTime() const 32 | { 33 | return m_value; 34 | } 35 | 36 | 37 | void CDateTimeProperty::setMaximumDateTime(const QDateTime &value) 38 | { 39 | m_maxDateTime = value; 40 | 41 | CBaseProperty::setValue(); 42 | } 43 | 44 | 45 | QDateTime CDateTimeProperty::getMaximumDateTime() const 46 | { 47 | return m_maxDateTime; 48 | } 49 | 50 | 51 | void CDateTimeProperty::setMinimumDateTime(const QDateTime &value) 52 | { 53 | m_minDateTime = value; 54 | 55 | CBaseProperty::setValue(); 56 | } 57 | 58 | 59 | QDateTime CDateTimeProperty::getMinimumDateTime() const 60 | { 61 | return m_minDateTime; 62 | } 63 | 64 | 65 | void CDateTimeProperty::setDateTimeRange(const QDateTime &min, const QDateTime &max) 66 | { 67 | m_maxDateTime = max; 68 | m_minDateTime = min; 69 | 70 | CBaseProperty::setValue(); 71 | } 72 | 73 | 74 | void CDateTimeProperty::setDisplayFormat(const QString &format) 75 | { 76 | m_format = format; 77 | 78 | displayValue(); 79 | } 80 | 81 | 82 | QString CDateTimeProperty::displayFormat() const 83 | { 84 | return m_format; 85 | } 86 | 87 | 88 | // reimp 89 | 90 | QVariant CDateTimeProperty::getVariantValue() const 91 | { 92 | return m_value; 93 | } 94 | 95 | 96 | void CDateTimeProperty::displayValue() 97 | { 98 | if (treeWidget()) 99 | treeWidget()->blockSignals(true); 100 | 101 | QString dateString = m_format.isEmpty() ? m_value.toString(): m_value.toString(m_format); 102 | 103 | setText(1, dateString); 104 | setToolTip(1, dateString); 105 | 106 | if (treeWidget()) 107 | treeWidget()->blockSignals(false); 108 | } 109 | 110 | 111 | void CDateTimeProperty::validateValue() 112 | { 113 | if (m_maxDateTime.isValid() && m_value > m_maxDateTime) 114 | { 115 | m_value = m_maxDateTime; 116 | } 117 | 118 | if (m_minDateTime.isValid() && m_value < m_minDateTime) 119 | { 120 | m_value = m_minDateTime; 121 | } 122 | } 123 | 124 | 125 | QWidget* CDateTimeProperty::createEditor() const 126 | { 127 | QDateTimeEdit* dateEditor = new QDateTimeEdit(); 128 | dateEditor->setCalendarPopup(true); 129 | 130 | return dateEditor; 131 | } 132 | 133 | 134 | void CDateTimeProperty::valueToEditor() 135 | { 136 | QDateTimeEdit* dateEditor = dynamic_cast(getActiveEditor()); 137 | if (dateEditor != NULL) 138 | { 139 | dateEditor->setDateTime(m_value); 140 | 141 | if (m_minDateTime.isValid()) 142 | dateEditor->setMinimumDateTime(m_minDateTime); 143 | else 144 | dateEditor->clearMinimumDateTime(); 145 | 146 | if (m_maxDateTime.isValid()) 147 | dateEditor->setMaximumDateTime(m_maxDateTime); 148 | else 149 | dateEditor->clearMaximumDateTime(); 150 | 151 | dateEditor->setDisplayFormat(m_format); 152 | } 153 | } 154 | 155 | 156 | void CDateTimeProperty::valueFromEditor() 157 | { 158 | QDateTimeEdit* dateEditor = dynamic_cast(getActiveEditor()); 159 | if (dateEditor != NULL && dateEditor->dateTime() != m_value) 160 | { 161 | setDateTime(dateEditor->dateTime()); 162 | 163 | emitValueChanged(); 164 | } 165 | } 166 | 167 | -------------------------------------------------------------------------------- /CDateTimeProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CDATETIMEPROPERTY_H 2 | #define CDATETIMEPROPERTY_H 3 | 4 | 5 | #include "CBaseProperty.h" 6 | 7 | #include 8 | 9 | 10 | class CDateTimeProperty : public CBaseProperty 11 | { 12 | public: 13 | CDateTimeProperty(const QByteArray& id, const QString &name, const QDateTime& value, const QDateTime& defaultValue = QDateTime::currentDateTime()); 14 | CDateTimeProperty(CBaseProperty *top, const QByteArray& id, const QString &name, const QDateTime& value, const QDateTime& defaultValue = QDateTime::currentDateTime()); 15 | 16 | void setDateTime(const QDateTime& value); 17 | QDateTime getDateTime() const; 18 | 19 | void setMaximumDateTime(const QDateTime& value); 20 | QDateTime getMaximumDateTime() const; 21 | void setMinimumDateTime(const QDateTime& value); 22 | QDateTime getMinimumDateTime() const; 23 | void setDateTimeRange(const QDateTime& min, const QDateTime& max); 24 | 25 | void setDisplayFormat(const QString& format); 26 | QString displayFormat() const; 27 | 28 | // reimp 29 | virtual QVariant getVariantValue() const; 30 | virtual void displayValue(); 31 | virtual void validateValue(); 32 | 33 | virtual QWidget* createEditor() const; 34 | virtual void valueToEditor(); 35 | virtual void valueFromEditor(); 36 | 37 | protected: 38 | mutable QDateTime m_value; 39 | QDateTime m_defaultValue, m_maxDateTime, m_minDateTime; 40 | QString m_format; 41 | }; 42 | 43 | 44 | #endif // CDATETIMEPROPERTY_H 45 | -------------------------------------------------------------------------------- /CDoubleProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CDoubleProperty.h" 2 | 3 | #include 4 | 5 | 6 | CDoubleProperty::CDoubleProperty(const QByteArray &id, const QString &name, double value, double defaultValue, double min, double max): 7 | CBaseProperty(id, name), 8 | m_value(value), 9 | m_defaultValue(defaultValue), 10 | m_min(min), m_max(max) 11 | { 12 | setValue(m_value); 13 | } 14 | 15 | 16 | CDoubleProperty::CDoubleProperty(CBaseProperty *top, const QByteArray &id, const QString &name, double value, double defaultValue, double min, double max): 17 | CBaseProperty(top, id, name), 18 | m_value(value), 19 | m_defaultValue(defaultValue), 20 | m_min(min), m_max(max) 21 | { 22 | setValue(m_value); 23 | } 24 | 25 | 26 | void CDoubleProperty::setValue(double value) 27 | { 28 | m_value = value; 29 | 30 | CBaseProperty::setValue(); 31 | } 32 | 33 | 34 | double CDoubleProperty::getValue() const 35 | { 36 | return m_value; 37 | } 38 | 39 | 40 | void CDoubleProperty::setRange(double min, double max) 41 | { 42 | m_min = min; 43 | m_max = max; 44 | 45 | CBaseProperty::setValue(); 46 | } 47 | 48 | 49 | // reimp 50 | 51 | QVariant CDoubleProperty::getVariantValue() const 52 | { 53 | return m_value; 54 | } 55 | 56 | 57 | void CDoubleProperty::displayValue() 58 | { 59 | setText(1, QString::number(m_value)); 60 | } 61 | 62 | 63 | void CDoubleProperty::validateValue() 64 | { 65 | if (m_value < m_min) 66 | m_value = m_min; 67 | 68 | if (m_value > m_max) 69 | m_value = m_max; 70 | } 71 | 72 | 73 | QWidget *CDoubleProperty::createEditor() const 74 | { 75 | return new QDoubleSpinBox(); 76 | } 77 | 78 | 79 | void CDoubleProperty::valueToEditor() 80 | { 81 | QDoubleSpinBox* spinEditor = dynamic_cast(getActiveEditor()); 82 | if (spinEditor != NULL) 83 | { 84 | spinEditor->setDecimals(3); 85 | spinEditor->setRange(m_min, m_max); 86 | spinEditor->setValue(m_value); 87 | } 88 | } 89 | 90 | 91 | void CDoubleProperty::valueFromEditor() 92 | { 93 | QDoubleSpinBox* spinEditor = dynamic_cast(getActiveEditor()); 94 | if (spinEditor != NULL) 95 | { 96 | double newValue = spinEditor->value(); 97 | if (newValue != m_value) 98 | { 99 | setValue(newValue); 100 | 101 | // emit valueChanged... 102 | } 103 | } 104 | } 105 | 106 | 107 | void CDoubleProperty::startEdit() 108 | { 109 | CBaseProperty::startEdit(); 110 | 111 | QDoubleSpinBox* spinEditor = dynamic_cast(getActiveEditor()); 112 | if (spinEditor != NULL) 113 | { 114 | spinEditor->selectAll(); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /CDoubleProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CDOUBLEPROPERTY_H 2 | #define CDOUBLEPROPERTY_H 3 | 4 | #include 5 | 6 | #include "CBaseProperty.h" 7 | 8 | 9 | class CDoubleProperty : public CBaseProperty 10 | { 11 | public: 12 | CDoubleProperty(const QByteArray& id, const QString &name, double value, double defaultValue = 0, double min = DBL_MIN, double max = DBL_MAX); 13 | CDoubleProperty(CBaseProperty *top, const QByteArray& id, const QString &name, double value, double defaultValue = 0, double min = DBL_MIN, double max = DBL_MAX); 14 | 15 | void setValue(double value); 16 | double getValue() const; 17 | 18 | void setRange(double min, double max); 19 | 20 | // reimp 21 | virtual QVariant getVariantValue() const; 22 | virtual void displayValue(); 23 | virtual void validateValue(); 24 | 25 | virtual QWidget* createEditor() const; 26 | virtual void valueToEditor(); 27 | virtual void valueFromEditor(); 28 | virtual void startEdit(); 29 | 30 | protected: 31 | mutable double m_value; 32 | double m_defaultValue; 33 | double m_min, m_max; 34 | }; 35 | 36 | #endif // CDOUBLEPROPERTY_H 37 | -------------------------------------------------------------------------------- /CFontProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CFontProperty.h" 2 | 3 | #include 4 | 5 | 6 | CFontProperty::CFontProperty(const QByteArray &id, const QString &name, const QFont &font, 7 | const QFontComboBox::FontFilters filters, const QFontDatabase::WritingSystem writeSystem): 8 | CBaseProperty(id, name), 9 | m_font(font), 10 | m_filters(filters), 11 | m_writeSystem(writeSystem) 12 | { 13 | init(); 14 | } 15 | 16 | 17 | CFontProperty::CFontProperty(CBaseProperty *top, const QByteArray &id, const QString &name, const QFont &font, 18 | const QFontComboBox::FontFilters filters, const QFontDatabase::WritingSystem writeSystem): 19 | CBaseProperty(top, id, name), 20 | m_font(font), 21 | m_filters(filters), 22 | m_writeSystem(writeSystem) 23 | { 24 | init(); 25 | } 26 | 27 | 28 | void CFontProperty::init() 29 | { 30 | setFont(m_font); 31 | } 32 | 33 | 34 | void CFontProperty::setFont(const QFont &font) 35 | { 36 | m_font = font; 37 | 38 | CBaseProperty::setValue(); 39 | } 40 | 41 | 42 | const QFont& CFontProperty::getFont() const 43 | { 44 | return m_font; 45 | } 46 | 47 | 48 | QVariant CFontProperty::getVariantValue() const 49 | { 50 | return getFont(); 51 | } 52 | 53 | 54 | void CFontProperty::displayValue() 55 | { 56 | if (treeWidget()) 57 | treeWidget()->blockSignals(true); 58 | 59 | QString fontString = QString("%1, %2pt") 60 | .arg(m_font.family()) 61 | .arg(m_font.pointSizeF()); 62 | 63 | if (m_font.bold()) fontString += ", bold"; 64 | if (m_font.italic()) fontString += ", italic"; 65 | if (m_font.underline()) fontString += ", underline"; 66 | 67 | setText(1, fontString); 68 | setToolTip(1, fontString); 69 | 70 | QFont showFont(m_font); 71 | showFont.setPointSize(font(0).pointSize()); 72 | QTreeWidgetItem::setFont(1, showFont); 73 | 74 | if (treeWidget()) 75 | treeWidget()->blockSignals(false); 76 | } 77 | 78 | 79 | QWidget* CFontProperty::createEditor() const 80 | { 81 | m_fontCombo.setWritingSystem(m_writeSystem); 82 | m_fontCombo.setFontFilters(m_filters); 83 | 84 | CFontButtonEditor* hostEditor = new CFontButtonEditor(&m_fontCombo, const_cast(this)); 85 | return hostEditor; 86 | } 87 | 88 | 89 | void CFontProperty::valueToEditor() 90 | { 91 | if (m_fontCombo.isVisible()) 92 | m_fontCombo.setCurrentFont(m_font); 93 | } 94 | 95 | 96 | void CFontProperty::valueFromEditor() 97 | { 98 | if (m_fontCombo.currentFont() != m_font) 99 | { 100 | setFont(m_fontCombo.currentFont()); 101 | 102 | emitValueChanged(); 103 | } 104 | } 105 | 106 | 107 | // CFontButtonEditor 108 | 109 | CFontProperty::CFontButtonEditor::CFontButtonEditor(QFontComboBox *fontComboEditor, CFontProperty *property) 110 | : TButtonBasedEditor(fontComboEditor), 111 | m_property(property) 112 | { 113 | } 114 | 115 | 116 | void CFontProperty::CFontButtonEditor::onEditButtonActivated() 117 | { 118 | QFontDialog fontDialog(getEditor()->currentFont()); 119 | 120 | if (fontDialog.exec() == QDialog::Accepted) 121 | { 122 | getEditor()->setCurrentFont(fontDialog.currentFont()); 123 | 124 | m_property->finishEdit(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /CFontProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CFONTPROPERTY_H 2 | #define CFONTPROPERTY_H 3 | 4 | #include "CBaseProperty.h" 5 | #include "CButtonBasedEditor.h" 6 | 7 | #include 8 | 9 | 10 | class CFontProperty : public CBaseProperty 11 | { 12 | public: 13 | CFontProperty(const QByteArray& id, const QString &name, const QFont& font, 14 | const QFontComboBox::FontFilters filters = QFontComboBox::AllFonts, 15 | const QFontDatabase::WritingSystem writeSystem = QFontDatabase::Any); 16 | 17 | CFontProperty(CBaseProperty *top, const QByteArray& id, const QString &name, const QFont& font, 18 | const QFontComboBox::FontFilters filters = QFontComboBox::AllFonts, 19 | const QFontDatabase::WritingSystem writeSystem = QFontDatabase::Any); 20 | 21 | void setFont(const QFont& font); 22 | const QFont& getFont() const; 23 | 24 | // reimp 25 | virtual QVariant getVariantValue() const; 26 | virtual void displayValue(); 27 | 28 | virtual QWidget* createEditor() const; 29 | virtual void valueToEditor(); 30 | virtual void valueFromEditor(); 31 | 32 | protected: 33 | void init(); 34 | 35 | class CFontButtonEditor : public TButtonBasedEditor 36 | { 37 | public: 38 | CFontButtonEditor(QFontComboBox* fontComboEditor, CFontProperty* property); 39 | 40 | protected: 41 | virtual void onEditButtonActivated(); 42 | 43 | CFontProperty* m_property; 44 | }; 45 | 46 | mutable QFont m_font; 47 | 48 | QFontComboBox::FontFilters m_filters; 49 | QFontDatabase::WritingSystem m_writeSystem; 50 | 51 | mutable QFontComboBox m_fontCombo; 52 | }; 53 | 54 | #endif // CFONTPROPERTY_H 55 | -------------------------------------------------------------------------------- /CIntegerProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CIntegerProperty.h" 2 | 3 | //#include "CPropertyEditor.h" // ? 4 | 5 | #include 6 | #include 7 | 8 | 9 | CIntegerProperty::CIntegerProperty(const QByteArray &id, const QString &name, int value, int defaultValue, int min, int max): 10 | CBaseProperty(id, name), 11 | m_value(value), 12 | m_defaultValue(defaultValue), 13 | m_min(min), m_max(max) 14 | { 15 | setValue(m_value); 16 | } 17 | 18 | 19 | CIntegerProperty::CIntegerProperty(CBaseProperty *top, const QByteArray &id, const QString &name, int value, int defaultValue, int min, int max): 20 | CBaseProperty(top, id, name), 21 | m_value(value), 22 | m_defaultValue(defaultValue), 23 | m_min(min), m_max(max) 24 | { 25 | setValue(m_value); 26 | } 27 | 28 | 29 | void CIntegerProperty::setValue(int value) 30 | { 31 | m_value = value; 32 | 33 | CBaseProperty::setValue(); 34 | 35 | //qDebug() << "CIntegerProperty::setValue() " << m_value; 36 | } 37 | 38 | 39 | int CIntegerProperty::getValue() const 40 | { 41 | // handle editor... 42 | 43 | //m_value = text(1).toInt(); 44 | 45 | return m_value; 46 | } 47 | 48 | 49 | void CIntegerProperty::setRange(int min, int max) 50 | { 51 | m_min = min; 52 | m_max = max; 53 | 54 | CBaseProperty::setValue(); 55 | } 56 | 57 | 58 | // event handlers 59 | 60 | QVariant CIntegerProperty::getVariantValue() const 61 | { 62 | return m_value; 63 | } 64 | 65 | 66 | void CIntegerProperty::displayValue() 67 | { 68 | setText(1, QString::number(m_value)); 69 | } 70 | 71 | 72 | void CIntegerProperty::validateValue() 73 | { 74 | if (m_value < m_min) 75 | m_value = m_min; 76 | 77 | if (m_value > m_max) 78 | m_value = m_max; 79 | } 80 | 81 | 82 | QWidget *CIntegerProperty::createEditor() const 83 | { 84 | return new QSpinBox(); 85 | } 86 | 87 | 88 | void CIntegerProperty::valueToEditor() 89 | { 90 | QSpinBox* spinEditor = dynamic_cast(getActiveEditor()); 91 | if (spinEditor != NULL) 92 | { 93 | spinEditor->setRange(m_min, m_max); 94 | spinEditor->setValue(m_value); 95 | } 96 | } 97 | 98 | 99 | void CIntegerProperty::valueFromEditor() 100 | { 101 | QSpinBox* spinEditor = dynamic_cast(getActiveEditor()); 102 | if (spinEditor != NULL) 103 | { 104 | int newValue = spinEditor->value(); 105 | if (newValue != m_value) 106 | { 107 | setValue(newValue); 108 | 109 | // emit valueChanged... 110 | } 111 | } 112 | } 113 | 114 | 115 | void CIntegerProperty::startEdit() 116 | { 117 | // qDebug() << "CIntegerProperty::onEdit()"; 118 | 119 | CBaseProperty::startEdit(); 120 | 121 | QSpinBox* spinEditor = dynamic_cast(getActiveEditor()); 122 | if (spinEditor != NULL) 123 | { 124 | spinEditor->selectAll(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /CIntegerProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CINTEGERPROPERTY_H 2 | #define CINTEGERPROPERTY_H 3 | 4 | #include "CBaseProperty.h" 5 | 6 | 7 | class CIntegerProperty : public CBaseProperty 8 | { 9 | public: 10 | CIntegerProperty(const QByteArray& id, const QString &name, int value, int defaultValue = 0, int min = INT_MIN, int max = INT_MAX); 11 | CIntegerProperty(CBaseProperty *top, const QByteArray& id, const QString &name, int value, int defaultValue = 0, int min = INT_MIN, int max = INT_MAX); 12 | 13 | void setValue(int value); 14 | int getValue() const; 15 | 16 | void setRange(int min, int max); 17 | 18 | // reimp 19 | virtual QVariant getVariantValue() const; 20 | virtual void displayValue(); 21 | virtual void validateValue(); 22 | 23 | virtual QWidget* createEditor() const; 24 | virtual void valueToEditor(); 25 | virtual void valueFromEditor(); 26 | virtual void startEdit(); 27 | 28 | protected: 29 | mutable int m_value; 30 | int m_defaultValue; 31 | int m_min, m_max; 32 | }; 33 | 34 | #endif // CINTEGERPROPERTY_H 35 | -------------------------------------------------------------------------------- /CListProperty.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "CListProperty.h" 4 | 5 | 6 | CListProperty::CListProperty(const QByteArray &id, const QString &name, const CListData &list, int index, int defaultIndex): 7 | CBaseProperty(id, name), 8 | m_index(index), 9 | m_listData(list), 10 | m_defaultIndex(defaultIndex) 11 | { 12 | setIndex(m_index); 13 | } 14 | 15 | 16 | CListProperty::CListProperty(CBaseProperty *top, const QByteArray &id, const QString &name, const CListData &list, int index, int defaultIndex): 17 | CBaseProperty(top, id, name), 18 | m_index(index), 19 | m_listData(list), 20 | m_defaultIndex(defaultIndex) 21 | { 22 | setIndex(m_index); 23 | } 24 | 25 | 26 | void CListProperty::setIndex(int index) 27 | { 28 | m_index = index; 29 | 30 | CBaseProperty::setValue(); 31 | } 32 | 33 | 34 | int CListProperty::getIndex() const 35 | { 36 | return m_index; 37 | } 38 | 39 | 40 | void CListProperty::setList(const CListData &list) 41 | { 42 | // handle editor... 43 | 44 | m_listData = list; 45 | 46 | CBaseProperty::setValue(); 47 | } 48 | 49 | 50 | void CListProperty::onShowEditor(QWidget *editWidget) 51 | { 52 | QComboBox* comboEditor = dynamic_cast(editWidget); 53 | if (comboEditor != NULL) 54 | { 55 | if (comboEditor->count() == 0) 56 | { 57 | for (int i = 0; i < m_listData.size(); i++) 58 | { 59 | const CListDataItem& data = m_listData.at(i); 60 | comboEditor->addItem(data.m_icon, data.m_text, data.m_userData); 61 | } 62 | } 63 | } 64 | } 65 | 66 | 67 | void CListProperty::validateValue() 68 | { 69 | if (m_index < 0) 70 | m_index = 0; 71 | 72 | if (m_index >= m_listData.size()) 73 | m_index = m_listData.size() - 1; 74 | } 75 | 76 | 77 | void CListProperty::displayValue() 78 | { 79 | if (treeWidget()) 80 | treeWidget()->blockSignals(true); 81 | 82 | if (m_listData.isEmpty()) 83 | { 84 | setText(1, QObject::tr("")); 85 | setIcon(1, QIcon()); 86 | } 87 | else 88 | if (m_index < 0) 89 | { 90 | setText(1, QObject::tr("")); 91 | setIcon(1, QIcon()); 92 | } 93 | else 94 | { 95 | const CListDataItem& data = m_listData.at(m_index); 96 | setText(1, data.m_text); 97 | setIcon(1, data.m_icon); 98 | } 99 | 100 | if (treeWidget()) 101 | treeWidget()->blockSignals(false); 102 | } 103 | 104 | 105 | QVariant CListProperty::getVariantValue() const 106 | { 107 | return m_index; 108 | } 109 | 110 | 111 | QWidget *CListProperty::createEditor() const 112 | { 113 | return new QComboBox(); 114 | } 115 | 116 | 117 | void CListProperty::valueToEditor() 118 | { 119 | QComboBox* comboEditor = dynamic_cast(getActiveEditor()); 120 | if (comboEditor != NULL) 121 | { 122 | //qDebug() << "CListProperty::valueToEditor()" << m_index << m_listData.size(); 123 | 124 | comboEditor->setCurrentIndex(m_index); 125 | } 126 | } 127 | 128 | 129 | void CListProperty::valueFromEditor() 130 | { 131 | QComboBox* comboEditor = dynamic_cast(getActiveEditor()); 132 | if (comboEditor != NULL) 133 | { 134 | int newIndex = comboEditor->currentIndex(); 135 | if (newIndex != m_index) 136 | { 137 | setIndex(newIndex); 138 | 139 | emitValueChanged(); 140 | } 141 | } 142 | } 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /CListProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CLISTPROPERTY_H 2 | #define CLISTPROPERTY_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "CBaseProperty.h" 9 | 10 | 11 | struct CListDataItem 12 | { 13 | CListDataItem(const QString& text, const QIcon& icon = QIcon(), const QVariant& data = QVariant()) 14 | : m_text(text), 15 | m_icon(icon), 16 | m_userData(data) 17 | { 18 | } 19 | 20 | QString m_text; 21 | QIcon m_icon; 22 | QVariant m_userData; 23 | }; 24 | 25 | typedef QList CListData; 26 | 27 | 28 | class CListProperty : public CBaseProperty 29 | { 30 | public: 31 | CListProperty(const QByteArray& id, const QString &name, const CListData& list, int index, int defaultIndex = 0); 32 | CListProperty(CBaseProperty *top, const QByteArray& id, const QString &name, const CListData& list, int index, int defaultIndex = 0); 33 | 34 | void setIndex(int index); 35 | int getIndex() const; 36 | 37 | void setList(const CListData& list); 38 | 39 | // event handlers 40 | virtual void onShowEditor(QWidget *editWidget); 41 | 42 | // reimp 43 | virtual QVariant getVariantValue() const; 44 | virtual void displayValue(); 45 | virtual void validateValue(); 46 | 47 | virtual QWidget* createEditor() const; 48 | virtual void valueToEditor(); 49 | virtual void valueFromEditor(); 50 | 51 | protected: 52 | mutable int m_index; 53 | CListData m_listData; 54 | 55 | int m_defaultIndex; 56 | }; 57 | 58 | #endif // CLISTPROPERTY_H 59 | -------------------------------------------------------------------------------- /CPropertyEditor.cpp: -------------------------------------------------------------------------------- 1 | #include "CPropertyEditor.h" 2 | #include "CBoolProperty.h" 3 | #include "CIntegerProperty.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | CPropertyEditor::CPropertyEditor(QWidget *parent) : 12 | QTreeWidget(parent), 13 | m_addingItem(false) 14 | { 15 | } 16 | 17 | 18 | void CPropertyEditor::init() 19 | { 20 | setColumnCount(2); 21 | 22 | QStringList labels; 23 | labels << tr("Parameter") << tr("Value"); 24 | setHeaderLabels(labels); 25 | 26 | header()->setSectionsMovable(false); 27 | // header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 28 | // header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); 29 | 30 | setUniformRowHeights(true); 31 | setAlternatingRowColors(true); 32 | setAllColumnsShowFocus(true); 33 | 34 | 35 | connect(this, 36 | SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), 37 | this, 38 | SLOT(onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)) 39 | ); 40 | 41 | connect(this, 42 | SIGNAL(itemClicked(QTreeWidgetItem*,int)), 43 | this, 44 | SLOT(onItemClicked(QTreeWidgetItem*,int)) 45 | ); 46 | 47 | connect(this, 48 | SIGNAL(itemChanged(QTreeWidgetItem*,int)), 49 | this, 50 | SLOT(onItemChanged(QTreeWidgetItem*,int)) 51 | ); 52 | 53 | connect(qApp, 54 | SIGNAL(focusChanged(QWidget*,QWidget*)), 55 | this, 56 | SLOT(onFocusChanged(QWidget*,QWidget*)) 57 | ); 58 | } 59 | 60 | 61 | void CPropertyEditor::adjustToContents() 62 | { 63 | header()->resizeSections(QHeaderView::ResizeToContents); 64 | } 65 | 66 | 67 | // properties 68 | 69 | bool CPropertyEditor::add(CBaseProperty *prop) 70 | { 71 | if (prop == NULL) 72 | return false; 73 | 74 | if (m_propertyMap.contains(prop->getId())) 75 | { 76 | qDebug() << "Property with id=" << prop->getId() << " already assigned"; 77 | return false; // exists 78 | } 79 | 80 | m_addingItem = true; 81 | 82 | prop->setSizeHint(1, QSize(100,24)); 83 | 84 | m_propertyMap[prop->getId()] = prop; 85 | addTopLevelItem(prop); 86 | 87 | prop->onAdded(); 88 | 89 | expandItem(prop); 90 | 91 | m_addingItem = false; 92 | 93 | return true; 94 | } 95 | 96 | 97 | bool CPropertyEditor::remove(CBaseProperty *prop) 98 | { 99 | if (prop == NULL) 100 | return false; 101 | 102 | if (!m_propertyMap.contains(prop->getId())) 103 | { 104 | qDebug() << "Property with id=" << prop->getId() << " has not been assigned"; 105 | return false; // exists 106 | } 107 | 108 | m_propertyMap.remove(prop->getId()); 109 | 110 | int idx = indexOfTopLevelItem(prop); 111 | takeTopLevelItem(idx); 112 | delete prop; 113 | 114 | return true; 115 | } 116 | 117 | 118 | // this slot is called from item widget editor to signal that editing is over 119 | 120 | void CPropertyEditor::onWidgetEditorFinished() 121 | { 122 | CBaseProperty* prop = dynamic_cast(currentItem()); 123 | if (prop != NULL) 124 | prop->finishEdit(); 125 | } 126 | 127 | 128 | // slots 129 | 130 | void CPropertyEditor::onCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) 131 | { 132 | if (current == previous) 133 | return; 134 | 135 | CBaseProperty* oldProp = dynamic_cast(previous); 136 | if (oldProp != NULL) 137 | oldProp->onLeave(); 138 | 139 | CBaseProperty* newProp = dynamic_cast(current); 140 | if (newProp != NULL) 141 | newProp->onEnter(); 142 | 143 | } 144 | 145 | 146 | void CPropertyEditor::onItemClicked(QTreeWidgetItem *item, int column) 147 | { 148 | CBaseProperty* prop = dynamic_cast(item); 149 | if (prop != NULL && !prop->isDisabled()) 150 | { 151 | if (column == 1) 152 | prop->startEdit(); 153 | else 154 | prop->finishEdit(); 155 | } 156 | } 157 | 158 | 159 | void CPropertyEditor::onItemChanged(QTreeWidgetItem *item, int column) 160 | { 161 | if (m_addingItem) 162 | return; 163 | 164 | CBaseProperty* prop = dynamic_cast(item); 165 | if (prop != NULL) 166 | { 167 | if (column) 168 | { 169 | qDebug() << "Value state of property [" << prop->getId() << "] changed to: " << prop->getVariantValue(); 170 | } 171 | else 172 | { 173 | if (prop->isMarkable()) 174 | qDebug() << "Marked state of property [" << prop->getId() << "] changed to: " << prop->isMarked(); 175 | } 176 | } 177 | } 178 | 179 | 180 | // keys event 181 | 182 | void CPropertyEditor::keyPressEvent(QKeyEvent *event) 183 | { 184 | 185 | // qDebug() << event->key(); 186 | 187 | CBaseProperty* prop = dynamic_cast(currentItem()); 188 | if (prop != NULL) 189 | { 190 | QWidget* editWidget = prop->getActiveEditor(); 191 | 192 | if (prop->onKeyPressed(event, editWidget)) 193 | return; 194 | 195 | switch (event->key()) 196 | { 197 | case Qt::Key_Return: 198 | 199 | if (editWidget == NULL) 200 | { 201 | prop->startEdit(); 202 | } 203 | else 204 | { 205 | if (editWidget->isVisible()) 206 | prop->finishEdit(); 207 | else 208 | prop->startEdit(); 209 | } 210 | 211 | break; 212 | 213 | case Qt::Key_Escape: 214 | 215 | if (editWidget != NULL && editWidget->isVisible()) 216 | prop->finishEdit(true); 217 | 218 | break; 219 | 220 | case Qt::Key_Space: 221 | 222 | if (prop->isMarkable()) 223 | prop->setMarked(!prop->isMarked()); 224 | 225 | return; 226 | 227 | default: 228 | break; 229 | } 230 | } 231 | 232 | QTreeWidget::keyPressEvent(event); 233 | } 234 | 235 | -------------------------------------------------------------------------------- /CPropertyEditor.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROPERTYEDITOR_H 2 | #define CPROPERTYEDITOR_H 3 | 4 | #include 5 | #include 6 | 7 | class CBaseProperty; 8 | class CBoolProperty; 9 | class CIntegerProperty; 10 | 11 | 12 | class CPropertyEditor : public QTreeWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit CPropertyEditor(QWidget *parent = 0); 17 | 18 | void init(); 19 | void adjustToContents(); 20 | 21 | bool add(CBaseProperty* prop); 22 | bool remove(CBaseProperty* prop); 23 | 24 | public Q_SLOTS: 25 | void onWidgetEditorFinished(); 26 | 27 | private Q_SLOTS: 28 | void onCurrentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem * previous); 29 | void onItemClicked(QTreeWidgetItem * item, int column); 30 | void onItemChanged(QTreeWidgetItem * item, int column); 31 | 32 | protected: 33 | virtual void keyPressEvent(QKeyEvent * event); 34 | 35 | QMap m_propertyMap; 36 | bool m_addingItem; 37 | }; 38 | 39 | #endif // CPROPERTYEDITOR_H 40 | -------------------------------------------------------------------------------- /CPropertyHeader.cpp: -------------------------------------------------------------------------------- 1 | #include "CPropertyHeader.h" 2 | 3 | 4 | CPropertyHeader::CPropertyHeader(const QByteArray &id, const QString &name) 5 | : CBaseProperty(id, name) 6 | { 7 | } 8 | 9 | 10 | CPropertyHeader::CPropertyHeader(CBaseProperty *top, const QByteArray &id, const QString &name) 11 | : CBaseProperty(top, id, name) 12 | { 13 | } 14 | 15 | 16 | void CPropertyHeader::onAdded() 17 | { 18 | setBackground(Qt::darkGray); 19 | setTextColor(Qt::white); 20 | 21 | // important to call this AFTER adding 22 | setFirstColumnSpanned(true); 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /CPropertyHeader.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROPERTYHEADER_H 2 | #define CPROPERTYHEADER_H 3 | 4 | #include "CBaseProperty.h" 5 | 6 | 7 | class CPropertyHeader : public CBaseProperty 8 | { 9 | public: 10 | CPropertyHeader(const QByteArray& id, const QString &name); 11 | CPropertyHeader(CBaseProperty *top, const QByteArray& id, const QString &name); 12 | 13 | // reimp 14 | virtual void onAdded(); 15 | virtual QVariant getVariantValue() const { return QVariant(); } 16 | }; 17 | 18 | 19 | #endif // CPROPERTYHEADER_H 20 | -------------------------------------------------------------------------------- /CStringProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CStringProperty.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | CStringProperty::CStringProperty(const QByteArray &id, const QString &name, const QString &value, const QString &defaultValue): 8 | CBaseProperty(id, name), 9 | m_value(value), 10 | m_defaultValue(defaultValue) 11 | { 12 | setValue(value); 13 | } 14 | 15 | 16 | CStringProperty::CStringProperty(CBaseProperty *top, const QByteArray &id, const QString &name, const QString &value, const QString &defaultValue): 17 | CBaseProperty(top, id, name), 18 | m_value(value), 19 | m_defaultValue(defaultValue) 20 | { 21 | setValue(value); 22 | } 23 | 24 | 25 | void CStringProperty::setValue(const QString &value) 26 | { 27 | m_value = value; 28 | 29 | CBaseProperty::setValue(); 30 | } 31 | 32 | 33 | const QString &CStringProperty::getValue() const 34 | { 35 | m_value = text(1); 36 | 37 | return m_value; 38 | } 39 | 40 | 41 | QVariant CStringProperty::getVariantValue() const 42 | { 43 | return getValue(); 44 | } 45 | 46 | void CStringProperty::displayValue() 47 | { 48 | setText(1, m_value); 49 | } 50 | 51 | 52 | void CStringProperty::startEdit() 53 | { 54 | setFlags(flags() | Qt::ItemIsEditable); 55 | 56 | treeWidget()->editItem(this, 1); 57 | 58 | QLineEdit* editor = dynamic_cast(getActiveEditor()); 59 | if (editor != NULL) 60 | { 61 | editor->selectAll(); 62 | } 63 | } 64 | 65 | 66 | void CStringProperty::finishEdit(bool cancel) 67 | { 68 | // qDebug() << "CStringProperty::finishEdit() " << text(1) << " : " << getActiveEditor(); 69 | 70 | if (!cancel) 71 | { 72 | QLineEdit* editor = dynamic_cast(getActiveEditor()); 73 | if (editor != NULL) 74 | { 75 | setValue(editor->text()); 76 | } 77 | } 78 | 79 | setFlags(flags() & ~Qt::ItemIsEditable); 80 | } 81 | 82 | -------------------------------------------------------------------------------- /CStringProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CSTRINGPROPERTY_H 2 | #define CSTRINGPROPERTY_H 3 | 4 | #include "CBaseProperty.h" 5 | 6 | class CStringProperty : public CBaseProperty 7 | { 8 | public: 9 | CStringProperty(const QByteArray& id, const QString &name, const QString& value, const QString& defaultValue = ""); 10 | CStringProperty(CBaseProperty *top, const QByteArray& id, const QString &name, const QString& value, const QString& defaultValue = ""); 11 | 12 | void setValue(const QString& value); 13 | const QString& getValue() const; 14 | 15 | // reimp 16 | virtual QVariant getVariantValue() const; 17 | virtual void displayValue(); 18 | 19 | virtual void startEdit(); 20 | virtual void finishEdit(bool cancel = false); 21 | 22 | protected: 23 | mutable QString m_value; 24 | QString m_defaultValue; 25 | }; 26 | 27 | #endif // CSTRINGPROPERTY_H 28 | -------------------------------------------------------------------------------- /CTimeProperty.cpp: -------------------------------------------------------------------------------- 1 | #include "CTimeProperty.h" 2 | 3 | #include 4 | 5 | 6 | CTimeProperty::CTimeProperty(const QByteArray &id, const QString &name, const QTime &value, const QTime &defaultValue): 7 | CBaseProperty(id, name), 8 | m_defaultValue(defaultValue), 9 | m_format("HH:mm:ss") 10 | { 11 | setTime(value); 12 | } 13 | 14 | 15 | CTimeProperty::CTimeProperty(CBaseProperty *top, const QByteArray &id, const QString &name, const QTime &value, const QTime &defaultValue): 16 | CBaseProperty(top, id, name), 17 | m_defaultValue(defaultValue), 18 | m_format("HH:mm:ss") 19 | { 20 | setTime(value); 21 | } 22 | 23 | 24 | void CTimeProperty::setTime(const QTime &value) 25 | { 26 | m_value = value; 27 | 28 | CBaseProperty::setValue(); 29 | } 30 | 31 | 32 | QTime CTimeProperty::getTime() const 33 | { 34 | return m_value; 35 | } 36 | 37 | 38 | void CTimeProperty::setMaximumTime(const QTime &value) 39 | { 40 | m_maxTime = value; 41 | 42 | CBaseProperty::setValue(); 43 | } 44 | 45 | 46 | QTime CTimeProperty::getMaximumTime() const 47 | { 48 | return m_maxTime; 49 | } 50 | 51 | 52 | void CTimeProperty::setMinimumTime(const QTime &value) 53 | { 54 | m_minTime = value; 55 | 56 | CBaseProperty::setValue(); 57 | } 58 | 59 | 60 | QTime CTimeProperty::getMinimumTime() const 61 | { 62 | return m_minTime; 63 | } 64 | 65 | 66 | void CTimeProperty::setTimeRange(const QTime &min, const QTime &max) 67 | { 68 | m_maxTime = max; 69 | m_minTime = min; 70 | 71 | CBaseProperty::setValue(); 72 | } 73 | 74 | 75 | void CTimeProperty::setDisplayFormat(const QString &format) 76 | { 77 | m_format = format; 78 | 79 | displayValue(); 80 | } 81 | 82 | 83 | QString CTimeProperty::displayFormat() const 84 | { 85 | return m_format; 86 | } 87 | 88 | 89 | // reimp 90 | 91 | QVariant CTimeProperty::getVariantValue() const 92 | { 93 | return m_value; 94 | } 95 | 96 | 97 | void CTimeProperty::displayValue() 98 | { 99 | if (treeWidget()) 100 | treeWidget()->blockSignals(true); 101 | 102 | QString timeString = m_format.isEmpty() ? m_value.toString(): m_value.toString(m_format); 103 | 104 | setText(1, timeString); 105 | setToolTip(1, timeString); 106 | 107 | if (treeWidget()) 108 | treeWidget()->blockSignals(false); 109 | } 110 | 111 | 112 | void CTimeProperty::validateValue() 113 | { 114 | if (m_maxTime.isValid() && m_value > m_maxTime) 115 | { 116 | m_value = m_maxTime; 117 | } 118 | 119 | if (m_minTime.isValid() && m_value < m_minTime) 120 | { 121 | m_value = m_minTime; 122 | } 123 | } 124 | 125 | 126 | QWidget* CTimeProperty::createEditor() const 127 | { 128 | QTimeEdit* timeEditor = new QTimeEdit(); 129 | 130 | return timeEditor; 131 | } 132 | 133 | 134 | void CTimeProperty::valueToEditor() 135 | { 136 | QTimeEdit* timeEditor = dynamic_cast(getActiveEditor()); 137 | if (timeEditor != NULL) 138 | { 139 | timeEditor->setTime(m_value); 140 | timeEditor->setTimeRange(m_minTime, m_maxTime); 141 | timeEditor->setDisplayFormat(m_format); 142 | } 143 | } 144 | 145 | 146 | void CTimeProperty::valueFromEditor() 147 | { 148 | QTimeEdit* timeEditor = dynamic_cast(getActiveEditor()); 149 | if (timeEditor != NULL && timeEditor->time() != m_value) 150 | { 151 | setTime(timeEditor->time()); 152 | 153 | emitValueChanged(); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /CTimeProperty.h: -------------------------------------------------------------------------------- 1 | #ifndef CTIMEPROPERTY_H 2 | #define CTIMEPROPERTY_H 3 | 4 | #include "CBaseProperty.h" 5 | 6 | #include 7 | 8 | 9 | class CTimeProperty : public CBaseProperty 10 | { 11 | public: 12 | CTimeProperty(const QByteArray& id, const QString &name, const QTime& value, const QTime& defaultValue = QTime::currentTime()); 13 | CTimeProperty(CBaseProperty *top, const QByteArray& id, const QString &name, const QTime& value, const QTime& defaultValue = QTime::currentTime()); 14 | 15 | void setTime(const QTime& value); 16 | QTime getTime() const; 17 | 18 | void setMaximumTime(const QTime& value); 19 | QTime getMaximumTime() const; 20 | void setMinimumTime(const QTime& value); 21 | QTime getMinimumTime() const; 22 | void setTimeRange(const QTime& min, const QTime& max); 23 | 24 | void setDisplayFormat(const QString& format); 25 | QString displayFormat() const; 26 | 27 | // reimp 28 | virtual QVariant getVariantValue() const; 29 | virtual void displayValue(); 30 | virtual void validateValue(); 31 | 32 | virtual QWidget* createEditor() const; 33 | virtual void valueToEditor(); 34 | virtual void valueFromEditor(); 35 | 36 | protected: 37 | mutable QTime m_value; 38 | QTime m_defaultValue, m_maxTime, m_minTime; 39 | QString m_format; 40 | }; 41 | 42 | #endif // CTIMEPROPERTY_H 43 | -------------------------------------------------------------------------------- /Icons/file-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qt-Widgets/Property-Editor/f173e7670f174b322646d9dc6da52eeb44587fad/Icons/file-open.png -------------------------------------------------------------------------------- /Icons/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qt-Widgets/Property-Editor/f173e7670f174b322646d9dc6da52eeb44587fad/Icons/info.png -------------------------------------------------------------------------------- /Icons/remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qt-Widgets/Property-Editor/f173e7670f174b322646d9dc6da52eeb44587fad/Icons/remove.png -------------------------------------------------------------------------------- /PropertyEditor.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2014-11-28T23:45:39 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = PropertyEditor 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | testwidget.cpp \ 17 | CPropertyEditor.cpp \ 18 | CBoolProperty.cpp \ 19 | CBaseProperty.cpp \ 20 | CIntegerProperty.cpp \ 21 | CStringProperty.cpp \ 22 | CDoubleProperty.cpp \ 23 | CListProperty.cpp \ 24 | CPropertyHeader.cpp \ 25 | CFontProperty.cpp \ 26 | CButtonBasedEditor.cpp \ 27 | QColorComboBox.cpp \ 28 | CColorProperty.cpp \ 29 | CDateProperty.cpp \ 30 | CTimeProperty.cpp \ 31 | CDateTimeProperty.cpp 32 | 33 | HEADERS += testwidget.h \ 34 | CPropertyEditor.h \ 35 | CBoolProperty.h \ 36 | CBaseProperty.h \ 37 | CIntegerProperty.h \ 38 | CStringProperty.h \ 39 | CDoubleProperty.h \ 40 | CListProperty.h \ 41 | CPropertyHeader.h \ 42 | CFontProperty.h \ 43 | CButtonBasedEditor.h \ 44 | QColorComboBox.h \ 45 | CColorProperty.h \ 46 | CDateProperty.h \ 47 | CTimeProperty.h \ 48 | CDateTimeProperty.h 49 | 50 | FORMS += testwidget.ui 51 | 52 | INCLUDEPATH += . 53 | 54 | RESOURCES += \ 55 | testwidget.qrc 56 | -------------------------------------------------------------------------------- /QColorComboBox.cpp: -------------------------------------------------------------------------------- 1 | #include "QColorComboBox.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | QColorComboBox::QColorComboBox(QWidget *parent) : 11 | QComboBox(parent), 12 | m_listOnly(false) 13 | { 14 | setDuplicatesEnabled(false); 15 | setInsertPolicy(QComboBox::NoInsert); 16 | 17 | setColorsList(QColor::colorNames()); 18 | 19 | //connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); 20 | 21 | setEditable(true); 22 | connect(lineEdit(), SIGNAL(editingFinished()), this, SLOT(onEdited())); 23 | 24 | // workaround of QCompleter bug (QTBUG-49165) 25 | connect(lineEdit(), SIGNAL(selectionChanged()), this, SLOT(onSelectionTextChanged())); 26 | connect(lineEdit(), SIGNAL(textChanged(QString&)), this, SLOT(onSelectionTextChanged())); 27 | } 28 | 29 | 30 | void QColorComboBox::setColorsList(const QStringList &colorNames) 31 | { 32 | blockSignals(true); 33 | 34 | QColor current = currentColor(); 35 | 36 | clear(); 37 | 38 | for (int i = 0; i < colorNames.count(); i++) 39 | { 40 | QColor col(colorNames.at(i)); 41 | 42 | // add to the list 43 | addItem(colorIcon(col), colorNames.at(i), col); 44 | } 45 | 46 | setCurrentColor(current); 47 | 48 | blockSignals(false); 49 | } 50 | 51 | 52 | void QColorComboBox::setColorsList(const QList &colors) 53 | { 54 | blockSignals(true); 55 | 56 | QColor current = currentColor(); 57 | 58 | clear(); 59 | 60 | for (int i = 0; i < colors.count(); i++) 61 | { 62 | QColor col(colors.at(i)); 63 | 64 | // add to the list 65 | addItem(colorIcon(col), col.name(), col); 66 | } 67 | 68 | setCurrentColor(current); 69 | 70 | blockSignals(false); 71 | } 72 | 73 | 74 | QColor QColorComboBox::currentColor() const 75 | { 76 | if (currentIndex() >= 0) 77 | return currentData().value(); 78 | 79 | if (m_listOnly) 80 | return QColor(); 81 | 82 | return QColor(currentText()); 83 | } 84 | 85 | 86 | void QColorComboBox::allowListColorsOnly(bool on) 87 | { 88 | if (on != m_listOnly) 89 | { 90 | m_listOnly = on; 91 | 92 | if (m_listOnly && currentIndex() < 0 && count()) 93 | { 94 | setCurrentIndex(0); 95 | } 96 | } 97 | } 98 | 99 | 100 | void QColorComboBox::setCurrentColor(const QColor &color) 101 | { 102 | int index = findData(color); 103 | if (index >= 0) 104 | { 105 | setCurrentIndex(index); 106 | } 107 | else 108 | { 109 | if (m_listOnly && count()) 110 | { 111 | setCurrentIndex(0); 112 | return; 113 | } 114 | 115 | setCurrentIndex(-1); 116 | setCurrentText(color.name()); 117 | } 118 | } 119 | 120 | 121 | QIcon QColorComboBox::colorIcon(const QColor &color, int size) 122 | { 123 | // create icon 124 | QPixmap pm(size, size); 125 | pm.fill(color); 126 | QPen p(Qt::black, 1); 127 | QPainter pt(&pm); 128 | pt.drawRect(QRect(0,0,size-1,size-1)); 129 | return QIcon(pm); 130 | } 131 | 132 | 133 | QStringList QColorComboBox::defaultColors() 134 | { 135 | return QColor::colorNames(); 136 | } 137 | 138 | 139 | QStringList QColorComboBox::baseColors() 140 | { 141 | static QStringList list; 142 | 143 | if (list.isEmpty()) 144 | { 145 | list << "white" << "lightGray" << "gray" << "darkGray" << "black" 146 | << "cyan" << "darkCyan" << "red" << "darkRed" 147 | << "magenta" << "darkMagenta" << "green" << "darkGreen" 148 | << "yellow" << /*"darkYellow"*/ "#808000" << "blue" << "darkBlue"; 149 | } 150 | 151 | return list; 152 | } 153 | 154 | 155 | QString QColorComboBox::colorName(const QColor &color) const 156 | { 157 | int index = findData(color); 158 | if (index >= 0) 159 | return itemText(index); 160 | 161 | return color.name(); 162 | } 163 | 164 | 165 | void QColorComboBox::onCurrentIndexChanged(int index) 166 | { 167 | if (index >= 0) 168 | { 169 | Q_EMIT(currentColorChanged(currentColor())); 170 | } 171 | } 172 | 173 | 174 | void QColorComboBox::onEdited() 175 | { 176 | QString colorName = lineEdit()->text(); 177 | // qDebug() << colorName; 178 | 179 | if (QColor::isValidColor(colorName)) 180 | { 181 | if (m_listOnly) 182 | { 183 | int index = findData(QColor(colorName)); 184 | if (index >= 0) 185 | { 186 | setCurrentIndex(index); 187 | } 188 | else if (count()) 189 | { 190 | setCurrentIndex(0); 191 | } 192 | } 193 | else 194 | { 195 | setCurrentIndex(-1); 196 | setCurrentText(colorName); 197 | } 198 | 199 | // qDebug() << currentColor(); 200 | 201 | Q_EMIT(currentColorChanged(currentColor())); 202 | } 203 | } 204 | 205 | 206 | void QColorComboBox::onSelectionTextChanged() 207 | { 208 | // workaround of QCompleter bug (QTBUG-49165) 209 | if (completer()) 210 | { 211 | completer()->setCompletionPrefix(currentText()); 212 | } 213 | } 214 | 215 | -------------------------------------------------------------------------------- /QColorComboBox.h: -------------------------------------------------------------------------------- 1 | #ifndef QCOLORCOMBOBOX_H 2 | #define QCOLORCOMBOBOX_H 3 | 4 | #include 5 | 6 | 7 | class QColorComboBox : public QComboBox 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit QColorComboBox(QWidget *parent = 0); 12 | 13 | void setColorsList(const QStringList& colorNames); 14 | void setColorsList(const QList& colors); 15 | 16 | QColor currentColor() const; 17 | 18 | void allowListColorsOnly(bool on); 19 | 20 | bool isListColorsOnly() const 21 | { return m_listOnly; } 22 | 23 | QString colorName(const QColor& color) const; 24 | 25 | static QIcon colorIcon(const QColor& color, int size = 14); 26 | 27 | static QStringList defaultColors(); 28 | static QStringList baseColors(); 29 | 30 | signals: 31 | void currentColorChanged(const QColor& color); 32 | 33 | public slots: 34 | void setCurrentColor(const QColor& color); 35 | 36 | protected slots: 37 | void onCurrentIndexChanged(int index); 38 | void onEdited(); 39 | void onSelectionTextChanged(); 40 | 41 | private: 42 | bool m_listOnly; 43 | }; 44 | 45 | 46 | #endif // QCOLORCOMBOBOX_H 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Property-Properties-Editor 2 | 3 | ![](https://github.com/Qt-Widgets/Property-Properties-Editor/blob/master/screenshot.png) 4 | 5 | ## Features 6 | * Currently supported: Boolean, Integer, Double, String, Font, List, Color, Date & Time, Data properties as well as header groups 7 | * Each property can have additional checkbox, own background and text color 8 | * Properties can be displayed in a hierarchical tree, be disabled and read-only 9 | * Properties Editor is based on QTreeWidget and provides very simple and clean Qt-style-like API 10 | 11 | Original Repository Link: https://sourceforge.net/projects/qsint-properties/ 12 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "testwidget.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | TestWidget w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qt-Widgets/Property-Editor/f173e7670f174b322646d9dc6da52eeb44587fad/screenshot.png -------------------------------------------------------------------------------- /testwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "testwidget.h" 2 | #include "ui_testwidget.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "CDateTimeProperty.h" 15 | 16 | 17 | TestWidget::TestWidget(QWidget *parent) : 18 | QWidget(parent), 19 | ui(new Ui::TestWidget) 20 | { 21 | ui->setupUi(this); 22 | 23 | ui->editor->init(); 24 | 25 | // Color properties 26 | CPropertyHeader* colorhead = new CPropertyHeader("ColorHead", "Color Properties"); 27 | ui->editor->add(colorhead); 28 | 29 | CColorProperty* c1 = new CColorProperty(colorhead, "Color1", "Color 1 (user editable)", Qt::red); 30 | ui->editor->add(c1); 31 | 32 | CColorProperty* c2 = new CColorProperty(colorhead, "Color2", "Color 2 (not user editable)", Qt::green); 33 | ui->editor->add(c2); 34 | c2->allowListColorsOnly(true); 35 | 36 | CColorProperty* c3 = new CColorProperty(colorhead, "Color3", "Color 3 (Base colors)", QColor("#345678")); 37 | ui->editor->add(c3); 38 | //c3->allowListColorsOnly(true); 39 | c3->setColorsList(QColorComboBox::baseColors()); 40 | 41 | // Boolean properties 42 | CPropertyHeader* bhead = new CPropertyHeader("BoolHead", "Boolean Properties"); 43 | ui->editor->add(bhead); 44 | 45 | CBoolProperty* b1 = new CBoolProperty(bhead, "SomeBool1", "Boolean 1 On", true); 46 | ui->editor->add(b1); 47 | b1->setMarked(Qt::Unchecked); 48 | 49 | CBoolProperty* b2 = new CBoolProperty(b1, "SomeBool2", "Boolean 2 Off", false); 50 | ui->editor->add(b2); 51 | b2->setBackground(Qt::yellow); 52 | 53 | CBoolProperty* b3 = new CBoolProperty(bhead, "SomeBool3", "Boolean 3 Disabled", false); 54 | ui->editor->add(b3); 55 | b3->setDisabled(true); 56 | 57 | CBoolProperty* b4 = new CBoolProperty(bhead, "SomeBool4", "Boolean 4 On", true); 58 | ui->editor->add(b4); 59 | b4->setMarked(Qt::Checked); 60 | 61 | CBoolProperty* b5 = new CBoolProperty(bhead, "SomeBool5", "Boolean 5 Off", false); 62 | ui->editor->add(b5); 63 | b5->setMarked(Qt::PartiallyChecked); 64 | 65 | 66 | // Integer properties 67 | CPropertyHeader* inthead = new CPropertyHeader("IntHead", "Integer Properties"); 68 | ui->editor->add(inthead); 69 | 70 | CIntegerProperty* i1 = new CIntegerProperty(inthead, "SomeInt1", "Integer 1", 123, 0); 71 | ui->editor->add(i1); 72 | i1->setBackground(Qt::cyan); 73 | 74 | CIntegerProperty* i2 = new CIntegerProperty(i1, "SomeInt2", "Integer 2 (-100..100)", -40, 0, -100, 100); 75 | ui->editor->add(i2); 76 | i2->setMarked(Qt::Checked); 77 | 78 | 79 | // Double properties 80 | CPropertyHeader* dblhead = new CPropertyHeader("DblHead", "Double Properties"); 81 | ui->editor->add(dblhead); 82 | 83 | CDoubleProperty* d1 = new CDoubleProperty(dblhead, "SomeDouble1", "Double 1", 45.639, 0, -15.93, 1378789123232.327878273); 84 | ui->editor->add(d1); 85 | 86 | 87 | // Text properties 88 | CPropertyHeader* txthead = new CPropertyHeader("TxtHead", "Textual Properties"); 89 | ui->editor->add(txthead); 90 | 91 | CStringProperty* s1 = new CStringProperty(txthead, "SomeString1", "A String", "the sun is shining :)"); 92 | ui->editor->add(s1); 93 | 94 | 95 | // List properties 96 | CPropertyHeader* listhead = new CPropertyHeader("ListHead", "List Properties"); 97 | listhead->setMarked(true); 98 | ui->editor->add(listhead); 99 | 100 | CListData list1; 101 | list1 << CListDataItem("Item 1", QIcon(":/Info")) 102 | << CListDataItem("Item 2") 103 | << CListDataItem("Item 3", QIcon(":/Open")) 104 | << CListDataItem("Item 4", QIcon(":/Remove")) 105 | << CListDataItem("Item 5"); 106 | 107 | CListProperty* l1 = new CListProperty(listhead, "List1", "List 1", list1, 0); 108 | ui->editor->add(l1); 109 | l1->setBackground(Qt::magenta); 110 | l1->setTextColor(Qt::green); 111 | l1->setMarked(Qt::Checked); 112 | 113 | CListProperty* l2 = new CListProperty(listhead, "List2", "List 2 (shared List 1)", list1, 5); 114 | ui->editor->add(l2); 115 | l2->setMarked(Qt::Unchecked); 116 | 117 | 118 | // Font properties 119 | CPropertyHeader* fonthead = new CPropertyHeader("FontHead", "Font Properties"); 120 | ui->editor->add(fonthead); 121 | 122 | QFont font1("Arial", 10, 100, true); 123 | CFontProperty* f1 = new CFontProperty(fonthead, "Font1", "Font 1", font1); 124 | ui->editor->add(f1); 125 | 126 | QFont font2("Courier", 12, 1, false); 127 | CFontProperty* f2 = new CFontProperty(fonthead, "Font2", "Font 2", font2); 128 | ui->editor->add(f2); 129 | 130 | 131 | // Date & Time properties 132 | CPropertyHeader* datehead = new CPropertyHeader("DateHead", "Date & Time Properties"); 133 | ui->editor->add(datehead); 134 | 135 | QDate somedate(1980, 7, 15); 136 | CDateProperty* date1 = new CDateProperty(datehead, "Date1", "Date", somedate); 137 | ui->editor->add(date1); 138 | date1->setBackground(Qt::green); 139 | date1->setTextColor(Qt::black); 140 | 141 | CDateProperty* date2 = new CDateProperty(date1, "Date2", "Date (limited 1985-2005)", somedate); 142 | date2->setMinimumDate(QDate(1985, 1, 1)); 143 | date2->setMaximumDate(QDate(2005, 12, 31)); 144 | date2->setDisplayFormat("yyyy-MM-dd"); 145 | ui->editor->add(date2); 146 | 147 | QTime sometime(21, 34, 56); 148 | CTimeProperty* time1 = new CTimeProperty(datehead, "Time1", "Time", sometime); 149 | ui->editor->add(time1); 150 | 151 | CTimeProperty* time2 = new CTimeProperty(time1, "Time2", "Time (limited)", sometime); 152 | time2->setTimeRange(QTime(8,0), QTime(20,0)); 153 | time2->setDisplayFormat("h:m:s ap"); // here be Qt bug 49234 under windows... 154 | ui->editor->add(time2); 155 | 156 | CDateTimeProperty* datetime1 = new CDateTimeProperty(datehead, "DateTime1", "Date & Time", QDateTime(somedate, sometime)); 157 | ui->editor->add(datetime1); 158 | 159 | 160 | ui->editor->adjustToContents(); 161 | } 162 | 163 | TestWidget::~TestWidget() 164 | { 165 | delete ui; 166 | } 167 | 168 | -------------------------------------------------------------------------------- /testwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTWIDGET_H 2 | #define TESTWIDGET_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class TestWidget; 8 | } 9 | 10 | class TestWidget : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit TestWidget(QWidget *parent = 0); 16 | ~TestWidget(); 17 | 18 | private: 19 | Ui::TestWidget *ui; 20 | }; 21 | 22 | #endif // TESTWIDGET_H 23 | -------------------------------------------------------------------------------- /testwidget.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Icons/file-open.png 4 | Icons/info.png 5 | Icons/remove.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /testwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TestWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 492 10 | 570 11 | 12 | 13 | 14 | TestWidget 15 | 16 | 17 | 18 | 19 | 20 | 21 | 1 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | CPropertyEditor 32 | QTreeWidget 33 |
CPropertyEditor.h
34 |
35 |
36 | 37 | 38 |
39 | --------------------------------------------------------------------------------