39 #include <QColorDialog>
42 #include <QFileDialog>
44 #include <QMessageBox>
45 #include <QPushButton>
46 #include <QStringListModel>
47 #include <QWidgetAction>
50 #include <itksys/SystemTools.hxx>
57 : QWidget(parent), m_ToolManager(NULL),
m_DataStorage(NULL), m_Completer(NULL)
59 m_Controls.setupUi(
this);
64 assert(m_ToolManager);
66 m_Controls.m_LabelSearchBox->setAlwaysShowClearIcon(
true);
67 m_Controls.m_LabelSearchBox->setShowSearchIcon(
true);
69 QStringList completionList;
71 m_Completer =
new QCompleter(completionList,
this);
72 m_Completer->setCaseSensitivity(Qt::CaseInsensitive);
73 m_Controls.m_LabelSearchBox->setCompleter(m_Completer);
75 connect(m_Controls.m_LabelSearchBox, SIGNAL(returnPressed()),
this, SLOT(OnSearchLabel()));
80 QStringListModel *completeModel =
static_cast<QStringListModel *
>(m_Completer->model());
83 m_Controls.m_LabelSearchBox->setEnabled(
false);
85 m_Controls.m_lblCaption->setText(
"");
87 InitializeTableWidget();
94 void QmitkLabelSetWidget::OnTableViewContextMenuRequested(
const QPoint &pos)
96 QTableWidgetItem *itemAt = m_Controls.m_LabelSetTableWidget->itemAt(pos);
102 int pixelValue = itemAt->data(Qt::UserRole).toInt();
103 QMenu *
menu =
new QMenu(m_Controls.m_LabelSetTableWidget);
105 if (m_Controls.m_LabelSetTableWidget->selectedItems().size() > 1)
107 QAction *mergeAction =
new QAction(QIcon(
":/Qmitk/MergeLabels.png"),
"Merge selection on current label",
this);
108 mergeAction->setEnabled(
true);
109 QObject::connect(mergeAction, SIGNAL(triggered(
bool)),
this, SLOT(OnMergeLabels(
bool)));
110 menu->addAction(mergeAction);
112 QAction *removeLabelsAction =
new QAction(QIcon(
":/Qmitk/RemoveLabel.png"),
"Remove selected labels",
this);
113 removeLabelsAction->setEnabled(
true);
114 QObject::connect(removeLabelsAction, SIGNAL(triggered(
bool)),
this, SLOT(OnRemoveLabels(
bool)));
115 menu->addAction(removeLabelsAction);
117 QAction *eraseLabelsAction =
new QAction(QIcon(
":/Qmitk/EraseLabel.png"),
"Erase selected labels",
this);
118 eraseLabelsAction->setEnabled(
true);
119 QObject::connect(eraseLabelsAction, SIGNAL(triggered(
bool)),
this, SLOT(OnEraseLabels(
bool)));
120 menu->addAction(eraseLabelsAction);
122 QAction *combineAndCreateSurfaceAction =
123 new QAction(QIcon(
":/Qmitk/CreateSurface.png"),
"Combine and create a surface",
this);
124 combineAndCreateSurfaceAction->setEnabled(
true);
126 combineAndCreateSurfaceAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCombineAndCreateSurface(
bool)));
129 QAction *createMasksAction =
130 new QAction(QIcon(
":/Qmitk/CreateMask.png"),
"Create a mask for each selected label",
this);
131 createMasksAction->setEnabled(
true);
132 QObject::connect(createMasksAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateMasks(
bool)));
135 QAction *combineAndCreateMaskAction =
136 new QAction(QIcon(
":/Qmitk/CreateMask.png"),
"Combine and create a mask",
this);
137 combineAndCreateMaskAction->setEnabled(
true);
138 QObject::connect(combineAndCreateMaskAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCombineAndCreateMask(
bool)));
143 QAction *renameAction =
new QAction(QIcon(
":/Qmitk/RenameLabel.png"),
"Rename...",
this);
144 renameAction->setEnabled(
true);
145 QObject::connect(renameAction, SIGNAL(triggered(
bool)),
this, SLOT(OnRenameLabel(
bool)));
146 menu->addAction(renameAction);
148 QAction *removeAction =
new QAction(QIcon(
":/Qmitk/RemoveLabel.png"),
"Remove...",
this);
149 removeAction->setEnabled(
true);
150 QObject::connect(removeAction, SIGNAL(triggered(
bool)),
this, SLOT(OnRemoveLabel(
bool)));
151 menu->addAction(removeAction);
153 QAction *eraseAction =
new QAction(QIcon(
":/Qmitk/EraseLabel.png"),
"Erase...",
this);
154 eraseAction->setEnabled(
true);
155 QObject::connect(eraseAction, SIGNAL(triggered(
bool)),
this, SLOT(OnEraseLabel(
bool)));
156 menu->addAction(eraseAction);
158 QAction *mergeAction =
new QAction(QIcon(
":/Qmitk/MergeLabels.png"),
"Merge...",
this);
159 mergeAction->setEnabled(
true);
160 QObject::connect(mergeAction, SIGNAL(triggered(
bool)),
this, SLOT(OnMergeLabel(
bool)));
161 menu->addAction(mergeAction);
163 QAction *randomColorAction =
new QAction(QIcon(
":/Qmitk/RandomColor.png"),
"Random color",
this);
164 randomColorAction->setEnabled(
true);
165 QObject::connect(randomColorAction, SIGNAL(triggered(
bool)),
this, SLOT(OnRandomColor(
bool)));
166 menu->addAction(randomColorAction);
168 QAction *viewOnlyAction =
new QAction(QIcon(
":/Qmitk/visible.png"),
"View only",
this);
169 viewOnlyAction->setEnabled(
true);
170 QObject::connect(viewOnlyAction, SIGNAL(triggered(
bool)),
this, SLOT(OnSetOnlyActiveLabelVisible(
bool)));
171 menu->addAction(viewOnlyAction);
173 QAction *viewAllAction =
new QAction(QIcon(
":/Qmitk/visible.png"),
"View all",
this);
174 viewAllAction->setEnabled(
true);
175 QObject::connect(viewAllAction, SIGNAL(triggered(
bool)),
this, SLOT(OnSetAllLabelsVisible(
bool)));
176 menu->addAction(viewAllAction);
178 QAction *hideAllAction =
new QAction(QIcon(
":/Qmitk/invisible.png"),
"Hide all",
this);
179 hideAllAction->setEnabled(
true);
180 QObject::connect(hideAllAction, SIGNAL(triggered(
bool)),
this, SLOT(OnSetAllLabelsInvisible(
bool)));
181 menu->addAction(hideAllAction);
183 QAction *lockAllAction =
new QAction(QIcon(
":/Qmitk/lock.png"),
"Lock all",
this);
184 lockAllAction->setEnabled(
true);
185 QObject::connect(lockAllAction, SIGNAL(triggered(
bool)),
this, SLOT(OnLockAllLabels(
bool)));
186 menu->addAction(lockAllAction);
188 QAction *unlockAllAction =
new QAction(QIcon(
":/Qmitk/unlock.png"),
"Unlock all",
this);
189 unlockAllAction->setEnabled(
true);
190 QObject::connect(unlockAllAction, SIGNAL(triggered(
bool)),
this, SLOT(OnUnlockAllLabels(
bool)));
191 menu->addAction(unlockAllAction);
193 QAction *createSurfaceAction =
new QAction(QIcon(
":/Qmitk/CreateSurface.png"),
"Create surface",
this);
194 createSurfaceAction->setEnabled(
true);
195 createSurfaceAction->setMenu(
new QMenu());
197 QAction *
tmp1 = createSurfaceAction->menu()->addAction(QString(
"Detailed"));
198 QAction *
tmp2 = createSurfaceAction->menu()->addAction(QString(
"Smoothed"));
200 QObject::connect(tmp1, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateDetailedSurface(
bool)));
201 QObject::connect(tmp2, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateSmoothedSurface(
bool)));
203 menu->addAction(createSurfaceAction);
205 QAction *createMaskAction =
new QAction(QIcon(
":/Qmitk/CreateMask.png"),
"Create mask",
this);
206 createMaskAction->setEnabled(
true);
207 QObject::connect(createMaskAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateMask(
bool)));
209 menu->addAction(createMaskAction);
211 QAction *createCroppedMaskAction =
new QAction(QIcon(
":/Qmitk/CreateMask.png"),
"Create cropped mask",
this);
212 createCroppedMaskAction->setEnabled(
true);
213 QObject::connect(createCroppedMaskAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateCroppedMask(
bool)));
220 menu->addAction(createCroppedMaskAction);
222 QSlider *opacitySlider =
new QSlider;
223 opacitySlider->setMinimum(0);
224 opacitySlider->setMaximum(100);
225 opacitySlider->setOrientation(Qt::Horizontal);
226 QObject::connect(opacitySlider, SIGNAL(valueChanged(
int)),
this, SLOT(OnOpacityChanged(
int)));
228 QLabel *_OpacityLabel =
new QLabel(
"Opacity: ");
229 QVBoxLayout *_OpacityWidgetLayout =
new QVBoxLayout;
230 _OpacityWidgetLayout->setContentsMargins(4, 4, 4, 4);
231 _OpacityWidgetLayout->addWidget(_OpacityLabel);
232 _OpacityWidgetLayout->addWidget(opacitySlider);
233 QWidget *_OpacityWidget =
new QWidget;
234 _OpacityWidget->setLayout(_OpacityWidgetLayout);
236 QWidgetAction *OpacityAction =
new QWidgetAction(
this);
237 OpacityAction->setDefaultWidget(_OpacityWidget);
239 opacitySlider->setValue(static_cast<int>(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetOpacity() * 100));
241 menu->addAction(OpacityAction);
243 menu->popup(QCursor::pos());
246 void QmitkLabelSetWidget::OnUnlockAllLabels(
bool )
252 void QmitkLabelSetWidget::OnLockAllLabels(
bool )
258 void QmitkLabelSetWidget::OnSetAllLabelsVisible(
bool )
265 void QmitkLabelSetWidget::OnSetAllLabelsInvisible(
bool )
272 void QmitkLabelSetWidget::OnSetOnlyActiveLabelVisible(
bool )
275 int pixelValue = GetPixelValueOfSelectedItem();
282 this->WaitCursorOn();
285 this->WaitCursorOff();
286 if (pos.GetVnlVector().max_value() > 0.0)
294 void QmitkLabelSetWidget::OnMergeLabel(
bool )
297 dialog.setWindowTitle(
"Select a second label..");
299 int dialogReturnValue = dialog.exec();
300 if (dialogReturnValue == QDialog::Rejected)
304 for (
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); i++)
306 if (dialog.GetLabelSetWidgetTableCompleteWord() == QString(m_Controls.m_LabelSetTableWidget->item(i, 0)->text()))
307 pixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt();
310 if (pixelValue == -1)
317 GetWorkingImage()->
MergeLabel(pixelValue, GetWorkingImage()->GetActiveLayer());
323 void QmitkLabelSetWidget::OnEraseLabel(
bool )
325 int pixelValue = GetPixelValueOfSelectedItem();
326 QString question =
"Do you really want to erase the contents of label \"";
327 question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
GetName()));
328 question.append(
"\"?");
330 QMessageBox::StandardButton answerButton =
331 QMessageBox::question(
this,
"Erase label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
333 if (answerButton == QMessageBox::Yes)
335 this->WaitCursorOn();
337 this->WaitCursorOff();
342 void QmitkLabelSetWidget::OnRemoveLabel(
bool )
344 int pixelValue = GetPixelValueOfSelectedItem();
345 QString question =
"Do you really want to remove label \"";
346 question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
GetName()));
347 question.append(
"\"?");
349 QMessageBox::StandardButton answerButton =
350 QMessageBox::question(
this,
"Remove label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
352 if (answerButton == QMessageBox::Yes)
354 this->WaitCursorOn();
357 this->WaitCursorOff();
364 void QmitkLabelSetWidget::OnRenameLabel(
bool )
367 dialog.setWindowTitle(
"Rename Label");
368 dialog.SetSuggestionList(m_OrganColors);
373 if (dialog.exec() == QDialog::Rejected)
377 GetWorkingImage()->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
SetColor(dialog.GetColor());
378 GetWorkingImage()->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
SetName(dialog.GetSegmentationName().toStdString());
385 void QmitkLabelSetWidget::OnCombineAndCreateMask(
bool )
387 m_Controls.m_LabelSetTableWidget->selectedRanges();
391 void QmitkLabelSetWidget::OnCreateMasks(
bool )
393 m_Controls.m_LabelSetTableWidget->selectedRanges();
397 void QmitkLabelSetWidget::OnCombineAndCreateSurface(
bool )
399 m_Controls.m_LabelSetTableWidget->selectedRanges();
403 void QmitkLabelSetWidget::OnEraseLabels(
bool )
405 QString question =
"Do you really want to erase the selected labels?";
407 QMessageBox::StandardButton answerButton = QMessageBox::question(
408 this,
"Erase selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
410 if (answerButton == QMessageBox::Yes)
412 QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
413 if (ranges.isEmpty())
416 std::vector<mitk::Label::PixelType> VectorOfLablePixelValues;
417 foreach (QTableWidgetSelectionRange a, ranges)
418 for (
int i = a.topRow(); i <= a.bottomRow(); i++)
419 VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
421 this->WaitCursorOn();
422 GetWorkingImage()->
EraseLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer());
423 this->WaitCursorOff();
428 void QmitkLabelSetWidget::OnRemoveLabels(
bool )
430 QString question =
"Do you really want to remove selected labels?";
431 QMessageBox::StandardButton answerButton = QMessageBox::question(
432 this,
"Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
434 if (answerButton == QMessageBox::Yes)
436 QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
437 if (ranges.isEmpty())
442 std::vector<mitk::Label::PixelType> VectorOfLablePixelValues;
443 foreach(QTableWidgetSelectionRange a, ranges)
445 for (
int i = a.topRow(); i <= a.bottomRow(); ++i)
447 VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
451 this->WaitCursorOn();
452 GetWorkingImage()->
RemoveLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer());
453 this->WaitCursorOff();
460 void QmitkLabelSetWidget::OnMergeLabels(
bool )
462 int pixelValue = GetPixelValueOfSelectedItem();
463 QString question =
"Do you really want to merge selected labels into \"";
464 question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
GetName()));
465 question.append(
"\"?");
467 QMessageBox::StandardButton answerButton = QMessageBox::question(
468 this,
"Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
470 if (answerButton == QMessageBox::Yes)
472 QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
473 if (ranges.isEmpty())
478 std::vector<mitk::Label::PixelType> VectorOfLablePixelValues;
479 foreach(QTableWidgetSelectionRange a, ranges)
481 for (
int i = a.topRow(); i <= a.bottomRow(); ++i)
483 VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
487 this->WaitCursorOn();
488 int pixelValue = m_Controls.m_LabelSetTableWidget->item(m_Controls.m_LabelSetTableWidget->currentRow(), 0)
492 GetWorkingImage()->
MergeLabels(VectorOfLablePixelValues, pixelValue, GetWorkingImage()->GetActiveLayer());
493 this->WaitCursorOff();
499 void QmitkLabelSetWidget::OnLockedButtonClicked()
502 for(
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
504 if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, LOCKED_COL))
509 if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount())
511 int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt();
512 GetWorkingImage()->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
SetLocked(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetLocked());
516 void QmitkLabelSetWidget::OnVisibleButtonClicked()
519 for(
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
521 if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, VISIBLE_COL))
528 if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount())
530 QTableWidgetItem *item = m_Controls.m_LabelSetTableWidget->item(row, 0);
532 int pixelValue = item->data(Qt::UserRole).toInt();
533 GetWorkingImage()->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
SetVisible(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetVisible());
539 void QmitkLabelSetWidget::OnColorButtonClicked()
542 for(
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
544 if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, COLOR_COL))
550 if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount())
552 int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt();
554 QColor initial(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255);
555 QColor qcolor = QColorDialog::getColor(initial, 0, QString(
"Change color"));
556 if (!qcolor.isValid())
561 QPushButton *button =
static_cast<QPushButton*
>(m_Controls.m_LabelSetTableWidget->cellWidget(row, COLOR_COL));
567 button->setAutoFillBackground(
true);
569 QString styleSheet =
"background-color:rgb(";
570 styleSheet.append(QString::number(qcolor.red()));
571 styleSheet.append(
",");
572 styleSheet.append(QString::number(qcolor.green()));
573 styleSheet.append(
",");
574 styleSheet.append(QString::number(qcolor.blue()));
575 styleSheet.append(
")");
576 button->setStyleSheet(styleSheet);
579 newColor.SetRed(qcolor.red() / 255.0);
580 newColor.SetGreen(qcolor.green() / 255.0);
581 newColor.SetBlue(qcolor.blue() / 255.0);
583 GetWorkingImage()->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
SetColor(newColor);
589 void QmitkLabelSetWidget::OnRandomColor(
bool )
591 int pixelValue = GetPixelValueOfSelectedItem();
599 m_OrganColors = organColors;
602 void QmitkLabelSetWidget::OnActiveLabelChanged(
int pixelValue)
605 assert(workingImage);
615 workingImage->Modified();
619 void QmitkLabelSetWidget::OnItemClicked(QTableWidgetItem *item)
624 int pixelValue = item->data(Qt::UserRole).toInt();
626 QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
627 if (!ranges.empty() && ranges.back().rowCount() == 1)
630 OnActiveLabelChanged(pixelValue);
635 void QmitkLabelSetWidget::OnItemDoubleClicked(QTableWidgetItem *item)
640 int pixelValue = item->data(Qt::UserRole).toInt();
647 if (pos.GetVnlVector().max_value() > 0.0)
652 workingImage->Modified();
660 if (!GetWorkingImage()->ExistLabel(pixelValue))
662 for (
int row = 0; row < m_Controls.m_LabelSetTableWidget->rowCount(); row++)
664 if (m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt() == pixelValue)
666 m_Controls.m_LabelSetTableWidget->clearSelection();
667 m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
668 m_Controls.m_LabelSetTableWidget->selectRow(row);
669 m_Controls.m_LabelSetTableWidget->scrollToItem(m_Controls.m_LabelSetTableWidget->item(row, 0));
670 m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
679 void QmitkLabelSetWidget::InsertTableWidgetItem(
mitk::Label *label)
683 QString styleSheet =
"background-color:rgb(";
684 styleSheet.append(QString::number(color[0] * 255));
685 styleSheet.append(
",");
686 styleSheet.append(QString::number(color[1] * 255));
687 styleSheet.append(
",");
688 styleSheet.append(QString::number(color[2] * 255));
689 styleSheet.append(
")");
691 QTableWidget* tableWidget = m_Controls.m_LabelSetTableWidget;
692 int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2;
693 QString text = fontMetrics().elidedText(label->
GetName().c_str(), Qt::ElideMiddle, colWidth);
694 QTableWidgetItem *nameItem =
new QTableWidgetItem(text);
695 nameItem->setTextAlignment(Qt::AlignCenter | Qt::AlignLeft);
698 nameItem->setData(Qt::UserRole, QVariant(label->
GetValue()));
701 QPushButton *pbColor =
new QPushButton(tableWidget);
702 pbColor->setFixedSize(24, 24);
703 pbColor->setCheckable(
false);
704 pbColor->setAutoFillBackground(
true);
705 pbColor->setToolTip(
"Change label color");
706 pbColor->setStyleSheet(styleSheet);
708 connect(pbColor, SIGNAL(clicked()),
this, SLOT(OnColorButtonClicked()));
710 QPushButton *pbLocked =
new QPushButton(tableWidget);
711 pbLocked->setFixedSize(24, 24);
712 QIcon *iconLocked =
new QIcon();
714 iconLocked->addFile(QString::fromUtf8(
":/Qmitk/lock.png"), QSize(), QIcon::Normal, QIcon::Off);
715 iconLocked->addFile(QString::fromUtf8(
":/Qmitk/unlock.png"), QSize(), QIcon::Normal, QIcon::On);
716 pbLocked->setIcon(*iconLocked);
717 pbLocked->setIconSize(QSize(24, 24));
718 pbLocked->setCheckable(
true);
719 pbLocked->setToolTip(
"Lock/unlock label");
720 pbLocked->setChecked(!label->
GetLocked());
721 connect(pbLocked, SIGNAL(clicked()),
this, SLOT(OnLockedButtonClicked()));
723 QPushButton *pbVisible =
new QPushButton(tableWidget);
724 pbVisible->setFixedSize(24, 24);
725 pbVisible->setAutoRepeat(
false);
726 QIcon *iconVisible =
new QIcon();
727 iconVisible->addFile(QString::fromUtf8(
":/Qmitk/visible.png"), QSize(), QIcon::Normal, QIcon::Off);
728 iconVisible->addFile(QString::fromUtf8(
":/Qmitk/invisible.png"), QSize(), QIcon::Normal, QIcon::On);
729 pbVisible->setIcon(*iconVisible);
730 pbVisible->setIconSize(QSize(24, 24));
731 pbVisible->setCheckable(
true);
732 pbVisible->setToolTip(
"Show/hide label");
735 connect(pbVisible, SIGNAL(clicked()),
this, SLOT(OnVisibleButtonClicked()));
737 int row = tableWidget->rowCount();
738 tableWidget->insertRow(row);
739 tableWidget->setRowHeight(row, 24);
740 tableWidget->setItem(row, 0, nameItem);
741 tableWidget->setCellWidget(row, 1, pbLocked);
742 tableWidget->setCellWidget(row, 2, pbColor);
743 tableWidget->setCellWidget(row, 3, pbVisible);
744 tableWidget->selectRow(row);
752 tableWidget->hideRow(row);
763 QTableWidget* tableWidget = m_Controls.m_LabelSetTableWidget;
764 m_LabelStringList.clear();
765 for(
int i = 0 ; i < tableWidget->rowCount(); ++i)
767 UpdateTableWidgetItem(tableWidget->item(i, 0));
768 m_LabelStringList.append(tableWidget->item(i, 0)->text());
771 OnLabelListModified(m_LabelStringList);
776 void QmitkLabelSetWidget::UpdateTableWidgetItem(QTableWidgetItem *item)
783 QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget;
785 QString styleSheet =
"background-color:rgb(";
786 styleSheet.append(QString::number(color[0] * 255));
787 styleSheet.append(
",");
788 styleSheet.append(QString::number(color[1] * 255));
789 styleSheet.append(
",");
790 styleSheet.append(QString::number(color[2] * 255));
791 styleSheet.append(
")");
794 int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2;
795 QString text = fontMetrics().elidedText(label->
GetName().c_str(), Qt::ElideMiddle, colWidth);
798 QPushButton *pbLocked =
dynamic_cast<QPushButton *
>(tableWidget->cellWidget(item->row(), 1));
799 pbLocked->setChecked(!label->
GetLocked());
801 QPushButton *pbColor =
dynamic_cast<QPushButton *
>(tableWidget->cellWidget(item->row(), 2));
802 pbColor->setStyleSheet(styleSheet);
804 QPushButton *pbVisible =
dynamic_cast<QPushButton *
>(tableWidget->cellWidget(item->row(), 3));
807 if (item->row() == 0)
808 tableWidget->hideRow(item->row());
813 QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget;
815 while (tableWidget->rowCount())
817 tableWidget->removeRow(0);
825 m_LabelStringList.clear();
833 InsertTableWidgetItem(it->second);
834 if (GetWorkingImage()->GetActiveLabel() == it->second)
835 pixelValue = it->first;
836 m_LabelStringList.append(QString(it->second->GetName().c_str()));
842 OnLabelListModified(m_LabelStringList);
844 std::stringstream captionText;
846 m_Controls.m_lblCaption->setText(captionText.str().c_str());
851 int QmitkLabelSetWidget::GetPixelValueOfSelectedItem()
853 if (m_Controls.m_LabelSetTableWidget->currentItem())
855 return m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt();
862 return m_LabelStringList;
865 void QmitkLabelSetWidget::InitializeTableWidget()
867 QTableWidget *tableWidged = m_Controls.m_LabelSetTableWidget;
869 tableWidged->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
870 tableWidged->setTabKeyNavigation(
false);
871 tableWidged->setAlternatingRowColors(
false);
872 tableWidged->setFocusPolicy(Qt::NoFocus);
873 tableWidged->setColumnCount(4);
874 tableWidged->resizeColumnToContents(NAME_COL);
875 tableWidged->setColumnWidth(LOCKED_COL, 25);
876 tableWidged->setColumnWidth(COLOR_COL, 25);
877 tableWidged->setColumnWidth(VISIBLE_COL, 25);
878 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
879 tableWidged->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
881 tableWidged->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
883 tableWidged->setContextMenuPolicy(Qt::CustomContextMenu);
884 tableWidged->horizontalHeader()->hide();
885 tableWidged->setSortingEnabled(
false);
886 tableWidged->verticalHeader()->hide();
887 tableWidged->setEditTriggers(QAbstractItemView::NoEditTriggers);
888 tableWidged->setSelectionMode(QAbstractItemView::ExtendedSelection);
889 tableWidged->setSelectionBehavior(QAbstractItemView::SelectRows);
891 connect(tableWidged, SIGNAL(itemClicked(QTableWidgetItem *)),
this, SLOT(OnItemClicked(QTableWidgetItem *)));
893 tableWidged, SIGNAL(itemDoubleClicked(QTableWidgetItem *)),
this, SLOT(OnItemDoubleClicked(QTableWidgetItem *)));
895 SIGNAL(customContextMenuRequested(
const QPoint &)),
897 SLOT(OnTableViewContextMenuRequested(
const QPoint &)));
921 void QmitkLabelSetWidget::OnOpacityChanged(
int value)
923 int pixelValue = m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt();
924 float opacity =
static_cast<float>(value) / 100.0f;
925 GetWorkingImage()->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
SetOpacity(opacity);
931 QWidget::setEnabled(enabled);
937 m_DataStorage = storage;
940 void QmitkLabelSetWidget::OnSearchLabel()
942 std::string text = m_Controls.m_LabelSearchBox->text().toStdString();
945 for(
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
947 if( m_Controls.m_LabelSetTableWidget->item(i, 0)->text().toStdString().compare(text) == 0)
949 pixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt();
954 if (pixelValue == -1)
961 QTableWidgetItem *nameItem = m_Controls.m_LabelSetTableWidget->item(row, NAME_COL);
967 m_Controls.m_LabelSetTableWidget->clearSelection();
968 m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
969 m_Controls.m_LabelSetTableWidget->selectRow(row);
970 m_Controls.m_LabelSetTableWidget->scrollToItem(nameItem);
971 m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
975 this->WaitCursorOn();
980 if (pos.GetVnlVector().max_value() > 0.0)
986 GetWorkingImage()->
UpdateCenterOfMass(pixelValue, GetWorkingImage()->GetActiveLayer());
991 this->WaitCursorOff();
994 void QmitkLabelSetWidget::OnLabelListModified(
const QStringList &list)
996 QStringListModel *completeModel =
static_cast<QStringListModel *
>(m_Completer->model());
997 completeModel->setStringList(list);
1004 assert(workingImage);
1005 return workingImage;
1011 assert(workingNode);
1018 bool hasWorkingData = (workingNode !=
nullptr);
1020 m_Controls.m_LabelSetTableWidget->setEnabled(hasWorkingData);
1021 m_Controls.m_LabelSearchBox->setEnabled(hasWorkingData);
1023 if (!hasWorkingData)
1026 QStringListModel *completeModel =
static_cast<QStringListModel *
>(m_Completer->model());
1030 void QmitkLabelSetWidget::OnCreateCroppedMask(
bool)
1036 int pixelValue = GetPixelValueOfSelectedItem();
1039 this->WaitCursorOn();
1043 cropFilter->SetBackgroundValue(0);
1044 cropFilter->SetMarginFactor(1.15);
1045 cropFilter->Update();
1047 maskImage = cropFilter->GetOutput();
1049 this->WaitCursorOff();
1053 this->WaitCursorOff();
1054 MITK_ERROR <<
"Exception caught: " << e.GetDescription();
1055 QMessageBox::information(
this,
"Create Mask",
"Could not create a mask out of the selected label.\n");
1059 if (maskImage.IsNull())
1061 QMessageBox::information(
this,
"Create Mask",
"Could not create a mask out of the selected label.\n");
1068 maskNode->SetName(name);
1069 maskNode->SetData(maskImage);
1070 maskNode->SetBoolProperty(
"binary",
true);
1071 maskNode->SetBoolProperty(
"outline binary",
true);
1072 maskNode->SetBoolProperty(
"outline binary shadow",
true);
1073 maskNode->SetFloatProperty(
"outline width", 2.0);
1075 maskNode->SetOpacity(1.0);
1077 m_DataStorage->
Add(maskNode, GetWorkingNode());
1080 void QmitkLabelSetWidget::OnCreateMask(
bool )
1086 int pixelValue = GetPixelValueOfSelectedItem();
1089 this->WaitCursorOn();
1091 this->WaitCursorOff();
1095 this->WaitCursorOff();
1096 MITK_ERROR <<
"Exception caught: " << e.GetDescription();
1097 QMessageBox::information(
this,
"Create Mask",
"Could not create a mask out of the selected label.\n");
1101 if (maskImage.IsNull())
1103 QMessageBox::information(
this,
"Create Mask",
"Could not create a mask out of the selected label.\n");
1110 maskNode->SetName(name);
1111 maskNode->SetData(maskImage);
1112 maskNode->SetBoolProperty(
"binary",
true);
1113 maskNode->SetBoolProperty(
"outline binary",
true);
1114 maskNode->SetBoolProperty(
"outline binary shadow",
true);
1115 maskNode->SetFloatProperty(
"outline width", 2.0);
1117 maskNode->SetOpacity(1.0);
1119 m_DataStorage->
Add(maskNode, GetWorkingNode());
1122 void QmitkLabelSetWidget::OnToggleOutline(
bool value)
1125 assert(workingNode);
1128 workingNode->
GetData()->Modified();
1132 void QmitkLabelSetWidget::OnCreateSmoothedSurface(
bool )
1138 int pixelValue = GetPixelValueOfSelectedItem();
1144 successCommand->SetCallbackFunction(
this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1149 errorCommand->SetCallbackFunction(
this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1153 surfaceFilter->SetPointerParameter(
"Group node", groupNode);
1154 surfaceFilter->SetPointerParameter(
"Input", workingImage);
1155 surfaceFilter->SetParameter(
"RequestedLabel", pixelValue);
1156 surfaceFilter->SetParameter(
"Smooth",
true);
1157 surfaceFilter->SetDataStorage(*m_DataStorage);
1163 surfaceFilter->StartAlgorithm();
1167 MITK_ERROR <<
"Exception caught: " << e.GetDescription();
1168 QMessageBox::information(
this,
1170 "Could not create a surface mesh out of the selected label. See error log for details.\n");
1174 void QmitkLabelSetWidget::OnCreateDetailedSurface(
bool )
1180 int pixelValue = GetPixelValueOfSelectedItem();
1186 successCommand->SetCallbackFunction(
this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1191 errorCommand->SetCallbackFunction(
this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1195 surfaceFilter->SetPointerParameter(
"Group node", groupNode);
1196 surfaceFilter->SetPointerParameter(
"Input", workingImage);
1197 surfaceFilter->SetParameter(
"RequestedLabel", pixelValue);
1198 surfaceFilter->SetParameter(
"Smooth",
false);
1199 surfaceFilter->SetDataStorage(*m_DataStorage);
1205 surfaceFilter->StartAlgorithm();
1209 MITK_ERROR <<
"Exception caught: " << e.GetDescription();
1210 QMessageBox::information(
this,
1212 "Could not create a surface mesh out of the selected label. See error log for details.\n");
1216 void QmitkLabelSetWidget::OnImportLabeledImage()
1268 void QmitkLabelSetWidget::OnImportSegmentation()
1306 void QmitkLabelSetWidget::WaitCursorOn()
1308 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1311 void QmitkLabelSetWidget::WaitCursorOff()
1313 this->RestoreOverrideCursor();
1316 void QmitkLabelSetWidget::RestoreOverrideCursor()
1318 QApplication::restoreOverrideCursor();
1321 void QmitkLabelSetWidget::OnThreadedCalculationDone()
virtual void Add(mitk::DataNode *node, const mitk::DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
std::string GetName() const
virtual Color GetNextColor() override
method to return another color
void UpdateLookupTable(PixelType pixelValue)
static SurfaceBasedInterpolationController * GetInstance()
void SetLocked(bool locked)
void SetAllLabelsLocked(bool)
mitk::Label * GetLabel(PixelType pixelValue, unsigned int layer=0) const
Returns the mitk::Label with the given pixelValue and for the given layer.
A data structure describing a label.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
void EraseLabel(PixelType pixelValue, unsigned int layer=0)
Erases the label with the given value in the given layer from the underlying image. The label itself will not be erased from the respective mitk::LabelSet. In order to remove the label itself use mitk::LabelSetImage::RemoveLabels()
LabelContainerConstIteratorType IteratorConstEnd() const
Returns a const iterator pointing to the end of the container.
void MergeLabels(std::vector< PixelType > &VectorOfLablePixelValues, PixelType index, unsigned int layer=0)
Merges a list of mitk::Labels with the mitk::Label that has a specific value.
void SetOpacity(float opacity)
void RemoveLabels(std::vector< PixelType > &VectorOfLabelPixelValues, unsigned int layer=0)
Removes labels from the mitk::LabelSet of given layer. Calls mitk::LabelSetImage::EraseLabels() which...
void SetColor(const mitk::Color &)
mitk::DataStorage::Pointer m_DataStorage
void MergeLabel(PixelType targetPixelValue, unsigned int layer=0)
Merges the mitk::Label with a given target value with the active label.
virtual void GoToBegin() override
method to set the color-index to begin again
void SetActiveLabel(int activeLabel)
An object of this class represents an exception of MITK. Please don't instantiate exceptions manually...
static RenderingManager * GetInstance()
void DisplayText(const char *t)
Send a string to the applications StatusBar.
void EraseLabels(std::vector< PixelType > &VectorOfLabelPixelValues, unsigned int layer=0)
Similar to mitk::LabelSetImage::EraseLabel() this funtion erase a list of labels from the image...
The custom viewer plugin implements simple viewer functionality presented in a customized look and feel It was developed to demonstrate extensibility and customizability of the blueberry application framework As an example for the GUI customization capabilities provided by the BlueBerry application the custom viewer plugin was developed It features simple viewer functionality presented in a customized look and feel The custom viewer consists of two i e a viewer perspective and a DICOM perspective As part of the viewer an instance of QmitkDataManagerView allows for data selection Visualization of the selected data is then performed by a simple render window view According data can either be directly loaded from file or be imported as DICOM data DICOM import functionality is accessible from the DICOM perspective incorporating the QmitkDicomExternalDataWidget The customization of Qt Stylesheets is used to give the application a non native look and feel This is further emphasized by a Tab Widget like unification of the perspectives with the according perspective bar In addition to an absence of menu
void SetVisible(bool visible)
mitk::LabelSet * GetActiveLabelSet()
Returns the currently active mitk::LabelSet.
mitk::Label * GetActiveLabel(unsigned int layer=0)
Returns the active label of a specific layer.
unsigned int GetNumberOfLabels(unsigned int layer=0) const
Get the number of all existing mitk::Labels for a given layer.
LabelContainerType::const_iterator LabelContainerConstIteratorType
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
static StatusBar * GetInstance()
static method to get the GUI dependent StatusBar-instance so the methods DisplayText, etc. can be called No reference counting, cause of decentral static use!
void SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer=nullptr)
Convenience method for setting boolean properties (instances of BoolProperty)
mitk::Point3D GetCenterOfMassCoordinates() const
void Clear()
removes any temporary message being shown.
void UpdateCenterOfMass(PixelType pixelValue, unsigned int layer=0)
LabelSetImage class for handling labels and layers in a segmentation session.
void SetActiveLabel(PixelType)
static std::string GetName(std::string fileName, std::string suffix)
const mitk::Color & GetColor() const
US_USE_NAMESPACE std::string tmp1
LabelContainerConstIteratorType IteratorConstBegin() const
Returns a const iterator poiting to the begining of the container.
Dialog for QmitkInteractiveSegmentation.
unsigned int GetActiveLayer() const
Gets the ID of the currently active layer.
PixelType GetValue() const
void RemoveLabel(PixelType)
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Class for nodes of the DataTree.
void SetName(const std::string &name)
void SetAllLabelsVisible(bool)
mitk::Image::Pointer CreateLabelMask(PixelType index)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.