diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp index 0aa7f2ec67..336f14d585 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp @@ -1,139 +1,150 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkHistogramVisualizationWidget.h" #include QmitkHistogramVisualizationWidget::QmitkHistogramVisualizationWidget(QWidget* parent) : QWidget(parent) { m_Controls.setupUi(this); #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) m_Controls.labelHistogramIsInvisibleWarning->setVisible(true); m_Controls.labelHistogramIsInvisibleWarning->setText("Histogram is not visible because Qt 5.10 is required for MitkChart. You can use the button Copy to Clipboard below to retrieve values.< / font>"); m_Controls.groupBoxPlot->setVisible(false); m_Controls.chartWidget->setVisible(false); #else m_Controls.labelHistogramIsInvisibleWarning->setVisible(false); m_Controls.checkBoxShowSubchart->setChecked(false); #endif CreateConnections(); } void QmitkHistogramVisualizationWidget::SetHistogram(itk::Statistics::Histogram::ConstPointer histogram, const std::string& dataLabel) { if (histogram == nullptr) return; m_Histogram = histogram; m_Controls.chartWidget->AddData2D(ConvertHistogramToMap(m_Histogram), dataLabel); m_Controls.chartWidget->SetChartType(dataLabel, QmitkChartWidget::ChartType::bar); m_Controls.chartWidget->SetXAxisLabel("Gray value"); m_Controls.chartWidget->SetYAxisLabel("Frequency"); #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) m_Controls.chartWidget->Show(m_Controls.checkBoxShowSubchart->isChecked()); #endif SetGUIElementsEnabled(true); } void QmitkHistogramVisualizationWidget::Reset() { #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) m_Controls.chartWidget->Clear(); #endif SetGUIElementsEnabled(false); } +void QmitkHistogramVisualizationWidget::SetTheme(QmitkChartWidget::ChartStyle style) +{ + m_ChartStyle = style; +} + void QmitkHistogramVisualizationWidget::CreateConnections() { connect(m_Controls.buttonCopyHistogramToClipboard, &QPushButton::clicked, this, &QmitkHistogramVisualizationWidget::OnClipboardButtonClicked); connect(m_Controls.checkBoxUseDefaultNBins, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnDefaultNBinsCheckBoxChanged); connect(m_Controls.spinBoxNBins, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnNBinsSpinBoxValueChanged); connect(m_Controls.checkBoxShowSubchart, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnShowSubchartCheckBoxChanged); + connect(m_Controls.chartWidget, &QmitkChartWidget::PageSuccessfullyLoaded, this, &QmitkHistogramVisualizationWidget::OnPageSuccessfullyLoaded); } void QmitkHistogramVisualizationWidget::SetGUIElementsEnabled(bool enabled) { this->setEnabled(enabled); m_Controls.groupBoxHistogram->setEnabled(enabled); m_Controls.groupBoxPlot->setEnabled(enabled); m_Controls.checkBoxShowSubchart->setEnabled(enabled); m_Controls.checkBoxUseDefaultNBins->setEnabled(enabled); m_Controls.spinBoxNBins->setEnabled(!m_Controls.checkBoxUseDefaultNBins->isChecked()); m_Controls.buttonCopyHistogramToClipboard->setEnabled(enabled); } std::map QmitkHistogramVisualizationWidget::ConvertHistogramToMap(itk::Statistics::Histogram::ConstPointer histogram) const { std::map histogramMap; if (histogram) { auto endIt = histogram->End(); auto it = histogram->Begin(); // generating Lists of measurement and frequencies for (; it != endIt; ++it) { double frequency = it.GetFrequency(); double measurement = it.GetMeasurementVector()[0]; histogramMap.emplace(measurement, frequency); } } return histogramMap; } void QmitkHistogramVisualizationWidget::OnClipboardButtonClicked() { if (m_Histogram) { QApplication::clipboard()->clear(); QString clipboard("Measurement \t Frequency\n"); auto iter = m_Histogram->Begin(); auto iterEnd = m_Histogram->End(); for (; iter != iterEnd; ++iter) { clipboard = clipboard.append("%L1 \t %L2\n") .arg(iter.GetMeasurementVector()[0], 0, 'f', 2) .arg(iter.GetFrequency()); } QApplication::clipboard()->setText(clipboard, QClipboard::Clipboard); } } void QmitkHistogramVisualizationWidget::OnDefaultNBinsCheckBoxChanged() { if (m_Controls.checkBoxUseDefaultNBins->isChecked()) { m_Controls.spinBoxNBins->setEnabled(false); m_Controls.spinBoxNBins->setValue(100); } else { m_Controls.spinBoxNBins->setEnabled(true); } } void QmitkHistogramVisualizationWidget::OnNBinsSpinBoxValueChanged() { emit RequestHistogramUpdate(m_Controls.spinBoxNBins->value()); } void QmitkHistogramVisualizationWidget::OnShowSubchartCheckBoxChanged() { m_Controls.chartWidget->Show(m_Controls.checkBoxShowSubchart->isChecked()); -} \ No newline at end of file +} + +void QmitkHistogramVisualizationWidget::OnPageSuccessfullyLoaded() +{ + m_Controls.chartWidget->SetTheme(m_ChartStyle); +} diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.h b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.h index 0db8951983..10f29d9e1d 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.h +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.h @@ -1,68 +1,72 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkHistogramVisualizationWidget_H__INCLUDED #define QmitkHistogramVisualizationWidget_H__INCLUDED #include #include //itk #include /** * \brief Widget for displaying Histograms. */ class MITKIMAGESTATISTICSUI_EXPORT QmitkHistogramVisualizationWidget : public QWidget { Q_OBJECT public: QmitkHistogramVisualizationWidget(QWidget* parent = nullptr); /** \brief Draws the histogram and enables the GUI elements. */ void SetHistogram(itk::Statistics::Histogram::ConstPointer histogram, const std::string& dataLabel); /** \brief Clears the histogram and disables all GUI elements. */ void Reset(); + /** \brief Sets the theme (either dark or light) */ + void SetTheme(QmitkChartWidget::ChartStyle style); signals: /** \brief Signal to be emitted when the number of bins is changed by the user. The HistogramCalculator should connect to this signal and recalculate the data accordingly. */ void RequestHistogramUpdate(unsigned int nBins); private: void CreateConnections(); void SetGUIElementsEnabled(bool enabled); /** \brief Helper function to convert the histogram in order to forward it to the ChartWidget. */ std::map ConvertHistogramToMap(itk::Statistics::Histogram::ConstPointer histogram) const; //slots /** \brief Saves the histogram to the clipboard. */ void OnClipboardButtonClicked(); /** \brief Enables / Disables SpinBox to change the number of bins. */ void OnDefaultNBinsCheckBoxChanged(); /** \brief Emits the signal RequestHistogramUpdate(unsigned int nBins) with the updated value. */ void OnNBinsSpinBoxValueChanged(); /** \brief Shows / Hides the subchart. */ void OnShowSubchartCheckBoxChanged(); + void OnPageSuccessfullyLoaded(); private: Ui::QmitkHistogramVisualizationControls m_Controls; itk::Statistics::Histogram::ConstPointer m_Histogram; + QmitkChartWidget::ChartStyle m_ChartStyle = QmitkChartWidget::ChartStyle::darkstyle; }; #endif //QmitkHistogramVisualizationWidget_H__INCLUDED \ No newline at end of file diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp index beb7b0241e..bb734fd5ed 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp @@ -1,71 +1,80 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkImageStatisticsWidget.h" QmitkImageStatisticsWidget::QmitkImageStatisticsWidget(QWidget* parent) : QWidget(parent) { m_Controls.setupUi(this); m_imageStatisticsModel = new QmitkImageStatisticsTableModel(parent); m_Controls.checkBox4dCompleteTable->setVisible(false); CreateConnections(); } void QmitkImageStatisticsWidget::SetStatistics(const std::vector& sc) { m_imageStatisticsModel->SetStatistics(sc); m_Controls.tableViewStatistics->setModel(m_imageStatisticsModel); m_Controls.tableViewStatistics->resizeColumnsToContents(); m_Controls.tableViewStatistics->resizeRowsToContents(); m_Controls.tableViewStatistics->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); m_Controls.tableViewStatistics->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); EnableAllGUIElements(); } void QmitkImageStatisticsWidget::SetImageNodes(const std::vector& nodes) { m_imageStatisticsModel->SetImageNodes(nodes); } void QmitkImageStatisticsWidget::SetMaskNodes(const std::vector& nodes) { m_imageStatisticsModel->SetMaskNodes(nodes); } void QmitkImageStatisticsWidget::Reset() { DisableAllGUIElements(); m_imageStatisticsModel->Clear(); } void QmitkImageStatisticsWidget::CreateConnections() { connect(m_Controls.buttonCopyImageStatisticsToClipboard, &QPushButton::clicked, this, &QmitkImageStatisticsWidget::OnClipboardButtonClicked); } void QmitkImageStatisticsWidget::EnableAllGUIElements() { this->setEnabled(true); //temporarily disabled because clipboard functionality is not implemented yet //m_Controls.buttonCopyImageStatisticsToClipboard->setEnabled(true); //m_Controls.checkBox4dCompleteTable->setEnabled(true); m_Controls.tableViewStatistics->setEnabled(true); m_Controls.groupBoxStatistics->setEnabled(true); } +void QmitkImageStatisticsWidget::DisableAllGUIElements() +{ + this->setEnabled(false); + m_Controls.buttonCopyImageStatisticsToClipboard->setEnabled(false); + m_Controls.checkBox4dCompleteTable->setEnabled(false); + m_Controls.tableViewStatistics->setEnabled(false); + m_Controls.groupBoxStatistics->setEnabled(false); +} + void QmitkImageStatisticsWidget::OnClipboardButtonClicked() { } diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsReloadedView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsReloadedView.cpp index 6824b52931..27f3b59870 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsReloadedView.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsReloadedView.cpp @@ -1,187 +1,204 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkImageStatisticsReloadedView.h" // berry includes -#include #include -#include +#include +#include #include #include #include #include #include const std::string QmitkImageStatisticsReloadedView::VIEW_ID = "org.mitk.views.imagestatisticsReloaded"; QmitkImageStatisticsReloadedView::QmitkImageStatisticsReloadedView(QObject* /*parent*/, const char* /*name*/) { this->m_CalculationThread = new QmitkImageStatisticsCalculationThread; } QmitkImageStatisticsReloadedView::~QmitkImageStatisticsReloadedView() { } void QmitkImageStatisticsReloadedView::CreateQtPartControl(QWidget *parent) { m_Controls.setupUi(parent); - + m_Controls.widget_histogram->SetTheme(this->GetColorTheme()); PrepareDataStorageComboBoxes(); CreateConnections(); } void QmitkImageStatisticsReloadedView::CreateConnections() { connect(m_Controls.imageSelector, QOverload::of(&QComboBox::currentIndexChanged), [=](int index) { OnImageOrMaskSelectorChanged(); }); connect(m_Controls.maskImageSelector, QOverload::of(&QComboBox::currentIndexChanged), [=](int index) { OnImageOrMaskSelectorChanged(); }); connect(this->m_CalculationThread, &QmitkImageStatisticsCalculationThread::finished, this, &QmitkImageStatisticsReloadedView::OnStatisticsCalculationEnds, Qt::QueuedConnection); } void QmitkImageStatisticsReloadedView::PartClosed(const berry::IWorkbenchPartReference::Pointer& ) { } void QmitkImageStatisticsReloadedView::FillStatisticsWidget(const std::vector& statistics) { m_Controls.widget_statistics->SetStatistics(statistics); m_Controls.widget_statistics->SetImageNodes({ m_selectedImageNode }); if (m_selectedMaskNode) { m_Controls.widget_statistics->SetMaskNodes({ m_selectedMaskNode }); } m_Controls.widget_statistics->setEnabled(true); } void QmitkImageStatisticsReloadedView::FillHistogramWidget(const std::vector& histogram, const std::vector& dataLabels) { m_Controls.widget_histogram->SetTheme(this->GetColorTheme()); m_Controls.widget_histogram->Reset(); m_Controls.widget_histogram->SetHistogram(histogram.front(), dataLabels.front()); } +QmitkChartWidget::ChartStyle QmitkImageStatisticsReloadedView::GetColorTheme() const +{ + ctkPluginContext* context = berry::WorkbenchPlugin::GetDefault()->GetPluginContext(); + ctkServiceReference styleManagerRef = context->getServiceReference(); + if (styleManagerRef) + { + auto styleManager = context->getService(styleManagerRef); + if (styleManager->GetStyle().name == "Dark") { + return QmitkChartWidget::ChartStyle::darkstyle; + } + else { + return QmitkChartWidget::ChartStyle::lightstyle; + } + } + return QmitkChartWidget::ChartStyle::darkstyle; +} + void QmitkImageStatisticsReloadedView::OnImageOrMaskSelectorChanged() { m_selectedImageNode = m_Controls.imageSelector->GetSelectedNode(); m_selectedMaskNode = m_Controls.maskImageSelector->GetSelectedNode(); if (m_selectedImageNode != nullptr) { auto image = dynamic_cast(m_selectedImageNode->GetData()); mitk::Image::Pointer mask = nullptr; if (m_selectedMaskNode != nullptr) { mask = dynamic_cast(m_selectedMaskNode->GetData()); } CalculateStatistics(image, mask); } else { m_Controls.widget_statistics->Reset(); m_Controls.widget_statistics->setEnabled(false); m_Controls.widget_histogram->Reset(); m_Controls.widget_histogram->setEnabled(false); } } void QmitkImageStatisticsReloadedView::OnStatisticsCalculationEnds() { mitk::StatusBar::GetInstance()->Clear(); if (this->m_CalculationThread->GetStatisticsUpdateSuccessFlag()) { this->FillStatisticsWidget(m_CalculationThread->GetStatisticsData()); this->FillHistogramWidget({ m_CalculationThread->GetTimeStepHistogram() }, {m_selectedImageNode->GetName()}); } else { mitk::StatusBar::GetInstance()->DisplayErrorText(m_CalculationThread->GetLastErrorMessage().c_str()); m_Controls.widget_histogram->setEnabled(false); m_Controls.widget_statistics->setEnabled(false); } } void QmitkImageStatisticsReloadedView::CalculateStatistics(mitk::Image::Pointer image, mitk::Image::Pointer mask) { this->m_StatisticsUpdatePending = true; this->m_CalculationThread->Initialize(image, mask, nullptr); this->m_CalculationThread->SetTimeStep(0); try { // Compute statistics this->m_CalculationThread->start(); } catch (const mitk::Exception& e) { mitk::StatusBar::GetInstance()->DisplayErrorText(e.GetDescription()); this->m_StatisticsUpdatePending = false; } catch (const std::runtime_error &e) { mitk::StatusBar::GetInstance()->DisplayErrorText(e.what()); this->m_StatisticsUpdatePending = false; } catch (const std::exception &e) { mitk::StatusBar::GetInstance()->DisplayErrorText(e.what()); this->m_StatisticsUpdatePending = false; } } void QmitkImageStatisticsReloadedView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*part*/, const QList &nodes ) { } void QmitkImageStatisticsReloadedView::PrepareDataStorageComboBoxes() { auto isImage = mitk::NodePredicateDataType::New("Image"); auto isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); auto isNoBinary = mitk::NodePredicateNot::New(isBinary); auto isBinaryImage = mitk::NodePredicateAnd::New(isImage, isBinary); auto isNoBinaryImage = mitk::NodePredicateAnd::New(isImage, isNoBinary); m_Controls.imageSelector->SetDataStorage(GetDataStorage()); m_Controls.imageSelector->SetPredicate(isNoBinaryImage); m_Controls.maskImageSelector->SetDataStorage(GetDataStorage()); m_Controls.maskImageSelector->SetPredicate(isBinaryImage); m_Controls.maskImageSelector->SetZeroEntryText(""); } void QmitkImageStatisticsReloadedView::Activated() { } void QmitkImageStatisticsReloadedView::Deactivated() { } void QmitkImageStatisticsReloadedView::Visible() { } void QmitkImageStatisticsReloadedView::Hidden() { m_Controls.imageSelector->disconnect(); m_Controls.maskImageSelector->disconnect(); } void QmitkImageStatisticsReloadedView::SetFocus() { } diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsReloadedView.h b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsReloadedView.h index 33c79e9932..e9d2683823 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsReloadedView.h +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsReloadedView.h @@ -1,94 +1,95 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkImageStatisticsReloadedView_H__INCLUDED #define QmitkImageStatisticsReloadedView_H__INCLUDED #include "ui_QmitkImageStatisticsReloadedViewControls.h" // Qmitk includes #include #include "QmitkImageStatisticsCalculationThread.h" #include #include #include /*! \brief QmitkImageStatisticsView is a bundle that allows statistics calculation from images. Three modes are supported: 1. Statistics of one image, 2. Statistics of an image and a segmentation, 3. Statistics of an image and a Planar Figure. The statistics calculation is realized in a separate thread to keep the gui accessible during calculation. \ingroup Plugins/org.mitk.gui.qt.measurementtoolbox */ class QmitkImageStatisticsReloadedView : public QmitkAbstractView, public mitk::ILifecycleAwarePart, public berry::IPartListener { Q_OBJECT public: using HistogramType = mitk::StatisticsContainer::HistogramType; /*! \brief default constructor */ QmitkImageStatisticsReloadedView(QObject *parent = nullptr, const char *name = nullptr); /*! \brief default destructor */ virtual ~QmitkImageStatisticsReloadedView(); /*! \brief method for creating the widget containing the application controls, like sliders, buttons etc. */ virtual void CreateQtPartControl(QWidget *parent) override; /*! \brief method for creating the connections of main and control widget */ virtual void CreateConnections(); /*! \brief Is called from the selection mechanism once the data manager selection has changed*/ void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList &selectedNodes) override; void PrepareDataStorageComboBoxes(); static const std::string VIEW_ID; void FillStatisticsWidget(const std::vector& statistics); void FillHistogramWidget(const std::vector& histogram, const std::vector& dataLabels); + QmitkChartWidget::ChartStyle GetColorTheme() const; protected: virtual void Activated() override; virtual void Deactivated() override; virtual void Visible() override; virtual void Hidden() override; virtual void SetFocus() override; /** \brief Is called right before the view closes (before the destructor) */ virtual void PartClosed(const berry::IWorkbenchPartReference::Pointer&) override; /** \brief Required for berry::IPartListener */ virtual Events::Types GetPartEventTypes() const override { return Events::CLOSED; } void OnImageOrMaskSelectorChanged(); void OnStatisticsCalculationEnds(); void CalculateStatistics(mitk::Image::Pointer image, mitk::Image::Pointer mask); // member variables Ui::QmitkImageStatisticsReloadedViewControls m_Controls; private: QmitkImageStatisticsCalculationThread * m_CalculationThread; bool m_StatisticsUpdatePending=false; mitk::DataNode::ConstPointer m_selectedImageNode, m_selectedMaskNode; }; #endif // QmitkImageStatisticsView_H__INCLUDED