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