diff options
Diffstat (limited to 'utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp')
-rw-r--r-- | utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp new file mode 100644 index 0000000000..b147cd089d --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp | |||
@@ -0,0 +1,236 @@ | |||
1 | // ************************************************************************************************* | ||
2 | // | ||
3 | // QPropertyEditor v 0.1 | ||
4 | // | ||
5 | // -------------------------------------- | ||
6 | // Copyright (C) 2007 Volker Wiendl | ||
7 | // | ||
8 | // | ||
9 | // This library is free software; you can redistribute it and/or | ||
10 | // modify it under the terms of the GNU Lesser General Public | ||
11 | // License as published by the Free Software Foundation; either | ||
12 | // version 2.1 of the License, or any later version. | ||
13 | // | ||
14 | // This library is distributed in the hope that it will be useful, | ||
15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | // Lesser General Public License for more details. | ||
18 | // | ||
19 | // You should have received a copy of the GNU Lesser General Public | ||
20 | // License along with this library; if not, write to the Free Software | ||
21 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | // | ||
23 | // ************************************************************************************************* | ||
24 | |||
25 | #include "QPropertyModel.h" | ||
26 | |||
27 | #include "Property.h" | ||
28 | |||
29 | #include <Qt/qapplication.h> | ||
30 | #include <Qt/qmetaobject.h> | ||
31 | #include <Qt/qitemeditorfactory.h> | ||
32 | |||
33 | struct PropertyPair { | ||
34 | PropertyPair(const QMetaObject* obj, QMetaProperty property) : Property(property), Object(obj) {} | ||
35 | |||
36 | QMetaProperty Property; | ||
37 | const QMetaObject* Object; | ||
38 | |||
39 | bool operator==(const PropertyPair& other) const { | ||
40 | return QString(other.Property.name()) == QString(Property.name()); | ||
41 | } | ||
42 | }; | ||
43 | |||
44 | |||
45 | QPropertyModel::QPropertyModel(QObject* parent /*= 0*/) : QAbstractItemModel(parent), m_userCallback(0) { | ||
46 | m_rootItem = new Property("Root",0, this); | ||
47 | } | ||
48 | |||
49 | |||
50 | QPropertyModel::~QPropertyModel() {} | ||
51 | |||
52 | QModelIndex QPropertyModel::index ( int row, int column, const QModelIndex & parent /*= QModelIndex()*/ ) const { | ||
53 | Property *parentItem = m_rootItem; | ||
54 | if (parent.isValid()) | ||
55 | parentItem = static_cast<Property*>(parent.internalPointer()); | ||
56 | if (row >= parentItem->children().size()) | ||
57 | return QModelIndex(); | ||
58 | return createIndex(row, column, parentItem->children().at(row)); | ||
59 | |||
60 | } | ||
61 | |||
62 | QModelIndex QPropertyModel::parent ( const QModelIndex & index ) const { | ||
63 | if (!index.isValid()) | ||
64 | return QModelIndex(); | ||
65 | |||
66 | Property *childItem = static_cast<Property*>(index.internalPointer()); | ||
67 | Property *parentItem = qobject_cast<Property*>(childItem->parent()); | ||
68 | |||
69 | if (!parentItem || parentItem == m_rootItem) | ||
70 | return QModelIndex(); | ||
71 | |||
72 | return createIndex(parentItem->row(), 0, parentItem); | ||
73 | } | ||
74 | |||
75 | int QPropertyModel::rowCount ( const QModelIndex & parent /*= QModelIndex()*/ ) const { | ||
76 | Property *parentItem = m_rootItem; | ||
77 | if (parent.isValid()) | ||
78 | parentItem = static_cast<Property*>(parent.internalPointer()); | ||
79 | return parentItem->children().size(); | ||
80 | } | ||
81 | |||
82 | int QPropertyModel::columnCount ( const QModelIndex & parent /*= QModelIndex()*/ ) const { | ||
83 | (void)parent; | ||
84 | return 2; | ||
85 | } | ||
86 | |||
87 | QVariant QPropertyModel::data ( const QModelIndex & index, int role /*= Qt::DisplayRole*/ ) const { | ||
88 | if (!index.isValid()) | ||
89 | return QVariant(); | ||
90 | |||
91 | Property *item = static_cast<Property*>(index.internalPointer()); | ||
92 | switch (role) { | ||
93 | case Qt::ToolTipRole: | ||
94 | case Qt::DecorationRole: | ||
95 | case Qt::DisplayRole: | ||
96 | case Qt::EditRole: | ||
97 | if (index.column() == 0) | ||
98 | return item->objectName(); | ||
99 | if (index.column() == 1) | ||
100 | return item->value(role); | ||
101 | case Qt::BackgroundRole: | ||
102 | if (item->isRoot()) return QApplication::palette("QTreeView").brush(QPalette::Normal, QPalette::Button).color(); | ||
103 | break; | ||
104 | }; | ||
105 | return QVariant(); | ||
106 | } | ||
107 | |||
108 | // edit methods | ||
109 | bool QPropertyModel::setData ( const QModelIndex & index, const QVariant & value, int role /*= Qt::EditRole*/ ) { | ||
110 | if (index.isValid() && role == Qt::EditRole) { | ||
111 | Property *item = static_cast<Property*>(index.internalPointer()); | ||
112 | item->setValue(value); | ||
113 | emit dataChanged(index, index); | ||
114 | return true; | ||
115 | } | ||
116 | return false; | ||
117 | } | ||
118 | |||
119 | Qt::ItemFlags QPropertyModel::flags ( const QModelIndex & index ) const { | ||
120 | if (!index.isValid()) | ||
121 | return Qt::ItemIsEnabled; | ||
122 | Property *item = static_cast<Property*>(index.internalPointer()); | ||
123 | // only allow change of value attribute | ||
124 | if (item->isRoot()) | ||
125 | return Qt::ItemIsEnabled; | ||
126 | else if (item->isReadOnly()) | ||
127 | return Qt::ItemIsDragEnabled | Qt::ItemIsSelectable; | ||
128 | else | ||
129 | return Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; | ||
130 | } | ||
131 | |||
132 | |||
133 | QVariant QPropertyModel::headerData ( int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole*/ ) const { | ||
134 | if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { | ||
135 | switch (section) { | ||
136 | case 0: | ||
137 | return tr("Name"); | ||
138 | case 1: | ||
139 | return tr("Value"); | ||
140 | } | ||
141 | } | ||
142 | return QVariant(); | ||
143 | } | ||
144 | |||
145 | QModelIndex QPropertyModel::buddy ( const QModelIndex & index ) const { | ||
146 | if (index.isValid() && index.column() == 0) | ||
147 | return createIndex(index.row(), 1, index.internalPointer()); | ||
148 | return index; | ||
149 | } | ||
150 | |||
151 | void QPropertyModel::addItem(QObject *propertyObject) { | ||
152 | // first create property <-> class hierarchy | ||
153 | QList<PropertyPair> propertyMap; | ||
154 | QList<const QMetaObject*> classList; | ||
155 | const QMetaObject* metaObject = propertyObject->metaObject(); | ||
156 | do { | ||
157 | int count = metaObject->propertyCount(); | ||
158 | for (int i=0; i<count; ++i) { | ||
159 | QMetaProperty property = metaObject->property(i); | ||
160 | if (property.isUser()) // Hide Qt specific properties | ||
161 | { | ||
162 | PropertyPair pair(metaObject, property); | ||
163 | int index = propertyMap.indexOf(pair); | ||
164 | if (index != -1) | ||
165 | propertyMap[index] = pair; | ||
166 | else | ||
167 | propertyMap.push_back(pair); | ||
168 | } | ||
169 | } | ||
170 | classList.push_front(metaObject); | ||
171 | } while ((metaObject = metaObject->superClass())!=0); | ||
172 | |||
173 | QList<const QMetaObject*> finalClassList; | ||
174 | // remove empty classes from hierarchy list | ||
175 | foreach(const QMetaObject* obj, classList) { | ||
176 | bool keep = false; | ||
177 | foreach(PropertyPair pair, propertyMap) { | ||
178 | if (pair.Object == obj) { | ||
179 | keep = true; | ||
180 | break; | ||
181 | } | ||
182 | } | ||
183 | if (keep) | ||
184 | finalClassList.push_back(obj); | ||
185 | } | ||
186 | |||
187 | // finally insert properties for classes containing them | ||
188 | int i=rowCount(); | ||
189 | beginInsertRows(QModelIndex(), i, i + finalClassList.count()); | ||
190 | foreach(const QMetaObject* metaObject, finalClassList) { | ||
191 | // Set default name of the hierarchy property to the class name | ||
192 | QString name = metaObject->className(); | ||
193 | // Check if there is a special name for the class | ||
194 | int index = metaObject->indexOfClassInfo(qPrintable(name)); | ||
195 | if (index != -1) | ||
196 | name = metaObject->classInfo(index).value(); | ||
197 | // Create Property Item for class node | ||
198 | Property* propertyItem = new Property(name, 0, m_rootItem); | ||
199 | foreach(PropertyPair pair, propertyMap) { | ||
200 | // Check if the property is associated with the current class from the finalClassList | ||
201 | if (pair.Object == metaObject) { | ||
202 | QMetaProperty property(pair.Property); | ||
203 | Property* p = 0; | ||
204 | if (property.type() == QVariant::UserType && m_userCallback) | ||
205 | p = m_userCallback(property.name(), propertyObject, propertyItem); | ||
206 | else | ||
207 | p = new Property(property.name(), propertyObject, propertyItem); | ||
208 | int index = metaObject->indexOfClassInfo(property.name()); | ||
209 | if (index != -1) | ||
210 | p->setEditorHints(metaObject->classInfo(index).value()); | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | endInsertRows(); | ||
215 | } | ||
216 | |||
217 | void QPropertyModel::updateItem ( QObject* propertyObject, const QModelIndex& parent /*= QModelIndex() */ ) { | ||
218 | Property *parentItem = m_rootItem; | ||
219 | if (parent.isValid()) | ||
220 | parentItem = static_cast<Property*>(parent.internalPointer()); | ||
221 | if (parentItem->propertyObject() != propertyObject) | ||
222 | parentItem = parentItem->findPropertyObject(propertyObject); | ||
223 | if (parentItem) // Indicate view that the data for the indices have changed | ||
224 | dataChanged(createIndex(parentItem->row(), 0, static_cast<Property*>(parentItem)), createIndex(parentItem->row(), 1, static_cast<Property*>(parentItem))); | ||
225 | } | ||
226 | |||
227 | void QPropertyModel::clear() { | ||
228 | beginRemoveRows(QModelIndex(), 0, rowCount()); | ||
229 | delete m_rootItem; | ||
230 | m_rootItem = new Property("Root",0, this); | ||
231 | endRemoveRows(); | ||
232 | } | ||
233 | |||
234 | void QPropertyModel::setCustomPropertyCB(QPropertyEditorWidget::UserTypeCB callback) { | ||
235 | m_userCallback = callback; | ||
236 | } | ||