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 
48 SingleObjectPropertyModel::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 
60 SingleObjectPropertyModel::~SingleObjectPropertyModel()
61 {
62  for (unsigned int i = 0; i < propertyVisualizers.size(); i++)
63  delete propertyVisualizers[i];
64 }
65 
70 void 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 
92 void 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 
127 void SingleObjectPropertyModel::duplicateProperty(QModelIndexList selectedIndices)
128 {
129  for (QModelIndexList::Iterator it = selectedIndices.begin(); it != selectedIndices.end(); ++it)
130  propertyVisualizers[it->row()]->duplicateProperty();
131 }
132 
133 void 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 
142 void 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 
168 int SingleObjectPropertyModel::rowCount(const QModelIndex & parent) const {
169  return propertyVisualizers.size();
170 }
171 
172 QVariant 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  }
179 }
180 
181 QVariant SingleObjectPropertyModel::headerData(int section, Qt::Orientation orientation, int role) const {
182  switch (role) {
183  case Qt::DisplayRole:
184  return tr("Some header. %1 %2").arg(section).arg(orientation);
185  break;
186  default:
187  return QAbstractListModel::headerData(section, orientation, role);
188  }
189 }
190 
192 {
193  for (unsigned int i = 0; i < currentlyVisualizedIndices.size(); i++)
194  {
195  propertyVisualizers[currentlyVisualizedIndices[i]]->visualize(false, 0);
196  }
197 }
198 
200 {
201  QString filter = getLoadFilenameFilter();
202  QString selected_filter = tr("All Files (*)");
203 
204  QString fileName = QFileDialog::getOpenFileName(0, tr("Load Property"), QString(), filter, &selected_filter);
205 
206  return fileName;
207 }
208 
210 {
211  return tr("");
212 }
213 
214 QString SingleObjectPropertyModel::getSaveFilename(unsigned int propId)
215 {
216  QString filter(getSaveFilenameFilter(propId));
217  QString defaultName = getDefaultSaveFilename(propId);
218 
219  QString fileName = QFileDialog::getSaveFileName(0, tr("Save Property"), defaultName, filter);
220 
221  return fileName;
222 }
223 
225 {
226  QString filter= tr("All Files (*)");
227 
228  return filter;
229 }
230 
232 {
233  PropertyVisualizer* propViz = propertyVisualizers[propId];
234 
235  QString name = tr(propViz->getPropertyInfo().propName().c_str());
236 
237  if (propViz->getPropertyInfo().isVertexProp())
238  name += tr(".vprop");
239  else if (propViz->getPropertyInfo().isHalfedgeProp())
240  name += tr(".hprop");
241  else if (propViz->getPropertyInfo().isEdgeProp())
242  name += tr(".eprop");
243  else if (propViz->getPropertyInfo().isFaceProp())
244  name += tr(".fprop");
245  else if (propViz->getPropertyInfo().isHalffaceProp())
246  name += tr(".hfprop");
247  else if (propViz->getPropertyInfo().isCellProp())
248  name += tr(".cprop");
249 
250  return name;
251 }
252 
254 {
255  PropertyVisualizer* propVis = propertyVisualizers[propId];
256 
257  QString filename = getSaveFilename(propId);
258  if (filename == "") return;
259 
260  QFile file(filename);
261  if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
262  std::cerr << "PropertyVis saveProperty(): cannot open file for writing" << std::endl;
263  return;
264  }
265  QTextStream file_stream(&file);
266 
267  file_stream << propVis->getHeader() << '\n';
268 
269  int n = propVis->getEntityCount();
270  for (int i = 0; i < n; ++i)
271  {
272  QString propertyText = propVis->getPropertyText(i);
273  file_stream << propertyText << '\n';
274  }
275 }
276 
278 {
279 
280  QString filename = getLoadFilename();
281  if (filename == "") return;
282 
283  QFile file(filename);
284  if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
285  std::cerr << "PropertyVis loadProperty(): cannot open file for reading" << std::endl;
286  return;
287  }
288 
289  QTextStream file_stream(&file);
290 
291  QString header = file_stream.readLine();
292  PropertyVisualizer* propVis;
293  unsigned int n;
294 
295  if (parseHeader(header, propVis, n))
296  {
297  setPropertyFromFile(file_stream, n, propVis);
298  }
299  else
300  {
301  emit log("Property could not be loaded.");
302  }
303 
304 }
305 
306 void SingleObjectPropertyModel::setPropertyFromFile(QTextStream& file_stream, unsigned int n, PropertyVisualizer* propVis)
307 {
308  for (unsigned int i = 0; i < n; ++i)
309  {
310  QString propertyText = file_stream.readLine();
311  propVis->setPropertyFromText(i, propertyText);
312  }
313 }
314 
315 PropertyVisualizer* SingleObjectPropertyModel::getPropertyVisualizer(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
316 {
317  for (unsigned int i = 0; i < propertyVisualizers.size(); ++i)
318  {
319  const PropertyInfo& propInfo = propertyVisualizers[i]->getPropertyInfo();
320  if ((propInfo.entityType() == filter) && (QString::compare(tr(propInfo.propName().c_str()), propName)==0) && (propInfo.typeinfo() == typeInfo))
321  return propertyVisualizers[i];
322  }
323  return 0;
324 }
325 
326 bool SingleObjectPropertyModel::isPropertyFree(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
327 {
328  return getPropertyVisualizer(propName, filter, typeInfo) == 0;
329 }
330 
332 {
333  return propertyVisualizers[index.row()]->getPropertyInfo();
334 }
335 
336 QScriptValue SingleObjectPropertyModel::getScriptObject(const QModelIndex index, QScriptContext *ctx)
337 {
338  PropertyVisualizer* vis = propertyVisualizers[index.row()];
339  return createSettingsScriptObject(ctx, vis->getWidget());
340 }
virtual QString getDefaultSaveFilename(unsigned int propId)
Returns the default file name.
virtual void duplicateProperty(QModelIndexList selectedIndices)
Duplicates the selected properties.
virtual QString getHeader()=0
Returns the header for saving.
QString getLoadFilename()
Asks the user for a file to load.
Logtype
Log types for Message Window.
void connectLogs(PropertyVisualizer *propViz)
Connects the PropertyVisualizer log signals with the log slot.
virtual void objectUpdated()
Revisualizes visualized properties.
const PropertyInfo & getPropertyInfo() const
Returns the PropertyInfo.
PropertyVisualizer * getPropertyVisualizer(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Returns a PropertyVisualizer.
virtual QString getSaveFilenameFilter(unsigned int propId)
Returns the filename filter for saving.
QString getSaveFilename(unsigned int propId)
Asks the user for a file to load.
virtual void setPropertyFromText(unsigned int index, QString text)=0
Returns the value of a property in text form.
Wraps the information of a type.
Definition: Utils.hh:73
virtual void updateWidget(const QModelIndexList &selectedIndices)
Updates the widget.
virtual void visualize(QModelIndexList selectedIndices, QWidgetList widgets=QWidgetList())
Visualizes the selected properties.
virtual int getEntityCount()=0
Returns the number of entities.
virtual void setPropertyFromFile(QTextStream &file_stream, unsigned int n, PropertyVisualizer *propVis)
Sets the property values from a given file.
This class vizualizes a property.
virtual void removeProperty(QModelIndexList selectedIndices)
Removes the selected properties.
virtual QWidget * getWidget()
Returns the visualizer&#39;s widget.
bool isPropertyFree(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Checks if the property name is still available.
void saveProperty(unsigned int propId)
Saves property.
virtual QScriptValue getScriptObject(const QModelIndex index, QScriptContext *ctx)
Returns a qscript object that can be used to access visualisation parameters.
virtual PropertyInfo getPropertyInfo(const QModelIndex index) const
Returns the property info for the property with the given index.
virtual QString getPropertyText(unsigned int i)=0
Returns the value of a property in text form.
Cellection of information about a property.
Definition: Utils.hh:109
virtual void clear(QModelIndexList selectedIndices)
Clears the selected property visualization.
virtual QString getLoadFilenameFilter()
Returns the filename filter for loading.