Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkPropertyDelegate.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #ifndef NOMINMAX
18 #define NOMINMAX
19 #endif
20 
21 #include "QmitkPropertyDelegate.h"
22 
23 #include "QmitkCustomVariants.h"
24 
25 #include "mitkRenderingManager.h"
26 
27 #include <QApplication>
28 #include <QCheckBox>
29 #include <QColorDialog>
30 #include <QComboBox>
31 #include <QDoubleSpinBox>
32 #include <QLabel>
33 #include <QMessageBox>
34 #include <QPainter>
35 #include <QPen>
36 #include <QPushButton>
37 #include <QStringList>
38 #include <bitset>
39 
41 {
42 }
43 
44 void QmitkPropertyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
45 {
46  QVariant data = index.data(Qt::DisplayRole);
47 
48  QString name = data.value<QString>();
49 
50  if (index.column() == 1 && data.type() == QVariant::Color)
51  {
52  QColor qcol = data.value<QColor>();
53 
54  painter->save();
55  painter->fillRect(option.rect, qcol);
56  QRect rect = option.rect;
57  rect.setWidth(rect.width() - 1);
58  rect.setHeight(rect.height() - 1);
59  QPen pen;
60  pen.setWidth(1);
61  painter->setPen(pen);
62  painter->drawRect(rect);
63  painter->restore();
64  }
65  else
66  {
67  QStyledItemDelegate::paint(painter, option, index);
68  }
69 }
70 
71 QWidget *QmitkPropertyDelegate::createEditor(QWidget *parent,
72  const QStyleOptionViewItem &option,
73  const QModelIndex &index) const
74 {
75  QVariant data = index.data(Qt::EditRole);
76  QVariant displayData = index.data(Qt::DisplayRole);
77  QString name = index.model()->data(index.model()->index(index.row(), index.column() - 1)).value<QString>();
78 
79  if (data.isValid())
80  {
81  QWidget *editorWidget = nullptr;
82 
83  if (data.type() == QVariant::Color)
84  {
85  auto colorBtn = new QPushButton(parent);
86  QColor color = data.value<QColor>();
87 
88  QColor result = QColorDialog::getColor(color);
89  if (result.isValid())
90  {
91  QPalette palette = colorBtn->palette();
92  palette.setColor(QPalette::Button, result);
93  colorBtn->setPalette(palette);
94  colorBtn->setStyleSheet(
95  QString("background-color: %1;foreground-color: %1; border-style: none;").arg(result.name()));
96  }
97  // QColorDialog closed by 'Cancel' button, use the old property color
98  else
99  {
100  QPalette palette = colorBtn->palette();
101  palette.setColor(QPalette::Button, color);
102  colorBtn->setPalette(palette);
103  colorBtn->setStyleSheet(
104  QString("background-color: %1;foreground-color: %1; border-style: none;").arg(color.name()));
105  }
106 
107  connect(colorBtn, SIGNAL(pressed()), this, SLOT(commitAndCloseEditor()));
108 
109  editorWidget = colorBtn;
110  }
111 
112  else if (data.type() == QVariant::Int)
113  {
114  auto spinBox = new QSpinBox(parent);
115  spinBox->setSingleStep(1);
116  spinBox->setMinimum(std::numeric_limits<int>::min());
117  spinBox->setMaximum(std::numeric_limits<int>::max());
118  editorWidget = spinBox;
119  }
120  // see qt documentation. cast is correct, it would be obsolete if we
121  // store doubles
122  else if (static_cast<QMetaType::Type>(data.type()) == QMetaType::Float)
123  {
124  auto spinBox = new QDoubleSpinBox(parent);
125  spinBox->setDecimals(2);
126  spinBox->setSingleStep(0.1);
127  if (name == "opacity")
128  {
129  spinBox->setMinimum(0.0);
130  spinBox->setMaximum(1.0);
131  }
132  else
133  {
134  spinBox->setMinimum(std::numeric_limits<float>::min());
135  spinBox->setMaximum(std::numeric_limits<float>::max());
136  }
137 
138  editorWidget = spinBox;
139  }
140 
141  else if (data.type() == QVariant::StringList)
142  {
143  QStringList entries = data.value<QStringList>();
144  auto comboBox = new QComboBox(parent);
145  comboBox->setEditable(false);
146  comboBox->addItems(entries);
147 
148  editorWidget = comboBox;
149  }
150 
151  else
152  {
153  editorWidget = QStyledItemDelegate::createEditor(parent, option, index);
154  }
155 
156  if (editorWidget)
157  {
158  // install event filter
159  editorWidget->installEventFilter(const_cast<QmitkPropertyDelegate *>(this));
160  }
161 
162  return editorWidget;
163  }
164  else
165  return new QLabel(displayData.toString(), parent);
166 }
167 
168 void QmitkPropertyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
169 {
170  QVariant data = index.data(Qt::EditRole);
171  QVariant displayData = index.data(Qt::DisplayRole);
172 
173  if (data.isValid())
174  {
175  if (data.type() == QVariant::Int)
176  {
177  QSpinBox *spinBox = qobject_cast<QSpinBox *>(editor);
178  spinBox->setValue(data.toInt());
179  }
180  // see qt documentation. cast is correct, it would be obsolete if we
181  // store doubles
182  else if (static_cast<QMetaType::Type>(data.type()) == QMetaType::Float)
183  {
184  QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox *>(editor);
185  spinBox->setValue(data.toDouble());
186  }
187 
188  else if (data.type() == QVariant::StringList)
189  {
190  QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
191  QString displayString = displayData.value<QString>();
192  comboBox->setCurrentIndex(comboBox->findData(displayString));
193  }
194 
195  else
196  return QStyledItemDelegate::setEditorData(editor, index);
197  }
198 }
199 
200 void QmitkPropertyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
201 {
202  QVariant data = index.data(Qt::EditRole);
203  QVariant displayData = index.data(Qt::DisplayRole);
204 
205  if (data.isValid())
206  {
207  if (data.type() == QVariant::Color)
208  {
209  QWidget *colorBtn = qobject_cast<QWidget *>(editor);
210  QVariant colorVariant;
211  colorVariant.setValue<QColor>(colorBtn->palette().color(QPalette::Button));
212  model->setData(index, colorVariant);
213  }
214 
215  else if (data.type() == QVariant::Int)
216  {
217  QSpinBox *spinBox = qobject_cast<QSpinBox *>(editor);
218  int intValue = spinBox->value();
219 
220  QVariant intValueVariant;
221  intValueVariant.setValue<float>(static_cast<float>(intValue));
222  model->setData(index, intValueVariant);
223  }
224 
225  else if (static_cast<QMetaType::Type>(data.type()) == QMetaType::Float)
226  {
227  QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox *>(editor);
228  double doubleValue = spinBox->value();
229 
230  QVariant doubleValueVariant;
231  doubleValueVariant.setValue<float>(static_cast<float>(doubleValue));
232  model->setData(index, doubleValueVariant);
233  }
234 
235  else if (data.type() == QVariant::StringList)
236  {
237  QString displayData = data.value<QString>();
238 
239  QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
240  QString comboBoxValue = comboBox->currentText();
241 
242  QVariant comboBoxValueVariant;
243  comboBoxValueVariant.setValue<QString>(comboBoxValue);
244  model->setData(index, comboBoxValueVariant);
245  }
246 
247  else
248  QStyledItemDelegate::setModelData(editor, model, index);
249  }
250 }
251 
252 void QmitkPropertyDelegate::commitAndCloseEditor()
253 {
254  QWidget *editor = nullptr;
255  if (QPushButton *pushBtn = qobject_cast<QPushButton *>(sender()))
256  {
257  editor = pushBtn;
258  }
259 
260  if (editor)
261  {
262  emit commitData(editor);
263  emit closeEditor(editor);
264  }
265 }
266 
268  const QStyleOptionViewItem &option,
269  const QModelIndex & /*index*/) const
270 {
271  editor->setGeometry(option.rect);
272 }
273 
274 void QmitkPropertyDelegate::ComboBoxCurrentIndexChanged(int /*index*/)
275 {
276  if (QComboBox *comboBox = qobject_cast<QComboBox *>(sender()))
277  {
278  emit commitData(comboBox);
279  emit closeEditor(comboBox);
280  }
281 }
282 
283 void QmitkPropertyDelegate::SpinBoxValueChanged(const QString & /*value*/)
284 {
285  QAbstractSpinBox *spinBox = nullptr;
286  if ((spinBox = qobject_cast<QSpinBox *>(sender())) || (spinBox = qobject_cast<QDoubleSpinBox *>(sender())))
287  {
288  emit commitData(spinBox);
289  emit closeEditor(spinBox);
290  }
291 }
292 
293 void QmitkPropertyDelegate::showColorDialog()
294 {
295 }
296 
297 bool QmitkPropertyDelegate::eventFilter(QObject *o, QEvent *e)
298 {
299  // filter all kind of events on our editor widgets
300  // when certain events occur, repaint all render windows, because rendering relevant properties might have changed
301  switch (e->type())
302  {
303  case QEvent::KeyRelease:
304  case QEvent::MouseButtonRelease:
305  case QEvent::MouseButtonDblClick:
306  case QEvent::Wheel:
307  case QEvent::FocusIn:
308  {
309  if (QWidget *editor = dynamic_cast<QWidget *>(o))
310  {
311  emit commitData(editor);
312  }
313 
315  break;
316  }
317  default:
318  {
319  break;
320  }
321  }
322 
323  return false;
324 }
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
signed integer value
Definition: jsoncpp.h:348
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Fit an editor to some geometry (overwritten from QItemDelegate)
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
bool eventFilter(QObject *o, QEvent *e) override
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
static RenderingManager * GetInstance()
static T max(T x, T y)
Definition: svm.cpp:70
int Int
Definition: jsoncpp.h:158
std::vector< std::string > StringList
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
static T min(T x, T y)
Definition: svm.cpp:67
QmitkPropertyDelegate(QObject *parent=nullptr)
void setEditorData(QWidget *editor, const QModelIndex &index) const override
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)