forked from qt-creator/qt-creator
QmlDesigner: Add tags for important imports
This makes the relevant imports a lot more discoverable. Change-Id: Ide0396cf844c071aaee050a8993eb06a9c544daf Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -29,32 +29,38 @@
|
||||
|
||||
#include <theme.h>
|
||||
|
||||
#include <itemlibrarymodel.h>
|
||||
#include <itemlibraryimageprovider.h>
|
||||
#include <itemlibraryinfo.h>
|
||||
#include <metainfo.h>
|
||||
#include <model.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
#include <utils/flowlayout.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/stylehelper.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include "itemlibrarymodel.h"
|
||||
#include "itemlibraryimageprovider.h"
|
||||
#include <model.h>
|
||||
#include <metainfo.h>
|
||||
#include "rewritingexception.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDrag>
|
||||
#include <QFileInfo>
|
||||
#include <QFileSystemModel>
|
||||
#include <QStackedWidget>
|
||||
#include <QGridLayout>
|
||||
#include <QTabBar>
|
||||
#include <QImageReader>
|
||||
#include <QMenu>
|
||||
#include <QMimeData>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QMenu>
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QShortcut>
|
||||
#include <QStackedWidget>
|
||||
#include <QTabBar>
|
||||
#include <QTimer>
|
||||
#include <QToolButton>
|
||||
#include <QWheelEvent>
|
||||
#include <QQmlContext>
|
||||
#include <QQuickItem>
|
||||
|
||||
@@ -69,6 +75,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
m_itemIconSize(24, 24),
|
||||
m_itemViewQuickWidget(new QQuickWidget),
|
||||
m_resourcesView(new ItemLibraryResourceView(this)),
|
||||
m_importTagsWidget(new QWidget(this)),
|
||||
m_filterFlag(QtBasic)
|
||||
{
|
||||
m_compressionTimer.setInterval(200);
|
||||
@@ -126,7 +133,6 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2);
|
||||
connect(m_filterLineEdit.data(), &Utils::FancyLineEdit::filterChanged, this, &ItemLibraryWidget::setSearchFilter);
|
||||
|
||||
|
||||
m_stackedWidget = new QStackedWidget(this);
|
||||
m_stackedWidget->addWidget(m_itemViewQuickWidget.data());
|
||||
m_stackedWidget->addWidget(m_resourcesView.data());
|
||||
@@ -141,7 +147,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
layout->addWidget(tabBar, 0, 0, 1, 1);
|
||||
layout->addWidget(spacer, 1, 0);
|
||||
layout->addWidget(lineEditFrame, 2, 0, 1, 1);
|
||||
layout->addWidget(m_stackedWidget.data(), 3, 0, 1, 1);
|
||||
layout->addWidget(m_importTagsWidget.data(), 3, 0, 1, 1);
|
||||
layout->addWidget(m_stackedWidget.data(), 4, 0, 1, 1);
|
||||
|
||||
setSearchFilter(QString());
|
||||
|
||||
@@ -154,6 +161,9 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
|
||||
connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel);
|
||||
|
||||
auto *flowLayout = new Utils::FlowLayout(m_importTagsWidget.data());
|
||||
flowLayout->setMargin(4);
|
||||
|
||||
// init the first load of the QML UI elements
|
||||
reloadQmlSource();
|
||||
}
|
||||
@@ -175,12 +185,8 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo)
|
||||
|
||||
void ItemLibraryWidget::updateImports()
|
||||
{
|
||||
if (m_model) {
|
||||
QStringList imports;
|
||||
foreach (const Import &import, m_model->imports())
|
||||
if (import.isLibraryImport())
|
||||
imports << import.url();
|
||||
}
|
||||
if (m_model)
|
||||
setupImportTagWidget();
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::setImportsWidget(QWidget *importsWidget)
|
||||
@@ -223,10 +229,16 @@ void ItemLibraryWidget::setModel(Model *model)
|
||||
|
||||
void ItemLibraryWidget::setCurrentIndexOfStackedWidget(int index)
|
||||
{
|
||||
if (index == 2)
|
||||
if (index == 2) {
|
||||
m_filterLineEdit->setVisible(false);
|
||||
else
|
||||
m_importTagsWidget->setVisible(true);
|
||||
} if (index == 1) {
|
||||
m_filterLineEdit->setVisible(true);
|
||||
m_importTagsWidget->setVisible(false);
|
||||
} else {
|
||||
m_filterLineEdit->setVisible(true);
|
||||
m_importTagsWidget->setVisible(true);
|
||||
}
|
||||
|
||||
m_stackedWidget->setCurrentIndex(index);
|
||||
}
|
||||
@@ -249,6 +261,38 @@ void ItemLibraryWidget::reloadQmlSource()
|
||||
m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlFilePath));
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::setupImportTagWidget()
|
||||
{
|
||||
QTC_ASSERT(m_model, return);
|
||||
|
||||
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(9);
|
||||
button->setFont(font);
|
||||
button->setIcon(Utils::Icons::PLUS.icon());
|
||||
button->setText(import);
|
||||
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
connect(button, &QToolButton::clicked, this, [this, import]() {
|
||||
addPossibleImport(import);
|
||||
});
|
||||
return button;
|
||||
};
|
||||
|
||||
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()
|
||||
{
|
||||
m_itemLibraryModel->update(m_itemLibraryInfo.data(), m_model.data());
|
||||
@@ -293,8 +337,7 @@ void ItemLibraryWidget::startDragAndDrop(QQuickItem *mouseArea, QVariant itemLib
|
||||
|
||||
void ItemLibraryWidget::removeImport(const QString &name)
|
||||
{
|
||||
if (!m_model)
|
||||
return;
|
||||
QTC_ASSERT(m_model, return);
|
||||
|
||||
QList<Import> toBeRemovedImportList;
|
||||
foreach (const Import &import, m_model->imports())
|
||||
@@ -306,9 +349,21 @@ void ItemLibraryWidget::removeImport(const QString &name)
|
||||
|
||||
void ItemLibraryWidget::addImport(const QString &name, const QString &version)
|
||||
{
|
||||
if (!m_model)
|
||||
return;
|
||||
QTC_ASSERT(m_model, return);
|
||||
m_model->changeImports({Import::createLibraryImport(name, version)}, {});
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::addPossibleImport(const QString &name)
|
||||
{
|
||||
QTC_ASSERT(m_model, return);
|
||||
const Import import = m_model->highestPossibleImport(name);
|
||||
try {
|
||||
m_model->changeImports({Import::createLibraryImport(name, import.version())}, {});
|
||||
}
|
||||
catch (const RewritingException &e) {
|
||||
e.showException();
|
||||
}
|
||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -86,18 +86,17 @@ public:
|
||||
|
||||
Q_INVOKABLE void startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibId);
|
||||
|
||||
protected:
|
||||
void removeImport(const QString &name);
|
||||
void addImport(const QString &name, const QString &version);
|
||||
|
||||
signals:
|
||||
void itemActivated(const QString& itemName);
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
QTimer m_compressionTimer;
|
||||
QSize m_itemIconSize;
|
||||
|
||||
@@ -111,6 +110,8 @@ private:
|
||||
QPointer<Utils::FancyLineEdit> m_filterLineEdit;
|
||||
QScopedPointer<QQuickWidget> m_itemViewQuickWidget;
|
||||
QScopedPointer<ItemLibraryResourceView> m_resourcesView;
|
||||
QScopedPointer<QWidget> m_importTagsWidget;
|
||||
|
||||
QShortcut *m_qmlSourceUpdateShortcut;
|
||||
|
||||
QPointer<Model> m_model;
|
||||
|
@@ -99,8 +99,10 @@ public:
|
||||
void setPossibleImports(const QList<Import> &possibleImports);
|
||||
void setUsedImports(const QList<Import> &usedImports);
|
||||
bool hasImport(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false);
|
||||
bool isImportPossible(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false);
|
||||
QString pathForImport(const Import &import);
|
||||
QStringList importPaths() const;
|
||||
Import highestPossibleImport(const QString &importPath);
|
||||
|
||||
RewriterView *rewriterView() const;
|
||||
void setRewriterView(RewriterView *rewriterView);
|
||||
|
@@ -1874,6 +1874,8 @@ void Model::setUsedImports(const QList<Import> &usedImports)
|
||||
|
||||
static bool compareVersions(const QString &version1, const QString &version2, bool allowHigherVersion)
|
||||
{
|
||||
if (version2.isEmpty())
|
||||
return true;
|
||||
if (version1 == version2)
|
||||
return true;
|
||||
if (!allowHigherVersion)
|
||||
@@ -1921,6 +1923,26 @@ bool Model::hasImport(const Import &import, bool ignoreAlias, bool allowHigherVe
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Model::isImportPossible(const Import &import, bool ignoreAlias, bool allowHigherVersion)
|
||||
{
|
||||
if (imports().contains(import))
|
||||
return true;
|
||||
if (!ignoreAlias)
|
||||
return false;
|
||||
|
||||
const auto importList = possibleImports();
|
||||
|
||||
for (const Import &possibleImport : importList) {
|
||||
if (possibleImport.isFileImport() && import.isFileImport())
|
||||
if (possibleImport.file() == import.file())
|
||||
return true;
|
||||
if (possibleImport.isLibraryImport() && import.isLibraryImport())
|
||||
if (possibleImport.url() == import.url() && compareVersions(possibleImport.version(), import.version(), allowHigherVersion))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString Model::pathForImport(const Import &import)
|
||||
{
|
||||
if (!rewriterView())
|
||||
@@ -1944,6 +1966,20 @@ QStringList Model::importPaths() const
|
||||
return importPathList;
|
||||
}
|
||||
|
||||
Import Model::highestPossibleImport(const QString &importPath)
|
||||
{
|
||||
Import candidate;
|
||||
|
||||
for (const Import &import : possibleImports()) {
|
||||
if (import.url() == importPath) {
|
||||
if (candidate.isEmpty() || compareVersions(import.version(), candidate.version(), true))
|
||||
candidate = import;
|
||||
}
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
RewriterView *Model::rewriterView() const
|
||||
{
|
||||
return d->rewriterView();
|
||||
|
Reference in New Issue
Block a user