diff --git a/Modules/QtWidgetsExt/src/QmitkBoundingObjectWidget.cpp b/Modules/QtWidgetsExt/src/QmitkBoundingObjectWidget.cpp index 2044658851..8195ef1e7c 100644 --- a/Modules/QtWidgetsExt/src/QmitkBoundingObjectWidget.cpp +++ b/Modules/QtWidgetsExt/src/QmitkBoundingObjectWidget.cpp @@ -1,442 +1,442 @@ /*============================================================================ 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 "QmitkBoundingObjectWidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include // micro services #include #include QmitkBoundingObjectWidget::QmitkBoundingObjectWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f), m_DataStorage(nullptr), m_lastSelectedItem(nullptr), m_lastAffineObserver(0), m_ItemNodeMap(), m_BoundingObjectCounter(1) { QBoxLayout *mainLayout = new QVBoxLayout(this); QHBoxLayout *buttonLayout = new QHBoxLayout(); QStringList boList; boList << tr("add") << tr("cube") << tr("cone") << tr("ellipse") << tr("cylinder"); m_addComboBox = new QComboBox(); m_addComboBox->addItems(boList); m_addComboBox->setItemIcon(1, QIcon(":/QmitkWidgetsExt/btnCube.xpm")); m_addComboBox->setItemIcon(2, QIcon(":/QmitkWidgetsExt/btnPyramid.xpm")); m_addComboBox->setItemIcon(3, QIcon(":/QmitkWidgetsExt/btnEllipsoid.xpm")); m_addComboBox->setItemIcon(4, QIcon(":/QmitkWidgetsExt/btnCylinder.xpm")); buttonLayout->addWidget(m_addComboBox); m_DelButton = new QPushButton("del"); buttonLayout->addWidget(m_DelButton); m_SaveButton = new QPushButton("save"); buttonLayout->addWidget(m_SaveButton); m_SaveButton->setEnabled(false); m_LoadButton = new QPushButton("load"); buttonLayout->addWidget(m_LoadButton); m_LoadButton->setEnabled(false); m_TreeWidget = new QTreeWidget(this); m_TreeWidget->setColumnCount(3); QStringList sList; sList << tr("name") << tr("inverted") << tr("visible"); m_TreeWidget->setHeaderLabels(sList); m_TreeWidget->setColumnWidth(0, 250); m_TreeWidget->setColumnWidth(1, 50); m_TreeWidget->setColumnWidth(2, 50); m_TreeWidget->setAutoScroll(true); m_TreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); mainLayout->addWidget(m_TreeWidget); mainLayout->addLayout(buttonLayout); connect(m_addComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(CreateBoundingObject(int))); connect(m_TreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(SelectionChanged())); connect(m_DelButton, SIGNAL(clicked()), this, SLOT(OnDelButtonClicked())); connect(m_TreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(OnItemDoubleClicked(QTreeWidgetItem *, int))); connect( m_TreeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnItemDataChanged(QTreeWidgetItem *, int))); } QmitkBoundingObjectWidget::~QmitkBoundingObjectWidget() { } void QmitkBoundingObjectWidget::setEnabled(bool flag) { ItemNodeMapType::iterator it = m_ItemNodeMap.begin(); while (it != m_ItemNodeMap.end()) { mitk::DataNode *node = it->second; QTreeWidgetItem *item = it->first; if (flag) node->SetVisibility(item->checkState(2)); else node->SetVisibility(flag); ++it; } QWidget::setEnabled(flag); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkBoundingObjectWidget::SelectionChanged() { QList selectedItems = m_TreeWidget->selectedItems(); if (selectedItems.size() < 1) return; QTreeWidgetItem *selectedItem = selectedItems.first(); if (selectedItem == m_lastSelectedItem) return; if (m_lastSelectedItem != nullptr) { m_TreeWidget->closePersistentEditor(m_lastSelectedItem, 0); ItemNodeMapType::iterator it = m_ItemNodeMap.find(m_lastSelectedItem); if (it != m_ItemNodeMap.end()) { mitk::DataNode *last_node = it->second; // remove observer last_node->RemoveObserver(m_lastAffineObserver); last_node->SetDataInteractor(nullptr); } } ItemNodeMapType::iterator it = m_ItemNodeMap.find(selectedItem); if (it == m_ItemNodeMap.end()) return; mitk::DataNode *new_node = it->second; mitk::AffineBaseDataInteractor3D::Pointer affineDataInteractor = mitk::AffineBaseDataInteractor3D::New(); affineDataInteractor->LoadStateMachine("AffineInteraction3D.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt")); affineDataInteractor->SetEventConfig("AffineConfig.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt")); affineDataInteractor->SetDataNode(new_node); new_node->SetBoolProperty("pickable", true); // create observer for node itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkBoundingObjectWidget::OnBoundingObjectModified); m_lastAffineObserver = new_node->AddObserver(mitk::AffineInteractionEvent(), command); m_lastSelectedItem = selectedItem; } void QmitkBoundingObjectWidget::AddItem(mitk::DataNode *node) { mitk::BoundingObject *boundingObject; boundingObject = dynamic_cast(node->GetData()); std::string name; node->GetStringProperty("name", name); if (boundingObject) { QTreeWidgetItem *item = new QTreeWidgetItem(); item->setData(0, Qt::EditRole, QString::fromLocal8Bit(name.c_str())); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); // checkbox for positive flag item->setData(1, Qt::CheckStateRole, tr("")); item->setCheckState(1, Qt::Unchecked); // checkbox for visibleflag item->setData(2, Qt::CheckStateRole, tr("")); item->setCheckState(2, Qt::Checked); m_TreeWidget->addTopLevelItem(item); m_ItemNodeMap.insert(std::make_pair(item, node)); m_TreeWidget->selectAll(); QList items = m_TreeWidget->selectedItems(); for (int i = 0; i < items.size(); i++) { - m_TreeWidget->setItemSelected(items.at(i), false); + items.at(i)->setSelected(false); } - m_TreeWidget->setItemSelected(item, true); + item->setSelected(true); } else MITK_ERROR << name << " is not a bounding object or does not exist in data storage" << endl; } void QmitkBoundingObjectWidget::OnItemDoubleClicked(QTreeWidgetItem *item, int col) { if (col == 0) { m_TreeWidget->openPersistentEditor(item, col); } } void QmitkBoundingObjectWidget::OnItemDataChanged(QTreeWidgetItem *item, int col) { if (m_ItemNodeMap.size() < 1) return; ItemNodeMapType::iterator it = m_ItemNodeMap.find(item); if (it == m_ItemNodeMap.end()) return; mitk::DataNode *node = it->second; // name if (col == 0) { m_TreeWidget->closePersistentEditor(item, col); node->SetName(item->text(0).toLocal8Bit().data()); } // positive else if (col == 1) { mitk::BoundingObject *boundingObject = dynamic_cast(node->GetData()); if (boundingObject) boundingObject->SetPositive(!(item->checkState(1))); emit BoundingObjectsChanged(); } // visible else if (col == 2) { node->SetVisibility(item->checkState(2)); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkBoundingObjectWidget::RemoveItem() { // selection mode is set to single selection, so there should not be more than one selected item QList selectedItems = m_TreeWidget->selectedItems(); QTreeWidgetItem *item = selectedItems.first(); QString str = item->text(0); ItemNodeMapType::iterator it = m_ItemNodeMap.find(item); if (it == m_ItemNodeMap.end()) return; mitk::DataNode *node = it->second; mitk::BoundingObject *boundingObject; if (node) { boundingObject = dynamic_cast(node->GetData()); if (boundingObject) { // delete item; m_TreeWidget->takeTopLevelItem(m_TreeWidget->indexOfTopLevelItem(item)); m_ItemNodeMap.erase(m_ItemNodeMap.find(item)); m_DataStorage->Remove(node); } } } void QmitkBoundingObjectWidget::RemoveAllItems() { ItemNodeMapType::iterator it = m_ItemNodeMap.begin(); while (it != m_ItemNodeMap.end()) { m_TreeWidget->takeTopLevelItem(m_TreeWidget->indexOfTopLevelItem(it->first)); m_ItemNodeMap.erase(m_ItemNodeMap.find(it->first)); ++it; } m_BoundingObjectCounter = 1; } mitk::BoundingObject::Pointer QmitkBoundingObjectWidget::GetSelectedBoundingObject() { mitk::BoundingObject *boundingObject; mitk::DataNode *node = this->GetSelectedBoundingObjectNode(); if (node) { boundingObject = dynamic_cast(node->GetData()); if (boundingObject) return boundingObject; } return nullptr; } void QmitkBoundingObjectWidget::SetDataStorage(mitk::DataStorage *dataStorage) { m_DataStorage = dataStorage; } mitk::DataStorage *QmitkBoundingObjectWidget::GetDataStorage() { return m_DataStorage; } void QmitkBoundingObjectWidget::OnDelButtonClicked() { RemoveItem(); } void QmitkBoundingObjectWidget::CreateBoundingObject(int type) { // get cross position mitk::Point3D pos; mitk::RenderingManager::RenderWindowVector windows = mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); // hopefully we have the renderwindows in the "normal" order const mitk::PlaneGeometry *plane1 = mitk::BaseRenderer::GetInstance(windows.at(0))->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry *plane2 = mitk::BaseRenderer::GetInstance(windows.at(1))->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry *plane3 = mitk::BaseRenderer::GetInstance(windows.at(2))->GetSliceNavigationController()->GetCurrentPlaneGeometry(); mitk::Line3D line; if ((plane1 != nullptr) && (plane2 != nullptr) && (plane1->IntersectionLine(plane2, line))) { if (!((plane3 != nullptr) && (plane3->IntersectionPoint(line, pos)))) { return; } } if (type != 0) { mitk::BoundingObject::Pointer boundingObject; QString name; name.setNum(m_BoundingObjectCounter); switch (type - 1) { case CUBOID: boundingObject = mitk::Cuboid::New(); name.prepend("Cube_"); break; case CONE: boundingObject = mitk::Cone::New(); name.prepend("Cone_"); break; case ELLIPSOID: boundingObject = mitk::Ellipsoid::New(); name.prepend("Ellipse_"); break; case CYLINDER: boundingObject = mitk::Cylinder::New(); name.prepend("Cylinder_"); break; default: return; break; } m_BoundingObjectCounter++; m_addComboBox->setCurrentIndex(0); // set initial size mitk::Vector3D size; size.Fill(10); boundingObject->GetGeometry()->SetSpacing(size); boundingObject->GetGeometry()->Translate(pos.GetVectorFromOrigin()); boundingObject->GetTimeGeometry()->Update(); // create node mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(boundingObject); node->SetProperty("name", mitk::StringProperty::New(name.toLocal8Bit().data())); node->SetProperty("color", mitk::ColorProperty::New(0.0, 0.0, 1.0)); node->SetProperty("opacity", mitk::FloatProperty::New(0.7)); node->SetProperty("bounding object", mitk::BoolProperty::New(true)); node->SetProperty("helper object", mitk::BoolProperty::New(true)); m_DataStorage->Add(node); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit BoundingObjectsChanged(); AddItem(node); } } mitk::DataNode::Pointer QmitkBoundingObjectWidget::GetAllBoundingObjects() { mitk::DataNode::Pointer boundingObjectGroupNode = mitk::DataNode::New(); mitk::BoundingObjectGroup::Pointer boundingObjectGroup = mitk::BoundingObjectGroup::New(); boundingObjectGroup->SetCSGMode(mitk::BoundingObjectGroup::Union); mitk::NodePredicateProperty::Pointer prop = mitk::NodePredicateProperty::New("bounding object", mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer allBO = m_DataStorage->GetSubset(prop); for (mitk::DataStorage::SetOfObjects::const_iterator it = allBO->begin(); it != allBO->end(); ++it) { mitk::DataNode::Pointer node = *it; mitk::BoundingObject::Pointer boundingObject = dynamic_cast(node->GetData()); if (boundingObject) boundingObjectGroup->AddBoundingObject(boundingObject); } boundingObjectGroupNode->SetData(boundingObjectGroup); if (boundingObjectGroup->GetCount() > 0) return boundingObjectGroupNode; return nullptr; } mitk::DataNode::Pointer QmitkBoundingObjectWidget::GetSelectedBoundingObjectNode() { QList selectedItems = m_TreeWidget->selectedItems(); if (selectedItems.size() < 1) return nullptr; QTreeWidgetItem *item = selectedItems.first(); mitk::DataNode *node = m_ItemNodeMap.find(item)->second; return node; } void QmitkBoundingObjectWidget::OnBoundingObjectModified(const itk::EventObject &) { emit BoundingObjectsChanged(); } diff --git a/Modules/SemanticRelationsUI/src/QmitkPatientTableHeaderView.cpp b/Modules/SemanticRelationsUI/src/QmitkPatientTableHeaderView.cpp index 7348ebcfda..eae7be7291 100644 --- a/Modules/SemanticRelationsUI/src/QmitkPatientTableHeaderView.cpp +++ b/Modules/SemanticRelationsUI/src/QmitkPatientTableHeaderView.cpp @@ -1,240 +1,240 @@ /*============================================================================ 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. ============================================================================*/ // semantic relations UI module #include "QmitkPatientTableHeaderView.h" // qt #include #include QmitkPatientTableHeaderView::QmitkPatientTableHeaderView(QWidget* parent/* = nullptr*/) : QHeaderView(Qt::Horizontal, parent) , m_HeaderModel(nullptr) { // nothing here } QmitkPatientTableHeaderView::~QmitkPatientTableHeaderView() { // nothing here } void QmitkPatientTableHeaderView::setModel(QAbstractItemModel* model) { // retrieve the header model from the given table model QVariant variant = model->data(QModelIndex(), HorizontalHeaderDataRole); if (variant.isValid() && variant.canConvert()) { m_HeaderModel = variant.value(); } QHeaderView::setModel(model); } void QmitkPatientTableHeaderView::paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const { if (rect.isValid()) { int top = rect.y(); QModelIndex leafIndex = HeaderIndex(logicalIndex); QModelIndexList indexes = ParentIndexList(leafIndex); for (const auto& index : qAsConst(indexes)) { top = PaintHeader(painter, index, logicalIndex, rect, top); } return; } QHeaderView::paintSection(painter, rect, logicalIndex); } QSize QmitkPatientTableHeaderView::sectionSizeFromContents(int logicalIndex) const { if (nullptr != m_HeaderModel) { QModelIndex headerIndex = HeaderIndex(logicalIndex); if (headerIndex.isValid()) { QSize headerSize = HeaderSize(headerIndex); headerIndex = headerIndex.parent(); while (headerIndex.isValid()) { QSize currentHeaderSize = HeaderSize(headerIndex); headerSize.rheight() += currentHeaderSize.height(); if (currentHeaderSize.width() > headerSize.width()) { headerSize.rwidth() = currentHeaderSize.width(); } headerIndex = headerIndex.parent(); } return headerSize; } } return QHeaderView::sectionSizeFromContents(logicalIndex); } int QmitkPatientTableHeaderView::PaintHeader(QPainter* painter, const QModelIndex& currentIndex, int logicalIndex, const QRect& sectionRect, int top) const { QModelIndex headerIndex = HeaderIndex(logicalIndex); int height = HeaderSize(currentIndex).height(); if (currentIndex == headerIndex) { height = sectionRect.height() - top; } int left = CurrentHeaderLeft(currentIndex, headerIndex, logicalIndex, sectionRect.left()); int width = CurrentHeaderWidth(currentIndex, headerIndex, logicalIndex); QStyleOptionHeader headerStyleOptions; initStyleOption(&headerStyleOptions); headerStyleOptions.text = currentIndex.data(Qt::DisplayRole).toString(); headerStyleOptions.textAlignment = Qt::AlignCenter; painter->save(); QRect rect(left, top, width, height); headerStyleOptions.rect = rect; style()->drawControl(QStyle::CE_Header, &headerStyleOptions, painter, this); painter->restore(); return top + height; } QSize QmitkPatientTableHeaderView::HeaderSize(const QModelIndex& index) const { QFont font = this->font(); font.setBold(true); QFontMetrics fontMetrics(font); QSize fontSize = fontMetrics.size(0, index.data(Qt::DisplayRole).toString()); QSize emptyFontSize = fontMetrics.size(0, ""); return fontSize + emptyFontSize; } int QmitkPatientTableHeaderView::CurrentHeaderLeft(const QModelIndex& currentIndex, const QModelIndex& headerIndex, int sectionIndex, int left) const { QModelIndexList headerList = ListHeader(currentIndex); if (!headerList.empty()) { int index = headerList.indexOf(headerIndex); int firstHeaderSectionIndex = sectionIndex - index; --index; for (; index >= 0; --index) { left -= sectionSize(firstHeaderSectionIndex + index); } } return left; } int QmitkPatientTableHeaderView::CurrentHeaderWidth(const QModelIndex& currentIndex, const QModelIndex& headerIndex, int sectionIndex) const { QModelIndexList headerList = ListHeader(currentIndex); if (headerList.empty()) { return sectionSize(sectionIndex); } int width = 0; int index = headerList.indexOf(headerIndex); int firstHeaderSectionIndex = sectionIndex - index; for (int i = 0; i < headerList.size(); ++i) { width += sectionSize(firstHeaderSectionIndex + i); } return width; } QModelIndexList QmitkPatientTableHeaderView::ParentIndexList(QModelIndex index) const { QModelIndexList indexList; while (index.isValid()) { indexList.push_front(index); index = index.parent(); } return indexList; } QModelIndex QmitkPatientTableHeaderView::HeaderIndex(int sectionIndex) const { if (nullptr != m_HeaderModel) { int currentHeaderIndex = -1; for (int i = 0; i < m_HeaderModel->columnCount(); ++i) { QModelIndex modelIndex = FindHeader(m_HeaderModel->index(0, i), sectionIndex, currentHeaderIndex); if (modelIndex.isValid()) { return modelIndex; } } } return QModelIndex(); } QModelIndex QmitkPatientTableHeaderView::FindHeader(const QModelIndex& currentIndex, int sectionIndex, int& currentHeaderIndex) const { if (currentIndex.isValid()) { int childCount = currentIndex.model()->columnCount(currentIndex); if (childCount > 0) { for (int i = 0; i < childCount; ++i) { - QModelIndex modelIndex = FindHeader(currentIndex.child(0, i), sectionIndex, currentHeaderIndex); + QModelIndex modelIndex = FindHeader(currentIndex.model()->index(0, i, currentIndex), sectionIndex, currentHeaderIndex); if (modelIndex.isValid()) { return modelIndex; } } } else { ++currentHeaderIndex; if (currentHeaderIndex == sectionIndex) { return currentIndex; } } } return QModelIndex(); } QModelIndexList QmitkPatientTableHeaderView::ListHeader(const QModelIndex& currentIndex) const { QModelIndexList headerList; if (currentIndex.isValid()) { int childCount = currentIndex.model()->columnCount(currentIndex); if (childCount > 0) { for (int i = 0; i < childCount; ++i) { - headerList += ListHeader(currentIndex.child(0, i)); + headerList += ListHeader(currentIndex.model()->index(0, i, currentIndex)); } } else { headerList.push_back(currentIndex); } } return headerList; } diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryQtShowViewDialog.cpp b/Plugins/org.blueberry.ui.qt/src/internal/berryQtShowViewDialog.cpp index 7c22f943da..7c801ef93e 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryQtShowViewDialog.cpp +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryQtShowViewDialog.cpp @@ -1,328 +1,328 @@ /*============================================================================ 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 "berryQtShowViewDialog.h" #include #include #include "berryWorkbenchPlugin.h" #include "berryXMLMemento.h" #include #include #include namespace berry { static const QString TAG_SHOWVIEWDIALOG = "ShowViewDialog"; static const QString TAG_CATEGORY = "category"; static const QString TAG_SELECTION = "selection"; static const QString TAG_GEOMETRY = "geometry"; class ViewFilterProxyModel : public QSortFilterProxyModel { public: ViewFilterProxyModel(QObject* parent = nullptr) : QSortFilterProxyModel(parent) , m_FilterOnKeywords(true) { this->setFilterCaseSensitivity(Qt::CaseInsensitive); } bool filterOnKeywords() const { return m_FilterOnKeywords; } void setFilterOnKeywords(bool filterOnKeywords) { if (m_FilterOnKeywords != filterOnKeywords) { m_FilterOnKeywords = filterOnKeywords; this->invalidateFilter(); } } protected: bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override { QRegularExpression regExp = filterRegularExpression(); if (!regExp.isValid() || regExp.pattern().isEmpty()) return true; QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); QStringList keywords; if (m_FilterOnKeywords) { keywords = sourceModel()->data(sourceIndex, ViewTreeModel::Keywords).toStringList(); } else { if (sourceModel()->hasChildren(sourceIndex)) { // this is a category item int numChildren = sourceModel()->rowCount(sourceIndex); for (int i = 0; i < numChildren; ++i) { - keywords.push_back(sourceModel()->data(sourceIndex.child(i, 0)).toString()); + keywords.push_back(sourceModel()->data(sourceModel()->index(i, 0, sourceIndex)).toString()); } } else { // this is a view item keywords.push_back(sourceModel()->data(sourceIndex).toString()); } } for(auto& keyword : keywords) { if (keyword.contains(regExp)) return true; } return false; } private: bool m_FilterOnKeywords; }; QtShowViewDialog::QtShowViewDialog(const IWorkbenchWindow* window, IViewRegistry* registry, QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) , m_Window(window) , m_ViewReg(registry) , m_FilterModel(nullptr) { m_UserInterface.setupUi(this); m_UserInterface.m_TreeView->header()->setVisible(false); m_UserInterface.m_TreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_FilterModel = new ViewFilterProxyModel(this); auto sourceModel = new ViewTreeModel(window, m_FilterModel); m_FilterModel->setSourceModel(sourceModel); m_UserInterface.m_TreeView->setModel(m_FilterModel); connect(m_UserInterface.m_Filter, SIGNAL(textChanged(QString)), this, SLOT(setFilter(QString))); connect(m_UserInterface.m_TreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(setDescription(QModelIndex))); connect(m_UserInterface.m_TreeView, SIGNAL(collapsed(QModelIndex)), this, SLOT(categoryCollapsed(QModelIndex))); connect(m_UserInterface.m_TreeView, SIGNAL(expanded(QModelIndex)), this, SLOT(categoryExpanded(QModelIndex))); connect(m_UserInterface.m_TreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); connect(m_UserInterface.m_TreeView, SIGNAL(activated(QModelIndex)), this, SLOT(accept())); connect(m_UserInterface.m_TreeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection))); connect(m_UserInterface.m_KeywordFilter, SIGNAL(clicked(bool)), this, SLOT(enableKeywordFilter(bool))); this->RestoreState(); m_UserInterface.m_Filter->selectAll(); this->UpdateButtons(); } void QtShowViewDialog::setDescription(const QModelIndex& index) { QString description = m_UserInterface.m_TreeView->model()->data(index, Qt::WhatsThisRole).toString(); m_UserInterface.m_Description->setText(description); } void QtShowViewDialog::enableKeywordFilter(bool enable) { m_FilterModel->setFilterOnKeywords(enable); this->RestoreExpandedState(); } void QtShowViewDialog::setFilter(const QString& filter) { m_FilterModel->setFilterWildcard(filter); this->RestoreExpandedState(); } void QtShowViewDialog::categoryCollapsed(const QModelIndex& index) { m_ExpandedCategories.removeAll(m_FilterModel->mapToSource(index)); } void QtShowViewDialog::categoryExpanded(const QModelIndex& index) { m_ExpandedCategories.push_back(m_FilterModel->mapToSource(index)); } void QtShowViewDialog::selectionChanged(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/) { UpdateButtons(); } void QtShowViewDialog::RestoreExpandedState() { int rowCount = m_FilterModel->rowCount(); for (int i = 0; i < rowCount; ++i) { QModelIndex index = m_FilterModel->index(i, 0); if (m_ExpandedCategories.contains(m_FilterModel->mapToSource(index))) { m_UserInterface.m_TreeView->expand(index); } } } void QtShowViewDialog::UpdateButtons() { QPushButton* okBtn = m_UserInterface.m_ButtonBox->button(QDialogButtonBox::Ok); if (okBtn) { okBtn->setEnabled(!m_UserInterface.m_TreeView->selectionModel()->selection().isEmpty()); } } void QtShowViewDialog::RestoreState() { auto* prefs = WorkbenchPlugin::GetDefault()->GetPreferences(); auto str = QString::fromStdString(prefs->Get(TAG_SHOWVIEWDIALOG.toStdString(), "")); if (str.isEmpty()) return; std::stringstream ss(str.toStdString()); XMLMemento::Pointer memento = XMLMemento::CreateReadRoot(ss); bool keywordFilter = false; if (memento->GetBoolean("keywordFilter", keywordFilter)) { m_UserInterface.m_KeywordFilter->setChecked(keywordFilter); m_FilterModel->setFilterOnKeywords(keywordFilter); } QString filter; if (memento->GetString("filter", filter)) { m_UserInterface.m_Filter->setText(filter); } IMemento::Pointer geomChild = memento->GetChild(TAG_GEOMETRY); if (geomChild.IsNotNull()) { QString geom = geomChild->GetTextData(); if (!geom.isEmpty()) { QByteArray ba = QByteArray::fromBase64(geom.toLatin1()); this->restoreGeometry(ba); } } QHash rootIndices; int rowCount = m_FilterModel->sourceModel()->rowCount(); for (int i = 0; i < rowCount; ++i) { QModelIndex sourceIndex = m_FilterModel->sourceModel()->index(i, 0); QString id = sourceIndex.data(ViewTreeModel::Id).toString(); if (!id.isEmpty()) { rootIndices[id] = sourceIndex; } } for (const IMemento::Pointer &categoryChild : memento->GetChildren(TAG_CATEGORY)) { QString id = categoryChild->GetID(); if (!id.isEmpty()) { if (rootIndices.contains(id)) { m_ExpandedCategories.push_back(rootIndices[id]); } } } this->RestoreExpandedState(); QItemSelection itemSelection; for (const IMemento::Pointer &selectionChild : memento->GetChildren(TAG_SELECTION)) { QString id = selectionChild->GetID(); if (!id.isEmpty()) { QModelIndexList indexList = m_FilterModel->match(m_FilterModel->index(0, 0), ViewTreeModel::Id, QVariant::fromValue(id), 1, Qt::MatchExactly | Qt::MatchRecursive); if (!indexList.isEmpty()) { QItemSelection subSelection(indexList.front(), indexList.front()); itemSelection.merge(subSelection, QItemSelectionModel::SelectCurrent); } } } m_UserInterface.m_TreeView->selectionModel()->select(itemSelection, QItemSelectionModel::ClearAndSelect); } void QtShowViewDialog::SaveState() { XMLMemento::Pointer memento = XMLMemento::CreateWriteRoot(TAG_SHOWVIEWDIALOG); memento->PutString("filter", m_UserInterface.m_Filter->text()); memento->PutBoolean("keywordFilter", m_UserInterface.m_KeywordFilter->isChecked()); // dialog geometry QByteArray geom = this->saveGeometry(); IMemento::Pointer geomChild = memento->CreateChild(TAG_GEOMETRY); geomChild->PutTextData(geom.toBase64().constData()); // expanded categories for (const QPersistentModelIndex &index : qAsConst(m_ExpandedCategories)) { if (index.isValid()) { QString id = index.data(ViewTreeModel::Id).toString(); if (!id.isEmpty()) { memento->CreateChild(TAG_CATEGORY, id); } } } // we only record a single selected item. restoring a multi-selection might be // confusing for the user QModelIndexList selectedIndices = m_UserInterface.m_TreeView->selectionModel()->selectedIndexes(); if (!selectedIndices.isEmpty()) { QString id = selectedIndices.back().data(ViewTreeModel::Id).toString(); if (!id.isEmpty()) { memento->CreateChild(TAG_SELECTION, id); } } std::stringstream ss; memento->Save(ss); auto* prefs = WorkbenchPlugin::GetDefault()->GetPreferences(); prefs->Put(TAG_SHOWVIEWDIALOG.toStdString(), ss.str()); prefs->Flush(); } void QtShowViewDialog::done(int r) { this->SaveState(); QDialog::done(r); } QList QtShowViewDialog::GetSelection() const { QList selected; QModelIndexList indices = m_UserInterface.m_TreeView->selectionModel()->selectedIndexes(); for(QModelIndex index : qAsConst(indices)) { QString id = m_FilterModel->data(index, ViewTreeModel::Id).toString(); selected.push_back(id); } return selected; } }