diff --git a/Modules/SegmentationUI/Qmitk/QmitkFindSegmentationTaskDialog.cpp b/Modules/SegmentationUI/Qmitk/QmitkFindSegmentationTaskDialog.cpp index 265aec95a6..30dd2c81fc 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkFindSegmentationTaskDialog.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkFindSegmentationTaskDialog.cpp @@ -1,135 +1,190 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include #include QmitkFindSegmentationTaskDialog::QmitkFindSegmentationTaskDialog(QWidget* parent) : QDialog(parent), m_Ui(new Ui::QmitkFindSegmentationTaskDialog) { this->setWindowFlag(Qt::WindowContextHelpButtonHint, false); m_Ui->setupUi(this); using Self = QmitkFindSegmentationTaskDialog; + connect(m_Ui->tableWidget, &QTableWidget::itemSelectionChanged, this, &Self::OnItemSelectionChanged); connect(m_Ui->tableWidget, &QTableWidget::itemDoubleClicked, this, &Self::OnItemDoubleClicked); + + auto applyFilter = [this](const QString&) { this->ApplyFilter(); }; + + connect(m_Ui->noLineEdit, &QLineEdit::textChanged, this, applyFilter); + connect(m_Ui->nameLineEdit, &QLineEdit::textChanged, this, applyFilter); + connect(m_Ui->statusComboBox, &QComboBox::currentTextChanged, applyFilter); } QmitkFindSegmentationTaskDialog::~QmitkFindSegmentationTaskDialog() { delete m_Ui; } void QmitkFindSegmentationTaskDialog::SetTaskList(const mitk::SegmentationTaskList* taskList) { if (m_TaskList != taskList) { m_TaskList = taskList; auto* table = m_Ui->tableWidget; - table->setSortingEnabled(false); + table->setSortingEnabled(false); // Do not sort while populating the table table->reset(); if (m_TaskList.IsNotNull()) { const int numberOfRows = static_cast(m_TaskList->GetNumberOfTasks()); const int numberOfColumns = table->columnCount(); table->setRowCount(numberOfRows); for (int row = 0; row < numberOfRows; ++row) { for (int column = 0; column < numberOfColumns; ++column) { auto* item = new QTableWidgetItem(); item->setData(Qt::UserRole, row); switch (column) { case Column::Number: item->setText(QString::number(row + 1)); break; case Column::Name: if (m_TaskList->HasName(row)) item->setText(QString::fromStdString(m_TaskList->GetName(row))); break; case Column::Status: item->setText(m_TaskList->IsDone(row) ? "Done" : "Not done"); break; case Column::Image: if (m_TaskList->HasImage(row)) item->setText(QString::fromStdString(m_TaskList->GetImage(row).string())); break; case Column::Segmentation: if (m_TaskList->HasSegmentation(row)) item->setText(QString::fromStdString(m_TaskList->GetSegmentation(row).string())); break; case Column::Result: if (m_TaskList->HasResult(row)) item->setText(QString::fromStdString(m_TaskList->GetResult(row).string())); break; case Column::Description: if (m_TaskList->HasDescription(row)) item->setText(QString::fromStdString(m_TaskList->GetDescription(row))); break; } table->setItem(row, column, item); } } - table->setSortingEnabled(true); + table->setSortingEnabled(true); // Sort fully populated table } } } std::optional QmitkFindSegmentationTaskDialog::GetSelectedTask() const { return m_SelectedTask; } bool QmitkFindSegmentationTaskDialog::LoadSelectedTask() const { return m_Ui->loadCheckBox->isChecked(); } void QmitkFindSegmentationTaskDialog::OnItemSelectionChanged() { auto selectedItems = m_Ui->tableWidget->selectedItems(); if (!selectedItems.empty()) { m_SelectedTask = static_cast(selectedItems.front()->data(Qt::UserRole).toInt()); } else { m_SelectedTask.reset(); } } void QmitkFindSegmentationTaskDialog::OnItemDoubleClicked(QTableWidgetItem*) { this->done(m_SelectedTask.has_value() ? QDialog::Accepted : QDialog::Rejected); } + +void QmitkFindSegmentationTaskDialog::ApplyFilter() +{ + auto* table = m_Ui->tableWidget; + const int numberOfRows = table->rowCount(); + bool foundSomething = false; + + for (int row = 0; row < numberOfRows; ++row) + { + if (!this->ContainsNumber(row) || !this->ContainsName(row) || !this->HasStatus(row)) + { + table->hideRow(row); + continue; + } + + table->showRow(row); + + if (!foundSomething) + { + // Select the *first* finding to accelerate user interaction. For example, in a fresh dialog, typing + // '4', '2', '' will close the dialog and load task 42. In combination with the Ctrl+F shortcut + // for this dialog, no mouse interaction is necessary at all to jump to specific tasks. + table->selectRow(row); + foundSomething = true; + } + } + + if (!foundSomething) + table->clearSelection(); // Hidden rows do not automatically lose selection +} + +bool QmitkFindSegmentationTaskDialog::ContainsNumber(int row) const +{ + auto numberText = m_Ui->noLineEdit->text().trimmed(); + return numberText.isEmpty() || m_Ui->tableWidget->item(row, Column::Number)->text().contains(numberText); +} + +bool QmitkFindSegmentationTaskDialog::ContainsName(int row) const +{ + auto name = m_Ui->nameLineEdit->text().trimmed(); + return name.isEmpty() || m_Ui->tableWidget->item(row, Column::Name)->text().contains(name, Qt::CaseInsensitive); +} + +bool QmitkFindSegmentationTaskDialog::HasStatus(int row) const +{ + auto status = m_Ui->statusComboBox->currentText(); + return status.isEmpty() || status == QStringLiteral("All") || m_Ui->tableWidget->item(row, Column::Status)->text() == status; +} diff --git a/Modules/SegmentationUI/Qmitk/QmitkFindSegmentationTaskDialog.h b/Modules/SegmentationUI/Qmitk/QmitkFindSegmentationTaskDialog.h index 0b42a2e9c7..be868f50b7 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkFindSegmentationTaskDialog.h +++ b/Modules/SegmentationUI/Qmitk/QmitkFindSegmentationTaskDialog.h @@ -1,57 +1,63 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkFindSegmentationTaskDialog_h #define QmitkFindSegmentationTaskDialog_h #include #include class QTableWidgetItem; namespace Ui { class QmitkFindSegmentationTaskDialog; } class QmitkFindSegmentationTaskDialog : public QDialog { Q_OBJECT public: explicit QmitkFindSegmentationTaskDialog(QWidget* parent = nullptr); ~QmitkFindSegmentationTaskDialog() override; void SetTaskList(const mitk::SegmentationTaskList* taskList); std::optional GetSelectedTask() const; bool LoadSelectedTask() const; private: enum Column { Number, Name, Status, Image, Segmentation, Result, Description }; + void OnItemSelectionChanged(); void OnItemDoubleClicked(QTableWidgetItem* item); + void ApplyFilter(); + bool ContainsNumber(int row) const; + bool ContainsName(int row) const; + bool HasStatus(int row) const; + Ui::QmitkFindSegmentationTaskDialog* m_Ui; mitk::SegmentationTaskList::ConstPointer m_TaskList; std::optional m_SelectedTask; }; #endif