Developer Documentation
SingleObjectPropertyModel.cc
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39* *
40\*===========================================================================*/
41
42
43#include "SingleObjectPropertyModel.hh"
44#include "ScriptObjects/ScriptSettings.hh"
45
46#include <QTextStream>
47
48SingleObjectPropertyModel::SingleObjectPropertyModel(QObject *parent)
49 : PropertyModel(parent),
50 widgets(0),
51 currentlySelectedIndices(),
52 currentlyVisualizedIndices()
53{
54 gatherProperties();
55 QVBoxLayout* layout = new QVBoxLayout();
56 widgets = new QWidget();
57 widgets->setLayout(layout);
58}
59
60SingleObjectPropertyModel::~SingleObjectPropertyModel()
61{
62 for (unsigned int i = 0; i < propertyVisualizers.size(); i++)
63 delete propertyVisualizers[i];
64}
65
70void SingleObjectPropertyModel::visualize(QModelIndexList selectedIndices, QWidgetList widgets)
71{
72 for (int i = 0; i < selectedIndices.size(); ++i)
73 {
74 const int row = selectedIndices[i].row();
75
76 if (widgets.empty())
77 {
78 propertyVisualizers[row]->visualize(true, 0);
79 }
80 else
81 {
82 propertyVisualizers[row]->visualize(true, widgets[i]);
83 }
84
85 //delete index and reinsert so it is the last element.
86 std::vector<unsigned int>& vec = currentlyVisualizedIndices;
87 vec.erase(std::remove(vec.begin(), vec.end(), row), vec.end());
88 vec.push_back(row);
89 }
90}
91
92void SingleObjectPropertyModel::removeProperty(QModelIndexList selectedIndices)
93{
94 std::vector<unsigned int> deleteIndices;
95
96 for (QModelIndexList::Iterator it = selectedIndices.begin(); it != selectedIndices.end(); ++it)
97 {
98 propertyVisualizers[it->row()]->removeProperty();
99 QWidget* w = propertyVisualizers[it->row()]->getWidget();
100 widgets->layout()->removeWidget(w);
101 delete propertyVisualizers[it->row()];
102 propertyVisualizers[it->row()] = 0;
103 deleteIndices.push_back(it->row());
104 }
105
106 std::sort(deleteIndices.begin(), deleteIndices.end());
107
108 for (int i = deleteIndices.size()-1; i >= 0; i--)
109 {
110 for (int j = currentlyVisualizedIndices.size()-1; j >= 0; j--)
111 {
112 if (currentlyVisualizedIndices[j] == deleteIndices[i])
113 //erase so the deleted property will not be revisualized on updateObject
114 currentlyVisualizedIndices.erase(currentlyVisualizedIndices.begin() + j);
115 else if (currentlyVisualizedIndices[j] > deleteIndices[i])
116 //decrease index by one since the index of all property visualizers in propertyVisualizers
117 //shifts by one for each property visualizer that gets deleted in front of them
118 currentlyVisualizedIndices[j]--;
119 }
120 }
121
122 for (int i = deleteIndices.size()-1; i >= 0; i--){
123 propertyVisualizers.erase(propertyVisualizers.begin() + deleteIndices[i]);
124 }
125}
126
127void SingleObjectPropertyModel::duplicateProperty(QModelIndexList selectedIndices)
128{
129 for (QModelIndexList::Iterator it = selectedIndices.begin(); it != selectedIndices.end(); ++it)
130 propertyVisualizers[it->row()]->duplicateProperty();
131}
132
133void SingleObjectPropertyModel::clear(QModelIndexList selectedIndices) {
134 for (QModelIndexList::Iterator it = selectedIndices.begin(); it != selectedIndices.end(); ++it)
135 {
136 propertyVisualizers[it->row()]->clear();
137 std::vector<unsigned int>& vec = currentlyVisualizedIndices;
138 vec.erase(std::remove(vec.begin(), vec.end(), it->row()), vec.end());
139 }
140}
141
142void SingleObjectPropertyModel::updateWidget(const QModelIndexList& selectedIndices)
143{
144 QLayout* layout = widgets->layout();
145
146 currentlySelectedIndices = selectedIndices;
147
148 for (unsigned int i = 0; i < propertyVisualizers.size(); i++)
149 {
150 propertyVisualizers[i]->getWidget()->hide();
151 }
152
153 for (QModelIndexList::const_iterator it = selectedIndices.begin(), it_end = selectedIndices.end();
154 it != it_end; ++it) {
155 QWidget* widget = propertyVisualizers[it->row()]->getWidget();
156 layout->addWidget(widget);
157 widget->show();
158 }
159 widgets->setLayout(layout);
160}
161
163{
164 connect(propViz, SIGNAL(log(QString)), this, SLOT(slotLog(QString)));
165 connect(propViz, SIGNAL(log(Logtype, QString)), this, SLOT(slotLog(Logtype, QString)));
166}
167
168int SingleObjectPropertyModel::rowCount(const QModelIndex & parent) const {
169 return propertyVisualizers.size();
170}
171
172QVariant SingleObjectPropertyModel::data(const QModelIndex & index, int role) const {
173 switch (role) {
174 case Qt::DisplayRole:
175 return propertyVisualizers[index.row()]->getName();
176 default:
177// return QVariant::Invalid;
178 return QVariant{};
179 }
180}
181
182QVariant SingleObjectPropertyModel::headerData(int section, Qt::Orientation orientation, int role) const {
183 switch (role) {
184 case Qt::DisplayRole:
185 return tr("Some header. %1 %2").arg(section).arg(orientation);
186 break;
187 default:
188 return QAbstractListModel::headerData(section, orientation, role);
189 }
190}
191
192QModelIndex SingleObjectPropertyModel::index(int row, int column, const QModelIndex &parent) const
193{
194 (void)parent;
195 return createIndex(row, column, propertyVisualizers[row]);
196}
197
199{
200 for (unsigned int i = 0; i < currentlyVisualizedIndices.size(); i++)
201 {
202 propertyVisualizers[currentlyVisualizedIndices[i]]->visualize(false, 0);
203 }
204}
205
207{
208 QString filter = getLoadFilenameFilter();
209 QString selected_filter = tr("All Files (*)");
210
211 QString fileName = QFileDialog::getOpenFileName(0, tr("Load Property"), QString(), filter, &selected_filter);
212
213 return fileName;
214}
215
217{
218 return tr("");
219}
220
222{
223 QString filter(getSaveFilenameFilter(propId));
224 QString defaultName = getDefaultSaveFilename(propId);
225
226 QString fileName = QFileDialog::getSaveFileName(0, tr("Save Property"), defaultName, filter);
227
228 return fileName;
229}
230
232{
233 QString filter= tr("All Files (*)");
234
235 return filter;
236}
237
239{
240 PropertyVisualizer* propViz = propertyVisualizers[propId];
241
242 QString name = tr(propViz->getPropertyInfo().propName().c_str());
243
244 if (propViz->getPropertyInfo().isVertexProp())
245 name += tr(".vprop");
246 else if (propViz->getPropertyInfo().isHalfedgeProp())
247 name += tr(".hprop");
248 else if (propViz->getPropertyInfo().isEdgeProp())
249 name += tr(".eprop");
250 else if (propViz->getPropertyInfo().isFaceProp())
251 name += tr(".fprop");
252 else if (propViz->getPropertyInfo().isHalffaceProp())
253 name += tr(".hfprop");
254 else if (propViz->getPropertyInfo().isCellProp())
255 name += tr(".cprop");
256
257 return name;
258}
259
261{
262 PropertyVisualizer* propVis = propertyVisualizers[propId];
263
264 QString filename = getSaveFilename(propId);
265 if (filename == "") return;
266
267 QFile file(filename);
268 if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
269 std::cerr << "PropertyVis saveProperty(): cannot open file for writing" << std::endl;
270 return;
271 }
272 QTextStream file_stream(&file);
273
274 file_stream << propVis->getHeader() << '\n';
275
276 int n = propVis->getEntityCount();
277 for (int i = 0; i < n; ++i)
278 {
279 QString propertyText = propVis->getPropertyText(i);
280 file_stream << propertyText << '\n';
281 }
282}
283
285{
286
287 QString filename = getLoadFilename();
288 if (filename == "") return;
289
290 QFile file(filename);
291 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
292 std::cerr << "PropertyVis loadProperty(): cannot open file for reading" << std::endl;
293 return;
294 }
295
296 QTextStream file_stream(&file);
297
298 QString header = file_stream.readLine();
299 PropertyVisualizer* propVis;
300 unsigned int n;
301
302 if (parseHeader(header, propVis, n))
303 {
304 setPropertyFromFile(file_stream, n, propVis);
305 }
306 else
307 {
308 emit log("Property could not be loaded.");
309 }
310
311}
312
313void SingleObjectPropertyModel::setPropertyFromFile(QTextStream& file_stream, unsigned int n, PropertyVisualizer* propVis)
314{
315 for (unsigned int i = 0; i < n; ++i)
316 {
317 QString propertyText = file_stream.readLine();
318 propVis->setPropertyFromText(i, propertyText);
319 }
320}
321
322PropertyVisualizer* SingleObjectPropertyModel::getPropertyVisualizer(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
323{
324 for (unsigned int i = 0; i < propertyVisualizers.size(); ++i)
325 {
326 const PropertyInfo& propInfo = propertyVisualizers[i]->getPropertyInfo();
327 if ((propInfo.entityType() == filter) && (QString::compare(tr(propInfo.propName().c_str()), propName)==0) && (propInfo.typeinfo() == typeInfo))
328 return propertyVisualizers[i];
329 }
330 return 0;
331}
332
333bool SingleObjectPropertyModel::isPropertyFree(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
334{
335 return getPropertyVisualizer(propName, filter, typeInfo) == 0;
336}
337
339{
340 return propertyVisualizers[index.row()]->getPropertyInfo();
341}
342
343#if QT_VERSION_MAJOR < 6
344QScriptValue SingleObjectPropertyModel::getScriptObject(const QModelIndex index, QScriptContext *ctx)
345{
346 PropertyVisualizer* vis = propertyVisualizers[index.row()];
347 return createSettingsScriptObject(ctx, vis->getWidget());
348}
349#endif
Logtype
Log types for Message Window.
Cellection of information about a property.
Definition: Utils.hh:109
This class vizualizes a property.
virtual int getEntityCount()=0
Returns the number of entities.
virtual QString getHeader()=0
Returns the header for saving.
virtual QString getPropertyText(unsigned int i)=0
Returns the value of a property in text form.
const PropertyInfo & getPropertyInfo() const
Returns the PropertyInfo.
virtual void setPropertyFromText(unsigned int index, QString text)=0
Returns the value of a property in text form.
virtual QWidget * getWidget()
Returns the visualizer's widget.
void connectLogs(PropertyVisualizer *propViz) override
Connects the PropertyVisualizer log signals with the log slot.
virtual void updateWidget(const QModelIndexList &selectedIndices) override
Updates the widget.
virtual void objectUpdated() override
Revisualizes visualized properties.
virtual void removeProperty(QModelIndexList selectedIndices) override
Removes the selected properties.
virtual QString getSaveFilenameFilter(unsigned int propId)
Returns the filename filter for saving.
virtual bool parseHeader(QString header, PropertyVisualizer *&propVis, unsigned int &n)
Parses the property file header.
bool isPropertyFree(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Checks if the property name is still available.
virtual QScriptValue getScriptObject(const QModelIndex index, QScriptContext *ctx)
Returns a qscript object that can be used to access visualisation parameters.
virtual void duplicateProperty(QModelIndexList selectedIndices) override
Duplicates the selected properties.
void saveProperty(unsigned int propId)
Saves property.
virtual QString getLoadFilenameFilter()
Returns the filename filter for loading.
QString getSaveFilename(unsigned int propId)
Asks the user for a file to load.
virtual QString getDefaultSaveFilename(unsigned int propId)
Returns the default file name.
virtual void visualize(QModelIndexList selectedIndices, QWidgetList widgets=QWidgetList()) override
Visualizes the selected properties.
virtual void clear(QModelIndexList selectedIndices) override
Clears the selected property visualization.
QString getLoadFilename()
Asks the user for a file to load.
PropertyVisualizer * getPropertyVisualizer(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Returns a PropertyVisualizer.
virtual void setPropertyFromFile(QTextStream &file_stream, unsigned int n, PropertyVisualizer *propVis)
Sets the property values from a given file.
virtual PropertyInfo getPropertyInfo(const QModelIndex index) const override
Returns the property info for the property with the given index.
Wraps the information of a type.
Definition: Utils.hh:73