diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsTreeItem.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsTreeItem.cpp index ca2c4de0f9..3ee475c4e8 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsTreeItem.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsTreeItem.cpp @@ -1,113 +1,132 @@ /*============================================================================ 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 "QmitkImageStatisticsTreeItem.h" QmitkImageStatisticsTreeItem::QmitkImageStatisticsTreeItem( ImageStatisticsObject statisticsData, StatisticNameVector statisticNames, QVariant label, bool isWIP, QmitkImageStatisticsTreeItem *parent) : m_statistics(statisticsData) , m_statisticNames(statisticNames), m_label(label), m_parentItem(parent), m_IsWIP(isWIP) { } QmitkImageStatisticsTreeItem::QmitkImageStatisticsTreeItem(StatisticNameVector statisticNames, QVariant label, bool isWIP, QmitkImageStatisticsTreeItem *parentItem) : QmitkImageStatisticsTreeItem(ImageStatisticsObject(), statisticNames, label, isWIP, parentItem ) { } QmitkImageStatisticsTreeItem::QmitkImageStatisticsTreeItem() : QmitkImageStatisticsTreeItem(StatisticNameVector(), QVariant(), false, nullptr ) {} QmitkImageStatisticsTreeItem::~QmitkImageStatisticsTreeItem() { qDeleteAll(m_childItems); } void QmitkImageStatisticsTreeItem::appendChild(QmitkImageStatisticsTreeItem *item) { m_childItems.append(item); } QmitkImageStatisticsTreeItem *QmitkImageStatisticsTreeItem::child(int row) { return m_childItems.value(row); } int QmitkImageStatisticsTreeItem::childCount() const { return m_childItems.count(); } int QmitkImageStatisticsTreeItem::columnCount() const { return m_statisticNames.size() + 1; } +struct StatValueVisitor : boost::static_visitor +{ + QVariant operator()(const mitk::ImageStatisticsContainer::RealType& val) const + { + return QVariant(val); + } + + QVariant operator()(const mitk::ImageStatisticsContainer::VoxelCountType& val) const + { + return QVariant::fromValue(val); + } + + QVariant operator()(const mitk::ImageStatisticsContainer::IndexType& val) const + { + std::stringstream ss; + ss << val; + return QVariant(QString::fromStdString(ss.str())); + } + +}; + QVariant QmitkImageStatisticsTreeItem::data(int column) const { QVariant result; if (column > 0 && !m_statisticNames.empty()) { if (column - 1 < static_cast(m_statisticNames.size())) { if (m_IsWIP) { result = QVariant(QString("...")); } else { auto statisticKey = m_statisticNames.at(column - 1); - std::stringstream ss; if (m_statistics.HasStatistic(statisticKey)) { - ss << m_statistics.GetValueNonConverted(statisticKey); + return boost::apply_visitor(StatValueVisitor(), m_statistics.GetValueNonConverted(statisticKey)); } else { return QVariant(); } - result = QVariant(QString::fromStdString(ss.str())); } } else { return QVariant(); } } else if (column == 0) { result = m_label; } return result; } QmitkImageStatisticsTreeItem *QmitkImageStatisticsTreeItem::parentItem() { return m_parentItem; } int QmitkImageStatisticsTreeItem::row() const { if (m_parentItem) return m_parentItem->m_childItems.indexOf(const_cast(this)); return 0; } bool QmitkImageStatisticsTreeItem::isWIP() const { return m_IsWIP; } diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp index 98664744e6..cfaea25dce 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsWidget.cpp @@ -1,102 +1,102 @@ /*============================================================================ 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::SetIgnoreZeroValueVoxel(bool _arg) { m_imageStatisticsModel->SetIgnoreZeroValueVoxel(_arg); } bool QmitkImageStatisticsWidget::GetIgnoreZeroValueVoxel() const { return this->m_imageStatisticsModel->GetIgnoreZeroValueVoxel(); } void QmitkImageStatisticsWidget::SetHistogramNBins(unsigned int nbins) { m_imageStatisticsModel->SetHistogramNBins(nbins); } unsigned int QmitkImageStatisticsWidget::GetHistogramNBins() const { return this->m_imageStatisticsModel->GetHistogramNBins(); } 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.SetModel(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 6783735d7f..9ddad668b6 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.cpp @@ -1,106 +1,128 @@ /*============================================================================ 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) +void QmitkStatisticsModelToStringConverter::SetModel(QmitkImageStatisticsTreeModel *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_columnDelimiter; } - textData += m_statisticsModel->headerData(i, Qt::Horizontal).toString(); + textData += m_statisticsModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); } textData += m_rowDelimiter; } textData += Iterate(m_rootIndex, m_statisticsModel); return textData; } void QmitkStatisticsModelToStringConverter::SetRowDelimiter(QChar rowDelimiter) { m_rowDelimiter = rowDelimiter; } void QmitkStatisticsModelToStringConverter::SetColumnDelimiter(QChar columnDelimiter) { m_columnDelimiter = columnDelimiter; } void QmitkStatisticsModelToStringConverter::SetIncludeHeaderData(bool includeHeaderData) { m_includeHeaderData = includeHeaderData; } QString QmitkStatisticsModelToStringConverter::Iterate(const QModelIndex &index, - const QAbstractItemModel *model, - int depth) const + const QmitkImageStatisticsTreeModel *model, + QString label) const { QString content; - if (index.isValid()) - { - content = index.data().toString(); - } - if (!model->hasChildren(index) || (index.flags() & Qt::ItemNeverHasChildren)) - { - return content; - } - else - { - content += m_rowDelimiter; - } - auto rows = model->rowCount(index); - auto cols = model->columnCount(index); - for (int i = 0; i < rows; ++i) + if (model->hasChildren(index)) { - if (i > 0) + if (index.isValid()) { - content += m_rowDelimiter; + label += index.data().toString() + QString(" >> "); } - for (int j = 0; j < cols; ++j) + + auto rows = model->rowCount(index); + for (int r = 0; r < rows; ++r) { - if (j > 0) + auto childIndex = model->index(r, 0, index); + + if (model->hasChildren(childIndex)) + { + content += Iterate(childIndex, model, label); + } + else { - content += m_columnDelimiter; + content += label; + + auto cols = model->columnCount(index); + for (int c = 0; c < cols; ++c) + { + if (c > 0) + { + content += m_columnDelimiter; + } + + auto columnChildIndex = model->index(r, c, index); + content += Iterate(columnChildIndex, model, label); + } + content += m_rowDelimiter; } - content += Iterate(model->index(i, j, index), model, depth + 1); } } + else + { + if (index.isValid()) + { + auto data = index.data(); + if (static_cast(data.type()) == QMetaType::Double) + { + content = QString("%L1").arg(data.toDouble(), 0, 'f'); + } + else + { + content = data.toString(); + } + } + } + return content; } diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.h b/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.h index 9fb66e10ad..6a8117ab61 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.h +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkStatisticsModelToStringConverter.h @@ -1,66 +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 QmitkTableModelToQString_H__INCLUDED #define QmitkTableModelToQString_H__INCLUDED #include -#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 +The content of a QmitkImageStatisticsTreeModel instance is converted to a string. Each cell is converted to a string. Default 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. */ class MITKIMAGESTATISTICSUI_EXPORT QmitkStatisticsModelToStringConverter { public: QmitkStatisticsModelToStringConverter(); - void SetTableModel(QAbstractItemModel *model); + void SetModel(QmitkImageStatisticsTreeModel *model); void SetRootIndex(QModelIndex rootIndex); /** \brief Returns the string \exception throws exception if model is nullptr */ QString GetString() const; 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; + const QmitkImageStatisticsTreeModel *model, + QString label = "") const; - QAbstractItemModel *m_statisticsModel = nullptr; + QmitkImageStatisticsTreeModel *m_statisticsModel = nullptr; QModelIndex m_rootIndex; QChar m_rowDelimiter = '\n'; QChar m_columnDelimiter = ','; bool m_includeHeaderData = false; }; #endif // QmitkTableModelToQString_H__INCLUDED