35 #include <QColorDialog> 38 #include <QFileDialog> 40 #include <QMessageBox> 41 #include <QPushButton> 42 #include <QStringListModel> 43 #include <QWidgetAction> 46 #include <itksys/SystemTools.hxx> 53 : QWidget(parent),
m_DataStorage(nullptr), m_Completer(nullptr), m_ToolManager(nullptr)
55 m_Controls.setupUi(
this);
60 assert(m_ToolManager);
62 m_Controls.m_LabelSearchBox->setAlwaysShowClearIcon(
true);
63 m_Controls.m_LabelSearchBox->setShowSearchIcon(
true);
65 QStringList completionList;
67 m_Completer =
new QCompleter(completionList,
this);
68 m_Completer->setCaseSensitivity(Qt::CaseInsensitive);
69 m_Controls.m_LabelSearchBox->setCompleter(m_Completer);
71 connect(m_Controls.m_LabelSearchBox, SIGNAL(returnPressed()),
this, SLOT(OnSearchLabel()));
76 QStringListModel *completeModel =
static_cast<QStringListModel *
>(m_Completer->model());
79 m_Controls.m_LabelSearchBox->setEnabled(
false);
81 m_Controls.m_lblCaption->setText(
"");
83 InitializeTableWidget();
88 void QmitkLabelSetWidget::OnTableViewContextMenuRequested(
const QPoint & )
90 int pixelValue = GetPixelValueOfSelectedItem();
95 QMenu *
menu =
new QMenu(m_Controls.m_LabelSetTableWidget);
97 if (m_Controls.m_LabelSetTableWidget->selectedItems().size() > 1)
99 QAction *mergeAction =
new QAction(QIcon(
":/Qmitk/MergeLabels.png"),
"Merge selection on current label",
this);
100 mergeAction->setEnabled(
true);
101 QObject::connect(mergeAction, SIGNAL(triggered(
bool)),
this, SLOT(OnMergeLabels(
bool)));
102 menu->addAction(mergeAction);
104 QAction *removeLabelsAction =
new QAction(QIcon(
":/Qmitk/RemoveLabel.png"),
"Remove selected labels",
this);
105 removeLabelsAction->setEnabled(
true);
106 QObject::connect(removeLabelsAction, SIGNAL(triggered(
bool)),
this, SLOT(OnRemoveLabels(
bool)));
107 menu->addAction(removeLabelsAction);
109 QAction *eraseLabelsAction =
new QAction(QIcon(
":/Qmitk/EraseLabel.png"),
"Erase selected labels",
this);
110 eraseLabelsAction->setEnabled(
true);
111 QObject::connect(eraseLabelsAction, SIGNAL(triggered(
bool)),
this, SLOT(OnEraseLabels(
bool)));
112 menu->addAction(eraseLabelsAction);
114 QAction *combineAndCreateSurfaceAction =
115 new QAction(QIcon(
":/Qmitk/CreateSurface.png"),
"Combine and create a surface",
this);
116 combineAndCreateSurfaceAction->setEnabled(
true);
118 combineAndCreateSurfaceAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCombineAndCreateSurface(
bool)));
121 QAction *createMasksAction =
122 new QAction(QIcon(
":/Qmitk/CreateMask.png"),
"Create a mask for each selected label",
this);
123 createMasksAction->setEnabled(
true);
124 QObject::connect(createMasksAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateMasks(
bool)));
127 QAction *combineAndCreateMaskAction =
128 new QAction(QIcon(
":/Qmitk/CreateMask.png"),
"Combine and create a mask",
this);
129 combineAndCreateMaskAction->setEnabled(
true);
130 QObject::connect(combineAndCreateMaskAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCombineAndCreateMask(
bool)));
135 QAction *renameAction =
new QAction(QIcon(
":/Qmitk/RenameLabel.png"),
"Rename...",
this);
136 renameAction->setEnabled(
true);
137 QObject::connect(renameAction, SIGNAL(triggered(
bool)),
this, SLOT(OnRenameLabel(
bool)));
138 menu->addAction(renameAction);
140 QAction *removeAction =
new QAction(QIcon(
":/Qmitk/RemoveLabel.png"),
"Remove...",
this);
141 removeAction->setEnabled(
true);
142 QObject::connect(removeAction, SIGNAL(triggered(
bool)),
this, SLOT(OnRemoveLabel(
bool)));
143 menu->addAction(removeAction);
145 QAction *eraseAction =
new QAction(QIcon(
":/Qmitk/EraseLabel.png"),
"Erase...",
this);
146 eraseAction->setEnabled(
true);
147 QObject::connect(eraseAction, SIGNAL(triggered(
bool)),
this, SLOT(OnEraseLabel(
bool)));
148 menu->addAction(eraseAction);
150 QAction *mergeAction =
new QAction(QIcon(
":/Qmitk/MergeLabels.png"),
"Merge...",
this);
151 mergeAction->setEnabled(
true);
152 QObject::connect(mergeAction, SIGNAL(triggered(
bool)),
this, SLOT(OnMergeLabel(
bool)));
153 menu->addAction(mergeAction);
155 QAction *randomColorAction =
new QAction(QIcon(
":/Qmitk/RandomColor.png"),
"Random color",
this);
156 randomColorAction->setEnabled(
true);
157 QObject::connect(randomColorAction, SIGNAL(triggered(
bool)),
this, SLOT(OnRandomColor(
bool)));
158 menu->addAction(randomColorAction);
160 QAction *viewOnlyAction =
new QAction(QIcon(
":/Qmitk/visible.png"),
"View only",
this);
161 viewOnlyAction->setEnabled(
true);
162 QObject::connect(viewOnlyAction, SIGNAL(triggered(
bool)),
this, SLOT(OnSetOnlyActiveLabelVisible(
bool)));
163 menu->addAction(viewOnlyAction);
165 QAction *viewAllAction =
new QAction(QIcon(
":/Qmitk/visible.png"),
"View all",
this);
166 viewAllAction->setEnabled(
true);
167 QObject::connect(viewAllAction, SIGNAL(triggered(
bool)),
this, SLOT(OnSetAllLabelsVisible(
bool)));
168 menu->addAction(viewAllAction);
170 QAction *hideAllAction =
new QAction(QIcon(
":/Qmitk/invisible.png"),
"Hide all",
this);
171 hideAllAction->setEnabled(
true);
172 QObject::connect(hideAllAction, SIGNAL(triggered(
bool)),
this, SLOT(OnSetAllLabelsInvisible(
bool)));
173 menu->addAction(hideAllAction);
175 QAction *lockAllAction =
new QAction(QIcon(
":/Qmitk/lock.png"),
"Lock all",
this);
176 lockAllAction->setEnabled(
true);
177 QObject::connect(lockAllAction, SIGNAL(triggered(
bool)),
this, SLOT(OnLockAllLabels(
bool)));
178 menu->addAction(lockAllAction);
180 QAction *unlockAllAction =
new QAction(QIcon(
":/Qmitk/unlock.png"),
"Unlock all",
this);
181 unlockAllAction->setEnabled(
true);
182 QObject::connect(unlockAllAction, SIGNAL(triggered(
bool)),
this, SLOT(OnUnlockAllLabels(
bool)));
183 menu->addAction(unlockAllAction);
185 QAction *createSurfaceAction =
new QAction(QIcon(
":/Qmitk/CreateSurface.png"),
"Create surface",
this);
186 createSurfaceAction->setEnabled(
true);
187 createSurfaceAction->setMenu(
new QMenu());
189 QAction *
tmp1 = createSurfaceAction->menu()->addAction(QString(
"Detailed"));
190 QAction *
tmp2 = createSurfaceAction->menu()->addAction(QString(
"Smoothed"));
192 QObject::connect(tmp1, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateDetailedSurface(
bool)));
193 QObject::connect(tmp2, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateSmoothedSurface(
bool)));
195 menu->addAction(createSurfaceAction);
197 QAction *createMaskAction =
new QAction(QIcon(
":/Qmitk/CreateMask.png"),
"Create mask",
this);
198 createMaskAction->setEnabled(
true);
199 QObject::connect(createMaskAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateMask(
bool)));
201 menu->addAction(createMaskAction);
203 QAction *createCroppedMaskAction =
new QAction(QIcon(
":/Qmitk/CreateMask.png"),
"Create cropped mask",
this);
204 createCroppedMaskAction->setEnabled(
true);
205 QObject::connect(createCroppedMaskAction, SIGNAL(triggered(
bool)),
this, SLOT(OnCreateCroppedMask(
bool)));
212 menu->addAction(createCroppedMaskAction);
214 QSlider *opacitySlider =
new QSlider;
215 opacitySlider->setMinimum(0);
216 opacitySlider->setMaximum(100);
217 opacitySlider->setOrientation(Qt::Horizontal);
218 QObject::connect(opacitySlider, SIGNAL(valueChanged(
int)),
this, SLOT(OnOpacityChanged(
int)));
220 QLabel *_OpacityLabel =
new QLabel(
"Opacity: ");
221 QVBoxLayout *_OpacityWidgetLayout =
new QVBoxLayout;
222 _OpacityWidgetLayout->setContentsMargins(4, 4, 4, 4);
223 _OpacityWidgetLayout->addWidget(_OpacityLabel);
224 _OpacityWidgetLayout->addWidget(opacitySlider);
225 QWidget *_OpacityWidget =
new QWidget;
226 _OpacityWidget->setLayout(_OpacityWidgetLayout);
228 QWidgetAction *OpacityAction =
new QWidgetAction(
this);
229 OpacityAction->setDefaultWidget(_OpacityWidget);
231 auto workingImage = this->GetWorkingImage();
232 auto activeLayer = workingImage->GetActiveLayer();
233 auto label = workingImage->GetLabel(pixelValue, activeLayer);
235 if (
nullptr != label)
237 auto opacity = label->GetOpacity();
238 opacitySlider->setValue(static_cast<int>(opacity * 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 )
264 void QmitkLabelSetWidget::OnSetAllLabelsInvisible(
bool )
270 void QmitkLabelSetWidget::OnSetOnlyActiveLabelVisible(
bool )
273 int pixelValue = GetPixelValueOfSelectedItem();
280 this->WaitCursorOn();
284 this->WaitCursorOff();
285 if (pos.GetVnlVector().max_value() > 0.0)
293 void QmitkLabelSetWidget::OnMergeLabel(
bool )
296 dialog.setWindowTitle(
"Select a second label..");
298 int dialogReturnValue = dialog.exec();
299 if (dialogReturnValue == QDialog::Rejected)
302 int sourcePixelValue = -1;
303 for (
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); i++)
306 sourcePixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt();
309 if (sourcePixelValue == -1)
315 int pixelValue = GetPixelValueOfSelectedItem();
316 GetWorkingImage()->
MergeLabel(pixelValue, sourcePixelValue, GetWorkingImage()->GetActiveLayer());
321 void QmitkLabelSetWidget::OnEraseLabel(
bool )
323 int pixelValue = GetPixelValueOfSelectedItem();
324 QString question =
"Do you really want to erase the contents of label \"";
326 QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
GetName()));
327 question.append(
"\"?");
329 QMessageBox::StandardButton answerButton =
330 QMessageBox::question(
this,
"Erase label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
332 if (answerButton == QMessageBox::Yes)
334 this->WaitCursorOn();
336 this->WaitCursorOff();
341 void QmitkLabelSetWidget::OnRemoveLabel(
bool )
343 int pixelValue = GetPixelValueOfSelectedItem();
344 QString question =
"Do you really want to remove label \"";
346 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();
363 void QmitkLabelSetWidget::OnRenameLabel(
bool )
365 int pixelValue = GetPixelValueOfSelectedItem();
367 dialog.setWindowTitle(
"Rename Label");
369 dialog.
SetColor(GetWorkingImage()->GetActiveLabelSet()->GetLabel(pixelValue)->GetColor());
371 QString::fromStdString(GetWorkingImage()->GetActiveLabelSet()->GetLabel(pixelValue)->
GetName()));
373 if (dialog.exec() == QDialog::Rejected)
378 if (segmentationName.isEmpty())
380 segmentationName =
"Unnamed";
389 void QmitkLabelSetWidget::OnCombineAndCreateMask(
bool )
391 m_Controls.m_LabelSetTableWidget->selectedRanges();
395 void QmitkLabelSetWidget::OnCreateMasks(
bool )
397 m_Controls.m_LabelSetTableWidget->selectedRanges();
401 void QmitkLabelSetWidget::OnCombineAndCreateSurface(
bool )
403 m_Controls.m_LabelSetTableWidget->selectedRanges();
407 void QmitkLabelSetWidget::OnEraseLabels(
bool )
409 QString question =
"Do you really want to erase the selected labels?";
411 QMessageBox::StandardButton answerButton = QMessageBox::question(
412 this,
"Erase selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
414 if (answerButton == QMessageBox::Yes)
416 QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
417 if (ranges.isEmpty())
420 std::vector<mitk::Label::PixelType> VectorOfLablePixelValues;
421 foreach (QTableWidgetSelectionRange a, ranges)
422 for (
int i = a.topRow(); i <= a.bottomRow(); i++)
423 VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
425 this->WaitCursorOn();
426 GetWorkingImage()->
EraseLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer());
427 this->WaitCursorOff();
432 void QmitkLabelSetWidget::OnRemoveLabels(
bool )
434 QString question =
"Do you really want to remove selected labels?";
435 QMessageBox::StandardButton answerButton = QMessageBox::question(
436 this,
"Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
438 if (answerButton == QMessageBox::Yes)
440 QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
441 if (ranges.isEmpty())
446 std::vector<mitk::Label::PixelType> VectorOfLablePixelValues;
447 foreach (QTableWidgetSelectionRange a, ranges)
449 for (
int i = a.topRow(); i <= a.bottomRow(); ++i)
451 VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
455 this->WaitCursorOn();
456 GetWorkingImage()->
RemoveLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer());
457 this->WaitCursorOff();
463 void QmitkLabelSetWidget::OnMergeLabels(
bool )
465 int pixelValue = GetPixelValueOfSelectedItem();
466 QString question =
"Do you really want to merge selected labels into \"";
468 QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
GetName()));
469 question.append(
"\"?");
471 QMessageBox::StandardButton answerButton = QMessageBox::question(
472 this,
"Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
474 if (answerButton == QMessageBox::Yes)
476 QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
477 if (ranges.isEmpty())
482 std::vector<mitk::Label::PixelType> vectorOfSourcePixelValues;
483 foreach (QTableWidgetSelectionRange a, ranges)
485 for (
int i = a.topRow(); i <= a.bottomRow(); ++i)
487 vectorOfSourcePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
491 this->WaitCursorOn();
492 GetWorkingImage()->
MergeLabels(pixelValue, vectorOfSourcePixelValues, 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();
513 ->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())
514 ->
SetLocked(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetLocked());
518 void QmitkLabelSetWidget::OnVisibleButtonClicked()
521 for (
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
523 if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, VISIBLE_COL))
530 if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount())
532 QTableWidgetItem *item = m_Controls.m_LabelSetTableWidget->item(row, 0);
533 int pixelValue = item->data(Qt::UserRole).toInt();
535 ->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())
536 ->
SetVisible(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetVisible());
541 void QmitkLabelSetWidget::OnColorButtonClicked()
544 for (
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
546 if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, COLOR_COL))
552 if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount())
554 int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt();
556 QColor initial(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255);
557 QColor qcolor = QColorDialog::getColor(initial,
nullptr, QString(
"Change color"));
558 if (!qcolor.isValid())
563 QPushButton *button =
static_cast<QPushButton *
>(m_Controls.m_LabelSetTableWidget->cellWidget(row, COLOR_COL));
569 button->setAutoFillBackground(
true);
571 QString styleSheet =
"background-color:rgb(";
572 styleSheet.append(QString::number(qcolor.red()));
573 styleSheet.append(
",");
574 styleSheet.append(QString::number(qcolor.green()));
575 styleSheet.append(
",");
576 styleSheet.append(QString::number(qcolor.blue()));
577 styleSheet.append(
"); border: 0;");
578 button->setStyleSheet(styleSheet);
581 newColor.SetRed(qcolor.red() / 255.0);
582 newColor.SetGreen(qcolor.green() / 255.0);
583 newColor.SetBlue(qcolor.blue() / 255.0);
585 GetWorkingImage()->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
SetColor(newColor);
591 void QmitkLabelSetWidget::OnRandomColor(
bool )
593 int pixelValue = GetPixelValueOfSelectedItem();
595 ->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())
603 m_OrganColors = organColors;
606 void QmitkLabelSetWidget::OnActiveLabelChanged(
int pixelValue)
609 assert(workingImage);
619 workingImage->Modified();
623 void QmitkLabelSetWidget::OnItemClicked(QTableWidgetItem *item)
628 int pixelValue = item->data(Qt::UserRole).toInt();
630 QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
631 if (!ranges.empty() && ranges.back().rowCount() == 1)
634 OnActiveLabelChanged(pixelValue);
639 void QmitkLabelSetWidget::OnItemDoubleClicked(QTableWidgetItem *item)
644 int pixelValue = item->data(Qt::UserRole).toInt();
652 if (pos.GetVnlVector().max_value() > 0.0)
657 workingImage->Modified();
665 if (!GetWorkingImage()->ExistLabel(pixelValue))
667 for (
int row = 0; row < m_Controls.m_LabelSetTableWidget->rowCount(); row++)
669 if (m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt() == pixelValue)
671 m_Controls.m_LabelSetTableWidget->clearSelection();
672 m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
673 m_Controls.m_LabelSetTableWidget->selectRow(row);
674 m_Controls.m_LabelSetTableWidget->scrollToItem(m_Controls.m_LabelSetTableWidget->item(row, 0));
675 m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
684 void QmitkLabelSetWidget::InsertTableWidgetItem(
mitk::Label *label)
688 QString styleSheet =
"background-color:rgb(";
689 styleSheet.append(QString::number(color[0] * 255));
690 styleSheet.append(
",");
691 styleSheet.append(QString::number(color[1] * 255));
692 styleSheet.append(
",");
693 styleSheet.append(QString::number(color[2] * 255));
694 styleSheet.append(
"); border: 0;");
696 QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget;
697 int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2;
698 QString text = fontMetrics().elidedText(label->
GetName().c_str(), Qt::ElideMiddle, colWidth);
699 QTableWidgetItem *nameItem =
new QTableWidgetItem(text);
700 nameItem->setTextAlignment(Qt::AlignCenter | Qt::AlignLeft);
703 nameItem->setData(Qt::UserRole, QVariant(label->
GetValue()));
706 QPushButton *pbColor =
new QPushButton(tableWidget);
707 pbColor->setFixedSize(24, 24);
708 pbColor->setCheckable(
false);
709 pbColor->setAutoFillBackground(
true);
710 pbColor->setToolTip(
"Change label color");
711 pbColor->setStyleSheet(styleSheet);
713 connect(pbColor, SIGNAL(clicked()),
this, SLOT(OnColorButtonClicked()));
715 QString transparentStyleSheet = QLatin1String(
"background-color: transparent; border: 0;");
717 QPushButton *pbLocked =
new QPushButton(tableWidget);
718 pbLocked->setFixedSize(24, 24);
719 QIcon *iconLocked =
new QIcon();
722 iconLocked->addPixmap(lockIcon.pixmap(64), QIcon::Normal, QIcon::Off);
723 iconLocked->addPixmap(unlockIcon.pixmap(64), QIcon::Normal, QIcon::On);
724 pbLocked->setIcon(*iconLocked);
725 pbLocked->setIconSize(QSize(24, 24));
726 pbLocked->setCheckable(
true);
727 pbLocked->setToolTip(
"Lock/unlock label");
728 pbLocked->setChecked(!label->
GetLocked());
729 pbLocked->setStyleSheet(transparentStyleSheet);
731 connect(pbLocked, SIGNAL(clicked()),
this, SLOT(OnLockedButtonClicked()));
733 QPushButton *pbVisible =
new QPushButton(tableWidget);
734 pbVisible->setFixedSize(24, 24);
735 pbVisible->setAutoRepeat(
false);
736 QIcon *iconVisible =
new QIcon();
739 iconVisible->addPixmap(visibleIcon.pixmap(64), QIcon::Normal, QIcon::Off);
740 iconVisible->addPixmap(invisibleIcon.pixmap(64), QIcon::Normal, QIcon::On);
741 pbVisible->setIcon(*iconVisible);
742 pbVisible->setIconSize(QSize(24, 24));
743 pbVisible->setCheckable(
true);
744 pbVisible->setToolTip(
"Show/hide label");
746 pbVisible->setStyleSheet(transparentStyleSheet);
748 connect(pbVisible, SIGNAL(clicked()),
this, SLOT(OnVisibleButtonClicked()));
750 int row = tableWidget->rowCount();
751 tableWidget->insertRow(row);
752 tableWidget->setRowHeight(row, 24);
753 tableWidget->setItem(row, 0, nameItem);
754 tableWidget->setCellWidget(row, 1, pbLocked);
755 tableWidget->setCellWidget(row, 2, pbColor);
756 tableWidget->setCellWidget(row, 3, pbVisible);
757 tableWidget->selectRow(row);
765 tableWidget->hideRow(row);
776 QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget;
777 m_LabelStringList.clear();
778 for (
int i = 0; i < tableWidget->rowCount(); ++i)
780 UpdateTableWidgetItem(tableWidget->item(i, 0));
781 m_LabelStringList.append(tableWidget->item(i, 0)->text());
784 OnLabelListModified(m_LabelStringList);
789 void QmitkLabelSetWidget::UpdateTableWidgetItem(QTableWidgetItem *item)
796 QString styleSheet =
"background-color:rgb(";
797 styleSheet.append(QString::number(color[0] * 255));
798 styleSheet.append(
",");
799 styleSheet.append(QString::number(color[1] * 255));
800 styleSheet.append(
",");
801 styleSheet.append(QString::number(color[2] * 255));
802 styleSheet.append(
"); border: 0;");
804 QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget;
805 int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2;
806 QString text = fontMetrics().elidedText(label->
GetName().c_str(), Qt::ElideMiddle, colWidth);
809 QPushButton *pbLocked =
dynamic_cast<QPushButton *
>(tableWidget->cellWidget(item->row(), 1));
810 pbLocked->setChecked(!label->
GetLocked());
812 QPushButton *pbColor =
dynamic_cast<QPushButton *
>(tableWidget->cellWidget(item->row(), 2));
813 pbColor->setStyleSheet(styleSheet);
815 QPushButton *pbVisible =
dynamic_cast<QPushButton *
>(tableWidget->cellWidget(item->row(), 3));
818 if (item->row() == 0)
820 tableWidget->hideRow(item->row());
826 QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget;
828 while (tableWidget->rowCount())
830 tableWidget->removeRow(0);
838 m_LabelStringList.clear();
846 InsertTableWidgetItem(it->second);
848 pixelValue = it->first;
849 m_LabelStringList.append(QString(it->second->GetName().c_str()));
855 OnLabelListModified(m_LabelStringList);
857 std::stringstream captionText;
859 m_Controls.m_lblCaption->setText(captionText.str().c_str());
864 int QmitkLabelSetWidget::GetPixelValueOfSelectedItem()
866 if (m_Controls.m_LabelSetTableWidget->currentItem())
868 return m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt();
875 return m_LabelStringList;
878 void QmitkLabelSetWidget::InitializeTableWidget()
880 QTableWidget *tableWidged = m_Controls.m_LabelSetTableWidget;
882 tableWidged->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
883 tableWidged->setTabKeyNavigation(
false);
884 tableWidged->setAlternatingRowColors(
false);
885 tableWidged->setFocusPolicy(Qt::NoFocus);
886 tableWidged->setColumnCount(4);
887 tableWidged->resizeColumnToContents(NAME_COL);
888 tableWidged->setColumnWidth(LOCKED_COL, 25);
889 tableWidged->setColumnWidth(COLOR_COL, 25);
890 tableWidged->setColumnWidth(VISIBLE_COL, 25);
891 tableWidged->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
892 tableWidged->setContextMenuPolicy(Qt::CustomContextMenu);
893 tableWidged->horizontalHeader()->hide();
894 tableWidged->setSortingEnabled(
false);
895 tableWidged->verticalHeader()->hide();
896 tableWidged->setEditTriggers(QAbstractItemView::NoEditTriggers);
897 tableWidged->setSelectionMode(QAbstractItemView::ExtendedSelection);
898 tableWidged->setSelectionBehavior(QAbstractItemView::SelectRows);
900 connect(tableWidged, SIGNAL(itemClicked(QTableWidgetItem *)),
this, SLOT(OnItemClicked(QTableWidgetItem *)));
902 tableWidged, SIGNAL(itemDoubleClicked(QTableWidgetItem *)),
this, SLOT(OnItemDoubleClicked(QTableWidgetItem *)));
904 SIGNAL(customContextMenuRequested(
const QPoint &)),
906 SLOT(OnTableViewContextMenuRequested(
const QPoint &)));
930 void QmitkLabelSetWidget::OnOpacityChanged(
int value)
932 int pixelValue = GetPixelValueOfSelectedItem();
933 float opacity =
static_cast<float>(value) / 100.0f;
934 GetWorkingImage()->
GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->
SetOpacity(opacity);
940 QWidget::setEnabled(enabled);
946 m_DataStorage = storage;
949 void QmitkLabelSetWidget::OnSearchLabel()
951 std::string text = m_Controls.m_LabelSearchBox->text().toStdString();
954 for (
int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
956 if (m_Controls.m_LabelSetTableWidget->item(i, 0)->text().toStdString().compare(text) == 0)
958 pixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt();
963 if (pixelValue == -1)
970 QTableWidgetItem *nameItem = m_Controls.m_LabelSetTableWidget->item(row, NAME_COL);
976 m_Controls.m_LabelSetTableWidget->clearSelection();
977 m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
978 m_Controls.m_LabelSetTableWidget->selectRow(row);
979 m_Controls.m_LabelSetTableWidget->scrollToItem(nameItem);
980 m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
984 this->WaitCursorOn();
990 if (pos.GetVnlVector().max_value() > 0.0)
996 GetWorkingImage()->
UpdateCenterOfMass(pixelValue, GetWorkingImage()->GetActiveLayer());
1002 this->WaitCursorOff();
1005 void QmitkLabelSetWidget::OnLabelListModified(
const QStringList &list)
1007 QStringListModel *completeModel =
static_cast<QStringListModel *
>(m_Completer->model());
1008 completeModel->setStringList(list);
1015 assert(workingImage);
1016 return workingImage;
1022 assert(workingNode);
1029 bool hasWorkingData = (workingNode !=
nullptr);
1031 m_Controls.m_LabelSetTableWidget->setEnabled(hasWorkingData);
1032 m_Controls.m_LabelSearchBox->setEnabled(hasWorkingData);
1034 if (!hasWorkingData)
1037 QStringListModel *completeModel =
static_cast<QStringListModel *
>(m_Completer->model());
1041 void QmitkLabelSetWidget::OnCreateCroppedMask(
bool)
1047 int pixelValue = GetPixelValueOfSelectedItem();
1050 this->WaitCursorOn();
1054 cropFilter->SetBackgroundValue(0);
1055 cropFilter->SetMarginFactor(1.15);
1056 cropFilter->Update();
1058 maskImage = cropFilter->GetOutput();
1060 this->WaitCursorOff();
1064 this->WaitCursorOff();
1065 MITK_ERROR <<
"Exception caught: " << e.GetDescription();
1066 QMessageBox::information(
this,
"Create Mask",
"Could not create a mask out of the selected label.\n");
1070 if (maskImage.IsNull())
1072 QMessageBox::information(
this,
"Create Mask",
"Could not create a mask out of the selected label.\n");
1079 maskNode->SetName(name);
1080 maskNode->SetData(maskImage);
1081 maskNode->SetBoolProperty(
"binary",
true);
1082 maskNode->SetBoolProperty(
"outline binary",
true);
1083 maskNode->SetBoolProperty(
"outline binary shadow",
true);
1084 maskNode->SetFloatProperty(
"outline width", 2.0);
1086 maskNode->SetOpacity(1.0);
1088 m_DataStorage->
Add(maskNode, GetWorkingNode());
1091 void QmitkLabelSetWidget::OnCreateMask(
bool )
1097 int pixelValue = GetPixelValueOfSelectedItem();
1100 this->WaitCursorOn();
1102 this->WaitCursorOff();
1106 this->WaitCursorOff();
1107 MITK_ERROR <<
"Exception caught: " << e.GetDescription();
1108 QMessageBox::information(
this,
"Create Mask",
"Could not create a mask out of the selected label.\n");
1112 if (maskImage.IsNull())
1114 QMessageBox::information(
this,
"Create Mask",
"Could not create a mask out of the selected label.\n");
1121 maskNode->SetName(name);
1122 maskNode->SetData(maskImage);
1123 maskNode->SetBoolProperty(
"binary",
true);
1124 maskNode->SetBoolProperty(
"outline binary",
true);
1125 maskNode->SetBoolProperty(
"outline binary shadow",
true);
1126 maskNode->SetFloatProperty(
"outline width", 2.0);
1128 maskNode->SetOpacity(1.0);
1130 m_DataStorage->
Add(maskNode, GetWorkingNode());
1133 void QmitkLabelSetWidget::OnToggleOutline(
bool value)
1136 assert(workingNode);
1139 workingNode->
GetData()->Modified();
1143 void QmitkLabelSetWidget::OnCreateSmoothedSurface(
bool )
1149 int pixelValue = GetPixelValueOfSelectedItem();
1153 itk::SimpleMemberCommand<QmitkLabelSetWidget>::Pointer successCommand =
1154 itk::SimpleMemberCommand<QmitkLabelSetWidget>::New();
1155 successCommand->SetCallbackFunction(
this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1158 itk::SimpleMemberCommand<QmitkLabelSetWidget>::Pointer errorCommand =
1159 itk::SimpleMemberCommand<QmitkLabelSetWidget>::New();
1160 errorCommand->SetCallbackFunction(
this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1164 surfaceFilter->SetPointerParameter(
"Group node", groupNode);
1165 surfaceFilter->SetPointerParameter(
"Input", workingImage);
1166 surfaceFilter->SetParameter(
"RequestedLabel", pixelValue);
1167 surfaceFilter->SetParameter(
"Smooth",
true);
1168 surfaceFilter->SetDataStorage(*m_DataStorage);
1174 surfaceFilter->StartAlgorithm();
1178 MITK_ERROR <<
"Exception caught: " << e.GetDescription();
1179 QMessageBox::information(
this,
1181 "Could not create a surface mesh out of the selected label. See error log for details.\n");
1185 void QmitkLabelSetWidget::OnCreateDetailedSurface(
bool )
1191 int pixelValue = GetPixelValueOfSelectedItem();
1195 itk::SimpleMemberCommand<QmitkLabelSetWidget>::Pointer successCommand =
1196 itk::SimpleMemberCommand<QmitkLabelSetWidget>::New();
1197 successCommand->SetCallbackFunction(
this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1200 itk::SimpleMemberCommand<QmitkLabelSetWidget>::Pointer errorCommand =
1201 itk::SimpleMemberCommand<QmitkLabelSetWidget>::New();
1202 errorCommand->SetCallbackFunction(
this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1206 surfaceFilter->SetPointerParameter(
"Group node", groupNode);
1207 surfaceFilter->SetPointerParameter(
"Input", workingImage);
1208 surfaceFilter->SetParameter(
"RequestedLabel", pixelValue);
1209 surfaceFilter->SetParameter(
"Smooth",
false);
1210 surfaceFilter->SetDataStorage(*m_DataStorage);
1216 surfaceFilter->StartAlgorithm();
1220 MITK_ERROR <<
"Exception caught: " << e.GetDescription();
1221 QMessageBox::information(
this,
1223 "Could not create a surface mesh out of the selected label. See error log for details.\n");
1227 void QmitkLabelSetWidget::OnImportLabeledImage()
1279 void QmitkLabelSetWidget::OnImportSegmentation()
1317 void QmitkLabelSetWidget::WaitCursorOn()
1319 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1322 void QmitkLabelSetWidget::WaitCursorOff()
1324 this->RestoreOverrideCursor();
1327 void QmitkLabelSetWidget::RestoreOverrideCursor()
1329 QApplication::restoreOverrideCursor();
1332 void QmitkLabelSetWidget::OnThreadedCalculationDone()
LabelContainerConstIteratorType IteratorConstBegin() const
Returns a const iterator poiting to the begining of the container.
unsigned int GetNumberOfLabels(unsigned int layer=0) const
Get the number of all existing mitk::Labels for a given layer.
mitk::Point3D GetCenterOfMassCoordinates() const
unsigned int GetActiveLayer() const
Gets the ID of the currently active layer.
Data management class that handles 'was created by' relations.
LabelContainerConstIteratorType IteratorConstEnd() const
Returns a const iterator pointing to the end of the container.
mitk::Image::Pointer CreateLabelMask(PixelType index, bool useActiveLayer=true, unsigned int layer=0)
Color GetNextColor() override
method to return another color
void UpdateLookupTable(PixelType pixelValue)
static SurfaceBasedInterpolationController * GetInstance()
void SetLocked(bool locked)
void SetAllLabelsLocked(bool)
void MergeLabel(PixelType pixelValue, PixelType sourcePixelValue, unsigned int layer=0)
Merges the mitk::Label with a given target value with the active label.
QString GetLabelSetWidgetTableCompleteWord()
A data structure describing a label.
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()
virtual void Add(DataNode *node, const DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
const QString GetSegmentationName()
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 SetSuggestionList(QStringList organColorList)
void SetColor(const mitk::Color &)
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
mitk::DataStorage::Pointer m_DataStorage
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...
void MergeLabels(PixelType pixelValue, std::vector< PixelType > &vectorOfSourcePixelValues, unsigned int layer=0)
Merges a list of mitk::Labels with the mitk::Label that has a specific value.
static RenderingManager * GetInstance()
void SetLabelSuggestionList(QStringList stringList)
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.
const mitk::Color & GetColor() const
LabelContainerType::const_iterator LabelContainerConstIteratorType
PixelType GetValue() const
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)
void Clear()
removes any temporary message being shown.
void UpdateCenterOfMass(PixelType pixelValue, unsigned int layer=0)
void SetColor(const mitk::Color &color)
void SetSegmentationName(const QString &segmentationName)
LabelSetImage class for handling labels and layers in a segmentation session.
void SetActiveLabel(PixelType)
static std::string GetName(std::string fileName, std::string suffix)
mitk::Label * GetLabel(PixelType pixelValue, unsigned int layer=0) const
Returns the mitk::Label with the given pixelValue and for the given layer.
US_USE_NAMESPACE std::string tmp1
Dialog for QmitkInteractiveSegmentation.
void RenameLabel(PixelType, const std::string &, const Color &)
static QIcon ThemeIcon(const QByteArray &originalSVG)
void RemoveLabel(PixelType)
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Class for nodes of the DataTree.
std::string GetName() const
void SetAllLabelsVisible(bool)