From 1ddc4b80da5a7a190548dac3b76bd41d49be1b4e Mon Sep 17 00:00:00 2001 From: Gennady Pospelov <g.pospelov@fz-juelich.de> Date: Wed, 18 May 2016 14:54:27 +0200 Subject: [PATCH] Finally info label appears/disappears when tree is empty --- GUI/coregui/Models/FitParameterAbsModel.cpp | 93 +++++++++++++++---- GUI/coregui/Models/FitParameterAbsModel.h | 7 +- GUI/coregui/Models/FitParameterItems.cpp | 5 + GUI/coregui/Models/FitParameterItems.h | 1 + GUI/coregui/Models/ModelPath.cpp | 15 +++ GUI/coregui/Models/ModelPath.h | 2 + .../Views/FitWidgets/FitParameterWidget.cpp | 68 +++++++++----- .../Views/FitWidgets/FitParameterWidget.h | 5 +- .../Views/InfoWidgets/InfoLabelController.cpp | 4 +- 9 files changed, 153 insertions(+), 47 deletions(-) diff --git a/GUI/coregui/Models/FitParameterAbsModel.cpp b/GUI/coregui/Models/FitParameterAbsModel.cpp index 6a5cbd38a07..3707b265921 100644 --- a/GUI/coregui/Models/FitParameterAbsModel.cpp +++ b/GUI/coregui/Models/FitParameterAbsModel.cpp @@ -21,6 +21,8 @@ #include "JobModel.h" #include "FitModelHelper.h" #include "ParameterTreeItems.h" +#include "GUIHelpers.h" +#include "ModelPath.h" #include <QColor> #include <QMimeData> #include <QDebug> @@ -71,6 +73,7 @@ QModelIndex FitParameterAbsModel::index(int row, int column, const QModelIndex & return QModelIndex(); SessionItem *parent_item = itemForIndex(parent); +// if(!isValidSourceItem(parent_item)) return QModelIndex(); Q_ASSERT(parent_item); if(parent_item->modelType() == Constants::FitParameterContainerType) { @@ -97,15 +100,22 @@ QModelIndex FitParameterAbsModel::index(int row, int column, const QModelIndex & QModelIndex FitParameterAbsModel::parent(const QModelIndex &child) const { - if(!m_root_item) return QModelIndex(); + if(!m_root_item) + return QModelIndex(); if (!child.isValid()) return QModelIndex(); if (SessionItem *child_item = itemForIndex(child)) { if (SessionItem *parent_item = child_item->parent()) { + + if(!isValidSourceItem(parent_item)) return QModelIndex(); + if(parent_item->modelType()==Constants::FitParameterLinkType) { SessionItem *fitPar = parent_item->parent(); + + if(!isValidSourceItem(fitPar)) return QModelIndex(); + return createIndex(fitPar->parentRow(), 0, fitPar); } } @@ -121,7 +131,9 @@ int FitParameterAbsModel::rowCount(const QModelIndex &parent) const if (parent.isValid() && parent.column() != 0) return 0; + SessionItem *parent_item = itemForIndex(parent); + if(parent_item!=m_root_item && !isValidSourceItem(parent_item)) return 0; if(parent_item->modelType() == Constants::FitParameterContainerType) { return parent_item->rowCount(); @@ -297,6 +309,7 @@ void FitParameterAbsModel::onSourceDataChanged(const QModelIndex &topLeft, const void FitParameterAbsModel::onSourceRowsInserted(const QModelIndex &parent, int first, int last) { + if(!m_root_item) return; // Q_UNUSED(parent); // Q_UNUSED(first); // Q_UNUSED(last); @@ -317,6 +330,8 @@ void FitParameterAbsModel::onSourceRowsInserted(const QModelIndex &parent, int f void FitParameterAbsModel::onSourceBeginRemoveRows(const QModelIndex &parent, int first, int last) { + if(!m_root_item) return; + qDebug() << "FitParameterAbsModel::onSourceBeginRemoveRows" << parent << first << last; JobModel *sourceModel = qobject_cast<JobModel *>(sender()); Q_ASSERT(sourceModel); @@ -327,31 +342,39 @@ void FitParameterAbsModel::onSourceBeginRemoveRows(const QModelIndex &parent, in // way #1 beginResetModel(); - QModelIndex itemIndex = sourceModel->index(first, 0, parent); - if(sourceModel->itemForIndex(itemIndex) == m_root_item) - m_root_item = 0; +//// QModelIndex itemIndex = sourceModel->index(first, 0, parent); +//// if(sourceModel->itemForIndex(itemIndex) == m_root_item) +//// m_root_item = 0; endResetModel(); - return; +// return; // way #2 - if(SessionItem *sourceItem = sourceModel->itemForIndex(parent)) { - QModelIndex localIndex = indexOfItem(sourceItem); - beginRemoveRows(localIndex, 0, rowCount(localIndex)); - endRemoveRows(); - - QModelIndex itemIndex = sourceModel->index(first, 0, parent); - if(sourceModel->itemForIndex(itemIndex) == m_root_item) - m_root_item = 0; +// if(SessionItem *sourceItem = sourceModel->itemForIndex(parent)) { +// QModelIndex localIndex = indexOfItem(sourceItem); +// if(localIndex.isValid()) { +// beginRemoveRows(localIndex, 0, rowCount(localIndex)); +// endRemoveRows(); +// } +// } +} - } +void FitParameterAbsModel::onSourceRowsRemoved(const QModelIndex &parent, int first, int last) +{ + qDebug() << "FitParameterAbsModel::onSourceRowsRemoved" << parent << first << last; + Q_UNUSED(parent); + Q_UNUSED(first); + Q_UNUSED(last); + beginResetModel(); + endResetModel(); } void FitParameterAbsModel::onSourceAboutToBeReset() { + if(!m_root_item) return; beginResetModel(); endResetModel(); } @@ -364,8 +387,10 @@ void FitParameterAbsModel::connectModel(QAbstractItemModel *sourceModel, bool is this, SLOT(onSourceDataChanged(QModelIndex,QModelIndex,QVector<int>))); // connect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), // this, SLOT(onSourceRowsInserted(QModelIndex,int,int))); - connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(onSourceBeginRemoveRows(QModelIndex,int,int))); +// connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), +// this, SLOT(onSourceBeginRemoveRows(QModelIndex,int,int))); + connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), + this, SLOT(onSourceRowsRemoved(QModelIndex,int,int))); connect(sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(onSourceAboutToBeReset())); @@ -377,13 +402,16 @@ void FitParameterAbsModel::connectModel(QAbstractItemModel *sourceModel, bool is this, SLOT(onSourceDataChanged(QModelIndex,QModelIndex,QVector<int>))); // disconnect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), // this, SLOT(onSourceRowsInserted(QModelIndex,int,int))); - disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(onSourceBeginRemoveRows(QModelIndex,int,int))); +// disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), +// this, SLOT(onSourceBeginRemoveRows(QModelIndex,int,int))); + disconnect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), + this, SLOT(onSourceRowsRemoved(QModelIndex,int,int))); disconnect(sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(onSourceAboutToBeReset())); } } -void FitParameterAbsModel::addColumn(FitParameterAbsModel::EColumn id, const QString &name, const QString &tooltip) +void FitParameterAbsModel::addColumn(FitParameterAbsModel::EColumn id, const QString &name, + const QString &tooltip) { m_columnNames[id] = name; m_columnToolTips[id] = tooltip; @@ -391,6 +419,7 @@ void FitParameterAbsModel::addColumn(FitParameterAbsModel::EColumn id, const QSt QModelIndex FitParameterAbsModel::indexOfItem(SessionItem *item) const { + if(!m_root_item) return QModelIndex(); if(SessionItem *parent_item = item->parent()) { if(parent_item->modelType() == Constants::FitParameterContainerType) { @@ -420,9 +449,33 @@ QModelIndex FitParameterAbsModel::indexOfItem(SessionItem *item) const SessionItem *FitParameterAbsModel::itemForIndex(const QModelIndex &index) const { + if(!m_root_item) return 0; + if (index.isValid()) { - if (SessionItem *item = static_cast<SessionItem *>(index.internalPointer())) + SessionItem *item = static_cast<SessionItem *>(index.internalPointer()); + if(item) { + if(!isValidSourceItem(item)) { + return 0; +// throw GUIHelpers::Error("FitParameterAbsModel::itemForIndex -> Error! Attempt to " +// "use destroyed item."); + } + return item; + } } return m_root_item; } + +SessionModel *FitParameterAbsModel::sourceModel() const +{ + Q_ASSERT(m_root_item); + return m_root_item->model(); +} + +//! Returns true if given item still exists in source model +bool FitParameterAbsModel::isValidSourceItem(SessionItem *item) const +{ + if(item == m_root_item) return true; + if(sourceModel() && ModelPath::isValidItem(sourceModel(), item, m_root_item->index())) return true; + return false; +} diff --git a/GUI/coregui/Models/FitParameterAbsModel.h b/GUI/coregui/Models/FitParameterAbsModel.h index 4126c674720..0078fcfd2d7 100644 --- a/GUI/coregui/Models/FitParameterAbsModel.h +++ b/GUI/coregui/Models/FitParameterAbsModel.h @@ -20,7 +20,7 @@ #include "WinDllMacros.h" #include <QAbstractItemModel> -class JobModel; +class SessionModel; class FitParameterContainerItem; class SessionItem; @@ -61,10 +61,15 @@ public: QModelIndex indexOfItem(SessionItem *item) const; SessionItem *itemForIndex(const QModelIndex &index) const; + SessionModel *sourceModel() const; + + bool isValidSourceItem(SessionItem *item) const; + private slots: void onSourceDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles); void onSourceRowsInserted(const QModelIndex & parent, int first, int last); void onSourceBeginRemoveRows(const QModelIndex & parent, int first, int last); + void onSourceRowsRemoved(const QModelIndex & parent, int first, int last); void onSourceAboutToBeReset(); private: diff --git a/GUI/coregui/Models/FitParameterItems.cpp b/GUI/coregui/Models/FitParameterItems.cpp index 9f9c9168cba..b2dfb7e4804 100644 --- a/GUI/coregui/Models/FitParameterItems.cpp +++ b/GUI/coregui/Models/FitParameterItems.cpp @@ -178,3 +178,8 @@ FitParameterItem *FitParameterContainerItem::getFitParameterItem(const QString & } return nullptr; } + +bool FitParameterContainerItem::isEmpty() +{ + return getItems(T_FIT_PARAMETERS).isEmpty() ? true : false; +} diff --git a/GUI/coregui/Models/FitParameterItems.h b/GUI/coregui/Models/FitParameterItems.h index 7b1488d6297..5d9ab0de7db 100644 --- a/GUI/coregui/Models/FitParameterItems.h +++ b/GUI/coregui/Models/FitParameterItems.h @@ -54,6 +54,7 @@ public: static const QString T_FIT_PARAMETERS; explicit FitParameterContainerItem(); FitParameterItem *getFitParameterItem(const QString &link); + bool isEmpty(); }; #endif diff --git a/GUI/coregui/Models/ModelPath.cpp b/GUI/coregui/Models/ModelPath.cpp index aaf8cd281a6..84734324e91 100644 --- a/GUI/coregui/Models/ModelPath.cpp +++ b/GUI/coregui/Models/ModelPath.cpp @@ -150,6 +150,21 @@ SessionItem *ModelPath::getItemFromPath(const QString &relPath, SessionItem *par return parent->model()->itemForIndex(ModelPath::getIndexFromPath(parent->model(), fullPath)); } +//! Iterates through all the model and returns true if item is found. This is to + +bool ModelPath::isValidItem(SessionModel *model, SessionItem *item, const QModelIndex &parent) +{ + for(int i_row=0; i_row<model->rowCount(parent); ++i_row) { + QModelIndex index = model->index(i_row, 0, parent); + SessionItem *curr = model->itemForIndex(index); + if(curr == item) return true; + + bool isvalid = isValidItem(model, item, index); + if(isvalid) return isvalid; + } + return false; +} + QStringList ModelPath::splitParameterName(const QString &par_name) { QStringList result; diff --git a/GUI/coregui/Models/ModelPath.h b/GUI/coregui/Models/ModelPath.h index d811ded3d1b..4b8ac90dee9 100644 --- a/GUI/coregui/Models/ModelPath.h +++ b/GUI/coregui/Models/ModelPath.h @@ -51,6 +51,8 @@ public: static SessionItem *getItemFromPath(const QString &relPath, SessionItem *parent); + static bool isValidItem(SessionModel *model, SessionItem *item, const QModelIndex &parent); + private: static QStringList splitParameterName(const QString& par_name); diff --git a/GUI/coregui/Views/FitWidgets/FitParameterWidget.cpp b/GUI/coregui/Views/FitWidgets/FitParameterWidget.cpp index a076c130206..f0fd298137c 100644 --- a/GUI/coregui/Views/FitWidgets/FitParameterWidget.cpp +++ b/GUI/coregui/Views/FitWidgets/FitParameterWidget.cpp @@ -202,6 +202,14 @@ void FitParameterWidget::onAddToFitParAction(int ipar) } } +void FitParameterWidget::onFitParameterModelChange() +{ + qDebug() << "FitParameterWidget::onFitParameterModelChange()"; + spanParameters(); + updateInfoLabel(); +} + + //! Context menu reimplemented to suppress the default one void FitParameterWidget::contextMenuEvent(QContextMenuEvent *event) @@ -272,15 +280,18 @@ void FitParameterWidget::init_fit_model() m_treeView->setModel(m_fitParameterModel); connect(m_fitParameterModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), - this, SLOT(spanParameters())); + this, SLOT(onFitParameterModelChange())); - spanParameters(); - connectFitParametersSelection(true); +// connect(m_fitParameterModel, SIGNAL(rowsInserted(QModelIndex,int,int)), +// this, SLOT(onFitParameterModelChange())); + connect(m_fitParameterModel, SIGNAL(modelReset()), this, SLOT(onFitParameterModelChange())); + +// connect(m_fitParameterModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), +// this, SLOT(onFitParameterModelChange())); -// InfoLabelWidget *label = new InfoLabelWidget(this); -// label->setPosition(0, 0); + onFitParameterModelChange(); - m_infoLabel->setShown(true); + connectFitParametersSelection(true); } //! Adds to JobItem all fit containers, if necessary. @@ -302,24 +313,6 @@ void FitParameterWidget::init_fit_containers() } } -//! Makes first column in FitParameterItem's tree related to ParameterItem link occupy whole space. - -void FitParameterWidget::spanParameters() -{ - m_treeView->expandAll(); - for (int i = 0; i < m_fitParameterModel->rowCount(QModelIndex()); i++){ - QModelIndex parameter = m_fitParameterModel->index(i,0,QModelIndex()); - if (!parameter.isValid()) - break; - int childRowCount = m_fitParameterModel->rowCount(parameter); - if (childRowCount > 0){ - for (int j = 0; j < childRowCount; j++) { - m_treeView->setFirstColumnSpanned(j, parameter, true); - } - } - } -} - //! Returns true if tuning widget contains selected ParameterItem's which can be used to create //! a fit parameter (i.e. it is not linked with some fit parameter already). @@ -393,6 +386,33 @@ QVector<FitParameterLinkItem *> FitParameterWidget::selectedFitParameterLinks() return result; } +//! Makes first column in FitParameterItem's tree related to ParameterItem link occupy whole space. + +void FitParameterWidget::spanParameters() +{ + m_treeView->expandAll(); + for (int i = 0; i < m_fitParameterModel->rowCount(QModelIndex()); i++){ + QModelIndex parameter = m_fitParameterModel->index(i,0,QModelIndex()); + if (!parameter.isValid()) + break; + int childRowCount = m_fitParameterModel->rowCount(parameter); + if (childRowCount > 0){ + for (int j = 0; j < childRowCount; j++) { + m_treeView->setFirstColumnSpanned(j, parameter, true); + } + } + } +} + +//! Places overlay label on top of tree view, if there is no fit parameters +void FitParameterWidget::updateInfoLabel() +{ + Q_ASSERT(m_jobItem); + bool is_to_show_label = m_jobItem->fitParameterContainerItem()->isEmpty(); + qDebug() << "FitParameterWidget::updateInfoLabel()" << m_jobItem->fitParameterContainerItem()->getItems(FitParameterContainerItem::T_FIT_PARAMETERS).size() << is_to_show_label << m_treeView; + m_infoLabel->setShown(is_to_show_label); +} + void FitParameterWidget::connectTuningWidgetSelection(bool active) { diff --git a/GUI/coregui/Views/FitWidgets/FitParameterWidget.h b/GUI/coregui/Views/FitWidgets/FitParameterWidget.h index f8808069a4a..065e5705f43 100644 --- a/GUI/coregui/Views/FitWidgets/FitParameterWidget.h +++ b/GUI/coregui/Views/FitWidgets/FitParameterWidget.h @@ -60,7 +60,7 @@ private slots: void onRemoveFromFitParAction(); void onRemoveFitParAction(); void onAddToFitParAction(int ipar); - void spanParameters(); + void onFitParameterModelChange(); protected: void contextMenuEvent(QContextMenuEvent *event); @@ -83,6 +83,9 @@ private: QVector<FitParameterItem *> selectedFitParameters(); QVector<FitParameterLinkItem *> selectedFitParameterLinks(); + void spanParameters(); + void updateInfoLabel(); + QTreeView *m_treeView; JobItem *m_jobItem; ParameterTuningWidget *m_tuningWidget; diff --git a/GUI/coregui/Views/InfoWidgets/InfoLabelController.cpp b/GUI/coregui/Views/InfoWidgets/InfoLabelController.cpp index 4c26e5ab04a..51f84d7a580 100644 --- a/GUI/coregui/Views/InfoWidgets/InfoLabelController.cpp +++ b/GUI/coregui/Views/InfoWidgets/InfoLabelController.cpp @@ -45,6 +45,7 @@ void InfoLabelController::setArea(QAbstractScrollArea *area) void InfoLabelController::setShown(bool shown) { if(shown) { + Q_ASSERT(m_area); if(!m_label) { m_label = new InfoLabelWidget(m_area); m_label->setText(m_text); @@ -72,7 +73,8 @@ bool InfoLabelController::eventFilter(QObject *obj, QEvent *event) void InfoLabelController::updateLabelGeometry() { if(!m_label || !m_area) return; - qDebug() << "InfoLabelController::updateLabelGeometry()" << m_area->width(), m_area->height(); + qDebug() << "InfoLabelController::updateLabelGeometry()" << m_area->width() << m_area->height() << m_area << m_text; m_label->setRectangle(QRect(0, 0, m_area->width(), m_area->height())); m_label->setPosition(0, 0); + m_label->show(); } -- GitLab