Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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)