Implement new item library UI
- Create a new header qml widget. - Move tabs and filtering search to the header widget. - Add imports/assets using a new "+" button on the tabs. - Remove import flow tag view (still some remainings to be removed in another commit). - Change layout from grid to vbox. - Rename some classes and variables to make them clearer. - New "Add Library" view that replaces the QML imports view (older QML imports classes removed). - Enable Search in the "add import" view. - Hide category header if only 1 category is under an import. - Assorted relevant fixes, tweaks, and clean ups. Task-number: QDS-3589 Change-Id: I710aed50858b32e024200911c6a21fd963e1b692 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Henning Gründl <henning.gruendl@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
@@ -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
|
||||
@@ -72,22 +95,61 @@ ScrollView {
|
||||
property int cellWidth: textWidth + 2 * cellHorizontalMargin
|
||||
property int cellHeight: itemLibraryIconHeight + textHeight +
|
||||
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);
|
||||
(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: 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
|
||||
|
||||
@@ -95,7 +157,7 @@ ScrollView {
|
||||
property int flexibleWidth: (parent.width - styleConstants.cellWidth * columns) / columns
|
||||
|
||||
Repeater {
|
||||
model: sectionEntries
|
||||
model: itemModel
|
||||
delegate: ItemDelegate {
|
||||
visible: itemVisible
|
||||
width: styleConstants.cellWidth + itemGrid.flexibleWidth
|
||||
@@ -106,5 +168,8 @@ ScrollView {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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,12 +95,28 @@ Item {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 <utils/utilsicons.h>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QIcon>
|
||||
|
||||
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
|
@@ -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 <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
#include <import.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
||||
|
||||
|
@@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/importmanager">
|
||||
<file>importmanager.css</file>
|
||||
</qresource>
|
||||
</RCC>
|
@@ -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 <utils/fileutils.h>
|
||||
|
||||
#include <QStyle>
|
||||
#include <QStyleFactory>
|
||||
#include <QStylePainter>
|
||||
|
||||
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("<Add Import>");
|
||||
|
||||
painter.drawComplexControl(QStyle::CC_ComboBox, opt);
|
||||
|
||||
// draw the icon and text
|
||||
painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
|
||||
}
|
@@ -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 <QComboBox>
|
||||
|
||||
class ImportManagerComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ImportManagerComboBox(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
};
|
@@ -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 <rewritingexception.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
|
||||
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<Import> &addedImports, const QList<Import> &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<Import> &/*possibleImports*/)
|
||||
{
|
||||
if (m_importsWidget)
|
||||
m_importsWidget->setPossibleImports(model()->possibleImports());
|
||||
}
|
||||
|
||||
void ImportManagerView::usedImportsChanged(const QList<Import> &/*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
|
@@ -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 <designdocument.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <designermcumanager.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QComboBox>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ImportsWidget::ImportsWidget(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
setWindowTitle(tr("Import Manager"));
|
||||
m_addImportComboBox = new ImportManagerComboBox(this);
|
||||
connect(m_addImportComboBox, QOverload<int>::of(&QComboBox::activated),
|
||||
this, &ImportsWidget::addSelectedImport);
|
||||
}
|
||||
|
||||
void ImportsWidget::removeImports()
|
||||
{
|
||||
qDeleteAll(m_importLabels);
|
||||
m_importLabels.clear();
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
static bool isImportAlreadyUsed(const Import &import, QList<ImportLabel *> 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<Import> possibleImports)
|
||||
{
|
||||
Utils::sort(possibleImports, importLess);
|
||||
m_addImportComboBox->clear();
|
||||
|
||||
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
||||
const bool isQtForMCUs = mcuManager.isMCUProject();
|
||||
|
||||
QList<Import> 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<Import> &usedImports)
|
||||
{
|
||||
const QStringList excludeList = {"SimulinkConnector"};
|
||||
|
||||
// exclude imports in the excludeList from being readonly (i.e. always enable their x button)
|
||||
QList<Import> 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<Import> &imports)
|
||||
{
|
||||
qDeleteAll(m_importLabels);
|
||||
m_importLabels.clear();
|
||||
|
||||
QList<Import> 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<Import>();
|
||||
|
||||
if (selectedImport.isEmpty())
|
||||
return;
|
||||
|
||||
emit addImport(selectedImport);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
BIN
src/plugins/qmldesigner/components/itemlibrary/images/add.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
src/plugins/qmldesigner/components/itemlibrary/images/add@2x.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.0 KiB |
BIN
src/plugins/qmldesigner/components/itemlibrary/images/down.png
Normal file
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 283 B |
After Width: | Height: | Size: 233 B |
After Width: | Height: | Size: 339 B |
BIN
src/plugins/qmldesigner/components/itemlibrary/images/x.png
Normal file
After Width: | Height: | Size: 218 B |
BIN
src/plugins/qmldesigner/components/itemlibrary/images/x@2x.png
Normal file
After Width: | Height: | Size: 383 B |
@@ -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
|
||||
|
@@ -29,5 +29,17 @@
|
||||
<file>images/asset_sound_192.png</file>
|
||||
<file>images/asset_sound_256.png</file>
|
||||
<file>images/asset_sound_384.png</file>
|
||||
<file>images/tab_icon.png</file>
|
||||
<file>images/tab_icon@2x.png</file>
|
||||
<file>images/x.png</file>
|
||||
<file>images/x@2x.png</file>
|
||||
<file>images/add.png</file>
|
||||
<file>images/add@2x.png</file>
|
||||
<file>images/add_unselected.png</file>
|
||||
<file>images/add_unselected@2x.png</file>
|
||||
<file>images/down.png</file>
|
||||
<file>images/down@2x.png</file>
|
||||
<file>qml/libraryheader.qml</file>
|
||||
<file>qml/addimport.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -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 <designermcumanager.h>
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QVariant>
|
||||
#include <QMetaProperty>
|
||||
|
||||
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<int, QByteArray> ItemLibraryAddImportModel::roleNames() const
|
||||
{
|
||||
return m_roleNames;
|
||||
}
|
||||
|
||||
void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
|
||||
{
|
||||
beginResetModel();
|
||||
m_importList.clear();
|
||||
|
||||
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
||||
const bool isQtForMCUs = mcuManager.isMCUProject();
|
||||
QList<Import> 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
|
@@ -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 <QAbstractListModel>
|
||||
#include <import.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
QT_END_NAMESPACE
|
||||
#include <QSet>
|
||||
|
||||
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<Import> &imports);
|
||||
void removeImports();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void setPossibleImports(QList<Import> possibleImports);
|
||||
void removePossibleImports();
|
||||
|
||||
void setUsedImports(const QList<Import> &possibleImports);
|
||||
void removeUsedImports();
|
||||
|
||||
signals:
|
||||
void removeImport(const Import &import);
|
||||
void addImport(const Import &import);
|
||||
|
||||
protected:
|
||||
void updateLayout();
|
||||
void update(const QList<Import> &possibleImports);
|
||||
void setSearchText(const QString &searchText);
|
||||
Import getImportAt(int index) const;
|
||||
|
||||
private:
|
||||
void addSelectedImport(int addImportComboBoxIndex);
|
||||
|
||||
private:
|
||||
QList<ImportLabel*> m_importLabels;
|
||||
QComboBox *m_addImportComboBox;
|
||||
QString m_searchText;
|
||||
QList<Import> m_importList;
|
||||
QSet<QString> m_importFilterList;
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -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 <utils/algorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QVariant>
|
||||
#include <QMetaProperty>
|
||||
#include <QMetaObject>
|
||||
|
||||
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<ItemLibraryItemsModel *>(value.value<QObject *>()))
|
||||
return QVariant::fromValue(model);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
qWarning() << Q_FUNC_INFO << "invalid role requested";
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ItemLibraryCategoriesModel::roleNames() const
|
||||
{
|
||||
return m_roleNames;
|
||||
}
|
||||
|
||||
void ItemLibraryCategoriesModel::addCategory(ItemLibraryCategory *category)
|
||||
{
|
||||
m_categoryList.append(category);
|
||||
|
||||
category->setVisible(true);
|
||||
}
|
||||
|
||||
const QList<QPointer<ItemLibraryCategory>> &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
|
@@ -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 <abstractview.h>
|
||||
#include "itemlibrarymodel.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
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<int, QByteArray> roleNames() const override;
|
||||
|
||||
void modelAttached(Model *model) override;
|
||||
void modelAboutToBeDetached(Model *model) override;
|
||||
void addCategory(ItemLibraryCategory *category);
|
||||
|
||||
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
||||
void possibleImportsChanged(const QList<Import> &possibleImports) override;
|
||||
void usedImportsChanged(const QList<Import> &usedImports) override;
|
||||
const QList<QPointer<ItemLibraryCategory>> &categorySections() const;
|
||||
|
||||
void sortCategorySections();
|
||||
void resetModel();
|
||||
|
||||
private:
|
||||
void removeImport(const Import &import);
|
||||
void addImport(const Import &import);
|
||||
void addRoleNames();
|
||||
|
||||
private:
|
||||
QPointer<ImportsWidget> m_importsWidget;
|
||||
QList<QPointer<ItemLibraryCategory>> m_categoryList;
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -23,70 +23,62 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "itemlibrarysectionmodel.h"
|
||||
|
||||
#include "itemlibraryitemsmodel.h"
|
||||
#include "itemlibraryitem.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMetaProperty>
|
||||
|
||||
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<ItemLibrarySectionModel *>(value.value<QObject*>()))
|
||||
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<int, QByteArray> ItemLibrarySectionModel::roleNames() const
|
||||
QHash<int, QByteArray> 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<QPointer<ItemLibraryItem>> &ItemLibrarySectionModel::items() const
|
||||
const QList<QPointer<ItemLibraryItem>> &ItemLibraryItemsModel::items() const
|
||||
{
|
||||
return m_itemList;
|
||||
}
|
||||
|
||||
void ItemLibrarySectionModel::sortItems()
|
||||
void ItemLibraryItemsModel::sortItems()
|
||||
{
|
||||
int nullPointerSectionCount = m_itemList.removeAll(QPointer<ItemLibraryItem>());
|
||||
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
|
@@ -25,8 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "itemlibrarymodel.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
@@ -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<QPointer<ItemLibraryItem> > &items() const;
|
||||
const QList<QPointer<ItemLibraryItem>> &items() const;
|
||||
|
||||
void sortItems();
|
||||
void resetModel();
|
||||
|
||||
private: // functions
|
||||
private:
|
||||
void addRoleNames();
|
||||
|
||||
private: // variables
|
||||
QList<QPointer<ItemLibraryItem>> m_itemList;
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
QML_DECLARE_TYPE(QmlDesigner::ItemLibrarySectionModel)
|
@@ -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 <model.h>
|
||||
#include <nodehints.h>
|
||||
#include <nodemetainfo.h>
|
||||
|
||||
#include <designdocument.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <designermcumanager.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
@@ -44,29 +43,18 @@
|
||||
#include <QMetaProperty>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <qdebug.h>
|
||||
|
||||
static Q_LOGGING_CATEGORY(itemlibraryPopulate, "qtc.itemlibrary.populate", QtWarningMsg)
|
||||
|
||||
static bool inline registerItemLibrarySortedModel() {
|
||||
qmlRegisterAnonymousType<QmlDesigner::ItemLibrarySectionModel>("ItemLibrarySectionModel", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
static QHash<QString, bool> 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<ItemLibrarySectionModel *>(value.value<QObject*>());
|
||||
auto model = qobject_cast<ItemLibraryCategoriesModel *>(value.value<QObject *>());
|
||||
if (model)
|
||||
return QVariant::fromValue(model);
|
||||
|
||||
auto model2 = qobject_cast<ItemLibraryModel *>(value.value<QObject*>());
|
||||
if (model2)
|
||||
return QVariant::fromValue(model2);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
qWarning() << Q_FUNC_INFO << "invalid role requested";
|
||||
|
||||
return QVariant();
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> 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<ItemLibraryEntry> 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<QString> 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<QmlDesigner::ItemLibrarySectionModel>("ItemLibrarySectionModel", 1);
|
||||
qmlRegisterAnonymousType<QmlDesigner::ItemLibraryModel>("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<Import> &usedImports)
|
||||
{
|
||||
// imports in the excludeList are not marked used and thus can always be removed even when in use.
|
||||
const QList<QString> 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<ItemLibrarySection>());
|
||||
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
|
||||
|
@@ -25,10 +25,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QMap>
|
||||
#include <QIcon>
|
||||
#include <QAbstractListModel>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <import.h>
|
||||
|
||||
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<int, QByteArray> roleNames() const override;
|
||||
|
||||
QString searchText() const;
|
||||
ItemLibraryImport *importByUrl(const QString &importName) const;
|
||||
|
||||
void update(ItemLibraryInfo *itemLibraryInfo, Model *model);
|
||||
void updateUsedImports(const QList<Import> &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<QPointer<ItemLibrarySection>> m_sections;
|
||||
QList<QPointer<ItemLibraryImport>> m_importList;
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
|
||||
QString m_searchText;
|
||||
bool m_flowMode = false;
|
||||
|
||||
QHash<QString, bool> collapsedStateHash;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
QML_DECLARE_TYPE(QmlDesigner::ItemLibraryModel)
|
||||
|
@@ -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
|
@@ -37,7 +37,6 @@
|
||||
#include <imagecache/imagecachestorage.h>
|
||||
#include <imagecache/timestampprovider.h>
|
||||
#include <import.h>
|
||||
#include <importmanagerview.h>
|
||||
#include <nodelistproperty.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
#include <projectexplorer/project.h>
|
||||
@@ -80,8 +79,7 @@ public:
|
||||
};
|
||||
|
||||
ItemLibraryView::ItemLibraryView(QObject* parent)
|
||||
: AbstractView(parent),
|
||||
m_importManagerView(new ImportManagerView(this))
|
||||
: AbstractView(parent)
|
||||
|
||||
{
|
||||
m_imageCacheData = std::make_unique<ImageCacheData>();
|
||||
@@ -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<Import> &addedImports, const QL
|
||||
}
|
||||
}
|
||||
|
||||
void ItemLibraryView::possibleImportsChanged(const QList<Import> &possibleImports)
|
||||
{
|
||||
m_widget->updatePossibleImports(possibleImports);
|
||||
}
|
||||
|
||||
void ItemLibraryView::usedImportsChanged(const QList<Import> &usedImports)
|
||||
{
|
||||
m_widget->updateUsedImports(usedImports);
|
||||
}
|
||||
|
||||
void ItemLibraryView::setResourcePath(const QString &resourcePath)
|
||||
{
|
||||
if (m_widget.isNull())
|
||||
|
@@ -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<Import> &addedImports, const QList<Import> &removedImports) override;
|
||||
void possibleImportsChanged(const QList<Import> &possibleImports) override;
|
||||
void usedImportsChanged(const QList<Import> &usedImports) override;
|
||||
void documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) override;
|
||||
void updateImport3DSupport(const QVariantMap &supportMap) override;
|
||||
|
||||
@@ -65,7 +66,6 @@ protected:
|
||||
private:
|
||||
std::unique_ptr<ImageCacheData> m_imageCacheData;
|
||||
QPointer<ItemLibraryWidget> m_widget;
|
||||
ImportManagerView *m_importManagerView;
|
||||
bool m_hasErrors = false;
|
||||
QVariantMap m_importableExtensions3DMap;
|
||||
QVariantMap m_importOptions3DMap;
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "customfilesystemmodel.h"
|
||||
#include "itemlibraryiconimageprovider.h"
|
||||
#include "itemlibraryimport.h"
|
||||
|
||||
#include <theme.h>
|
||||
|
||||
@@ -35,6 +36,7 @@
|
||||
#include <itemlibraryimageprovider.h>
|
||||
#include <itemlibraryinfo.h>
|
||||
#include <itemlibrarymodel.h>
|
||||
#include <itemlibraryaddimportmodel.h>
|
||||
#include <metainfo.h>
|
||||
#include <model.h>
|
||||
#include <rewritingexception.h>
|
||||
@@ -57,7 +59,7 @@
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QFileSystemModel>
|
||||
#include <QGridLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QImageReader>
|
||||
#include <QMenu>
|
||||
#include <QMimeData>
|
||||
@@ -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<QQmlContext::PropertyPair>{
|
||||
{{"itemLibraryModel"}, QVariant::fromValue(m_itemLibraryModel.data())},
|
||||
@@ -111,66 +147,30 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
m_previewTooltipBackend = std::make_unique<PreviewTooltipBackend>(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("<Filter>", "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<QToolButton *> ItemLibraryWidget::createToolBarWidgets()
|
||||
{
|
||||
// TODO: implement
|
||||
QList<QToolButton *> 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<QWidget*>("", 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<Import> &possibleImports)
|
||||
{
|
||||
m_itemLibraryAddImportModel->update(possibleImports);
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::updateUsedImports(const QList<Import> &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<Import> 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<Import> 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<QString, QString> partitionedFileNames;
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "itemlibraryinfo.h"
|
||||
#include "itemlibraryresourceview.h"
|
||||
#include "import.h"
|
||||
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/dropsupport.h>
|
||||
@@ -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<QToolButton *> 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<Import> &possibleImports);
|
||||
void updateUsedImports(const QList<Import> &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<Utils::DropSupport::FileSpec> &files);
|
||||
void updateSearch();
|
||||
|
||||
QTimer m_compressionTimer;
|
||||
QSize m_itemIconSize;
|
||||
@@ -117,23 +109,30 @@ private:
|
||||
QPointer<ItemLibraryInfo> m_itemLibraryInfo;
|
||||
|
||||
QPointer<ItemLibraryModel> m_itemLibraryModel;
|
||||
QPointer<ItemLibraryAddImportModel> m_itemLibraryAddImportModel;
|
||||
QPointer<CustomFileSystemModel> m_resourcesFileSystemModel;
|
||||
|
||||
QPointer<QStackedWidget> m_stackedWidget;
|
||||
|
||||
QPointer<Utils::FancyLineEdit> m_filterLineEdit;
|
||||
QScopedPointer<QQuickWidget> m_headerWidget;
|
||||
QScopedPointer<QQuickWidget> m_addImportWidget;
|
||||
QScopedPointer<QQuickWidget> m_itemViewQuickWidget;
|
||||
QScopedPointer<ItemLibraryResourceView> m_resourcesView;
|
||||
QScopedPointer<QWidget> m_importTagsWidget;
|
||||
QScopedPointer<QWidget> m_addResourcesWidget;
|
||||
std::unique_ptr<PreviewTooltipBackend> m_previewTooltipBackend;
|
||||
|
||||
QShortcut *m_qmlSourceUpdateShortcut;
|
||||
AsynchronousImageCache &m_imageCache;
|
||||
QPointer<Model> 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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ QtcProduct {
|
||||
"../components/debugview",
|
||||
"../components/edit3d",
|
||||
"../components/formeditor",
|
||||
"../components/importmanager",
|
||||
"../components/integration",
|
||||
"../components/itemlibrary",
|
||||
"../components/navigator",
|
||||
|
@@ -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;
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "subcomponentmanager.h"
|
||||
|
||||
#include <itemlibraryimport.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
|
||||
#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);
|
||||
|
@@ -1024,8 +1024,6 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
|
||||
collectLinkErrors(&errors, ctxt);
|
||||
|
||||
setupImports(m_document, differenceHandler);
|
||||
|
||||
if (!justSanityCheck)
|
||||
setupPossibleImports(snapshot, m_vContext);
|
||||
|
||||
qCInfo(rewriterBenchmark) << "imports setup:" << time.elapsed();
|
||||
|
@@ -37,7 +37,6 @@
|
||||
#include <designmodewidget.h>
|
||||
#include <edit3dview.h>
|
||||
#include <formeditorview.h>
|
||||
#include <importmanagerview.h>
|
||||
#include <itemlibraryview.h>
|
||||
#include <navigatorview.h>
|
||||
#include <nodeinstanceview.h>
|
||||
|
@@ -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 \
|
||||
|
@@ -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)
|
||||
|
@@ -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",
|
||||
|