diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp index fcdf871989..f06b177119 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp @@ -1,197 +1,197 @@ /*============================================================================ 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 "QmitkHistogramVisualizationWidget.h" #include QmitkHistogramVisualizationWidget::QmitkHistogramVisualizationWidget(QWidget* parent) : QWidget(parent) { m_Controls.setupUi(this); m_Controls.checkBoxShowSubchart->setChecked(false); m_Controls.spinBoxNBins->setValue(m_DefaultNBins); m_Controls.spinBoxNBins->setMinimum(m_MinNBins); m_Controls.spinBoxNBins->setMaximum(m_MaxNBins); SetGUIElementsEnabled(false); CreateConnections(); } void QmitkHistogramVisualizationWidget::SetHistogram(itk::Statistics::Histogram::ConstPointer histogram, const std::string& dataLabel) { if (histogram == nullptr) return; m_Histogram = histogram; m_Controls.chartWidget->AddData2D(ConvertHistogramToPairList(m_Histogram), dataLabel); m_Controls.chartWidget->SetChartType(dataLabel, QmitkChartWidget::ChartType::bar); m_Controls.chartWidget->SetXAxisLabel("Gray value"); m_Controls.chartWidget->SetYAxisLabel("Frequency"); m_Controls.chartWidget->Show(m_Controls.checkBoxShowSubchart->isChecked()); SetGUIElementsEnabled(true); } void QmitkHistogramVisualizationWidget::Reset() { m_Controls.chartWidget->Clear(); SetGUIElementsEnabled(false); } int QmitkHistogramVisualizationWidget::GetBins() { return m_Controls.spinBoxNBins->value(); } void QmitkHistogramVisualizationWidget::ResetDefault() { m_Controls.checkBoxUseDefaultNBins->setChecked(true); m_Controls.spinBoxNBins->setEnabled(false); m_Controls.spinBoxNBins->setValue(100); m_Controls.checkBoxShowSubchart->setChecked(false); } void QmitkHistogramVisualizationWidget::SetTheme(QmitkChartWidget::ColorTheme style) { m_Controls.chartWidget->SetTheme(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.checkBoxViewMinMax, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnViewMinMaxCheckBoxChanged); connect(m_Controls.doubleSpinBoxMaxValue, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnMaxValueSpinBoxValueChanged); connect(m_Controls.doubleSpinBoxMinValue, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnMinValueSpinBoxValueChanged); } void QmitkHistogramVisualizationWidget::SetGUIElementsEnabled(bool enabled) { this->setEnabled(enabled); m_Controls.tabWidgetPlot->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); m_Controls.checkBoxViewMinMax->setEnabled(enabled); m_Controls.doubleSpinBoxMaxValue->setEnabled(m_Controls.checkBoxViewMinMax->isChecked()); m_Controls.doubleSpinBoxMinValue->setEnabled(m_Controls.checkBoxViewMinMax->isChecked()); } std::vector< std::pair > QmitkHistogramVisualizationWidget::ConvertHistogramToPairList(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); } } std::vector< std::pair > histogram_list; for(auto iter = histogramMap.begin(); iter != histogramMap.end(); ++iter) histogram_list.emplace_back( iter->first, iter->second ); return histogram_list; } 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()); - } + if (m_Histogram) + { + 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); - } + QApplication::clipboard()->clear(); + QApplication::clipboard()->setText(clipboard, QClipboard::Clipboard); + } } void QmitkHistogramVisualizationWidget::OnDefaultNBinsCheckBoxChanged() { if (m_Controls.checkBoxUseDefaultNBins->isChecked()) { m_Controls.spinBoxNBins->setEnabled(false); if (m_Controls.spinBoxNBins->value() != static_cast(m_DefaultNBins) ) { m_Controls.spinBoxNBins->setValue(m_DefaultNBins); OnNBinsSpinBoxValueChanged(); } } 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()); } void QmitkHistogramVisualizationWidget::OnViewMinMaxCheckBoxChanged() { double min = m_Histogram->GetBinMin(0, 0); auto maxVector = m_Histogram->GetDimensionMaxs(0); double max; if (m_Controls.checkBoxUseDefaultNBins->isChecked()) max = maxVector[m_DefaultNBins - 1]; else max = maxVector[m_Controls.spinBoxNBins->value() - 1]; if (!m_Controls.checkBoxViewMinMax->isChecked()) { m_Controls.doubleSpinBoxMaxValue->setEnabled(false); m_Controls.doubleSpinBoxMinValue->setEnabled(false); m_Controls.chartWidget->Reload(); } else { m_Controls.doubleSpinBoxMinValue->setMinimum(min); m_Controls.doubleSpinBoxMinValue->setValue(min); m_Controls.doubleSpinBoxMaxValue->setMaximum(max); m_Controls.doubleSpinBoxMaxValue->setValue(max); m_Controls.doubleSpinBoxMaxValue->setEnabled(true); m_Controls.doubleSpinBoxMinValue->setEnabled(true); } } void QmitkHistogramVisualizationWidget::OnMinValueSpinBoxValueChanged() { m_Controls.doubleSpinBoxMaxValue->setMinimum(m_Controls.doubleSpinBoxMinValue->value()+1); m_Controls.chartWidget->SetMinMaxValueXView(m_Controls.doubleSpinBoxMinValue->value(),m_Controls.doubleSpinBoxMaxValue->value()); m_Controls.chartWidget->Show(); } void QmitkHistogramVisualizationWidget::OnMaxValueSpinBoxValueChanged() { m_Controls.doubleSpinBoxMinValue->setMaximum(m_Controls.doubleSpinBoxMaxValue->value()-1); m_Controls.chartWidget->SetMinMaxValueXView(m_Controls.doubleSpinBoxMinValue->value(),m_Controls.doubleSpinBoxMaxValue->value()); m_Controls.chartWidget->Show(); } diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp index 23e9c0cc99..78047bcec0 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp @@ -1,79 +1,81 @@ /*============================================================================ 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 "QmitkImageStatisticsWidget.h" #include "QmitkStatisticsModelToStringConverter.h" #include "QmitkImageStatisticsTreeModel.h" #include #include QmitkImageStatisticsWidget::QmitkImageStatisticsWidget(QWidget* parent) : QWidget(parent) { m_Controls.setupUi(this); m_imageStatisticsModel = new QmitkImageStatisticsTreeModel(parent); CreateConnections(); m_ProxyModel = new QSortFilterProxyModel(this); m_Controls.treeViewStatistics->setEnabled(false); m_Controls.treeViewStatistics->setModel(m_ProxyModel); m_ProxyModel->setSourceModel(m_imageStatisticsModel); connect(m_imageStatisticsModel, &QmitkImageStatisticsTreeModel::dataAvailable, this, &QmitkImageStatisticsWidget::OnDataAvailable); connect(m_imageStatisticsModel, &QmitkImageStatisticsTreeModel::modelChanged, m_Controls.treeViewStatistics, &QTreeView::expandAll); } void QmitkImageStatisticsWidget::SetDataStorage(mitk::DataStorage* newDataStorage) { m_imageStatisticsModel->SetDataStorage(newDataStorage); } 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() { m_imageStatisticsModel->Clear(); m_Controls.treeViewStatistics->setEnabled(false); m_Controls.buttonCopyImageStatisticsToClipboard->setEnabled(false); } void QmitkImageStatisticsWidget::CreateConnections() { connect(m_Controls.buttonCopyImageStatisticsToClipboard, &QPushButton::clicked, this, &QmitkImageStatisticsWidget::OnClipboardButtonClicked); } void QmitkImageStatisticsWidget::OnDataAvailable() { m_Controls.buttonCopyImageStatisticsToClipboard->setEnabled(true); m_Controls.treeViewStatistics->setEnabled(true); } void QmitkImageStatisticsWidget::OnClipboardButtonClicked() { QmitkStatisticsModelToStringConverter converter; + converter.SetColumnDelimiter('\t'); converter.SetTableModel(m_imageStatisticsModel); converter.SetRootIndex(m_Controls.treeViewStatistics->rootIndex()); converter.SetIncludeHeaderData(true); QString clipboardAsString = converter.GetString(); + QApplication::clipboard()->clear(); QApplication::clipboard()->setText(clipboardAsString, QClipboard::Clipboard); } diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.cpp index 168c04cd40..6783735d7f 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.cpp @@ -1,106 +1,106 @@ /*============================================================================ 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 "QmitkStatisticsModelToStringConverter.h" #include "mitkExceptionMacro.h" QmitkStatisticsModelToStringConverter::QmitkStatisticsModelToStringConverter() {} void QmitkStatisticsModelToStringConverter::SetTableModel(QAbstractItemModel *model) { m_statisticsModel = model; } void QmitkStatisticsModelToStringConverter::SetRootIndex(QModelIndex rootIndex) { m_rootIndex = rootIndex; } QString QmitkStatisticsModelToStringConverter::GetString() const { if (m_statisticsModel == nullptr) { mitkThrow() << "Cannot convert TableModel to String: TableModel is nullptr"; } QString textData; int columns = m_statisticsModel->columnCount(); if (m_includeHeaderData) { for (int i = 0; i < columns; i++) { if (i > 0) { - textData += m_columnDelimiterWithSpace; + textData += m_columnDelimiter; } textData += m_statisticsModel->headerData(i, Qt::Horizontal).toString(); } - textData += m_lineDelimiter; + textData += m_rowDelimiter; } textData += Iterate(m_rootIndex, m_statisticsModel); return textData; } -void QmitkStatisticsModelToStringConverter::SetRowDelimiter(QChar lineDelimiter) +void QmitkStatisticsModelToStringConverter::SetRowDelimiter(QChar rowDelimiter) { - m_lineDelimiter = lineDelimiter; + m_rowDelimiter = rowDelimiter; } void QmitkStatisticsModelToStringConverter::SetColumnDelimiter(QChar columnDelimiter) { - m_columnDelimiterWithSpace = columnDelimiter + QString(" "); + m_columnDelimiter = columnDelimiter; } void QmitkStatisticsModelToStringConverter::SetIncludeHeaderData(bool includeHeaderData) { m_includeHeaderData = includeHeaderData; } QString QmitkStatisticsModelToStringConverter::Iterate(const QModelIndex &index, const QAbstractItemModel *model, int depth) const { QString content; if (index.isValid()) { content = index.data().toString(); } if (!model->hasChildren(index) || (index.flags() & Qt::ItemNeverHasChildren)) { return content; } else { - content += m_lineDelimiter; + content += m_rowDelimiter; } auto rows = model->rowCount(index); auto cols = model->columnCount(index); for (int i = 0; i < rows; ++i) { if (i > 0) { - content += m_lineDelimiter; + content += m_rowDelimiter; } for (int j = 0; j < cols; ++j) { if (j > 0) { - content += m_columnDelimiterWithSpace; + content += m_columnDelimiter; } content += Iterate(model->index(i, j, index), model, depth + 1); } } return content; } diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.h b/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.h index 51430815d8..9fb66e10ad 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.h +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.h @@ -1,64 +1,66 @@ /*============================================================================ 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 QmitkTableModelToQString_H__INCLUDED #define QmitkTableModelToQString_H__INCLUDED #include #include /** \brief Converts the content of the statistics model to a string \details The content of a table model is converted to a string. Each cell is converted to a string. Default -oder: iteration over rows. The line separation delimiter (default: '\n') and the column separation +order: iteration over rows. The row separation delimiter (default: '\n') and the column separation delimiter (default: ',') can be chosen. It also can be chosen if the headers should be exported to the string. - -By default, the produced string is csv conform */ class MITKIMAGESTATISTICSUI_EXPORT QmitkStatisticsModelToStringConverter { public: QmitkStatisticsModelToStringConverter(); void SetTableModel(QAbstractItemModel *model); void SetRootIndex(QModelIndex rootIndex); /** \brief Returns the string \exception throws exception if model is nullptr */ QString GetString() const; - void SetRowDelimiter(QChar lineDelimiter); + void SetRowDelimiter(QChar rowDelimiter); void SetColumnDelimiter(QChar columnDelimiter); /** \brief If header data (column/row captions) are exported */ void SetIncludeHeaderData(bool includeHeaderData); private: /** \brief Iterates recursively over all cells and returns their content \details based on https://stackoverflow.com/questions/39153835/how-to-loop-over-qabstractitemview-indexes */ QString Iterate(const QModelIndex &index, const QAbstractItemModel *model, int depth = 0) const; QAbstractItemModel *m_statisticsModel = nullptr; QModelIndex m_rootIndex; - QChar m_lineDelimiter = '\n'; + + QChar m_rowDelimiter = '\n'; + QChar m_columnDelimiter = ','; + bool m_includeHeaderData = false; - QString m_columnDelimiterWithSpace = ", "; + }; + #endif // QmitkTableModelToQString_H__INCLUDED