forked from qt-creator/qt-creator
Navigator: Add search/filter to navigator
Task-number: QDS-6063 Change-Id: I922a04a46f673befe8811a62342cf2cdd9c61583 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Henning Gründl <henning.gruendl@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -276,6 +276,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
nameitemdelegate.cpp nameitemdelegate.h
|
||||
navigator.qrc
|
||||
navigatormodelinterface.h
|
||||
navigatorsearchwidget.cpp navigatorsearchwidget.h
|
||||
navigatortreemodel.cpp navigatortreemodel.h
|
||||
navigatortreeview.cpp navigatortreeview.h
|
||||
navigatorview.cpp navigatorview.h
|
||||
|
@@ -45,6 +45,7 @@ public:
|
||||
virtual void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) = 0;
|
||||
virtual void notifyIconsChanged() = 0;
|
||||
virtual void setFilter(bool showObjects) = 0;
|
||||
virtual void setNameFilter(const QString &filter) = 0;
|
||||
virtual void setOrder(bool reverse) = 0;
|
||||
virtual void resetModel() = 0;
|
||||
};
|
||||
|
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "navigatorsearchwidget.h"
|
||||
|
||||
#include <utils/stylehelper.h>
|
||||
#include <theme.h>
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
NavigatorSearchWidget::NavigatorSearchWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
auto layout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
setLayout(layout);
|
||||
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
const int iconSize = 15;
|
||||
const QColor iconColor(QmlDesigner::Theme::getColor(QmlDesigner::Theme::IconsBaseColor));
|
||||
const QIcon searchIcon = Utils::StyleHelper::getIconFromIconFont(
|
||||
fontName, QmlDesigner::Theme::getIconUnicode(QmlDesigner::Theme::Icon::search),
|
||||
iconSize, iconSize, iconColor);
|
||||
|
||||
m_textField = new QLineEdit;
|
||||
m_textField->setPlaceholderText(tr("Filter"));
|
||||
m_textField->setFrame(false);
|
||||
m_textField->setClearButtonEnabled(true);
|
||||
m_textField->addAction(searchIcon, QLineEdit::LeadingPosition);
|
||||
|
||||
connect(m_textField, &QLineEdit::textChanged, this, &NavigatorSearchWidget::textChanged);
|
||||
|
||||
layout->addWidget(m_textField);
|
||||
}
|
||||
|
||||
void NavigatorSearchWidget::clear()
|
||||
{
|
||||
m_textField->clear();
|
||||
}
|
||||
|
||||
} // QmlDesigner
|
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class NavigatorSearchWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NavigatorSearchWidget(QWidget *parent = nullptr);
|
||||
|
||||
void clear();
|
||||
|
||||
signals:
|
||||
void textChanged(const QString &text);
|
||||
|
||||
private:
|
||||
|
||||
QLineEdit *m_textField;
|
||||
};
|
||||
|
||||
} //QmlDesigner
|
@@ -324,14 +324,25 @@ QList<ModelNode> NavigatorTreeModel::filteredList(const NodeListProperty &proper
|
||||
return it.value();
|
||||
|
||||
QList<ModelNode> list;
|
||||
QList<ModelNode> propertyNodes = property.toModelNodeList();
|
||||
QList<ModelNode> nameFilteredList;
|
||||
|
||||
if (m_nameFilter.isEmpty()) {
|
||||
nameFilteredList = propertyNodes;
|
||||
} else {
|
||||
nameFilteredList.append(Utils::filtered(propertyNodes, [&] (const ModelNode &arg){
|
||||
const bool value = m_nameFilteredList.contains(arg);
|
||||
return value;
|
||||
}));
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
list.append(Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) {
|
||||
list.append(Utils::filtered(nameFilteredList, [] (const ModelNode &arg) {
|
||||
const bool value = QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
|
||||
return value;
|
||||
}));
|
||||
} else {
|
||||
list = property.toModelNodeList();
|
||||
list = nameFilteredList;
|
||||
}
|
||||
|
||||
appendForcedNodes(property, list);
|
||||
@@ -1222,6 +1233,35 @@ void NavigatorTreeModel::setFilter(bool showOnlyVisibleItems)
|
||||
resetModel();
|
||||
}
|
||||
|
||||
void NavigatorTreeModel::setNameFilter(const QString &filter)
|
||||
{
|
||||
m_nameFilter = filter;
|
||||
m_rowCache.clear();
|
||||
|
||||
ModelNode rootNode = m_view->rootModelNode();
|
||||
QList<ModelNode> allNodes = rootNode.allSubModelNodes();
|
||||
m_nameFilteredList.clear();
|
||||
|
||||
if (filter.isEmpty()) {
|
||||
m_nameFilteredList = allNodes;
|
||||
} else {
|
||||
for (ModelNode &node : rootNode.allSubModelNodes()) {
|
||||
if (node.displayName().contains(filter, Qt::CaseSensitivity::CaseInsensitive)) {
|
||||
m_nameFilteredList.append(node);
|
||||
ModelNode n = node;
|
||||
while (n.hasParentProperty()) {
|
||||
n = n.parentProperty().parentModelNode();
|
||||
if (n.isRootNode() || m_nameFilteredList.contains(n))
|
||||
break;
|
||||
m_nameFilteredList.append(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resetModel();
|
||||
}
|
||||
|
||||
void NavigatorTreeModel::setOrder(bool reverseItemOrder)
|
||||
{
|
||||
m_reverseItemOrder = reverseItemOrder;
|
||||
|
@@ -101,6 +101,7 @@ public:
|
||||
void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) override;
|
||||
void notifyIconsChanged() override;
|
||||
void setFilter(bool showOnlyVisibleItems) override;
|
||||
void setNameFilter(const QString &filter) override;
|
||||
void setOrder(bool reverseItemOrder) override;
|
||||
void resetModel() override;
|
||||
|
||||
@@ -140,6 +141,8 @@ private:
|
||||
bool m_showOnlyVisibleItems = true;
|
||||
bool m_reverseItemOrder = false;
|
||||
DesignerActionManager *m_actionManager = nullptr;
|
||||
QString m_nameFilter;
|
||||
QList<ModelNode> m_nameFilteredList;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -152,6 +152,8 @@ void NavigatorView::modelAttached(Model *model)
|
||||
treeView->setIndentation(20);
|
||||
|
||||
m_currentModelInterface->setFilter(false);
|
||||
m_currentModelInterface->setNameFilter("");
|
||||
m_widget->clearSearch();
|
||||
|
||||
QTimer::singleShot(0, this, [this, treeView]() {
|
||||
m_currentModelInterface->setFilter(
|
||||
@@ -576,6 +578,12 @@ void NavigatorView::reverseOrderToggled(bool flag)
|
||||
DesignerSettings::setValue(DesignerSettingsKey::NAVIGATOR_REVERSE_ITEM_ORDER, flag);
|
||||
}
|
||||
|
||||
void NavigatorView::textFilterChanged(const QString &text)
|
||||
{
|
||||
m_treeModel->setNameFilter(text);
|
||||
treeWidget()->expandAll();
|
||||
}
|
||||
|
||||
void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, const QItemSelection &/*deselected*/)
|
||||
{
|
||||
if (m_blockSelectionChangedSignal)
|
||||
@@ -704,6 +712,8 @@ void NavigatorView::setupWidget()
|
||||
connect(m_widget.data(), &NavigatorWidget::filterToggled, this, &NavigatorView::filterToggled);
|
||||
connect(m_widget.data(), &NavigatorWidget::reverseOrderToggled, this, &NavigatorView::reverseOrderToggled);
|
||||
|
||||
connect(m_widget.data(), &NavigatorWidget::textFilterChanged, this, &NavigatorView::textFilterChanged);
|
||||
|
||||
#ifndef QMLDESIGNER_TEST
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
const QSize size = QSize(28, 28);
|
||||
|
@@ -118,6 +118,8 @@ private:
|
||||
void filterToggled(bool);
|
||||
void reverseOrderToggled(bool);
|
||||
|
||||
void textFilterChanged(const QString &text);
|
||||
|
||||
protected: //functions
|
||||
QTreeView *treeWidget() const;
|
||||
NavigatorTreeModel *treeModel();
|
||||
|
@@ -23,6 +23,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "navigatorsearchwidget.h"
|
||||
#include "navigatorwidget.h"
|
||||
#include "navigatorview.h"
|
||||
|
||||
@@ -160,6 +161,10 @@ QToolBar *NavigatorWidget::createToolBar()
|
||||
for (auto toolButton : buttons)
|
||||
toolBar->addWidget(toolButton);
|
||||
|
||||
m_searchWidget = new NavigatorSearchWidget();
|
||||
connect(m_searchWidget, &NavigatorSearchWidget::textChanged, this, &NavigatorWidget::textFilterChanged);
|
||||
toolBar->addWidget(m_searchWidget);
|
||||
|
||||
return toolBar;
|
||||
}
|
||||
|
||||
@@ -211,4 +216,9 @@ QByteArray NavigatorWidget::dragType() const
|
||||
return m_dragType;
|
||||
}
|
||||
|
||||
void NavigatorWidget::clearSearch()
|
||||
{
|
||||
m_searchWidget->clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -39,6 +39,7 @@ QT_FORWARD_DECLARE_CLASS(QAbstractItemModel)
|
||||
namespace QmlDesigner {
|
||||
|
||||
class NavigatorView;
|
||||
class NavigatorSearchWidget;
|
||||
|
||||
class NavigatorWidget: public QFrame
|
||||
{
|
||||
@@ -59,6 +60,8 @@ public:
|
||||
void setDragType(const QByteArray &type);
|
||||
QByteArray dragType() const;
|
||||
|
||||
void clearSearch();
|
||||
|
||||
signals:
|
||||
void leftButtonClicked();
|
||||
void rightButtonClicked();
|
||||
@@ -66,6 +69,7 @@ signals:
|
||||
void downButtonClicked();
|
||||
void filterToggled(bool);
|
||||
void reverseOrderToggled(bool);
|
||||
void textFilterChanged(const QString &name);
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
||||
@@ -77,6 +81,7 @@ private:
|
||||
NavigatorTreeView *m_treeView;
|
||||
QPointer<NavigatorView> m_navigatorView;
|
||||
QByteArray m_dragType;
|
||||
NavigatorSearchWidget *m_searchWidget;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -680,6 +680,8 @@ Project {
|
||||
"navigator/nameitemdelegate.cpp",
|
||||
"navigator/nameitemdelegate.h",
|
||||
"navigator/navigator.qrc",
|
||||
"navigator/navigatorsearchwidget.cpp",
|
||||
"navigator/navigatorsearchwidget.h",
|
||||
"navigator/navigatortreemodel.cpp",
|
||||
"navigator/navigatortreemodel.h",
|
||||
"navigator/navigatortreeview.cpp",
|
||||
|
Reference in New Issue
Block a user