diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml index c7619526934..7d007cc7e35 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml @@ -27,38 +27,61 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 import QtQuickDesignerTheme 1.0 import HelperWidgets 2.0 +import StudioControls 1.0 as StudioControls import StudioTheme 1.0 as StudioTheme /* The view displaying the item grid. The following Qml context properties have to be set: -- listmodel itemLibraryModel +- ItemLibraryModel listmodel - int itemLibraryIconWidth - int itemLibraryIconHeight -itemLibraryModel has to have the following structure: +itemLibraryModel structure: -ListModel { -ListElement { -int sectionLibId -string sectionName -list sectionEntries: [ -ListElement { -int itemLibId -string itemName -pixmap itemPixmap -}, -... +itemLibraryModel [ + ItemLibraryImport { + string importName + string importUrl + bool importVisible + bool importUsed + bool importExpanded + + list categoryModel [ + ItemLibraryCategory { + string categoryName + bool categoryVisible + bool categoryExpanded + + list itemModel [ + ItemLibraryItem { + string itemName + string itemLibraryIconPath + bool itemVisible + string componentPath + var itemLibraryEntry + }, + ... more items + ] + }, + ... more categories + ] + }, + ... more imports ] -} -... -} */ - ScrollView { id: itemsView + property string importToRemove: "" + + // called from C++ to close context menu on focus out + function closeContextMenu() + { + contextMenu.close() + } + Item { id: styleConstants property int textWidth: 58 @@ -71,35 +94,77 @@ ScrollView { // the following depend on the actual shape of the item delegate property int cellWidth: textWidth + 2 * cellHorizontalMargin property int cellHeight: itemLibraryIconHeight + textHeight + - 2 * cellVerticalMargin + cellVerticalSpacing + 2 * cellVerticalMargin + cellVerticalSpacing + + StudioControls.Menu { + id: contextMenu + + StudioControls.MenuItem { + text: qsTr("Remove Library") + enabled: importToRemove !== "" + && importToRemove !== "QtQuick" + onTriggered: rootView.removeImport(importToRemove) + } + } } Column { - id: column + spacing: 2 Repeater { model: itemLibraryModel // to be set in Qml context delegate: Section { width: itemsView.width - - (itemsView.verticalScrollBarVisible ? StudioTheme.Values.scrollBarThickness : 0) - caption: sectionName // to be set by model - visible: sectionVisible - topPadding: 2 - leftPadding: 2 - rightPadding: 1 - expanded: sectionExpanded - onExpandedChanged: itemLibraryModel.setExpanded(expanded, sectionName); - Grid { - id: itemGrid - - columns: parent.width / styleConstants.cellWidth - property int flexibleWidth: (parent.width - styleConstants.cellWidth * columns) / columns + (itemsView.verticalScrollBarVisible ? itemsView.verticalThickness : 0) + caption: importName + visible: importVisible + sectionHeight: 30 + sectionFontSize: 15 + showArrow: categoryModel.rowCount() > 0 + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + expanded: importExpanded + onExpandedChanged: itemLibraryModel.setExpanded(expanded, importUrl); + onShowContextMenu: { + importToRemove = importUsed ? "" : importUrl + contextMenu.popup() + } + Column { + spacing: 2 Repeater { - model: sectionEntries - delegate: ItemDelegate { - visible: itemVisible - width: styleConstants.cellWidth + itemGrid.flexibleWidth - height: styleConstants.cellHeight + model: categoryModel + delegate: Section { + width: itemsView.width - + (itemsView.verticalScrollBarVisible ? itemsView.verticalThickness : 0) + sectionBackgroundColor: "transparent" + showTopSeparator: index > 0 + hideHeader: categoryModel.rowCount() <= 1 + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + caption: categoryName + " (" + itemModel.rowCount() + ")" + visible: categoryVisible + expanded: categoryExpanded + onExpandedChanged: itemLibraryModel.setExpanded(expanded, categoryName); + + Grid { + id: itemGrid + + columns: parent.width / styleConstants.cellWidth + property int flexibleWidth: (parent.width - styleConstants.cellWidth * columns) / columns + + Repeater { + model: itemModel + delegate: ItemDelegate { + visible: itemVisible + width: styleConstants.cellWidth + itemGrid.flexibleWidth + height: styleConstants.cellHeight + } + } + } } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ScrollView.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ScrollView.qml index c101bff09c7..e9ef50386ed 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ScrollView.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ScrollView.qml @@ -32,8 +32,9 @@ Flickable { property alias horizontalThickness: horizontalScrollBar.height property alias verticalThickness: verticalScrollBar.width - property bool bothVisible: verticalScrollBar.scrollBarVisible - && horizontalScrollBar.scrollBarVisible + property bool verticalScrollBarVisible: verticalScrollBar.scrollBarVisible + property bool horizontalScrollBarVisible: horizontalScrollBar.scrollBarVisible + property bool bothVisible: verticalScrollBarVisible && horizontalScrollBarVisible contentWidth: areaItem.childrenRect.width contentHeight: areaItem.childrenRect.height diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml index 58fe3cf3d02..6f19bd00f37 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml @@ -32,6 +32,12 @@ import StudioTheme 1.0 as StudioTheme Item { id: section property alias caption: label.text + property alias sectionHeight: header.height + property alias sectionBackgroundColor: header.color + property alias sectionFontSize: label.font.pixelSize + property alias showTopSeparator: topSeparator.visible + property alias showArrow: arrow.visible + property int leftPadding: 8 property int topPadding: 4 property int rightPadding: 0 @@ -42,9 +48,18 @@ Item { property bool expanded: true property int level: 0 property int levelShift: 10 + property bool hideHeader: false + + onHideHeaderChanged: + { + header.visible = !hideHeader + header.height = hideHeader ? 0 : 20 + } clip: true + signal showContextMenu() + Rectangle { id: header height: 20 @@ -80,13 +95,29 @@ Item { MouseArea { id: mouseArea anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: { - section.animationDuration = 120 - section.expanded = !section.expanded + if (mouse.button === Qt.LeftButton) { + section.animationDuration = 120 + section.expanded = !section.expanded + } else { + section.showContextMenu() + } } } } + Rectangle { + id: topSeparator + height: 1 + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: 5 + leftPadding + anchors.leftMargin: 5 - leftPadding + visible: false + color: "#666666" + } + default property alias __content: row.children readonly property alias contentItem: row diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 72fb68836cc..8cdc542ae4e 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -285,16 +285,6 @@ extend_qtc_plugin(QmlDesigner transitiontool.cpp transitiontool.h ) -extend_qtc_plugin(QmlDesigner - SOURCES_PREFIX components/importmanager - SOURCES - importlabel.cpp importlabel.h - importmanager.qrc - importmanagercombobox.cpp importmanagercombobox.h - importmanagerview.cpp importmanagerview.h - importswidget.cpp importswidget.h -) - extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/integration PUBLIC_INCLUDES components/integration @@ -316,14 +306,17 @@ extend_qtc_plugin(QmlDesigner itemlibraryitem.cpp itemlibraryitem.h itemlibrarymodel.cpp itemlibrarymodel.h itemlibraryresourceview.cpp itemlibraryresourceview.h - itemlibrarysection.cpp itemlibrarysection.h - itemlibrarysectionmodel.cpp itemlibrarysectionmodel.h + itemlibrarycategory.cpp itemlibrarycategory.h + itemlibraryitemsmodel.cpp itemlibraryitemsmodel.h itemlibraryview.cpp itemlibraryview.h itemlibrarywidget.cpp itemlibrarywidget.h itemlibraryassetimportdialog.cpp itemlibraryassetimportdialog.h itemlibraryassetimportdialog.ui itemlibraryassetimporter.cpp itemlibraryassetimporter.h itemlibraryiconimageprovider.cpp itemlibraryiconimageprovider.h + itemLibraryimport.cpp itemLibraryimport.h + itemLibrarycategoriesmodel.cpp itemLibrarycategoriesmodel.h + itemlibraryaddimportmodel.cpp itemlibraryaddimportmodel.h ) extend_qtc_plugin(QmlDesigner diff --git a/src/plugins/qmldesigner/components/importmanager/importlabel.cpp b/src/plugins/qmldesigner/components/importmanager/importlabel.cpp deleted file mode 100644 index cd192460097..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importlabel.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "importlabel.h" -#include - -#include -#include -#include - -namespace QmlDesigner { - -ImportLabel::ImportLabel(QWidget *parent) : - QWidget(parent) -{ - auto layout = new QHBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - - - m_removeButton = new QPushButton(this); - m_removeButton->setIcon(Utils::Icons::CLOSE_TOOLBAR.icon()); - m_removeButton->setFlat(true); - m_removeButton->setMaximumWidth(20); - m_removeButton->setMaximumHeight(20); - m_removeButton->setFocusPolicy(Qt::NoFocus); - m_removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - m_removeButton->setToolTip(tr("Remove Import")); - connect(m_removeButton, &QAbstractButton::clicked, this, [this] { emit removeImport(m_import); }); - layout->addWidget(m_removeButton); - - m_importLabel = new QLabel(this); - layout->addWidget(m_importLabel); - - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); -} - -void ImportLabel::setImport(const Import &import) -{ - m_importLabel->setText(import.toString(false)); - - m_import = import; -} - -const Import ImportLabel::import() const -{ - return m_import; -} - -void ImportLabel::setReadOnly(bool readOnly) const -{ - m_removeButton->setDisabled(readOnly); - m_removeButton->setIcon(readOnly ? QIcon() - : Utils::Icons::CLOSE_TOOLBAR.icon()); -} - -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/importmanager/importlabel.h b/src/plugins/qmldesigner/components/importmanager/importlabel.h deleted file mode 100644 index 31a8c4c856c..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importlabel.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 -#include - -#include - -namespace QmlDesigner { - -class ImportLabel : public QWidget -{ - Q_OBJECT -public: - explicit ImportLabel(QWidget *parent = nullptr); - - void setImport(const Import &import); - const Import import() const; - void setReadOnly(bool) const; - -signals: - void removeImport(const Import &import); - -private: - Import m_import; - QLabel *m_importLabel; - QPushButton *m_removeButton; -}; - -} diff --git a/src/plugins/qmldesigner/components/importmanager/importmanager.css b/src/plugins/qmldesigner/components/importmanager/importmanager.css deleted file mode 100644 index 8eb646cdc60..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importmanager.css +++ /dev/null @@ -1,87 +0,0 @@ -QPushButton, QComboBox[editable="false"], -QComboBox[editable="true"] { - background-color: creatorTheme.QmlDesigner_BackgroundColorDarkAlternate; - border-width: 3; - font-size: creatorTheme.captionFontPixelSize; -} - -QPushButton:hover, QComboBox[editable="false"]:hover, -QComboBox[editable="true"]:hover, QMenuBar::item:hover { - background-color: creatorTheme.QmlDesigner_BackgroundColorDarkAlternate; - border-width: 3; -} - -QPushButton:pressed, QComboBox[editable="false"]:on, -QComboBox[editable="true"]:on, QMenuBar::item:on { - background-color: creatorTheme.QmlDesigner_BackgroundColorDarkAlternate; - border-width: 3; -} - -QComboBox -{ - font-size: creatorTheme.captionFontPixelSize; - color: white; - min-width: 60px; -} - -QComboBox[editable="false"] { - padding-left: 16px; - padding-right: 0px; - spacing: 2px; -} - -QFontComboBox { - padding-left: 16px; -} - -QComboBox[editable="false"]::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 12px; - border-left-style: solid; - border-left-color: black; - border-left-width: 0px; -} - -QComboBox[editable="false"]::down-arrow { - subcontrol-origin: content; - subcontrol-position: center; - position: relative; - right: 3px; -} - -QComboBox[editable="false"]::down-arrow:on { - position: relative; - top: 1px; -} - -QComboBox[editable="true"] { - padding-right: 10px; -} - -QComboBox[editable="true"]::drop-down { - subcontrol-origin: border; - subcontrol-position: top right; - width: 13px; - position: absolute; - top: 2px; - bottom: 2px; - right: 2px; -} - -QComboBox[editable="true"]::drop-down, -QComboBox[editable="true"]::drop-down:hover, -QComboBox[editable="true"]::drop-down:on { - border-width: 0px; - border-left-width: 3px; -} - -QComboBox[editable="true"]::down-arrow:on { - position: relative; - top: 1px; - left: 1px; -} - -QComboBox::disabled { - color: gray; -} diff --git a/src/plugins/qmldesigner/components/importmanager/importmanager.pri b/src/plugins/qmldesigner/components/importmanager/importmanager.pri deleted file mode 100644 index 5d0ccd25d63..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importmanager.pri +++ /dev/null @@ -1,16 +0,0 @@ -VPATH += $$PWD - -HEADERS += importmanagerview.h \ - components/importmanager/importlabel.h \ - components/importmanager/importmanagercombobox.h -HEADERS += importswidget.h - -SOURCES += importmanagerview.cpp \ - components/importmanager/importlabel.cpp \ - components/importmanager/importmanagercombobox.cpp -SOURCES += components/importmanager/importswidget.cpp - -RESOURCES += \ - components/importmanager/importmanager.qrc - - diff --git a/src/plugins/qmldesigner/components/importmanager/importmanager.qrc b/src/plugins/qmldesigner/components/importmanager/importmanager.qrc deleted file mode 100644 index 5e3b6be1dcd..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importmanager.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - importmanager.css - - diff --git a/src/plugins/qmldesigner/components/importmanager/importmanagercombobox.cpp b/src/plugins/qmldesigner/components/importmanager/importmanagercombobox.cpp deleted file mode 100644 index b703f780c8b..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importmanagercombobox.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "importmanagercombobox.h" - -#include - -#include -#include -#include - -ImportManagerComboBox::ImportManagerComboBox(QWidget *parent) : - QComboBox(parent) -{ - QStyle *style = QStyleFactory::create("fusion"); - setStyle(style); - setStyleSheet(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/importmanager/importmanager.css")))); - setToolTip(tr("Add new import")); -} - -void ImportManagerComboBox::paintEvent(QPaintEvent *) -{ - QStylePainter painter(this); - painter.setPen(palette().color(QPalette::Text)); - - // draw the combobox frame, focusrect and selected etc. - QStyleOptionComboBox opt; - initStyleOption(&opt); - - opt.currentText = tr(""); - - painter.drawComplexControl(QStyle::CC_ComboBox, opt); - - // draw the icon and text - painter.drawControl(QStyle::CE_ComboBoxLabel, opt); -} diff --git a/src/plugins/qmldesigner/components/importmanager/importmanagercombobox.h b/src/plugins/qmldesigner/components/importmanager/importmanagercombobox.h deleted file mode 100644 index 350a2fcb832..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importmanagercombobox.h +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 - -class ImportManagerComboBox : public QComboBox -{ - Q_OBJECT -public: - explicit ImportManagerComboBox(QWidget *parent = nullptr); - -protected: - void paintEvent(QPaintEvent *e) override; -}; diff --git a/src/plugins/qmldesigner/components/importmanager/importmanagerview.cpp b/src/plugins/qmldesigner/components/importmanager/importmanagerview.cpp deleted file mode 100644 index 941cd2e7d42..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importmanagerview.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "importmanagerview.h" -#include "importswidget.h" - -#include -#include -#include - -namespace QmlDesigner { - -ImportManagerView::ImportManagerView(QObject *parent) - : AbstractView(parent) -{ -} - -ImportManagerView::~ImportManagerView() = default; - -bool ImportManagerView::hasWidget() const -{ - return true; -} - -WidgetInfo ImportManagerView::widgetInfo() -{ - if (m_importsWidget == nullptr) { - m_importsWidget = new ImportsWidget; - connect(m_importsWidget.data(), &ImportsWidget::removeImport, this, &ImportManagerView::removeImport); - connect(m_importsWidget.data(), &ImportsWidget::addImport, this, &ImportManagerView::addImport); - - if (model()) - m_importsWidget->setImports(model()->imports()); - } - - return createWidgetInfo(m_importsWidget, nullptr, QLatin1String("ImportManager"), WidgetInfo::LeftPane, 1, tr("Import Manager")); -} - -void ImportManagerView::modelAttached(Model *model) -{ - AbstractView::modelAttached(model); - - if (m_importsWidget) { - m_importsWidget->setImports(model->imports()); - m_importsWidget->setPossibleImports(model->possibleImports()); - m_importsWidget->setUsedImports(model->usedImports()); - } -} - -void ImportManagerView::modelAboutToBeDetached(Model *model) -{ - if (m_importsWidget) { - m_importsWidget->removeImports(); - m_importsWidget->removePossibleImports(); - m_importsWidget->removeUsedImports(); - } - - AbstractView::modelAboutToBeDetached(model); -} - -void ImportManagerView::importsChanged(const QList &addedImports, const QList &removedImports) -{ - Q_UNUSED(addedImports); - Q_UNUSED(removedImports); - if (m_importsWidget) { - m_importsWidget->setImports(model()->imports()); - // setImports recreates labels, so we need to update used imports, as it is not guaranteed - // usedImportsChanged notification will come after this. - m_importsWidget->setUsedImports(model()->usedImports()); - // setPossibleImports done in response to possibleImportsChanged comes before importsChanged, - // which causes incorrect "already used" filtering to be applied to possible imports list, - // so update the possible imports list here, too. - m_importsWidget->setPossibleImports(model()->possibleImports()); - } -} - -void ImportManagerView::possibleImportsChanged(const QList &/*possibleImports*/) -{ - if (m_importsWidget) - m_importsWidget->setPossibleImports(model()->possibleImports()); -} - -void ImportManagerView::usedImportsChanged(const QList &/*usedImports*/) -{ - if (m_importsWidget) - m_importsWidget->setUsedImports(model()->usedImports()); -} - -void ImportManagerView::removeImport(const Import &import) -{ - try { - if (model()) - model()->changeImports({}, {import}); - } - catch (const RewritingException &e) { - e.showException(); - } -} - -void ImportManagerView::addImport(const Import &import) -{ - if (import.isLibraryImport() - && (import.url().startsWith("QtQuick") - || import.url().startsWith("SimulinkConnector"))) { - QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_IMPORT_ADDED - + import.toImportString()); - } - - try { - if (model()) - model()->changeImports({import}, {}); - } - catch (const RewritingException &e) { - e.showException(); - } - - QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager(); -} - -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/importmanager/importswidget.cpp b/src/plugins/qmldesigner/components/importmanager/importswidget.cpp deleted file mode 100644 index 283a0501150..00000000000 --- a/src/plugins/qmldesigner/components/importmanager/importswidget.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "importswidget.h" -#include "importlabel.h" -#include "importmanagercombobox.h" - -#include -#include -#include - -#include - -#include -#include - -namespace QmlDesigner { - -ImportsWidget::ImportsWidget(QWidget *parent) : - QWidget(parent) -{ - setWindowTitle(tr("Import Manager")); - m_addImportComboBox = new ImportManagerComboBox(this); - connect(m_addImportComboBox, QOverload::of(&QComboBox::activated), - this, &ImportsWidget::addSelectedImport); -} - -void ImportsWidget::removeImports() -{ - qDeleteAll(m_importLabels); - m_importLabels.clear(); - updateLayout(); -} - -static bool isImportAlreadyUsed(const Import &import, QList importLabels) -{ - foreach (ImportLabel *importLabel, importLabels) { - if (importLabel->import() == import) - return true; - } - - return false; -} - -static bool importLess(const Import &firstImport, const Import &secondImport) -{ - if (firstImport.url() == secondImport.url()) - return firstImport.toString() < secondImport.toString(); - - if (firstImport.url() == "QtQuick") - return true; - - if (secondImport.url() == "QtQuick") - return false; - - if (firstImport.isLibraryImport() && secondImport.isFileImport()) - return false; - - if (firstImport.isFileImport() && secondImport.isLibraryImport()) - return true; - - if (firstImport.isFileImport() && secondImport.isFileImport()) - return QString::localeAwareCompare(firstImport.file(), secondImport.file()) < 0; - - if (firstImport.isLibraryImport() && secondImport.isLibraryImport()) - return QString::localeAwareCompare(firstImport.url(), secondImport.url()) < 0; - - return false; -} - -void ImportsWidget::setPossibleImports(QList possibleImports) -{ - Utils::sort(possibleImports, importLess); - m_addImportComboBox->clear(); - - const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); - const bool isQtForMCUs = mcuManager.isMCUProject(); - - QList filteredImports; - - const QStringList mcuAllowedList = mcuManager.allowedImports(); - const QStringList mcuBannedList = mcuManager.bannedImports(); - - if (isQtForMCUs) { - filteredImports = Utils::filtered(possibleImports, - [mcuAllowedList, mcuBannedList](const Import &import) { - return (mcuAllowedList.contains(import.url()) - || !import.url().startsWith("Qt")) - && !mcuBannedList.contains(import.url()); - }); - } else { - filteredImports = possibleImports; - } - - for (const Import &possibleImport : filteredImports) { - if (!isImportAlreadyUsed(possibleImport, m_importLabels)) - m_addImportComboBox->addItem(possibleImport.toString(true), QVariant::fromValue(possibleImport)); - } -} - -void ImportsWidget::removePossibleImports() -{ - m_addImportComboBox->clear(); -} - -void ImportsWidget::setUsedImports(const QList &usedImports) -{ - const QStringList excludeList = {"SimulinkConnector"}; - - // exclude imports in the excludeList from being readonly (i.e. always enable their x button) - QList filteredImports = Utils::filtered(usedImports, [excludeList](const Import &import) { - return !excludeList.contains(import.url()); - }); - - foreach (ImportLabel *importLabel, m_importLabels) - importLabel->setReadOnly(filteredImports.contains(importLabel->import())); -} - -void ImportsWidget::removeUsedImports() -{ - foreach (ImportLabel *importLabel, m_importLabels) - importLabel->setEnabled(true); -} - -void ImportsWidget::setImports(const QList &imports) -{ - qDeleteAll(m_importLabels); - m_importLabels.clear(); - - QList sortedImports = imports; - - Utils::sort(sortedImports, importLess); - - foreach (const Import &import, sortedImports) { - auto importLabel = new ImportLabel(this); - importLabel->setImport(import); - m_importLabels.append(importLabel); - connect(importLabel, &ImportLabel::removeImport, this, &ImportsWidget::removeImport); - } - - updateLayout(); -} - - -void ImportsWidget::updateLayout() -{ - delete layout(); - - auto layout = new QVBoxLayout(this); - layout->setSpacing(0); - - layout->addWidget(m_addImportComboBox); - - foreach (ImportLabel *importLabel, m_importLabels) - layout->addWidget(importLabel); - - layout->addStretch(); -} - -void ImportsWidget::addSelectedImport(int addImportComboBoxIndex) -{ - Import selectedImport = m_addImportComboBox->itemData(addImportComboBoxIndex).value(); - - if (selectedImport.isEmpty()) - return; - - emit addImport(selectedImport); -} - -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/add.png b/src/plugins/qmldesigner/components/itemlibrary/images/add.png new file mode 100644 index 00000000000..1b9edadee58 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/add.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/add@2x.png b/src/plugins/qmldesigner/components/itemlibrary/images/add@2x.png new file mode 100644 index 00000000000..ba352300c65 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/add@2x.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/add_unselected.png b/src/plugins/qmldesigner/components/itemlibrary/images/add_unselected.png new file mode 100644 index 00000000000..8e237ce4a12 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/add_unselected.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/add_unselected@2x.png b/src/plugins/qmldesigner/components/itemlibrary/images/add_unselected@2x.png new file mode 100644 index 00000000000..8be6882f3d9 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/add_unselected@2x.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/down.png b/src/plugins/qmldesigner/components/itemlibrary/images/down.png new file mode 100644 index 00000000000..d2772546bc8 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/down.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/down@2x.png b/src/plugins/qmldesigner/components/itemlibrary/images/down@2x.png new file mode 100644 index 00000000000..a635f09e554 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/down@2x.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/tab_icon.png b/src/plugins/qmldesigner/components/itemlibrary/images/tab_icon.png new file mode 100644 index 00000000000..df8abc4b794 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/tab_icon.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/tab_icon@2x.png b/src/plugins/qmldesigner/components/itemlibrary/images/tab_icon@2x.png new file mode 100644 index 00000000000..a5adb189877 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/tab_icon@2x.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/x.png b/src/plugins/qmldesigner/components/itemlibrary/images/x.png new file mode 100644 index 00000000000..323d2a2911a Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/x.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/x@2x.png b/src/plugins/qmldesigner/components/itemlibrary/images/x@2x.png new file mode 100644 index 00000000000..18fa9a35f78 Binary files /dev/null and b/src/plugins/qmldesigner/components/itemlibrary/images/x@2x.png differ diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri index bb4ebaa5bb3..3f05f1ab0b1 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri @@ -7,9 +7,12 @@ HEADERS += itemlibraryview.h \ itemlibrarymodel.h \ itemlibraryresourceview.h \ itemlibraryimageprovider.h \ - itemlibrarysectionmodel.h \ itemlibraryitem.h \ - itemlibrarysection.h \ + itemlibrarycategory.h \ + itemlibraryitemsmodel.h \ + itemlibraryimport.h \ + itemlibrarycategoriesmodel.h \ + itemlibraryaddimportmodel.h \ itemlibraryassetimportdialog.h \ itemlibraryassetimporter.h \ customfilesystemmodel.h @@ -20,9 +23,12 @@ SOURCES += itemlibraryview.cpp \ itemlibrarymodel.cpp \ itemlibraryresourceview.cpp \ itemlibraryimageprovider.cpp \ - itemlibrarysectionmodel.cpp \ itemlibraryitem.cpp \ - itemlibrarysection.cpp \ + itemlibrarycategory.cpp \ + itemlibraryitemsmodel.cpp \ + itemlibraryimport.cpp \ + itemlibrarycategoriesmodel.cpp \ + itemlibraryaddimportmodel.cpp \ itemlibraryassetimportdialog.cpp \ itemlibraryassetimporter.cpp \ customfilesystemmodel.cpp diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc index aa1cc0b79d8..69ef5b2c1f8 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc @@ -29,5 +29,17 @@ images/asset_sound_192.png images/asset_sound_256.png images/asset_sound_384.png + images/tab_icon.png + images/tab_icon@2x.png + images/x.png + images/x@2x.png + images/add.png + images/add@2x.png + images/add_unselected.png + images/add_unselected@2x.png + images/down.png + images/down@2x.png + qml/libraryheader.qml + qml/addimport.qml diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp new file mode 100644 index 00000000000..377662b032b --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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 "itemlibraryaddimportmodel.h" + +#include +#include + +#include +#include +#include + +namespace QmlDesigner { + +ItemLibraryAddImportModel::ItemLibraryAddImportModel(QObject *parent) + : QAbstractListModel(parent) +{ + // add role names + m_roleNames.insert(Qt::UserRole + 1, "importUrl"); + m_roleNames.insert(Qt::UserRole + 2, "importVisible"); +} + +ItemLibraryAddImportModel::~ItemLibraryAddImportModel() +{ + +} + +int ItemLibraryAddImportModel::rowCount(const QModelIndex & /*parent*/) const +{ + return m_importList.count(); +} + +QVariant ItemLibraryAddImportModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= m_importList.count()) + return {}; + + QString importUrl = m_importList[index.row()].url(); + + if (m_roleNames[role] == "importUrl") + return importUrl; + + if (m_roleNames[role] == "importVisible") + return m_searchText.isEmpty() || m_importFilterList.contains(importUrl); + + qWarning() << Q_FUNC_INFO << "invalid role requested"; + + return {}; +} + +QHash ItemLibraryAddImportModel::roleNames() const +{ + return m_roleNames; +} + +void ItemLibraryAddImportModel::update(const QList &possibleImports) +{ + beginResetModel(); + m_importList.clear(); + + const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); + const bool isQtForMCUs = mcuManager.isMCUProject(); + QList filteredImports; + const QStringList mcuAllowedList = mcuManager.allowedImports(); + const QStringList mcuBannedList = mcuManager.bannedImports(); + if (isQtForMCUs) { + filteredImports = Utils::filtered(possibleImports, + [&](const Import &import) { + return (mcuAllowedList.contains(import.url()) + || !import.url().startsWith("Qt")) + && !mcuBannedList.contains(import.url()); + }); + } else { + filteredImports = possibleImports; + } + + Utils::sort(filteredImports, [](const Import &firstImport, const Import &secondImport) { + if (firstImport.url() == secondImport.url()) + return firstImport.toString() < secondImport.toString(); + + if (firstImport.url() == "QtQuick") + return true; + + if (secondImport.url() == "QtQuick") + return false; + + if (firstImport.isLibraryImport() && secondImport.isFileImport()) + return false; + + if (firstImport.isFileImport() && secondImport.isLibraryImport()) + return true; + + if (firstImport.isFileImport() && secondImport.isFileImport()) + return QString::localeAwareCompare(firstImport.file(), secondImport.file()) < 0; + + if (firstImport.isLibraryImport() && secondImport.isLibraryImport()) + return QString::localeAwareCompare(firstImport.url(), secondImport.url()) < 0; + + return false; + }); + + // create import sections + for (const Import &import : std::as_const(filteredImports)) { + if (import.isLibraryImport()) + m_importList.append(import); + } + + endResetModel(); +} + +void ItemLibraryAddImportModel::setSearchText(const QString &searchText) +{ + QString lowerSearchText = searchText.toLower(); + + if (m_searchText != lowerSearchText) { + beginResetModel(); + m_searchText = lowerSearchText; + + for (const Import &import : std::as_const(m_importList)) { + if (import.url().toLower().contains(lowerSearchText)) + m_importFilterList.insert(import.url()); + else + m_importFilterList.remove(import.url()); + } + endResetModel(); + } +} + +Import ItemLibraryAddImportModel::getImportAt(int index) const +{ + return m_importList.at(index); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/importmanager/importswidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h similarity index 62% rename from src/plugins/qmldesigner/components/importmanager/importswidget.h rename to src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h index 22603f9bc09..bab5ecf73c5 100644 --- a/src/plugins/qmldesigner/components/importmanager/importswidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -25,46 +25,36 @@ #pragma once +#include #include -#include - -QT_BEGIN_NAMESPACE -class QComboBox; -QT_END_NAMESPACE +#include namespace QmlDesigner { -class ImportLabel; +class ItemLibraryEntry; -class ImportsWidget : public QWidget +class ItemLibraryAddImportModel : public QAbstractListModel { Q_OBJECT + public: - explicit ImportsWidget(QWidget *parent = nullptr); + explicit ItemLibraryAddImportModel(QObject *parent = nullptr); + ~ItemLibraryAddImportModel() override; - void setImports(const QList &imports); - void removeImports(); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; - void setPossibleImports(QList possibleImports); - void removePossibleImports(); - - void setUsedImports(const QList &possibleImports); - void removeUsedImports(); - -signals: - void removeImport(const Import &import); - void addImport(const Import &import); - -protected: - void updateLayout(); + void update(const QList &possibleImports); + void setSearchText(const QString &searchText); + Import getImportAt(int index) const; private: - void addSelectedImport(int addImportComboBoxIndex); - -private: - QList m_importLabels; - QComboBox *m_addImportComboBox; + QString m_searchText; + QList m_importList; + QSet m_importFilterList; + QHash m_roleNames; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp new file mode 100644 index 00000000000..f104cb978fb --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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 "itemlibrarycategoriesmodel.h" +#include "itemlibrarycategory.h" + +#include +#include + +#include +#include +#include + +namespace QmlDesigner { + +ItemLibraryCategoriesModel::ItemLibraryCategoriesModel(QObject *parent) : + QAbstractListModel(parent) +{ + addRoleNames(); +} + +ItemLibraryCategoriesModel::~ItemLibraryCategoriesModel() +{ +} + +int ItemLibraryCategoriesModel::rowCount(const QModelIndex &) const +{ + return m_categoryList.count(); +} + +QVariant ItemLibraryCategoriesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= m_categoryList.count()) { + qWarning() << Q_FUNC_INFO << "invalid index requested"; + return {}; + } + + if (m_roleNames.contains(role)) { + QVariant value = m_categoryList.at(index.row())->property(m_roleNames.value(role)); + + if (auto model = qobject_cast(value.value())) + return QVariant::fromValue(model); + + return value; + } + + qWarning() << Q_FUNC_INFO << "invalid role requested"; + + return {}; +} + +QHash ItemLibraryCategoriesModel::roleNames() const +{ + return m_roleNames; +} + +void ItemLibraryCategoriesModel::addCategory(ItemLibraryCategory *category) +{ + m_categoryList.append(category); + + category->setVisible(true); +} + +const QList> &ItemLibraryCategoriesModel::categorySections() const +{ + return m_categoryList; +} + +void ItemLibraryCategoriesModel::sortCategorySections() +{ + auto categorySort = [](ItemLibraryCategory *first, ItemLibraryCategory *second) { + return QString::localeAwareCompare(first->sortingName(), second->sortingName()) < 0; + }; + + std::sort(m_categoryList.begin(), m_categoryList.end(), categorySort); +} + +void ItemLibraryCategoriesModel::resetModel() +{ + beginResetModel(); + endResetModel(); +} + +void ItemLibraryCategoriesModel::addRoleNames() +{ + int role = 0; + const QMetaObject meta = ItemLibraryCategory::staticMetaObject; + for (int i = meta.propertyOffset(); i < meta.propertyCount(); ++i) + m_roleNames.insert(role++, meta.property(i).name()); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/importmanager/importmanagerview.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h similarity index 61% rename from src/plugins/qmldesigner/components/importmanager/importmanagerview.h rename to src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h index a79b53e5ad5..369f9c2002a 100644 --- a/src/plugins/qmldesigner/components/importmanager/importmanagerview.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -25,37 +25,39 @@ #pragma once -#include +#include "itemlibrarymodel.h" + +#include #include namespace QmlDesigner { -class ImportsWidget; +class ItemLibraryCategory; -class ImportManagerView : public AbstractView +class ItemLibraryCategoriesModel : public QAbstractListModel { Q_OBJECT public: - explicit ImportManagerView(QObject *parent = nullptr); - ~ImportManagerView() override; + ItemLibraryCategoriesModel(QObject *parent = nullptr); + ~ItemLibraryCategoriesModel() override; - bool hasWidget() const override; - WidgetInfo widgetInfo() override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; - void modelAttached(Model *model) override; - void modelAboutToBeDetached(Model *model) override; + void addCategory(ItemLibraryCategory *category); - void importsChanged(const QList &addedImports, const QList &removedImports) override; - void possibleImportsChanged(const QList &possibleImports) override; - void usedImportsChanged(const QList &usedImports) override; + const QList> &categorySections() const; + + void sortCategorySections(); + void resetModel(); private: - void removeImport(const Import &import); - void addImport(const Import &import); + void addRoleNames(); -private: - QPointer m_importsWidget; + QList> m_categoryList; + QHash m_roleNames; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp new file mode 100644 index 00000000000..cb244839bd0 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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 "itemlibrarycategory.h" + +#include "itemlibraryitem.h" + +namespace QmlDesigner { + +ItemLibraryCategory::ItemLibraryCategory(const QString &groupName, QObject *parent) + : QObject(parent), + m_name(groupName) +{ +} + +QString ItemLibraryCategory::categoryName() const +{ + return m_name; +} + +bool ItemLibraryCategory::categoryExpanded() const +{ + return m_categoryExpanded; +} + +QString ItemLibraryCategory::sortingName() const +{ + return categoryName(); +} + +void ItemLibraryCategory::addItem(ItemLibraryItem *itemEntry) +{ + m_itemModel.addItem(itemEntry); +} + +QObject *ItemLibraryCategory::itemModel() +{ + return &m_itemModel; +} + +bool ItemLibraryCategory::updateItemVisibility(const QString &searchText, bool *changed) +{ + bool hasVisibleItems = false; + + *changed = false; + + for (const auto &item : m_itemModel.items()) { + bool itemVisible = item->itemName().toLower().contains(searchText) + || item->typeName().toLower().contains(searchText); + + bool itemChanged = item->setVisible(itemVisible); + + *changed |= itemChanged; + + if (itemVisible) + hasVisibleItems = true; + } + + return hasVisibleItems; +} + +bool ItemLibraryCategory::setVisible(bool isVisible) +{ + if (isVisible != m_isVisible) { + m_isVisible = isVisible; + return true; + } + + return false; +} + +bool ItemLibraryCategory::isVisible() const +{ + return m_isVisible; +} + +void ItemLibraryCategory::sortItems() +{ + m_itemModel.sortItems(); +} + +void ItemLibraryCategory::setExpanded(bool expanded) +{ + m_categoryExpanded = expanded; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.h similarity index 61% rename from src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.h rename to src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.h index 8287f0fe234..944af3ba28b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -25,47 +25,49 @@ #pragma once -#include "itemlibrarysectionmodel.h" +#include "itemlibraryitemsmodel.h" namespace QmlDesigner { -class ItemLibrarySection: public QObject { +class ItemLibraryItem; +class ItemLibraryCategory : public QObject +{ Q_OBJECT - Q_PROPERTY(QObject* sectionEntries READ sectionEntries NOTIFY sectionEntriesChanged FINAL) - Q_PROPERTY(QString sectionName READ sectionName FINAL) - Q_PROPERTY(bool sectionVisible READ isVisible NOTIFY visibilityChanged FINAL) - Q_PROPERTY(bool sectionExpanded READ sectionExpanded FINAL) + Q_PROPERTY(QString categoryName READ categoryName FINAL) + Q_PROPERTY(bool categoryVisible READ isVisible NOTIFY visibilityChanged FINAL) + Q_PROPERTY(bool categoryExpanded READ categoryExpanded FINAL) + Q_PROPERTY(QObject *itemModel READ itemModel NOTIFY itemModelChanged FINAL) public: - ItemLibrarySection(const QString §ionName, QObject *parent = nullptr); + ItemLibraryCategory(const QString &groupName, QObject *parent = nullptr); - QString sectionName() const; - bool sectionExpanded() const; + QString categoryName() const; + bool categoryExpanded() const; QString sortingName() const; - void addSectionEntry(ItemLibraryItem *sectionEntry); - QObject *sectionEntries(); + void addItem(ItemLibraryItem *item); + QObject *itemModel(); - bool updateSectionVisibility(const QString &searchText, bool *changed); + bool updateItemVisibility(const QString &searchText, bool *changed); bool setVisible(bool isVisible); bool isVisible() const; void sortItems(); - void setSectionExpanded(bool expanded); + void setExpanded(bool expanded); signals: - void sectionEntriesChanged(); + void itemModelChanged(); void visibilityChanged(); private: - ItemLibrarySectionModel m_sectionEntries; + ItemLibraryItemsModel m_itemModel; QString m_name; - bool m_sectionExpanded; - bool m_isVisible; + bool m_categoryExpanded = true; + bool m_isVisible = true; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp new file mode 100644 index 00000000000..3afda6b0a72 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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 "itemlibraryimport.h" +#include "itemlibrarycategory.h" + +namespace QmlDesigner { + +ItemLibraryImport::ItemLibraryImport(const Import &import, QObject *parent) + : QObject(parent), + m_import(import) +{ +} + +QString ItemLibraryImport::importName() const +{ + if (importUrl().isEmpty()) + return userComponentsTitle(); + + if (importUrl() == "QtQuick") + return tr("Default Components"); + + return importUrl().replace('.', ' '); +} + +QString ItemLibraryImport::importUrl() const +{ + return m_import.url(); +} + +bool ItemLibraryImport::importExpanded() const +{ + return m_importExpanded; +} + +QString ItemLibraryImport::sortingName() const +{ + if (importName() == userComponentsTitle()) // user components always come first + return "_"; + + return importName(); +} + +void ItemLibraryImport::addCategory(ItemLibraryCategory *category) +{ + m_categoryModel.addCategory(category); +} + +QObject *ItemLibraryImport::categoryModel() +{ + return &m_categoryModel; +} + +bool ItemLibraryImport::updateCategoryVisibility(const QString &searchText, bool *changed) +{ + bool hasVisibleItems = false; + + *changed = false; + + for (const auto &category : m_categoryModel.categorySections()) { + bool categoryChanged = false; + hasVisibleItems = category->updateItemVisibility(searchText, &categoryChanged); + categoryChanged |= category->setVisible(hasVisibleItems); + + *changed |= categoryChanged; + *changed |= hasVisibleItems; + } + + if (*changed) + m_categoryModel.resetModel(); + + return hasVisibleItems; +} + +Import ItemLibraryImport::importEntry() const +{ + return m_import; +} + +bool ItemLibraryImport::setVisible(bool isVisible) +{ + if (isVisible != m_isVisible) { + m_isVisible = isVisible; + return true; + } + + return false; +} + +bool ItemLibraryImport::isVisible() const +{ + return m_isVisible; +} + +void ItemLibraryImport::setImportUsed(bool importUsed) +{ + m_importUsed = importUsed; +} + +bool ItemLibraryImport::isImportUsed() const +{ + return m_importUsed; +} + +void ItemLibraryImport::sortCategorySections() +{ + m_categoryModel.sortCategorySections(); +} + +void ItemLibraryImport::setExpanded(bool expanded) +{ + m_importExpanded = expanded; +} + +ItemLibraryCategory *ItemLibraryImport::getCategorySection(const QString &categoryName) const +{ + for (ItemLibraryCategory *catSec : std::as_const(m_categoryModel.categorySections())) { + if (catSec->categoryName() == categoryName) + return catSec; + } + + return nullptr; +} + +// static +QString ItemLibraryImport::userComponentsTitle() +{ + return tr("My Components"); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h new file mode 100644 index 00000000000..344ceb5f090 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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 "itemlibrarycategoriesmodel.h" +#include "import.h" + +namespace QmlDesigner { + +class ItemLibraryCategory; + +class ItemLibraryImport : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString importName READ importName FINAL) + Q_PROPERTY(QString importUrl READ importUrl FINAL) + Q_PROPERTY(bool importVisible READ isVisible NOTIFY visibilityChanged FINAL) + Q_PROPERTY(bool importUsed READ isImportUsed NOTIFY importUsedChanged FINAL) + Q_PROPERTY(bool importExpanded READ importExpanded FINAL) + Q_PROPERTY(QObject *categoryModel READ categoryModel NOTIFY categoryModelChanged FINAL) + +public: + ItemLibraryImport(const Import &import, QObject *parent = nullptr); + + QString importName() const; + QString importUrl() const; + bool importExpanded() const; + QString sortingName() const; + Import importEntry() const; + bool isVisible() const; + bool isImportUsed() const; + ItemLibraryCategory *getCategorySection(const QString &categoryName) const; + + void addCategory(ItemLibraryCategory *category); + QObject *categoryModel(); + bool updateCategoryVisibility(const QString &searchText, bool *changed); + bool setVisible(bool isVisible); + void setImportUsed(bool importUsed); + void sortCategorySections(); + void setExpanded(bool expanded); + + static QString userComponentsTitle(); + +signals: + void categoryModelChanged(); + void visibilityChanged(); + void importUsedChanged(); + +private: + Import m_import; + bool m_importExpanded = true; + bool m_isVisible = true; + bool m_importUsed = false; + ItemLibraryCategoriesModel m_categoryModel; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp index 0d46140f12e..31d5edb57cf 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp @@ -27,9 +27,9 @@ namespace QmlDesigner { -ItemLibraryItem::ItemLibraryItem(QObject *parent) +ItemLibraryItem::ItemLibraryItem(const ItemLibraryEntry &itemLibraryEntry, QObject *parent) : QObject(parent), - m_isVisible(true) + m_itemLibraryEntry(itemLibraryEntry) { } @@ -77,11 +77,6 @@ bool ItemLibraryItem::isVisible() const return m_isVisible; } -void ItemLibraryItem::setItemLibraryEntry(const ItemLibraryEntry &itemLibraryEntry) -{ - m_itemLibraryEntry = itemLibraryEntry; -} - QVariant ItemLibraryItem::itemLibraryEntry() const { return QVariant::fromValue(m_itemLibraryEntry); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h index 859cbe51dd0..d7321b11794 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h @@ -34,8 +34,8 @@ namespace QmlDesigner { -class ItemLibraryItem: public QObject { - +class ItemLibraryItem: public QObject +{ Q_OBJECT Q_PROPERTY(QVariant itemLibraryEntry READ itemLibraryEntry FINAL) @@ -45,7 +45,7 @@ class ItemLibraryItem: public QObject { Q_PROPERTY(QString componentPath READ componentPath FINAL) public: - ItemLibraryItem(QObject *parent); + ItemLibraryItem(const ItemLibraryEntry &itemLibraryEntry, QObject *parent); ~ItemLibraryItem() override; QString itemName() const; @@ -56,7 +56,6 @@ public: bool setVisible(bool isVisible); bool isVisible() const; - void setItemLibraryEntry(const ItemLibraryEntry &itemLibraryEntry); QVariant itemLibraryEntry() const; signals: @@ -64,7 +63,7 @@ signals: private: ItemLibraryEntry m_itemLibraryEntry; - bool m_isVisible; + bool m_isVisible = true; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitemsmodel.cpp similarity index 62% rename from src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp rename to src/plugins/qmldesigner/components/itemlibrary/itemlibraryitemsmodel.cpp index 413ef7f3e8c..b9530917241 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitemsmodel.cpp @@ -23,70 +23,62 @@ ** ****************************************************************************/ -#include "itemlibrarysectionmodel.h" - +#include "itemlibraryitemsmodel.h" #include "itemlibraryitem.h" - #include - #include +#include namespace QmlDesigner { -ItemLibrarySectionModel::ItemLibrarySectionModel(QObject *parent) : +ItemLibraryItemsModel::ItemLibraryItemsModel(QObject *parent) : QAbstractListModel(parent) { addRoleNames(); } -ItemLibrarySectionModel::~ItemLibrarySectionModel() +ItemLibraryItemsModel::~ItemLibraryItemsModel() { } -int ItemLibrarySectionModel::rowCount(const QModelIndex &) const +int ItemLibraryItemsModel::rowCount(const QModelIndex &) const { return m_itemList.count(); } -QVariant ItemLibrarySectionModel::data(const QModelIndex &index, int role) const +QVariant ItemLibraryItemsModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() + 1 > m_itemList.count()) { + if (!index.isValid() || index.row() >= m_itemList.count()) { qDebug() << Q_FUNC_INFO << "invalid index requested"; - return QVariant(); + return {}; } - if (m_roleNames.contains(role)) { - QVariant value = m_itemList.at(index.row())->property(m_roleNames.value(role)); - - if (auto model = qobject_cast(value.value())) - return QVariant::fromValue(model); - + if (m_roleNames.contains(role)) return m_itemList.at(index.row())->property(m_roleNames.value(role)); - } qWarning() << Q_FUNC_INFO << "invalid role requested"; - return QVariant(); + return {}; } -QHash ItemLibrarySectionModel::roleNames() const +QHash ItemLibraryItemsModel::roleNames() const { return m_roleNames; } -void ItemLibrarySectionModel::addItem(ItemLibraryItem *element) +void ItemLibraryItemsModel::addItem(ItemLibraryItem *element) { m_itemList.append(element); element->setVisible(true); } -const QList> &ItemLibrarySectionModel::items() const +const QList> &ItemLibraryItemsModel::items() const { return m_itemList; } -void ItemLibrarySectionModel::sortItems() +void ItemLibraryItemsModel::sortItems() { int nullPointerSectionCount = m_itemList.removeAll(QPointer()); QTC_ASSERT(nullPointerSectionCount == 0,;); @@ -97,20 +89,18 @@ void ItemLibrarySectionModel::sortItems() std::sort(m_itemList.begin(), m_itemList.end(), itemSort); } -void ItemLibrarySectionModel::resetModel() +void ItemLibraryItemsModel::resetModel() { beginResetModel(); endResetModel(); } -void ItemLibrarySectionModel::addRoleNames() +void ItemLibraryItemsModel::addRoleNames() { int role = 0; - for (int propertyIndex = 0; propertyIndex < ItemLibraryItem::staticMetaObject.propertyCount(); ++propertyIndex) { - QMetaProperty property = ItemLibraryItem::staticMetaObject.property(propertyIndex); - m_roleNames.insert(role, property.name()); - ++role; - } + const QMetaObject meta = ItemLibraryItem::staticMetaObject; + for (int i = meta.propertyOffset(); i < meta.propertyCount(); ++i) + m_roleNames.insert(role++, meta.property(i).name()); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitemsmodel.h similarity index 83% rename from src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.h rename to src/plugins/qmldesigner/components/itemlibrary/itemlibraryitemsmodel.h index 4995e0c8c58..3d8459508da 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysectionmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitemsmodel.h @@ -25,8 +25,7 @@ #pragma once -#include "itemlibrarymodel.h" - +#include #include #include @@ -34,13 +33,13 @@ namespace QmlDesigner { class ItemLibraryItem; -class ItemLibrarySectionModel: public QAbstractListModel { - +class ItemLibraryItemsModel : public QAbstractListModel +{ Q_OBJECT public: - ItemLibrarySectionModel(QObject *parent = nullptr); - ~ItemLibrarySectionModel() override; + ItemLibraryItemsModel(QObject *parent = nullptr); + ~ItemLibraryItemsModel() override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; @@ -48,19 +47,16 @@ public: void addItem(ItemLibraryItem *item); - const QList > &items() const; + const QList> &items() const; void sortItems(); void resetModel(); -private: // functions +private: void addRoleNames(); -private: // variables QList> m_itemList; QHash m_roleNames; }; } // namespace QmlDesigner - -QML_DECLARE_TYPE(QmlDesigner::ItemLibrarySectionModel) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index a01ce38fc72..949e974afde 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -24,17 +24,16 @@ ****************************************************************************/ #include "itemlibrarymodel.h" -#include "itemlibraryinfo.h" -#include "itemlibrarysection.h" +#include "itemlibrarycategoriesmodel.h" +#include "itemlibraryimport.h" +#include "itemlibrarycategory.h" #include "itemlibraryitem.h" -#include "itemlibrarysection.h" +#include "itemlibraryinfo.h" #include #include #include -#include -#include #include #include @@ -44,29 +43,18 @@ #include #include #include -#include -#include -#include - -static Q_LOGGING_CATEGORY(itemlibraryPopulate, "qtc.itemlibrary.populate", QtWarningMsg) - -static bool inline registerItemLibrarySortedModel() { - qmlRegisterAnonymousType("ItemLibrarySectionModel", 1); - return true; -} namespace QmlDesigner { -static QHash collapsedStateHash; - - -void ItemLibraryModel::setExpanded(bool expanded, const QString §ion) +// sectionName can be an import or category section +void ItemLibraryModel::setExpanded(bool expanded, const QString §ionName) { - if (collapsedStateHash.contains(section)) - collapsedStateHash.remove(section); + collapsedStateHash.insert(sectionName, expanded); +} - if (!expanded) //default is true - collapsedStateHash.insert(section, expanded); +bool ItemLibraryModel::sectionExpanded(const QString §ionName) const +{ + return collapsedStateHash.value(sectionName, true); } void ItemLibraryModel::setFlowMode(bool b) @@ -89,32 +77,27 @@ ItemLibraryModel::~ItemLibraryModel() int ItemLibraryModel::rowCount(const QModelIndex & /*parent*/) const { - return m_sections.count(); + return m_importList.count(); } QVariant ItemLibraryModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() +1 > m_sections.count()) - return QVariant(); - + if (!index.isValid() || index.row() +1 > m_importList.count()) + return {}; if (m_roleNames.contains(role)) { - QVariant value = m_sections.at(index.row())->property(m_roleNames.value(role)); + QVariant value = m_importList.at(index.row())->property(m_roleNames.value(role)); - auto model = qobject_cast(value.value()); + auto model = qobject_cast(value.value()); if (model) return QVariant::fromValue(model); - auto model2 = qobject_cast(value.value()); - if (model2) - return QVariant::fromValue(model2); - return value; } qWarning() << Q_FUNC_INFO << "invalid role requested"; - return QVariant(); + return {}; } QHash ItemLibraryModel::roleNames() const @@ -127,19 +110,15 @@ QString ItemLibraryModel::searchText() const return m_searchText; } - void ItemLibraryModel::setSearchText(const QString &searchText) { QString lowerSearchText = searchText.toLower(); if (m_searchText != lowerSearchText) { m_searchText = lowerSearchText; - emit searchTextChanged(); bool changed = false; updateVisibility(&changed); - if (changed) - emit dataChanged(QModelIndex(), QModelIndex()); } } @@ -153,14 +132,6 @@ Import entryToImport(const ItemLibraryEntry &entry) } -bool sectionExapanded(const QString §ionName) -{ - if (collapsedStateHash.contains(sectionName)) - return collapsedStateHash.value(sectionName); - - return true; -} - void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) { if (!model) @@ -169,32 +140,24 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) beginResetModel(); clearSections(); - QStringList imports; - foreach (const Import &import, model->imports()) - if (import.isLibraryImport()) - imports << import.url() + QLatin1Char(' ') + import.version(); - - - qCInfo(itemlibraryPopulate) << Q_FUNC_INFO; - foreach (ItemLibraryEntry entry, itemLibraryInfo->entries()) { - - qCInfo(itemlibraryPopulate) << entry.typeName() << entry.majorVersion() << entry.minorVersion(); + // create import sections + for (const Import &import : model->imports()) { + if (import.isLibraryImport()) { + ItemLibraryImport *itemLibImport = new ItemLibraryImport(import, this); + m_importList.append(itemLibImport); + itemLibImport->setExpanded(sectionExpanded(import.url())); + } + } + const QList itemLibEntries = itemLibraryInfo->entries(); + for (const ItemLibraryEntry &entry : itemLibEntries) { NodeMetaInfo metaInfo = model->metaInfo(entry.typeName()); - qCInfo(itemlibraryPopulate) << "valid: " << metaInfo.isValid() << metaInfo.majorVersion() << metaInfo.minorVersion(); - bool valid = metaInfo.isValid() && metaInfo.majorVersion() == entry.majorVersion(); bool isItem = valid && metaInfo.isSubclassOf("QtQuick.Item"); - - qCInfo(itemlibraryPopulate) << "isItem: " << isItem; - - qCInfo(itemlibraryPopulate) << "required import: " << entry.requiredImport() << entryToImport(entry).toImportString(); - bool forceVisiblity = valid && NodeHints::fromItemLibraryEntry(entry).visibleInLibrary(); if (m_flowMode && metaInfo.isValid()) { - isItem = metaInfo.isSubclassOf("FlowView.FlowItem") || metaInfo.isSubclassOf("FlowView.FlowWildcard") || metaInfo.isSubclassOf("FlowView.FlowDecision"); @@ -202,7 +165,6 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) } const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); - if (mcuManager.isMCUProject()) { const QSet blockTypes = mcuManager.bannedItems(); @@ -210,22 +172,44 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) valid = false; } - if (valid && (isItem || forceVisiblity) //We can change if the navigator does support pure QObjects + if (valid && (isItem || forceVisiblity) // We can change if the navigator does support pure QObjects && (entry.requiredImport().isEmpty() || model->hasImport(entryToImport(entry), true, true))) { - QString itemSectionName = entry.category(); - qCInfo(itemlibraryPopulate) << "Adding:" << entry.typeName() << "to:" << entry.category(); - ItemLibrarySection *sectionModel = sectionByName(itemSectionName); - if (sectionModel == nullptr) { - sectionModel = new ItemLibrarySection(itemSectionName, this); - m_sections.append(sectionModel); - sectionModel->setSectionExpanded(sectionExapanded(itemSectionName)); + ItemLibraryImport *importSection = nullptr; + + QString catName = entry.category(); + if (catName == ItemLibraryImport::userComponentsTitle()) { + // create an import section for user components + importSection = importByUrl(ItemLibraryImport::userComponentsTitle()); + if (!importSection) { + importSection = new ItemLibraryImport({}, this); + m_importList.append(importSection); + importSection->setExpanded(sectionExpanded(catName)); + } + } else { + if (catName.startsWith("Qt Quick - ")) + catName = catName.mid(11); // remove "Qt Quick - " + + importSection = importByUrl(entry.requiredImport()); } - auto item = new ItemLibraryItem(sectionModel); - item->setItemLibraryEntry(entry); - sectionModel->addSectionEntry(item); + if (!importSection) { // should not happen, but just in case + qWarning() << __FUNCTION__ << "No import section found! skipping entry: " << entry.name(); + continue; + } + + // get or create category section + ItemLibraryCategory *categorySection = importSection->getCategorySection(catName); + if (!categorySection) { + categorySection = new ItemLibraryCategory(catName, importSection); + importSection->addCategory(categorySection); + categorySection->setExpanded(sectionExpanded(categorySection->categoryName())); + } + + // create item + auto item = new ItemLibraryItem(entry, categorySection); + categorySection->addItem(item); } } @@ -251,67 +235,68 @@ QMimeData *ItemLibraryModel::getMimeData(const ItemLibraryEntry &itemLibraryEntr void ItemLibraryModel::clearSections() { - qDeleteAll(m_sections); - m_sections.clear(); + qDeleteAll(m_importList); + m_importList.clear(); } void ItemLibraryModel::registerQmlTypes() { - qmlRegisterAnonymousType("ItemLibrarySectionModel", 1); qmlRegisterAnonymousType("ItemLibraryModel", 1); } -ItemLibrarySection *ItemLibraryModel::sectionByName(const QString §ionName) +ItemLibraryImport *ItemLibraryModel::importByUrl(const QString &importUrl) const { - foreach (ItemLibrarySection *itemLibrarySection, m_sections) { - if (itemLibrarySection->sectionName() == sectionName) - return itemLibrarySection; + for (ItemLibraryImport *itemLibraryImport : std::as_const(m_importList)) { + if (itemLibraryImport->importUrl() == importUrl + || (importUrl.isEmpty() && itemLibraryImport->importUrl() == "QtQuick") + || (importUrl == ItemLibraryImport::userComponentsTitle() + && itemLibraryImport->importName() == ItemLibraryImport::userComponentsTitle())) { + return itemLibraryImport; + } } return nullptr; } +void ItemLibraryModel::updateUsedImports(const QList &usedImports) +{ + // imports in the excludeList are not marked used and thus can always be removed even when in use. + const QList excludeList = {"SimulinkConnector"}; + + for (ItemLibraryImport *importSection : std::as_const(m_importList)) { + if (!excludeList.contains(importSection->importUrl())) + importSection->setImportUsed(usedImports.contains(importSection->importEntry())); + } +} + void ItemLibraryModel::updateVisibility(bool *changed) { - foreach (ItemLibrarySection *itemLibrarySection, m_sections) { - QString sectionSearchText = m_searchText; + for (ItemLibraryImport *import : std::as_const(m_importList)) { + bool categoryChanged = false; + import->updateCategoryVisibility(m_searchText, &categoryChanged); - bool sectionChanged = false; - bool sectionVisibility = itemLibrarySection->updateSectionVisibility(sectionSearchText, - §ionChanged); - - *changed |= sectionChanged; - *changed |= itemLibrarySection->setVisible(sectionVisibility); + *changed |= categoryChanged; } } void ItemLibraryModel::addRoleNames() { int role = 0; - for (int propertyIndex = 0; propertyIndex < ItemLibrarySection::staticMetaObject.propertyCount(); ++propertyIndex) { - QMetaProperty property = ItemLibrarySection::staticMetaObject.property(propertyIndex); - m_roleNames.insert(role, property.name()); - ++role; - } + const QMetaObject meta = ItemLibraryImport::staticMetaObject; + for (int i = meta.propertyOffset(); i < meta.propertyCount(); ++i) + m_roleNames.insert(role++, meta.property(i).name()); } void ItemLibraryModel::sortSections() { - int nullPointerSectionCount = m_sections.removeAll(QPointer()); - QTC_ASSERT(nullPointerSectionCount == 0,;); - auto sectionSort = [](ItemLibrarySection *first, ItemLibrarySection *second) { + auto sectionSort = [](ItemLibraryImport *first, ItemLibraryImport *second) { return QString::localeAwareCompare(first->sortingName(), second->sortingName()) < 0; }; - std::sort(m_sections.begin(), m_sections.end(), sectionSort); + std::sort(m_importList.begin(), m_importList.end(), sectionSort); - for (const auto &itemLibrarySection : qAsConst(m_sections)) - itemLibrarySection->sortItems(); -} - -void registerQmlTypes() -{ - registerItemLibrarySortedModel(); + for (ItemLibraryImport *itemLibImport : qAsConst(m_importList)) + itemLibImport->sortCategorySections(); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index fc988966053..9600d0e8617 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -25,10 +25,9 @@ #pragma once -#include -#include #include #include +#include QT_FORWARD_DECLARE_CLASS(QMimeData) @@ -37,12 +36,11 @@ namespace QmlDesigner { class ItemLibraryInfo; class ItemLibraryEntry; class Model; -class ItemLibrarySection; - -class ItemLibraryModel: public QAbstractListModel { +class ItemLibraryImport; +class ItemLibraryModel : public QAbstractListModel +{ Q_OBJECT - Q_PROPERTY(QString searchText READ searchText WRITE setSearchText NOTIFY searchTextChanged) public: explicit ItemLibraryModel(QObject *parent = nullptr); @@ -53,39 +51,34 @@ public: QHash roleNames() const override; QString searchText() const; + ItemLibraryImport *importByUrl(const QString &importName) const; void update(ItemLibraryInfo *itemLibraryInfo, Model *model); + void updateUsedImports(const QList &usedImports); QMimeData *getMimeData(const ItemLibraryEntry &itemLibraryEntry); - static void registerQmlTypes(); - void setSearchText(const QString &searchText); + void setFlowMode(bool); + + static void registerQmlTypes(); Q_INVOKABLE void setExpanded(bool, const QString §ion); - void setFlowMode(bool); - -signals: - void qmlModelChanged(); - void searchTextChanged(); - -private: // functions - ItemLibrarySection *sectionByName(const QString §ionName); +private: void updateVisibility(bool *changed); void addRoleNames(); void sortSections(); void clearSections(); + bool sectionExpanded(const QString §ionName) const; - -private: // variables - QList> m_sections; + QList> m_importList; QHash m_roleNames; QString m_searchText; bool m_flowMode = false; + + QHash collapsedStateHash; }; } // namespace QmlDesigner - -QML_DECLARE_TYPE(QmlDesigner::ItemLibraryModel) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp deleted file mode 100644 index e68169d9da1..00000000000 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "itemlibrarysection.h" - -#include "itemlibraryitem.h" - -namespace QmlDesigner { - -ItemLibrarySection::ItemLibrarySection(const QString §ionName, QObject *parent) - : QObject(parent), - m_sectionEntries(parent), - m_name(sectionName), - m_sectionExpanded(true), - m_isVisible(true) -{ -} - - -QString ItemLibrarySection::sectionName() const -{ - return m_name; -} - -bool ItemLibrarySection::sectionExpanded() const -{ - return m_sectionExpanded; -} - -QString ItemLibrarySection::sortingName() const -{ - - if (sectionName() == QStringLiteral("My QML Components")) //Qml Components always come first - return QStringLiteral("aaaa"); - - return sectionName(); -} - -void ItemLibrarySection::addSectionEntry(ItemLibraryItem *sectionEntry) -{ - m_sectionEntries.addItem(sectionEntry); -} - -QObject *ItemLibrarySection::sectionEntries() -{ - return &m_sectionEntries; -} - -bool ItemLibrarySection::updateSectionVisibility(const QString &searchText, bool *changed) -{ - bool haveVisibleItems = false; - - *changed = false; - - for (const auto &itemLibraryItem : m_sectionEntries.items()) { - bool itemVisible = itemLibraryItem->itemName().toLower().contains(searchText) - || itemLibraryItem->typeName().toLower().contains(searchText); - - bool itemChanged = itemLibraryItem->setVisible(itemVisible); - - *changed |= itemChanged; - - if (itemVisible) - haveVisibleItems = true; - } - - if (*changed) - m_sectionEntries.resetModel(); - - return haveVisibleItems; -} - - -bool ItemLibrarySection::setVisible(bool isVisible) -{ - if (isVisible != m_isVisible) { - m_isVisible = isVisible; - return true; - } - - return false; -} - -bool ItemLibrarySection::isVisible() const -{ - return m_isVisible; -} - -void ItemLibrarySection::sortItems() -{ - m_sectionEntries.sortItems(); -} - -void ItemLibrarySection::setSectionExpanded(bool expanded) -{ - m_sectionExpanded = expanded; -} - -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp index c1a3c704d8c..dde17dbad32 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -80,8 +79,7 @@ public: }; ItemLibraryView::ItemLibraryView(QObject* parent) - : AbstractView(parent), - m_importManagerView(new ImportManagerView(this)) + : AbstractView(parent) { m_imageCacheData = std::make_unique(); @@ -123,7 +121,6 @@ WidgetInfo ItemLibraryView::widgetInfo() m_widget = new ItemLibraryWidget{m_imageCacheData->cache, m_imageCacheData->asynchronousFontImageCache, m_imageCacheData->synchronousFontImageCache}; - m_widget->setImportsWidget(m_importManagerView->widgetInfo().widget); } return createWidgetInfo(m_widget.data(), @@ -141,7 +138,6 @@ void ItemLibraryView::modelAttached(Model *model) m_widget->clearSearchFilter(); m_widget->setModel(model); updateImports(); - model->attachView(m_importManagerView); m_hasErrors = !rewriterView()->errors().isEmpty(); m_widget->setFlowMode(QmlItemNode(rootModelNode()).isFlowView()); setResourcePath(DocumentManager::currentResourcePath().toFileInfo().absoluteFilePath()); @@ -149,8 +145,6 @@ void ItemLibraryView::modelAttached(Model *model) void ItemLibraryView::modelAboutToBeDetached(Model *model) { - model->detachView(m_importManagerView); - AbstractView::modelAboutToBeDetached(model); m_widget->setModel(nullptr); @@ -189,6 +183,16 @@ void ItemLibraryView::importsChanged(const QList &addedImports, const QL } } +void ItemLibraryView::possibleImportsChanged(const QList &possibleImports) +{ + m_widget->updatePossibleImports(possibleImports); +} + +void ItemLibraryView::usedImportsChanged(const QList &usedImports) +{ + m_widget->updateUsedImports(usedImports); +} + void ItemLibraryView::setResourcePath(const QString &resourcePath) { if (m_widget.isNull()) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h index 25d411f7b16..5668b8fbc61 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h @@ -33,7 +33,6 @@ namespace QmlDesigner { class ItemLibraryWidget; -class ImportManagerView; class ImageCacheData; class AsynchronousImageCache; @@ -52,6 +51,8 @@ public: void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; void importsChanged(const QList &addedImports, const QList &removedImports) override; + void possibleImportsChanged(const QList &possibleImports) override; + void usedImportsChanged(const QList &usedImports) override; void documentMessagesChanged(const QList &errors, const QList &warnings) override; void updateImport3DSupport(const QVariantMap &supportMap) override; @@ -65,7 +66,6 @@ protected: private: std::unique_ptr m_imageCacheData; QPointer m_widget; - ImportManagerView *m_importManagerView; bool m_hasErrors = false; QVariantMap m_importableExtensions3DMap; QVariantMap m_importOptions3DMap; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 34d9201360d..031c3f4555e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -27,6 +27,7 @@ #include "customfilesystemmodel.h" #include "itemlibraryiconimageprovider.h" +#include "itemlibraryimport.h" #include @@ -35,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +59,7 @@ #include #include #include -#include +#include #include #include #include @@ -77,16 +79,28 @@ static QString propertyEditorResourcesPath() { return Core::ICore::resourcePath() + QStringLiteral("/qmldesigner/propertyEditorQmlSources"); } +bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::FocusOut) { + if (obj == m_itemViewQuickWidget.data()) + QMetaObject::invokeMethod(m_itemViewQuickWidget->rootObject(), "closeContextMenu"); + } + + return QObject::eventFilter(obj, event); +} + ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache, AsynchronousImageCache &asynchronousFontImageCache, SynchronousImageCache &synchronousFontImageCache) : m_itemIconSize(24, 24) + , m_itemLibraryModel(new ItemLibraryModel(this)) + , m_itemLibraryAddImportModel(new ItemLibraryAddImportModel(this)) + , m_resourcesFileSystemModel{new CustomFileSystemModel(synchronousFontImageCache, this)} + , m_headerWidget(new QQuickWidget(this)) + , m_addImportWidget(new QQuickWidget(this)) , m_itemViewQuickWidget(new QQuickWidget(this)) , m_resourcesView(new ItemLibraryResourceView(asynchronousFontImageCache, this)) - , m_importTagsWidget(new QWidget(this)) - , m_addResourcesWidget(new QWidget(this)) , m_imageCache{imageCache} - , m_filterFlag(QtBasic) { m_compressionTimer.setInterval(200); m_compressionTimer.setSingleShot(true); @@ -94,11 +108,33 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache, setWindowTitle(tr("Library", "Title of library view")); - /* create Items view and its model */ - m_itemViewQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + // create header widget + m_headerWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + m_headerWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate)); + Theme::setupTheme(m_headerWidget->engine()); + m_headerWidget->setSource(QUrl("qrc:/ItemLibrary/qml/libraryheader.qml")); + QObject::connect(m_headerWidget->rootObject(), SIGNAL(tabChanged(int)), this, + SLOT(handleTabChanged(int))); + QObject::connect(m_headerWidget->rootObject(), SIGNAL(filterChanged(QString)), this, + SLOT(handleFilterChanged(QString))); + QObject::connect(m_headerWidget->rootObject(), SIGNAL(addLibraryClicked()), this, + SLOT(handleAddLibrary())); + QObject::connect(m_headerWidget->rootObject(), SIGNAL(addAssetClicked()), this, + SLOT(handleAddAsset())); + // create add imports widget + m_addImportWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + m_addImportWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate)); + Theme::setupTheme(m_addImportWidget->engine()); + m_addImportWidget->setSource(QUrl("qrc:/ItemLibrary/qml/addimport.qml")); + m_addImportWidget->rootContext()->setContextProperty( + "addImportModel", QVariant::fromValue(m_itemLibraryAddImportModel.data())); + QObject::connect(m_addImportWidget->rootObject(), SIGNAL(addImport(int)), this, + SLOT(handleAddImport(int))); + + // set up Item Library view and model + m_itemViewQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); m_itemViewQuickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports"); - m_itemLibraryModel = new ItemLibraryModel(this); m_itemViewQuickWidget->rootContext()->setContextProperties(QVector{ {{"itemLibraryModel"}, QVariant::fromValue(m_itemLibraryModel.data())}, @@ -111,66 +147,30 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache, m_previewTooltipBackend = std::make_unique(m_imageCache); m_itemViewQuickWidget->rootContext()->setContextProperty("tooltipBackend", m_previewTooltipBackend.get()); - m_itemViewQuickWidget->setClearColor( - Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate)); - - /* create Resources view and its model */ - m_resourcesFileSystemModel = new CustomFileSystemModel(synchronousFontImageCache, this); - m_resourcesView->setModel(m_resourcesFileSystemModel.data()); - - /* create image provider for loading item icons */ - m_itemViewQuickWidget->engine()->addImageProvider(QStringLiteral("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider); + m_itemViewQuickWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_ButtonColor)); + m_itemViewQuickWidget->engine()->addImageProvider(QStringLiteral("qmldesigner_itemlibrary"), + new Internal::ItemLibraryImageProvider); Theme::setupTheme(m_itemViewQuickWidget->engine()); + m_itemViewQuickWidget->installEventFilter(this); - /* other widgets */ - auto tabBar = new QTabBar(this); - tabBar->addTab(tr("QML Types", "Title of library QML types view")); - tabBar->addTab(tr("Assets", "Title of library assets view")); - tabBar->addTab(tr("QML Imports", "Title of QML imports view")); - tabBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - connect(tabBar, &QTabBar::currentChanged, this, &ItemLibraryWidget::setCurrentIndexOfStackedWidget); - connect(tabBar, &QTabBar::currentChanged, this, &ItemLibraryWidget::updateSearch); - - m_filterLineEdit = new Utils::FancyLineEdit(this); - m_filterLineEdit->setObjectName(QStringLiteral("itemLibrarySearchInput")); - m_filterLineEdit->setPlaceholderText(tr("", "Library search input hint text")); - m_filterLineEdit->setDragEnabled(false); - m_filterLineEdit->setMinimumWidth(75); - m_filterLineEdit->setTextMargins(0, 0, 20, 0); - m_filterLineEdit->setFiltering(true); - QWidget *lineEditFrame = new QWidget(this); - lineEditFrame->setObjectName(QStringLiteral("itemLibrarySearchInputFrame")); - auto lineEditLayout = new QGridLayout(lineEditFrame); - lineEditLayout->setContentsMargins(2, 2, 2, 2); - lineEditLayout->setSpacing(0); - lineEditLayout->addItem(new QSpacerItem(5, 3, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 0, 1, 3); - lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 0); - lineEditLayout->addWidget(m_filterLineEdit.data(), 1, 1, 1, 1); - lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2); - connect(m_filterLineEdit.data(), &Utils::FancyLineEdit::filterChanged, this, &ItemLibraryWidget::setSearchFilter); + // connect Resources view and its model + m_resourcesView->setModel(m_resourcesFileSystemModel.data()); m_stackedWidget = new QStackedWidget(this); m_stackedWidget->addWidget(m_itemViewQuickWidget.data()); m_stackedWidget->addWidget(m_resourcesView.data()); + m_stackedWidget->addWidget(m_addImportWidget.data()); m_stackedWidget->setMinimumHeight(30); m_stackedWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - QWidget *spacer = new QWidget(this); - spacer->setObjectName(QStringLiteral("itemLibrarySearchInputSpacer")); - spacer->setFixedHeight(4); - - auto layout = new QGridLayout(this); - layout->setContentsMargins(0, 0, 0, 0); + auto layout = new QVBoxLayout(this); + layout->setContentsMargins({}); layout->setSpacing(0); - layout->addWidget(tabBar, 0, 0, 1, 1); - layout->addWidget(spacer, 1, 0); - layout->addWidget(lineEditFrame, 2, 0, 1, 1); - layout->addWidget(m_importTagsWidget.data(), 3, 0, 1, 1); - layout->addWidget(m_addResourcesWidget.data(), 4, 0, 1, 1); - layout->addWidget(m_stackedWidget.data(), 5, 0, 1, 1); + layout->addWidget(m_headerWidget.data()); + layout->addWidget(m_stackedWidget.data()); - setSearchFilter(QString()); + updateSearch(); /* style sheets */ setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/stylesheet.css"))))); @@ -181,25 +181,6 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache, connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel); - auto flowLayout = new Utils::FlowLayout(m_importTagsWidget.data()); - flowLayout->setContentsMargins(4, 4, 4, 4); - - m_addResourcesWidget->setVisible(false); - flowLayout = new Utils::FlowLayout(m_addResourcesWidget.data()); - flowLayout->setContentsMargins(4, 4, 4, 4); - auto button = new QToolButton(m_addResourcesWidget.data()); - auto font = button->font(); - font.setPixelSize(Theme::instance()->smallFontPixelSize()); - button->setFont(font); - button->setIcon(Utils::Icons::PLUS.icon()); - button->setText(tr("Add New Assets...")); - button->setToolTip(tr("Add new assets to project.")); - button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - flowLayout->addWidget(button); - connect(button, &QToolButton::clicked, [this]() { - addResources({}); - }); - const auto dropSupport = new Utils::DropSupport( m_resourcesView.data(), [this](QDropEvent *event, Utils::DropSupport *) { // Accept supported file types @@ -250,35 +231,43 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo) delayedUpdateModel(); } -void ItemLibraryWidget::updateImports() -{ - if (m_model) - setupImportTagWidget(); -} - -void ItemLibraryWidget::setImportsWidget(QWidget *importsWidget) -{ - m_stackedWidget->addWidget(importsWidget); -} - QList ItemLibraryWidget::createToolBarWidgets() { +// TODO: implement QList buttons; return buttons; } -void ItemLibraryWidget::setSearchFilter(const QString &searchFilter) +void ItemLibraryWidget::handleFilterChanged(const QString &filterText) { - if (m_stackedWidget->currentIndex() == 0) { - m_itemLibraryModel->setSearchText(searchFilter); - m_itemViewQuickWidget->update(); - } else { - QStringList nameFilterList; + m_filterText = filterText; - m_resourcesFileSystemModel->setSearchFilter(searchFilter); - m_resourcesFileSystemModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); - m_resourcesView->scrollToTop(); + updateSearch(); +} + +void ItemLibraryWidget::handleAddLibrary() +{ + QMetaObject::invokeMethod(m_headerWidget->rootObject(), "setTab", Q_ARG(QVariant, 0)); + handleTabChanged(2); +} + +void ItemLibraryWidget::handleAddAsset() +{ + addResources({}); +} + +void ItemLibraryWidget::handleAddImport(int index) +{ + Import import = m_itemLibraryAddImportModel->getImportAt(index); + if (import.isLibraryImport() && (import.url().startsWith("QtQuick") + || import.url().startsWith("SimulinkConnector"))) { + QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_IMPORT_ADDED + + import.toImportString()); } + + m_model->changeImports({import}, {}); + QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager(); + m_stackedWidget->setCurrentIndex(0); // switch to the Components Library after import is added } void ItemLibraryWidget::delayedUpdateModel() @@ -299,24 +288,10 @@ void ItemLibraryWidget::setModel(Model *model) setItemLibraryInfo(model->metaInfo().itemLibraryInfo()); } -void ItemLibraryWidget::setCurrentIndexOfStackedWidget(int index) +void ItemLibraryWidget::handleTabChanged(int index) { - if (index == 2) { - m_filterLineEdit->setVisible(false); - m_importTagsWidget->setVisible(true); - m_addResourcesWidget->setVisible(false); - } - if (index == 1) { - m_filterLineEdit->setVisible(true); - m_importTagsWidget->setVisible(false); - m_addResourcesWidget->setVisible(true); - } else { - m_filterLineEdit->setVisible(true); - m_importTagsWidget->setVisible(true); - m_addResourcesWidget->setVisible(false); - } - m_stackedWidget->setCurrentIndex(index); + updateSearch(); } QString ItemLibraryWidget::qmlSourcesPath() @@ -326,55 +301,18 @@ QString ItemLibraryWidget::qmlSourcesPath() void ItemLibraryWidget::clearSearchFilter() { - m_filterLineEdit->clear(); + QMetaObject::invokeMethod(m_headerWidget->rootObject(), "clearSearchFilter"); } void ItemLibraryWidget::reloadQmlSource() { QString itemLibraryQmlFilePath = qmlSourcesPath() + QStringLiteral("/ItemsView.qml"); + QTC_ASSERT(QFileInfo::exists(itemLibraryQmlFilePath), return); m_itemViewQuickWidget->engine()->clearComponentCache(); m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlFilePath)); } -void ItemLibraryWidget::setupImportTagWidget() -{ - QTC_ASSERT(m_model, return); - - const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); - const bool isQtForMCUs = mcuManager.isMCUProject(); - - const QStringList imports = m_model->metaInfo().itemLibraryInfo()->showTagsForImports(); - - qDeleteAll(m_importTagsWidget->findChildren("", Qt::FindDirectChildrenOnly)); - - auto flowLayout = m_importTagsWidget->layout(); - - auto createButton = [this](const QString &import) { - auto button = new QToolButton(m_importTagsWidget.data()); - auto font = button->font(); - font.setPixelSize(Theme::instance()->smallFontPixelSize()); - button->setFont(font); - button->setIcon(Utils::Icons::PLUS.icon()); - button->setText(import); - button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - button->setToolTip(tr("Add import %1").arg(import)); - connect(button, &QToolButton::clicked, this, [this, import]() { - addPossibleImport(import); - }); - return button; - }; - - if (!isQtForMCUs) { - for (const QString &importPath : imports) { - const Import import = Import::createLibraryImport(importPath); - if (!m_model->hasImport(import, true, true) - && m_model->isImportPossible(import, true, true)) - flowLayout->addWidget(createButton(importPath)); - } - } -} - void ItemLibraryWidget::updateModel() { QTC_ASSERT(m_itemLibraryModel, return); @@ -392,13 +330,31 @@ void ItemLibraryWidget::updateModel() } else { m_updateRetry = false; } - updateImports(); updateSearch(); } +void ItemLibraryWidget::updatePossibleImports(const QList &possibleImports) +{ + m_itemLibraryAddImportModel->update(possibleImports); +} + +void ItemLibraryWidget::updateUsedImports(const QList &usedImports) +{ + m_itemLibraryModel->updateUsedImports(usedImports); +} + void ItemLibraryWidget::updateSearch() { - setSearchFilter(m_filterLineEdit->text()); + if (m_stackedWidget->currentIndex() == 0) { // Item Library tab selected + m_itemLibraryModel->setSearchText(m_filterText); + m_itemViewQuickWidget->update(); + } else if (m_stackedWidget->currentIndex() == 1) { // Assets tab selected + m_resourcesFileSystemModel->setSearchFilter(m_filterText); + m_resourcesFileSystemModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); + m_resourcesView->scrollToTop(); + } else if (m_stackedWidget->currentIndex() == 2) { // QML imports tab selected + m_itemLibraryAddImportModel->setSearchText(m_filterText); + } } void ItemLibraryWidget::setResourcePath(const QString &resourcePath) @@ -436,52 +392,13 @@ void ItemLibraryWidget::setFlowMode(bool b) m_itemLibraryModel->setFlowMode(b); } -void ItemLibraryWidget::removeImport(const QString &name) +void ItemLibraryWidget::removeImport(const QString &importUrl) { QTC_ASSERT(m_model, return); - QList toBeRemovedImportList; - foreach (const Import &import, m_model->imports()) - if (import.isLibraryImport() && import.url().compare(name, Qt::CaseInsensitive) == 0) - toBeRemovedImportList.append(import); - - m_model->changeImports({}, toBeRemovedImportList); -} - -void ItemLibraryWidget::addImport(const QString &name, const QString &version) -{ - QTC_ASSERT(m_model, return); - m_model->changeImports({Import::createLibraryImport(name, version)}, {}); -} - -void ItemLibraryWidget::addPossibleImport(const QString &name) -{ - QTC_ASSERT(m_model, return); - QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_IMPORT_ADDED_FLOWTAG - + name); - const Import import = m_model->highestPossibleImport(name); - try { - QList addedImports = {Import::createLibraryImport(name, import.version())}; - // Special case for adding an import for 3D asset - also add QtQuick3D import - const QString asset3DPrefix = QLatin1String(Constants::QUICK_3D_ASSETS_FOLDER + 1) - + QLatin1Char('.'); - if (name.startsWith(asset3DPrefix)) { - const QString q3Dlib = QLatin1String(Constants::QT_QUICK_3D_MODULE_NAME); - Import q3DImport = m_model->highestPossibleImport(q3Dlib); - if (q3DImport.url() == q3Dlib) - addedImports.prepend(Import::createLibraryImport(q3Dlib, q3DImport.version())); - } - RewriterTransaction transaction - = m_model->rewriterView()->beginRewriterTransaction( - QByteArrayLiteral("ItemLibraryWidget::addPossibleImport")); - - m_model->changeImports(addedImports, {}); - transaction.commit(); - } - catch (const RewritingException &e) { - e.showException(); - } - QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager(); + ItemLibraryImport *importSection = m_itemLibraryModel->importByUrl(importUrl); + if (importSection) + m_model->changeImports({}, {importSection->importEntry()}); } void ItemLibraryWidget::addResources(const QStringList &files) @@ -534,8 +451,12 @@ void ItemLibraryWidget::addResources(const QStringList &files) currentDir, filters.join(";;")); - if (!fileNames.isEmpty()) + if (!fileNames.isEmpty()) { lastDir = QFileInfo(fileNames.first()).absolutePath(); + // switch to assets view after an asset is added + m_stackedWidget->setCurrentIndex(1); + QMetaObject::invokeMethod(m_headerWidget->rootObject(), "setTab", Q_ARG(QVariant, 1)); + } } QMultiMap partitionedFileNames; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 72e2d1cfc93..d599bdfdc00 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -27,6 +27,7 @@ #include "itemlibraryinfo.h" #include "itemlibraryresourceview.h" +#include "import.h" #include #include @@ -55,6 +56,7 @@ class CustomFileSystemModel; class ItemLibraryModel; +class ItemLibraryAddImportModel; class ItemLibraryResourceView; class SynchronousImageCache; class AsynchronousImageCache; @@ -64,11 +66,6 @@ class ItemLibraryWidget : public QFrame { Q_OBJECT - enum FilterChangeFlag { - QtBasic = 0x0, - Meego = 0x1 - }; - public: ItemLibraryWidget(AsynchronousImageCache &imageCache, AsynchronousImageCache &asynchronousFontImageCache, @@ -78,38 +75,33 @@ public: void setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo); QList createToolBarWidgets(); - void updateImports(); - - void setImportsWidget(QWidget *importsWidget); - static QString qmlSourcesPath(); void clearSearchFilter(); - void setSearchFilter(const QString &searchFilter); void delayedUpdateModel(); void updateModel(); - void updateSearch(); + void updatePossibleImports(const QList &possibleImports); + void updateUsedImports(const QList &usedImports); void setResourcePath(const QString &resourcePath); - void setModel(Model *model); + void setFlowMode(bool b); Q_INVOKABLE void startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibId); - - void setFlowMode(bool b); + Q_INVOKABLE void removeImport(const QString &importUrl); signals: void itemActivated(const QString& itemName); +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + private: - void setCurrentIndexOfStackedWidget(int index); void reloadQmlSource(); - void setupImportTagWidget(); - void removeImport(const QString &name); - void addImport(const QString &name, const QString &version); - void addPossibleImport(const QString &name); + void addResources(const QStringList &files); void importDroppedFiles(const QList &files); + void updateSearch(); QTimer m_compressionTimer; QSize m_itemIconSize; @@ -117,23 +109,30 @@ private: QPointer m_itemLibraryInfo; QPointer m_itemLibraryModel; + QPointer m_itemLibraryAddImportModel; QPointer m_resourcesFileSystemModel; QPointer m_stackedWidget; - QPointer m_filterLineEdit; + QScopedPointer m_headerWidget; + QScopedPointer m_addImportWidget; QScopedPointer m_itemViewQuickWidget; QScopedPointer m_resourcesView; - QScopedPointer m_importTagsWidget; - QScopedPointer m_addResourcesWidget; std::unique_ptr m_previewTooltipBackend; QShortcut *m_qmlSourceUpdateShortcut; AsynchronousImageCache &m_imageCache; QPointer m_model; - FilterChangeFlag m_filterFlag; ItemLibraryEntry m_currentitemLibraryEntry; bool m_updateRetry = false; + QString m_filterText; + +private slots: + void handleTabChanged(int index); + void handleFilterChanged(const QString &filterText); + void handleAddLibrary(); + void handleAddAsset(); + void handleAddImport(int index); }; } diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/addimport.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/addimport.qml new file mode 100644 index 00000000000..a326ecfcb70 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/addimport.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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. +** +****************************************************************************/ + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuickDesignerTheme 1.0 + +Column { + id: root + + signal addImport(int index) + + Text { + id: header + text: qsTr("Select a Library to add") + color: "#ffffff" + font.pixelSize: 16 + width: parent.width + height: 50 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + ScrollView { // ListView not used because of QTBUG-52941 + id: listView + width: parent.width + height: parent.height - header.height + clip: true + + Column { + spacing: 2 + + Repeater { + model: addImportModel + + delegate: Rectangle { + width: listView.width + height: 25 + color: mouseArea.containsMouse ? Qt.lighter(Theme.qmlDesignerButtonColor(), 1.3) + : Theme.qmlDesignerButtonColor() + visible: importVisible + + Text { + text: importUrl + color: Theme.color(Theme.PanelTextColorLight) + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 10 + anchors.rightMargin: 10 + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: addImport(index) + } + } + } + } + } +} + diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/libraryheader.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/libraryheader.qml new file mode 100644 index 00000000000..c28a99086e6 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/libraryheader.qml @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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. +** +****************************************************************************/ + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuickDesignerTheme 1.0 + +Item { + id: root + width: 200 + height: 75 + + signal tabChanged(int index) + signal filterChanged(string filterText) + signal addLibraryClicked() + signal addAssetClicked() + + function setTab(index) + { + tabBar.setCurrentIndex(index); + } + + function clearSearchFilter() + { + searchFilterText.text = ""; + } + + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: 10 + + TabBar { + id: tabBar + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 5 + anchors.rightMargin: 5 + spacing: 40 + + background: Rectangle { + color: Theme.color(Theme.QmlDesigner_BackgroundColorDarkAlternate) + } + + Repeater { + model: [{title: qsTr("Components"), addToolTip: qsTr("Add Library")}, + {title: qsTr("Assets"), addToolTip: qsTr("Add new assets to project.")}] + + TabButton { + contentItem: Text { // TabButton text + text: modelData.title + font.pixelSize: 13 + font.bold: true + color: tabBar.currentIndex === index ? "#0094ce" : "#dadada" + anchors.bottomMargin: 2 + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignBottom + elide: Text.ElideRight + } + + background: Item { // TabButton background + Rectangle { // + button + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.rightMargin: 2 + anchors.bottomMargin: 2 + width: img.width + 10 + height: img.height + 10 + color: mouseArea.containsMouse ? "#353535" : "#262626" + + ToolTip.delay: 500 + ToolTip.text: modelData.addToolTip + ToolTip.visible: mouseArea.containsMouse + + Image { + id: img + source: tabBar.currentIndex === index ? "../images/add.png" + : "../images/add_unselected.png" + anchors.centerIn: parent + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: index == 0 ? addLibraryClicked() : addAssetClicked() + } + } + + Rectangle { // bottom strip + anchors.bottom: parent.bottom + width: parent.width + height: 2 + color: tabBar.currentIndex === index ? "#0094ce" : "#a8a8a8" + } + } + + onClicked: tabChanged(index) + } + } + } + + TextField { // filter + id: searchFilterText + placeholderText: qsTr("Search") + placeholderTextColor: "#a8a8a8" + color: "#dadada" + selectedTextColor: "#0094ce" + background: Rectangle { + color: "#111111" + border.color: "#666666" + } + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 5 + anchors.rightMargin: 5 + selectByMouse: true + + onTextChanged: filterChanged(text) + + Image { // clear text button + source: "../images/x.png" + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.verticalCenter: parent.verticalCenter + visible: searchFilterText.text !== "" + + MouseArea { + anchors.fill: parent + onClicked: searchFilterText.text = "" + } + } + } + } +} diff --git a/src/plugins/qmldesigner/components/resources/stylesheet.css b/src/plugins/qmldesigner/components/resources/stylesheet.css index cc72eae062d..59d883b9a85 100644 --- a/src/plugins/qmldesigner/components/resources/stylesheet.css +++ b/src/plugins/qmldesigner/components/resources/stylesheet.css @@ -26,17 +26,6 @@ QGraphicsView { background-color: creatorTheme.QmlDesigner_BackgroundColorDarkAlternate; } -QLineEdit#itemLibrarySearchInput -{ - color: creatorTheme.PanelTextColorLight; - font-size: creatorTheme.smallFontPixelSize; - border: 1px solid creatorTheme.QmlDesigner_BackgroundColorDarker; - border-width: 1; - max-height: 20px; - min-height: 20px; - background-color: creatorTheme.FancyToolButtonSelectedColor; -} - QTreeView { color: creatorTheme.PanelTextColorLight; selection-color: creatorTheme.PanelTextColorLight; @@ -76,11 +65,7 @@ QTabBar::tab { border-image: none; background-color: creatorTheme.QmlDesigner_TabDark; color: creatorTheme.QmlDesigner_TabLight; - - margin-top: 0x; - margin-bottom: 0px; - margin-left: 0px; - margin-right: 0px; + margin: 0px; font: bold; font-size: creatorTheme.captionFontPixelSize; } @@ -90,7 +75,3 @@ QTabBar::tab:selected { background-color: creatorTheme.QmlDesigner_TabLight; color: creatorTheme.QmlDesigner_TabDark; } - -QWidget#itemLibrarySearchInputSpacer { - background-color: creatorTheme.QmlDesigner_TabLight; -} diff --git a/src/plugins/qmldesigner/componentsplugin/componentsplugin.qbs b/src/plugins/qmldesigner/componentsplugin/componentsplugin.qbs index a49c475f800..84adc2b5304 100644 --- a/src/plugins/qmldesigner/componentsplugin/componentsplugin.qbs +++ b/src/plugins/qmldesigner/componentsplugin/componentsplugin.qbs @@ -18,7 +18,6 @@ QtcProduct { "../components/debugview", "../components/edit3d", "../components/formeditor", - "../components/importmanager", "../components/integration", "../components/itemlibrary", "../components/navigator", diff --git a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp index ccda886fdba..31ad31aa91f 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp @@ -344,6 +344,7 @@ QStringList ItemLibraryInfo::blacklistImports() const return list; } +// TODO: remove this and its dependencies, as flow tags are removed QStringList ItemLibraryInfo::showTagsForImports() const { auto list = m_showTagsForImports; diff --git a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp index cf2ce9ecc3c..adc7b482d55 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp @@ -25,6 +25,7 @@ #include "subcomponentmanager.h" +#include #include #include "model.h" @@ -336,7 +337,7 @@ void SubComponentManager::registerQmlFile(const QFileInfo &fileInfo, const QStri ItemLibraryEntry itemLibraryEntry; itemLibraryEntry.setType(componentName.toUtf8()); itemLibraryEntry.setName(baseComponentName); - itemLibraryEntry.setCategory(tr("My QML Components")); + itemLibraryEntry.setCategory(ItemLibraryImport::userComponentsTitle()); itemLibraryEntry.setCustomComponentSource(fileInfo.absoluteFilePath()); if (!qualifier.isEmpty()) { itemLibraryEntry.setRequiredImport(fixedQualifier); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 62732172494..309ab558f23 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -1024,9 +1024,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH collectLinkErrors(&errors, ctxt); setupImports(m_document, differenceHandler); - - if (!justSanityCheck) - setupPossibleImports(snapshot, m_vContext); + setupPossibleImports(snapshot, m_vContext); qCInfo(rewriterBenchmark) << "imports setup:" << time.elapsed(); diff --git a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp index a32be8fc146..c2ef27fb583 100644 --- a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp +++ b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/src/plugins/qmldesigner/qmldesigner_dependencies.pri b/src/plugins/qmldesigner/qmldesigner_dependencies.pri index 473692aa5db..98d81cf5565 100644 --- a/src/plugins/qmldesigner/qmldesigner_dependencies.pri +++ b/src/plugins/qmldesigner/qmldesigner_dependencies.pri @@ -23,7 +23,6 @@ INCLUDEPATH *= \ $$PWD/designercore/include \ $$PWD/components/integration \ $$PWD/components/componentcore \ - $$PWD/components/importmanager \ $$PWD/components/itemlibrary \ $$PWD/components/edit3d \ $$PWD/components/formeditor \ diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pro b/src/plugins/qmldesigner/qmldesignerplugin.pro index 8f34f42d0a6..85a7685da59 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pro +++ b/src/plugins/qmldesigner/qmldesignerplugin.pro @@ -22,7 +22,6 @@ include(components/navigator/navigator.pri) include(components/stateseditor/stateseditor.pri) include(components/resources/resources.pri) include(components/debugview/debugview.pri) -include(components/importmanager/importmanager.pri) include(components/sourcetool/sourcetool.pri) include(components/colortool/colortool.pri) include(components/texttool/texttool.pri) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index e7d1192f05c..85beae0fd20 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -49,7 +49,6 @@ Project { "components/curveeditor", "components/connectioneditor", "components/debugview", - "components/importmanager", "components/integration", "components/propertyeditor", "components/edit3d", @@ -594,16 +593,6 @@ Project { "formeditor/formeditortoolbutton.h", "formeditor/transitiontool.cpp", "formeditor/transitiontool.h", - "importmanager/importlabel.cpp", - "importmanager/importlabel.h", - "importmanager/importmanagercombobox.cpp", - "importmanager/importmanagercombobox.h", - "importmanager/importmanager.css", - "importmanager/importmanager.qrc", - "importmanager/importmanagerview.cpp", - "importmanager/importmanagerview.h", - "importmanager/importswidget.cpp", - "importmanager/importswidget.h", "integration/componentaction.cpp", "integration/componentaction.h", "integration/componentview.cpp",