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 * *
44 * $Revision: 21016 $ *
45 * $LastChangedBy: schultz $ *
46 * $Date: 2015-07-16 16:48:42 +0200 (Thu, 16 Jul 2015) $ *
47 * *
48 \*===========================================================================*/
49 
50 #include "SingleObjectPropertyModel.hh"
51 
52 SingleObjectPropertyModel::SingleObjectPropertyModel(QObject *parent)
53  : PropertyModel(parent),
54  widgets(0),
55  currentlySelectedIndices(),
56  currentlyVisualizedIndices()
57 {
58  gatherProperties();
59  QVBoxLayout* layout = new QVBoxLayout();
60  widgets = new QWidget();
61  widgets->setLayout(layout);
62 }
63 
64 SingleObjectPropertyModel::~SingleObjectPropertyModel()
65 {
66  for (unsigned int i = 0; i < propertyVisualizers.size(); i++)
67  delete propertyVisualizers[i];
68 }
69 
74 void SingleObjectPropertyModel::visualize(QModelIndexList selectedIndices, QWidgetList widgets)
75 {
76  for (int i = 0; i < selectedIndices.size(); ++i)
77  {
78  const int row = selectedIndices[i].row();
79 
80  if (widgets.empty())
81  {
82  propertyVisualizers[row]->visualize(true, 0);
83  }
84  else
85  {
86  propertyVisualizers[row]->visualize(true, widgets[i]);
87  }
88 
89  //delete index and reinsert so it is the last element.
90  std::vector<unsigned int>& vec = currentlyVisualizedIndices;
91  vec.erase(std::remove(vec.begin(), vec.end(), row), vec.end());
92  vec.push_back(row);
93  }
94 }
95 
96 void SingleObjectPropertyModel::removeProperty(QModelIndexList selectedIndices)
97 {
98  std::vector<unsigned int> deleteIndices;
99 
100  for (QModelIndexList::Iterator it = selectedIndices.begin(); it != selectedIndices.end(); ++it)
101  {
102  propertyVisualizers[it->row()]->removeProperty();
103  QWidget* w = propertyVisualizers[it->row()]->getWidget();
104  widgets->layout()->removeWidget(w);
105  delete propertyVisualizers[it->row()];
106  propertyVisualizers[it->row()] = 0;
107  deleteIndices.push_back(it->row());
108  }
109 
110  std::sort(deleteIndices.begin(), deleteIndices.end());
111 
112  for (int i = deleteIndices.size()-1; i >= 0; i--)
113  {
114  for (int j = currentlyVisualizedIndices.size()-1; j >= 0; j--)
115  {
116  if (currentlyVisualizedIndices[j] == deleteIndices[i])
117  //erase so the deleted property will not be revisualized on updateObject
118  currentlyVisualizedIndices.erase(currentlyVisualizedIndices.begin() + j);
119  else if (currentlyVisualizedIndices[j] > deleteIndices[i])
120  //decrease index by one since the index of all property visualizers in propertyVisualizers
121  //shifts by one for each property visualizer that gets deleted in front of them
122  currentlyVisualizedIndices[j]--;
123  }
124  }
125 
126  for (int i = deleteIndices.size()-1; i >= 0; i--){
127  propertyVisualizers.erase(propertyVisualizers.begin() + deleteIndices[i]);
128  }
129 }
130 
131 void SingleObjectPropertyModel::duplicateProperty(QModelIndexList selectedIndices)
132 {
133  for (QModelIndexList::Iterator it = selectedIndices.begin(); it != selectedIndices.end(); ++it)
134  propertyVisualizers[it->row()]->duplicateProperty();
135 }
136 
137 void SingleObjectPropertyModel::clear(QModelIndexList selectedIndices) {
138  for (QModelIndexList::Iterator it = selectedIndices.begin(); it != selectedIndices.end(); ++it)
139  {
140  propertyVisualizers[it->row()]->clear();
141  std::vector<unsigned int>& vec = currentlyVisualizedIndices;
142  vec.erase(std::remove(vec.begin(), vec.end(), it->row()), vec.end());
143  }
144 }
145 
146 void SingleObjectPropertyModel::updateWidget(const QModelIndexList& selectedIndices)
147 {
148  QLayout* layout = widgets->layout();
149 
150  currentlySelectedIndices = selectedIndices;
151 
152  for (unsigned int i = 0; i < propertyVisualizers.size(); i++)
153  {
154  propertyVisualizers[i]->getWidget()->hide();
155  }
156 
157  for (QModelIndexList::const_iterator it = selectedIndices.begin(), it_end = selectedIndices.end();
158  it != it_end; ++it) {
159  QWidget* widget = propertyVisualizers[it->row()]->getWidget();
160  layout->addWidget(widget);
161  widget->show();
162  }
163  widgets->setLayout(layout);
164 }
165 
167 {
168  connect(propViz, SIGNAL(log(QString)), this, SLOT(slotLog(QString)));
169  connect(propViz, SIGNAL(log(Logtype, QString)), this, SLOT(slotLog(Logtype, QString)));
170 }
171 
172 int SingleObjectPropertyModel::rowCount(const QModelIndex & parent) const {
173  return propertyVisualizers.size();
174 }
175 
176 QVariant SingleObjectPropertyModel::data(const QModelIndex & index, int role) const {
177  switch (role) {
178  case Qt::DisplayRole:
179  return propertyVisualizers[index.row()]->getName();
180  default:
181  return QVariant::Invalid;
182  }
183 }
184 
185 QVariant SingleObjectPropertyModel::headerData(int section, Qt::Orientation orientation, int role) const {
186  switch (role) {
187  case Qt::DisplayRole:
188  return tr("Some header. %1 %2").arg(section).arg(orientation);
189  break;
190  default:
191  return QAbstractListModel::headerData(section, orientation, role);
192  }
193 }
194 
196 {
197  for (unsigned int i = 0; i < currentlyVisualizedIndices.size(); i++)
198  {
199  propertyVisualizers[currentlyVisualizedIndices[i]]->visualize(false, 0);
200  }
201 }
202 
204 {
205  QString filter = getLoadFilenameFilter();
206  QString selected_filter = tr("All Files (*)");
207 
208  QString fileName = QFileDialog::getOpenFileName(0, tr("Load Property"), QString(), filter, &selected_filter);
209 
210  return fileName;
211 }
212 
214 {
215  return tr("");
216 }
217 
218 QString SingleObjectPropertyModel::getSaveFilename(unsigned int propId)
219 {
220  QString filter(getSaveFilenameFilter(propId));
221  QString defaultName = getDefaultSaveFilename(propId);
222 
223  QString fileName = QFileDialog::getSaveFileName(0, tr("Save Property"), defaultName, filter);
224 
225  return fileName;
226 }
227 
229 {
230  QString filter= tr("All Files (*)");
231 
232  return filter;
233 }
234 
236 {
237  PropertyVisualizer* propViz = propertyVisualizers[propId];
238 
239  QString name = tr(propViz->getPropertyInfo().propName().c_str());
240 
241  if (propViz->getPropertyInfo().isVertexProp())
242  name += tr(".vprop");
243  else if (propViz->getPropertyInfo().isHalfedgeProp())
244  name += tr(".hprop");
245  else if (propViz->getPropertyInfo().isEdgeProp())
246  name += tr(".eprop");
247  else if (propViz->getPropertyInfo().isFaceProp())
248  name += tr(".fprop");
249  else if (propViz->getPropertyInfo().isHalffaceProp())
250  name += tr(".hfprop");
251  else if (propViz->getPropertyInfo().isCellProp())
252  name += tr(".cprop");
253 
254  return name;
255 }
256 
257 void SingleObjectPropertyModel::openFile(QString _filename, QFile& file_, QTextStream*& file_stream_)
258 {
259  closeFile(file_, file_stream_);
260  file_.setFileName(_filename);
261  if(file_.open(QIODevice::ReadWrite | QIODevice::Text))
262  file_stream_ = new QTextStream(&file_);
263 }
264 
265 void SingleObjectPropertyModel::closeFile(QFile& file_, QTextStream*& file_stream_)
266 {
267  if( file_stream_)
268  {
269  delete file_stream_;
270  file_stream_ = 0;
271  }
272  if(file_.exists())
273  {
274  file_.close();
275  }
276 }
277 
278 QString SingleObjectPropertyModel::readLine(QTextStream* file_stream_)
279 {
280  if(file_stream_)
281  {
282  QString s;
283  s = file_stream_->readLine();
284  return s;
285  }
286  else return QString("");
287 }
288 
289 void SingleObjectPropertyModel::writeLine(QString _s, QTextStream*& file_stream_)
290 {
291  if(file_stream_)
292  {
293  (*file_stream_) << _s << '\n';
294  }
295  else std::cerr << "Warning: filestream not available...\n";
296 }
297 
299 {
300  PropertyVisualizer* propVis = propertyVisualizers[propId];
301 
302  QString filename = getSaveFilename(propId);
303  if (filename == "") return;
304 
305  QFile file_;
306  QTextStream* file_stream_ = 0;
307 
308  openFile(filename, file_, file_stream_);
309 
310  QString header = propVis->getHeader();
311  writeLine(header, file_stream_);
312 
313  int n = propVis->getEntityCount();
314 
315  for (int i = 0; i < n; ++i)
316  {
317  QString propertyText = propVis->getPropertyText(i);
318  writeLine(propertyText, file_stream_);
319  }
320 
321  closeFile(file_, file_stream_);
322 }
323 
325 {
326 
327  QString filename = getLoadFilename();
328  if (filename == "") return;
329 
330  QFile file_;
331  QTextStream* file_stream_ = 0;
332 
333  openFile(filename, file_, file_stream_);
334 
335  QString header = readLine(file_stream_);
336 
337  PropertyVisualizer* propVis;
338  unsigned int n;
339 
340 
341  if (parseHeader(header, propVis, n))
342  {
343  setPropertyFromFile(file_stream_, n, propVis);
344  }
345  else
346  {
347  emit log("Property could not be loaded.");
348  }
349 
350  closeFile(file_, file_stream_);
351 }
352 
353 void SingleObjectPropertyModel::setPropertyFromFile(QTextStream*& file_stream_, unsigned int n, PropertyVisualizer* propVis)
354 {
355  for (unsigned int i = 0; i < n; ++i)
356  {
357  QString propertyText = readLine(file_stream_);
358  propVis->setPropertyFromText(i, propertyText);
359  }
360 }
361 
362 PropertyVisualizer* SingleObjectPropertyModel::getPropertyVisualizer(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
363 {
364  for (unsigned int i = 0; i < propertyVisualizers.size(); ++i)
365  {
366  const PropertyInfo& propInfo = propertyVisualizers[i]->getPropertyInfo();
367  if ((propInfo.entityType() == filter) && (QString::compare(tr(propInfo.propName().c_str()), propName)==0) && (propInfo.typeinfo() == typeInfo))
368  return propertyVisualizers[i];
369  }
370  return 0;
371 }
372 
373 bool SingleObjectPropertyModel::isPropertyFree(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
374 {
375  return getPropertyVisualizer(propName, filter, typeInfo) == 0;
376 }
377 
379 {
380  return propertyVisualizers[index.row()]->getPropertyInfo();
381 }
virtual void setPropertyFromFile(QTextStream *&file_stream_, unsigned int n, PropertyVisualizer *propVis)
Sets the property values from a given file.
virtual void removeProperty(QModelIndexList selectedIndices)
Removes the selected properties.
void writeLine(QString _s, QTextStream *&file_stream_)
Writes a line to a file.
virtual void updateWidget(const QModelIndexList &selectedIndices)
Updates the widget.
virtual void setPropertyFromText(unsigned int index, QString text)=0
Returns the value of a property in text form.
Cellection of information about a property.
Definition: Utils.hh:115
Logtype
Log types for Message Window.
const PropertyInfo & getPropertyInfo() const
Returns the PropertyInfo.
This class vizualizes a property.
QString getSaveFilename(unsigned int propId)
Asks the user for a file to load.
virtual QString getHeader()=0
Returns the header for saving.
virtual int getEntityCount()=0
Returns the number of entities.
virtual void clear(QModelIndexList selectedIndices)
Clears the selected property visualization.
virtual QString getDefaultSaveFilename(unsigned int propId)
Returns the default file name.
void openFile(QString _filename, QFile &file_, QTextStream *&file_stream_)
Opens a file.
virtual void visualize(QModelIndexList selectedIndices, QWidgetList widgets=QWidgetList())
Visualizes the selected properties.
virtual PropertyInfo getPropertyInfo(const QModelIndex index) const
Returns the property info for the property with the given index.
virtual QString getLoadFilenameFilter()
Returns the filename filter for loading.
virtual QString getPropertyText(unsigned int i)=0
Returns the value of a property in text form.
QString getLoadFilename()
Asks the user for a file to load.
bool isPropertyFree(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Checks if the property name is still available.
void connectLogs(PropertyVisualizer *propViz)
Connects the PropertyVisualizer log signals with the log slot.
PropertyVisualizer * getPropertyVisualizer(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Returns a PropertyVisualizer.
void closeFile(QFile &file_, QTextStream *&file_stream_)
Closes a file.
QString readLine(QTextStream *file_stream_)
Read line from a file.
void saveProperty(unsigned int propId)
Saves property.
Wraps the information of a type.
Definition: Utils.hh:79
virtual void objectUpdated()
Revisualizes visualized properties.
virtual void duplicateProperty(QModelIndexList selectedIndices)
Duplicates the selected properties.
virtual QString getSaveFilenameFilter(unsigned int propId)
Returns the filename filter for saving.