2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2010-01-07 12:14:35 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2010-01-07 12:14:35 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2010-01-07 12:14:35 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** 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
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2010-01-07 12:14:35 +01:00
|
|
|
**
|
2015-09-18 11:34:48 +02:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2010-12-17 16:01:08 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2010-01-07 12:14:35 +01:00
|
|
|
|
2010-12-10 17:57:42 +01:00
|
|
|
#include "itemlibrarywidget.h"
|
2010-01-07 12:14:35 +01:00
|
|
|
|
2017-02-17 16:34:11 +01:00
|
|
|
#include "customfilesystemmodel.h"
|
2019-09-18 17:12:45 +03:00
|
|
|
#include "itemlibraryassetimportdialog.h"
|
2020-09-16 13:44:43 +02:00
|
|
|
#include "itemlibraryiconimageprovider.h"
|
2017-02-17 16:34:11 +01:00
|
|
|
|
2017-03-07 16:06:02 +01:00
|
|
|
#include <theme.h>
|
2016-07-12 12:37:41 +02:00
|
|
|
|
2020-09-16 13:44:43 +02:00
|
|
|
#include <designeractionmanager.h>
|
|
|
|
|
#include <designermcumanager.h>
|
2018-01-13 16:21:07 +01:00
|
|
|
#include <itemlibraryimageprovider.h>
|
|
|
|
|
#include <itemlibraryinfo.h>
|
2020-09-16 13:44:43 +02:00
|
|
|
#include <itemlibrarymodel.h>
|
2018-01-13 16:21:07 +01:00
|
|
|
#include <metainfo.h>
|
|
|
|
|
#include <model.h>
|
2020-09-16 13:44:43 +02:00
|
|
|
#include <previewtooltip/previewtooltipbackend.h>
|
2018-01-13 16:21:07 +01:00
|
|
|
#include <rewritingexception.h>
|
2019-09-18 17:12:45 +03:00
|
|
|
#include <qmldesignerconstants.h>
|
2020-09-16 13:44:43 +02:00
|
|
|
#include <qmldesignerplugin.h>
|
2018-01-13 16:21:07 +01:00
|
|
|
|
2018-02-07 16:29:46 +01:00
|
|
|
#include <utils/algorithm.h>
|
2018-01-13 16:21:07 +01:00
|
|
|
#include <utils/flowlayout.h>
|
2011-03-30 15:15:15 +02:00
|
|
|
#include <utils/fileutils.h>
|
2014-06-06 16:06:32 +02:00
|
|
|
#include <utils/stylehelper.h>
|
2018-01-13 16:21:07 +01:00
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
#include <utils/utilsicons.h>
|
2014-06-06 16:06:32 +02:00
|
|
|
|
2010-12-14 16:52:29 +01:00
|
|
|
#include <coreplugin/coreconstants.h>
|
2014-06-11 13:44:04 +02:00
|
|
|
#include <coreplugin/icore.h>
|
2018-01-25 16:41:24 +01:00
|
|
|
#include <coreplugin/messagebox.h>
|
2010-01-07 12:14:35 +01:00
|
|
|
|
2019-10-08 15:08:51 +03:00
|
|
|
#ifdef IMPORT_QUICK3D_ASSETS
|
|
|
|
|
#include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-01-13 16:21:07 +01:00
|
|
|
#include <QApplication>
|
2017-10-05 15:14:29 +02:00
|
|
|
#include <QDrag>
|
2018-01-25 16:41:24 +01:00
|
|
|
#include <QFileDialog>
|
2010-03-10 12:45:49 +02:00
|
|
|
#include <QFileInfo>
|
2011-07-27 13:32:10 +02:00
|
|
|
#include <QFileSystemModel>
|
2010-03-10 12:45:49 +02:00
|
|
|
#include <QGridLayout>
|
2010-02-16 17:24:18 +02:00
|
|
|
#include <QImageReader>
|
2018-01-13 16:21:07 +01:00
|
|
|
#include <QMenu>
|
2010-03-10 12:45:49 +02:00
|
|
|
#include <QMimeData>
|
2017-03-24 10:44:33 +01:00
|
|
|
#include <QMouseEvent>
|
2014-06-11 13:44:04 +02:00
|
|
|
#include <QShortcut>
|
2018-01-13 16:21:07 +01:00
|
|
|
#include <QStackedWidget>
|
|
|
|
|
#include <QTabBar>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
#include <QToolButton>
|
|
|
|
|
#include <QWheelEvent>
|
2017-10-05 15:14:29 +02:00
|
|
|
#include <QQmlContext>
|
2013-09-13 17:06:10 +02:00
|
|
|
#include <QQuickItem>
|
2010-01-07 12:14:35 +01:00
|
|
|
|
|
|
|
|
namespace QmlDesigner {
|
|
|
|
|
|
2017-11-06 15:56:16 +01:00
|
|
|
static QString propertyEditorResourcesPath() {
|
|
|
|
|
return Core::ICore::resourcePath() + QStringLiteral("/qmldesigner/propertyEditorQmlSources");
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-16 13:44:43 +02:00
|
|
|
ItemLibraryWidget::ItemLibraryWidget(ImageCache &imageCache)
|
|
|
|
|
: m_itemIconSize(24, 24)
|
|
|
|
|
, m_itemViewQuickWidget(new QQuickWidget(this))
|
|
|
|
|
, m_resourcesView(new ItemLibraryResourceView(this))
|
|
|
|
|
, m_importTagsWidget(new QWidget(this))
|
|
|
|
|
, m_addResourcesWidget(new QWidget(this))
|
|
|
|
|
, m_imageCache{imageCache}
|
|
|
|
|
, m_filterFlag(QtBasic)
|
2010-01-07 12:14:35 +01:00
|
|
|
{
|
2016-06-24 15:49:26 +02:00
|
|
|
m_compressionTimer.setInterval(200);
|
|
|
|
|
m_compressionTimer.setSingleShot(true);
|
2014-05-15 17:52:13 +02:00
|
|
|
ItemLibraryModel::registerQmlTypes();
|
2013-08-06 16:45:59 +02:00
|
|
|
|
2010-03-10 12:45:49 +02:00
|
|
|
setWindowTitle(tr("Library", "Title of library view"));
|
2010-02-16 17:24:18 +02:00
|
|
|
|
2010-03-10 12:45:49 +02:00
|
|
|
/* create Items view and its model */
|
2014-09-11 15:49:10 +02:00
|
|
|
m_itemViewQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
2017-11-06 15:56:16 +01:00
|
|
|
|
|
|
|
|
m_itemViewQuickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
2014-05-14 14:26:06 +02:00
|
|
|
m_itemLibraryModel = new ItemLibraryModel(this);
|
2012-08-29 15:57:03 +02:00
|
|
|
|
2020-09-16 13:44:43 +02:00
|
|
|
m_itemViewQuickWidget->rootContext()->setContextProperties(QVector<QQmlContext::PropertyPair>{
|
|
|
|
|
{{"itemLibraryModel"}, QVariant::fromValue(m_itemLibraryModel.data())},
|
|
|
|
|
{{"itemLibraryIconWidth"}, m_itemIconSize.width()},
|
|
|
|
|
{{"itemLibraryIconHeight"}, m_itemIconSize.height()},
|
|
|
|
|
{{"rootView"}, QVariant::fromValue(this)},
|
|
|
|
|
{{"highlightColor"}, Utils::StyleHelper::notTooBrightHighlightColor()},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
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));
|
2010-02-16 17:24:18 +02:00
|
|
|
|
2010-03-10 12:45:49 +02:00
|
|
|
/* create Resources view and its model */
|
2017-02-17 16:34:11 +01:00
|
|
|
m_resourcesFileSystemModel = new CustomFileSystemModel(this);
|
2012-08-29 15:57:03 +02:00
|
|
|
m_resourcesView->setModel(m_resourcesFileSystemModel.data());
|
2010-03-10 12:45:49 +02:00
|
|
|
|
2010-07-13 10:11:05 +10:00
|
|
|
/* create image provider for loading item icons */
|
2014-09-11 15:49:10 +02:00
|
|
|
m_itemViewQuickWidget->engine()->addImageProvider(QStringLiteral("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider);
|
2020-09-16 13:44:43 +02:00
|
|
|
|
2017-03-07 16:06:02 +01:00
|
|
|
Theme::setupTheme(m_itemViewQuickWidget->engine());
|
2010-07-13 10:11:05 +10:00
|
|
|
|
2010-03-10 12:45:49 +02:00
|
|
|
/* other widgets */
|
2018-07-24 23:56:45 +02:00
|
|
|
auto tabBar = new QTabBar(this);
|
2013-03-13 11:39:36 +01:00
|
|
|
tabBar->addTab(tr("QML Types", "Title of library QML types view"));
|
2020-02-13 13:11:07 +01:00
|
|
|
tabBar->addTab(tr("Assets", "Title of library assets view"));
|
2020-02-20 16:32:01 +01:00
|
|
|
tabBar->addTab(tr("QML Imports", "Title of QML imports view"));
|
2010-03-10 12:45:49 +02:00
|
|
|
tabBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
2017-03-19 00:19:33 +02:00
|
|
|
connect(tabBar, &QTabBar::currentChanged, this, &ItemLibraryWidget::setCurrentIndexOfStackedWidget);
|
|
|
|
|
connect(tabBar, &QTabBar::currentChanged, this, &ItemLibraryWidget::updateSearch);
|
2013-08-15 13:09:54 +02:00
|
|
|
|
2014-02-13 13:54:39 +01:00
|
|
|
m_filterLineEdit = new Utils::FancyLineEdit(this);
|
2014-05-12 14:09:02 +02:00
|
|
|
m_filterLineEdit->setObjectName(QStringLiteral("itemLibrarySearchInput"));
|
2013-08-15 13:09:54 +02:00
|
|
|
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);
|
2014-02-13 13:54:39 +01:00
|
|
|
m_filterLineEdit->setFiltering(true);
|
2010-03-10 12:45:49 +02:00
|
|
|
QWidget *lineEditFrame = new QWidget(this);
|
2014-05-12 14:09:02 +02:00
|
|
|
lineEditFrame->setObjectName(QStringLiteral("itemLibrarySearchInputFrame"));
|
2018-07-24 23:56:45 +02:00
|
|
|
auto lineEditLayout = new QGridLayout(lineEditFrame);
|
2019-08-29 10:36:01 +02:00
|
|
|
lineEditLayout->setContentsMargins(2, 2, 2, 2);
|
2010-03-10 12:45:49 +02:00
|
|
|
lineEditLayout->setSpacing(0);
|
2010-04-29 18:37:04 +03:00
|
|
|
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);
|
2013-08-15 13:09:54 +02:00
|
|
|
lineEditLayout->addWidget(m_filterLineEdit.data(), 1, 1, 1, 1);
|
2010-04-29 18:37:04 +03:00
|
|
|
lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2);
|
2017-03-19 00:19:33 +02:00
|
|
|
connect(m_filterLineEdit.data(), &Utils::FancyLineEdit::filterChanged, this, &ItemLibraryWidget::setSearchFilter);
|
2010-03-10 12:45:49 +02:00
|
|
|
|
2012-08-29 15:57:03 +02:00
|
|
|
m_stackedWidget = new QStackedWidget(this);
|
2014-09-11 15:49:10 +02:00
|
|
|
m_stackedWidget->addWidget(m_itemViewQuickWidget.data());
|
2012-08-29 15:57:03 +02:00
|
|
|
m_stackedWidget->addWidget(m_resourcesView.data());
|
2020-01-24 17:14:05 +01:00
|
|
|
m_stackedWidget->setMinimumHeight(30);
|
|
|
|
|
m_stackedWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
2010-03-10 12:45:49 +02:00
|
|
|
|
2010-04-29 18:37:04 +03:00
|
|
|
QWidget *spacer = new QWidget(this);
|
2014-05-12 14:09:02 +02:00
|
|
|
spacer->setObjectName(QStringLiteral("itemLibrarySearchInputSpacer"));
|
2010-04-29 18:37:04 +03:00
|
|
|
spacer->setFixedHeight(4);
|
|
|
|
|
|
2018-07-24 23:56:45 +02:00
|
|
|
auto layout = new QGridLayout(this);
|
2010-03-10 12:45:49 +02:00
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
layout->setSpacing(0);
|
|
|
|
|
layout->addWidget(tabBar, 0, 0, 1, 1);
|
2010-04-29 18:37:04 +03:00
|
|
|
layout->addWidget(spacer, 1, 0);
|
|
|
|
|
layout->addWidget(lineEditFrame, 2, 0, 1, 1);
|
2018-01-13 16:21:07 +01:00
|
|
|
layout->addWidget(m_importTagsWidget.data(), 3, 0, 1, 1);
|
2018-01-25 16:41:24 +01:00
|
|
|
layout->addWidget(m_addResourcesWidget.data(), 4, 0, 1, 1);
|
|
|
|
|
layout->addWidget(m_stackedWidget.data(), 5, 0, 1, 1);
|
2010-03-10 12:45:49 +02:00
|
|
|
|
|
|
|
|
setSearchFilter(QString());
|
|
|
|
|
|
|
|
|
|
/* style sheets */
|
2017-03-07 16:06:02 +01:00
|
|
|
setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/stylesheet.css")))));
|
|
|
|
|
m_resourcesView->setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css")))));
|
2014-06-11 13:44:04 +02:00
|
|
|
|
|
|
|
|
m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F5), this);
|
2017-03-19 00:19:33 +02:00
|
|
|
connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &ItemLibraryWidget::reloadQmlSource);
|
2014-06-11 13:44:04 +02:00
|
|
|
|
2017-03-19 00:19:33 +02:00
|
|
|
connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel);
|
2016-06-24 15:49:26 +02:00
|
|
|
|
2018-07-24 23:56:45 +02:00
|
|
|
auto flowLayout = new Utils::FlowLayout(m_importTagsWidget.data());
|
2019-08-29 10:36:01 +02:00
|
|
|
flowLayout->setContentsMargins(4, 4, 4, 4);
|
2018-01-13 16:21:07 +01:00
|
|
|
|
2018-01-25 16:41:24 +01:00
|
|
|
m_addResourcesWidget->setVisible(false);
|
|
|
|
|
flowLayout = new Utils::FlowLayout(m_addResourcesWidget.data());
|
2019-08-29 10:36:01 +02:00
|
|
|
flowLayout->setContentsMargins(4, 4, 4, 4);
|
2018-01-25 16:41:24 +01:00
|
|
|
auto button = new QToolButton(m_addResourcesWidget.data());
|
|
|
|
|
auto font = button->font();
|
2018-04-09 16:26:25 +02:00
|
|
|
font.setPixelSize(Theme::instance()->smallFontPixelSize());
|
2018-01-25 16:41:24 +01:00
|
|
|
button->setFont(font);
|
|
|
|
|
button->setIcon(Utils::Icons::PLUS.icon());
|
2020-02-13 13:11:07 +01:00
|
|
|
button->setText(tr("Add New Assets..."));
|
|
|
|
|
button->setToolTip(tr("Add new assets to project."));
|
2018-01-25 16:41:24 +01:00
|
|
|
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
|
|
|
flowLayout->addWidget(button);
|
|
|
|
|
connect(button, &QToolButton::clicked, this, &ItemLibraryWidget::addResources);
|
|
|
|
|
|
2019-09-18 17:12:45 +03:00
|
|
|
#ifdef IMPORT_QUICK3D_ASSETS
|
|
|
|
|
DesignerActionManager *actionManager =
|
|
|
|
|
&QmlDesignerPlugin::instance()->viewManager().designerActionManager();
|
|
|
|
|
|
|
|
|
|
auto handle3DModel = [](const QStringList &fileNames, const QString &defaultDir) -> bool {
|
2020-01-14 16:06:45 +02:00
|
|
|
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir, Core::ICore::mainWindow());
|
2019-09-18 17:12:45 +03:00
|
|
|
importDlg->show();
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
2019-10-08 15:08:51 +03:00
|
|
|
auto add3DHandler = [&](const QString &category, const QString &ext) {
|
|
|
|
|
const QString filter = QStringLiteral("*.%1").arg(ext);
|
2019-09-18 17:12:45 +03:00
|
|
|
actionManager->registerAddResourceHandler(
|
|
|
|
|
AddResourceHandler(category, filter, handle3DModel, 10));
|
|
|
|
|
};
|
|
|
|
|
|
2019-10-08 15:08:51 +03:00
|
|
|
QSSGAssetImportManager importManager;
|
|
|
|
|
QHash<QString, QStringList> supportedExtensions = importManager.getSupportedExtensions();
|
|
|
|
|
|
2019-10-10 12:18:38 +03:00
|
|
|
// All things importable by QSSGAssetImportManager are considered to be in the same category
|
|
|
|
|
// so we don't get multiple separate import dialogs when different file types are imported.
|
|
|
|
|
const QString category = tr("3D Assets");
|
|
|
|
|
|
|
|
|
|
// Skip if 3D asset handlers have already been added
|
2019-09-18 17:12:45 +03:00
|
|
|
const QList<AddResourceHandler> handlers = actionManager->addResourceHandler();
|
2019-10-10 12:18:38 +03:00
|
|
|
bool categoryAlreadyAdded = false;
|
|
|
|
|
for (const auto &handler : handlers) {
|
|
|
|
|
if (handler.category == category) {
|
|
|
|
|
categoryAlreadyAdded = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!categoryAlreadyAdded) {
|
|
|
|
|
const auto groups = supportedExtensions.keys();
|
|
|
|
|
for (const auto &group : groups) {
|
|
|
|
|
const auto extensions = supportedExtensions[group];
|
|
|
|
|
for (const auto &ext : extensions)
|
|
|
|
|
add3DHandler(category, ext);
|
|
|
|
|
}
|
2019-09-18 17:12:45 +03:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2014-06-11 13:44:04 +02:00
|
|
|
// init the first load of the QML UI elements
|
|
|
|
|
reloadQmlSource();
|
2010-01-07 12:14:35 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-16 13:44:43 +02:00
|
|
|
ItemLibraryWidget::~ItemLibraryWidget() = default;
|
|
|
|
|
|
2010-12-10 17:57:42 +01:00
|
|
|
void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo)
|
2010-03-10 12:45:49 +02:00
|
|
|
{
|
2012-08-29 15:57:03 +02:00
|
|
|
if (m_itemLibraryInfo.data() == itemLibraryInfo)
|
2010-05-12 11:56:23 +02:00
|
|
|
return;
|
|
|
|
|
|
2019-09-18 17:12:45 +03:00
|
|
|
if (m_itemLibraryInfo) {
|
2017-03-19 00:19:33 +02:00
|
|
|
disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
|
|
|
|
|
this, &ItemLibraryWidget::delayedUpdateModel);
|
2019-09-18 17:12:45 +03:00
|
|
|
disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::importTagsChanged,
|
|
|
|
|
this, &ItemLibraryWidget::delayedUpdateModel);
|
|
|
|
|
}
|
2012-08-29 15:57:03 +02:00
|
|
|
m_itemLibraryInfo = itemLibraryInfo;
|
2019-09-18 17:12:45 +03:00
|
|
|
if (itemLibraryInfo) {
|
2017-03-19 00:19:33 +02:00
|
|
|
connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
|
|
|
|
|
this, &ItemLibraryWidget::delayedUpdateModel);
|
2019-09-18 17:12:45 +03:00
|
|
|
connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::importTagsChanged,
|
|
|
|
|
this, &ItemLibraryWidget::delayedUpdateModel);
|
|
|
|
|
}
|
2016-11-07 11:06:10 +01:00
|
|
|
delayedUpdateModel();
|
2010-03-10 12:45:49 +02:00
|
|
|
}
|
|
|
|
|
|
2010-12-14 16:52:29 +01:00
|
|
|
void ItemLibraryWidget::updateImports()
|
|
|
|
|
{
|
2018-01-13 16:21:07 +01:00
|
|
|
if (m_model)
|
|
|
|
|
setupImportTagWidget();
|
2010-12-14 16:52:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-08-14 17:42:48 +02:00
|
|
|
void ItemLibraryWidget::setImportsWidget(QWidget *importsWidget)
|
|
|
|
|
{
|
|
|
|
|
m_stackedWidget->addWidget(importsWidget);
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-14 16:52:29 +01:00
|
|
|
QList<QToolButton *> ItemLibraryWidget::createToolBarWidgets()
|
|
|
|
|
{
|
|
|
|
|
QList<QToolButton *> buttons;
|
|
|
|
|
return buttons;
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-10 17:57:42 +01:00
|
|
|
void ItemLibraryWidget::setSearchFilter(const QString &searchFilter)
|
2010-01-07 12:14:35 +01:00
|
|
|
{
|
2012-08-29 15:57:03 +02:00
|
|
|
if (m_stackedWidget->currentIndex() == 0) {
|
|
|
|
|
m_itemLibraryModel->setSearchText(searchFilter);
|
2014-09-11 15:49:10 +02:00
|
|
|
m_itemViewQuickWidget->update();
|
2010-02-16 17:24:18 +02:00
|
|
|
} else {
|
|
|
|
|
QStringList nameFilterList;
|
|
|
|
|
|
2017-02-17 16:34:11 +01:00
|
|
|
m_resourcesFileSystemModel->setSearchFilter(searchFilter);
|
2012-08-29 15:57:03 +02:00
|
|
|
m_resourcesFileSystemModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
|
|
|
|
|
m_resourcesView->scrollToTop();
|
2010-01-07 12:14:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-24 15:49:26 +02:00
|
|
|
void ItemLibraryWidget::delayedUpdateModel()
|
|
|
|
|
{
|
2020-03-25 19:28:24 +01:00
|
|
|
static bool disableTimer = DesignerSettings::getValue(DesignerSettingsKey::DISABLE_ITEM_LIBRARY_UPDATE_TIMER).toBool();
|
|
|
|
|
if (disableTimer)
|
|
|
|
|
updateModel();
|
|
|
|
|
else
|
|
|
|
|
m_compressionTimer.start();
|
2016-06-24 15:49:26 +02:00
|
|
|
}
|
|
|
|
|
|
2010-12-10 22:01:55 +01:00
|
|
|
void ItemLibraryWidget::setModel(Model *model)
|
|
|
|
|
{
|
2020-09-16 13:44:43 +02:00
|
|
|
m_itemViewQuickWidget->engine()->removeImageProvider("itemlibrary_preview");
|
2012-08-29 15:57:03 +02:00
|
|
|
m_model = model;
|
2010-12-13 10:54:30 +01:00
|
|
|
if (!model)
|
|
|
|
|
return;
|
2020-09-16 13:44:43 +02:00
|
|
|
|
|
|
|
|
m_itemViewQuickWidget->engine()->addImageProvider("itemlibrary_preview",
|
|
|
|
|
new ItemLibraryIconImageProvider{m_imageCache});
|
|
|
|
|
|
2010-12-10 22:01:55 +01:00
|
|
|
setItemLibraryInfo(model->metaInfo().itemLibraryInfo());
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-15 13:09:54 +02:00
|
|
|
void ItemLibraryWidget::setCurrentIndexOfStackedWidget(int index)
|
|
|
|
|
{
|
2018-01-13 16:21:07 +01:00
|
|
|
if (index == 2) {
|
2013-08-15 13:10:37 +02:00
|
|
|
m_filterLineEdit->setVisible(false);
|
2018-01-13 16:21:07 +01:00
|
|
|
m_importTagsWidget->setVisible(true);
|
2018-01-25 16:41:24 +01:00
|
|
|
m_addResourcesWidget->setVisible(false);
|
2020-09-16 13:44:43 +02:00
|
|
|
}
|
|
|
|
|
if (index == 1) {
|
2013-08-15 13:10:37 +02:00
|
|
|
m_filterLineEdit->setVisible(true);
|
2018-01-13 16:21:07 +01:00
|
|
|
m_importTagsWidget->setVisible(false);
|
2018-01-25 16:41:24 +01:00
|
|
|
m_addResourcesWidget->setVisible(true);
|
2018-01-13 16:21:07 +01:00
|
|
|
} else {
|
|
|
|
|
m_filterLineEdit->setVisible(true);
|
|
|
|
|
m_importTagsWidget->setVisible(true);
|
2018-01-25 16:41:24 +01:00
|
|
|
m_addResourcesWidget->setVisible(false);
|
2018-01-13 16:21:07 +01:00
|
|
|
}
|
2013-08-15 13:10:37 +02:00
|
|
|
|
2013-08-15 13:09:54 +02:00
|
|
|
m_stackedWidget->setCurrentIndex(index);
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-11 13:44:04 +02:00
|
|
|
QString ItemLibraryWidget::qmlSourcesPath()
|
|
|
|
|
{
|
|
|
|
|
return Core::ICore::resourcePath() + QStringLiteral("/qmldesigner/itemLibraryQmlSources");
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-20 11:59:41 +02:00
|
|
|
void ItemLibraryWidget::clearSearchFilter()
|
|
|
|
|
{
|
|
|
|
|
m_filterLineEdit->clear();
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-11 13:44:04 +02:00
|
|
|
void ItemLibraryWidget::reloadQmlSource()
|
|
|
|
|
{
|
|
|
|
|
QString itemLibraryQmlFilePath = qmlSourcesPath() + QStringLiteral("/ItemsView.qml");
|
|
|
|
|
QTC_ASSERT(QFileInfo::exists(itemLibraryQmlFilePath), return);
|
2014-09-11 15:49:10 +02:00
|
|
|
m_itemViewQuickWidget->engine()->clearComponentCache();
|
|
|
|
|
m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlFilePath));
|
2014-06-11 13:44:04 +02:00
|
|
|
}
|
|
|
|
|
|
2018-01-13 16:21:07 +01:00
|
|
|
void ItemLibraryWidget::setupImportTagWidget()
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(m_model, return);
|
2020-09-28 17:33:40 +02:00
|
|
|
|
|
|
|
|
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
|
|
|
|
const bool isQtForMCUs = mcuManager.isMCUProject();
|
2018-01-13 16:21:07 +01:00
|
|
|
|
|
|
|
|
const QStringList imports = m_model->metaInfo().itemLibraryInfo()->showTagsForImports();
|
|
|
|
|
|
|
|
|
|
qDeleteAll(m_importTagsWidget->findChildren<QWidget*>("", Qt::FindDirectChildrenOnly));
|
|
|
|
|
|
2018-07-24 23:56:45 +02:00
|
|
|
auto flowLayout = m_importTagsWidget->layout();
|
2018-01-13 16:21:07 +01:00
|
|
|
|
|
|
|
|
auto createButton = [this](const QString &import) {
|
|
|
|
|
auto button = new QToolButton(m_importTagsWidget.data());
|
|
|
|
|
auto font = button->font();
|
2018-04-09 16:26:25 +02:00
|
|
|
font.setPixelSize(Theme::instance()->smallFontPixelSize());
|
2018-01-13 16:21:07 +01:00
|
|
|
button->setFont(font);
|
|
|
|
|
button->setIcon(Utils::Icons::PLUS.icon());
|
|
|
|
|
button->setText(import);
|
|
|
|
|
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
2018-01-25 16:41:24 +01:00
|
|
|
button->setToolTip(tr("Add import %1").arg(import));
|
2018-01-13 16:21:07 +01:00
|
|
|
connect(button, &QToolButton::clicked, this, [this, import]() {
|
|
|
|
|
addPossibleImport(import);
|
|
|
|
|
});
|
|
|
|
|
return button;
|
|
|
|
|
};
|
|
|
|
|
|
2020-09-02 09:34:18 +02:00
|
|
|
if (!isQtForMCUs) {
|
|
|
|
|
for (const QString &importPath : imports) {
|
|
|
|
|
const Import import = Import::createLibraryImport(importPath);
|
|
|
|
|
if (!m_model->hasImport(import, true, true)
|
2018-01-13 16:21:07 +01:00
|
|
|
&& m_model->isImportPossible(import, true, true))
|
2020-09-02 09:34:18 +02:00
|
|
|
flowLayout->addWidget(createButton(importPath));
|
|
|
|
|
}
|
2018-01-13 16:21:07 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-10 17:57:42 +01:00
|
|
|
void ItemLibraryWidget::updateModel()
|
2010-05-12 11:56:23 +02:00
|
|
|
{
|
2019-03-06 16:42:28 +01:00
|
|
|
QTC_ASSERT(m_itemLibraryModel, return);
|
|
|
|
|
|
2020-04-30 15:11:01 +03:00
|
|
|
if (m_compressionTimer.isActive()) {
|
|
|
|
|
m_updateRetry = false;
|
|
|
|
|
m_compressionTimer.stop();
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-29 15:57:03 +02:00
|
|
|
m_itemLibraryModel->update(m_itemLibraryInfo.data(), m_model.data());
|
2020-04-30 15:11:01 +03:00
|
|
|
|
|
|
|
|
if (m_itemLibraryModel->rowCount() == 0 && !m_updateRetry) {
|
|
|
|
|
m_updateRetry = true; // Only retry once to avoid endless loops
|
|
|
|
|
m_compressionTimer.start();
|
|
|
|
|
} else {
|
|
|
|
|
m_updateRetry = false;
|
|
|
|
|
}
|
2010-12-14 16:52:29 +01:00
|
|
|
updateImports();
|
2010-05-12 11:56:23 +02:00
|
|
|
updateSearch();
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-10 17:57:42 +01:00
|
|
|
void ItemLibraryWidget::updateSearch()
|
2010-01-07 12:14:35 +01:00
|
|
|
{
|
2013-08-15 13:09:54 +02:00
|
|
|
setSearchFilter(m_filterLineEdit->text());
|
2010-01-07 12:14:35 +01:00
|
|
|
}
|
|
|
|
|
|
2010-12-10 17:57:42 +01:00
|
|
|
void ItemLibraryWidget::setResourcePath(const QString &resourcePath)
|
2010-01-07 12:14:35 +01:00
|
|
|
{
|
2012-08-29 15:57:03 +02:00
|
|
|
if (m_resourcesView->model() == m_resourcesFileSystemModel.data()) {
|
|
|
|
|
m_resourcesFileSystemModel->setRootPath(resourcePath);
|
2017-02-28 17:16:07 +01:00
|
|
|
m_resourcesView->setRootIndex(m_resourcesFileSystemModel->indexForPath(resourcePath));
|
2011-07-27 13:32:10 +02:00
|
|
|
}
|
2010-04-19 14:36:02 +03:00
|
|
|
updateSearch();
|
2010-01-07 12:14:35 +01:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 10:44:33 +01:00
|
|
|
void ItemLibraryWidget::startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibraryId)
|
2010-01-07 12:14:35 +01:00
|
|
|
{
|
2014-06-19 17:50:34 +02:00
|
|
|
m_currentitemLibraryEntry = itemLibraryId.value<ItemLibraryEntry>();
|
2014-01-06 15:20:54 +01:00
|
|
|
|
2014-06-19 17:50:34 +02:00
|
|
|
QMimeData *mimeData = m_itemLibraryModel->getMimeData(m_currentitemLibraryEntry);
|
2018-07-24 23:56:45 +02:00
|
|
|
auto drag = new QDrag(this);
|
2010-02-16 17:24:18 +02:00
|
|
|
|
2015-12-08 11:56:08 +01:00
|
|
|
drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile(
|
|
|
|
|
m_currentitemLibraryEntry.libraryEntryIconPath()));
|
2010-02-16 17:24:18 +02:00
|
|
|
drag->setMimeData(mimeData);
|
|
|
|
|
|
2017-03-24 10:44:33 +01:00
|
|
|
/* Workaround for bug in Qt. The release event is not delivered for Qt < 5.9 if a drag is started */
|
|
|
|
|
QMouseEvent event (QEvent::MouseButtonRelease, QPoint(-1, -1), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
|
|
|
|
QApplication::sendEvent(mouseArea, &event);
|
2014-06-30 14:53:34 +02:00
|
|
|
|
2017-03-24 10:44:33 +01:00
|
|
|
QTimer::singleShot(0, [drag]() {
|
|
|
|
|
drag->exec();
|
|
|
|
|
drag->deleteLater();
|
|
|
|
|
});
|
2010-01-07 12:14:35 +01:00
|
|
|
}
|
|
|
|
|
|
2020-01-29 12:28:30 +01:00
|
|
|
void ItemLibraryWidget::setFlowMode(bool b)
|
|
|
|
|
{
|
|
|
|
|
m_itemLibraryModel->setFlowMode(b);
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-29 15:57:03 +02:00
|
|
|
void ItemLibraryWidget::removeImport(const QString &name)
|
|
|
|
|
{
|
2018-01-13 16:21:07 +01:00
|
|
|
QTC_ASSERT(m_model, return);
|
2012-08-29 15:57:03 +02:00
|
|
|
|
|
|
|
|
QList<Import> toBeRemovedImportList;
|
|
|
|
|
foreach (const Import &import, m_model->imports())
|
|
|
|
|
if (import.isLibraryImport() && import.url().compare(name, Qt::CaseInsensitive) == 0)
|
|
|
|
|
toBeRemovedImportList.append(import);
|
2011-02-10 15:44:40 +01:00
|
|
|
|
2017-04-26 14:32:02 +02:00
|
|
|
m_model->changeImports({}, toBeRemovedImportList);
|
2012-08-29 15:57:03 +02:00
|
|
|
}
|
2011-02-10 15:44:40 +01:00
|
|
|
|
2012-08-29 15:57:03 +02:00
|
|
|
void ItemLibraryWidget::addImport(const QString &name, const QString &version)
|
|
|
|
|
{
|
2018-01-13 16:21:07 +01:00
|
|
|
QTC_ASSERT(m_model, return);
|
2017-04-26 14:32:02 +02:00
|
|
|
m_model->changeImports({Import::createLibraryImport(name, version)}, {});
|
2012-08-29 15:57:03 +02:00
|
|
|
}
|
2010-12-14 16:52:29 +01:00
|
|
|
|
2018-01-13 16:21:07 +01:00
|
|
|
void ItemLibraryWidget::addPossibleImport(const QString &name)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(m_model, return);
|
2020-12-10 10:57:03 +01:00
|
|
|
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_IMPORT_ADDED_FLOWTAG
|
|
|
|
|
+ name);
|
2018-01-13 16:21:07 +01:00
|
|
|
const Import import = m_model->highestPossibleImport(name);
|
|
|
|
|
try {
|
2019-09-27 15:41:46 +03:00
|
|
|
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();
|
2018-01-13 16:21:07 +01:00
|
|
|
}
|
|
|
|
|
catch (const RewritingException &e) {
|
|
|
|
|
e.showException();
|
|
|
|
|
}
|
|
|
|
|
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-25 16:41:24 +01:00
|
|
|
void ItemLibraryWidget::addResources()
|
|
|
|
|
{
|
|
|
|
|
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(document, return);
|
|
|
|
|
|
|
|
|
|
QList<AddResourceHandler> handlers = QmlDesignerPlugin::instance()->viewManager().designerActionManager().addResourceHandler();
|
2018-02-07 16:29:46 +01:00
|
|
|
|
2018-01-25 16:41:24 +01:00
|
|
|
QMultiMap<QString, QString> map;
|
|
|
|
|
for (const AddResourceHandler &handler : handlers) {
|
|
|
|
|
map.insert(handler.category, handler.filter);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-20 17:38:54 +02:00
|
|
|
QMap<QString, QString> reverseMap;
|
|
|
|
|
for (const AddResourceHandler &handler : handlers) {
|
|
|
|
|
reverseMap.insert(handler.filter, handler.category);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-07 16:29:46 +01:00
|
|
|
QMap<QString, int> priorities;
|
|
|
|
|
for (const AddResourceHandler &handler : handlers) {
|
|
|
|
|
priorities.insert(handler.category, handler.piority);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList sortedKeys = map.uniqueKeys();
|
|
|
|
|
Utils::sort(sortedKeys, [&priorities](const QString &first,
|
|
|
|
|
const QString &second){
|
|
|
|
|
return priorities.value(first) < priorities.value(second);
|
|
|
|
|
});
|
|
|
|
|
|
2018-01-25 16:41:24 +01:00
|
|
|
QStringList filters;
|
|
|
|
|
|
2018-02-07 16:29:46 +01:00
|
|
|
for (const QString &key : sortedKeys) {
|
2018-01-25 16:41:24 +01:00
|
|
|
QString str = key + " (";
|
|
|
|
|
str.append(map.values(key).join(" "));
|
|
|
|
|
str.append(")");
|
|
|
|
|
filters.append(str);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-20 17:38:54 +02:00
|
|
|
filters.prepend(tr("All Files (%1)").arg(map.values().join(" ")));
|
|
|
|
|
|
2019-04-01 17:58:33 +02:00
|
|
|
static QString lastDir;
|
|
|
|
|
const QString currentDir = lastDir.isEmpty() ? document->fileName().parentDir().toString() : lastDir;
|
|
|
|
|
|
2020-06-02 09:10:40 +02:00
|
|
|
const auto fileNames = QFileDialog::getOpenFileNames(Core::ICore::dialogParent(),
|
|
|
|
|
tr("Add Assets"),
|
|
|
|
|
currentDir,
|
|
|
|
|
filters.join(";;"));
|
2019-04-01 17:58:33 +02:00
|
|
|
|
|
|
|
|
if (!fileNames.isEmpty())
|
|
|
|
|
lastDir = QFileInfo(fileNames.first()).absolutePath();
|
|
|
|
|
|
2018-04-20 17:38:54 +02:00
|
|
|
QMultiMap<QString, QString> partitionedFileNames;
|
|
|
|
|
|
|
|
|
|
for (const QString &fileName : fileNames) {
|
2019-10-22 17:12:20 +03:00
|
|
|
const QString suffix = "*." + QFileInfo(fileName).suffix().toLower();
|
2018-04-20 17:38:54 +02:00
|
|
|
const QString category = reverseMap.value(suffix);
|
|
|
|
|
partitionedFileNames.insert(category, fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const QString &category : partitionedFileNames.uniqueKeys()) {
|
|
|
|
|
for (const AddResourceHandler &handler : handlers) {
|
|
|
|
|
QStringList fileNames = partitionedFileNames.values(category);
|
|
|
|
|
if (handler.category == category) {
|
2020-11-11 17:33:35 +01:00
|
|
|
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_RESOURCE_IMPORTED + category);
|
2018-04-20 17:38:54 +02:00
|
|
|
if (!handler.operation(fileNames, document->fileName().parentDir().toString()))
|
|
|
|
|
Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), tr("Could not add %1 to project.").arg(fileNames.join(" ")));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-25 16:41:24 +01:00
|
|
|
}
|
|
|
|
|
}
|
2020-09-16 13:44:43 +02:00
|
|
|
} // namespace QmlDesigner
|