forked from qt-creator/qt-creator
Implement new Assets library
Build a new Qml based item library assets view. Task-number: QDS-3590 Change-Id: Ib3a4bcac8f873469ec5f3429817c49f466ec1e2a Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
184
share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml
Normal file
184
share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml
Normal file
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QtQuick.Layouts 1.15
|
||||
import QtQuickDesignerTheme 1.0
|
||||
import HelperWidgets 2.0
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
Item {
|
||||
DropArea {
|
||||
id: dropArea
|
||||
|
||||
property var files // list of supported dropped files
|
||||
|
||||
enabled: true
|
||||
anchors.fill: parent
|
||||
|
||||
onEntered: {
|
||||
files = []
|
||||
for (var i = 0; i < drag.urls.length; ++i) {
|
||||
var url = drag.urls[i].toString();
|
||||
if (url.startsWith("file:///")) // remove file scheme (happens on Windows)
|
||||
url = url.substr(8)
|
||||
var ext = url.slice(url.lastIndexOf('.') + 1).toLowerCase()
|
||||
if (rootView.supportedSuffixes().includes('*.' + ext))
|
||||
files.push(url)
|
||||
}
|
||||
|
||||
if (files.length === 0)
|
||||
drag.accepted = false;
|
||||
}
|
||||
|
||||
onDropped: {
|
||||
if (files.length > 0)
|
||||
rootView.handleFilesDrop(files)
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView { // TODO: experiment using ListView instead of ScrollView + Column
|
||||
id: assetsView
|
||||
anchors.fill: parent
|
||||
|
||||
Column {
|
||||
spacing: 2
|
||||
Repeater {
|
||||
model: assetsModel // context property
|
||||
delegate: dirSection
|
||||
}
|
||||
|
||||
Component {
|
||||
id: dirSection
|
||||
|
||||
Section {
|
||||
width: assetsView.width -
|
||||
(assetsView.verticalScrollBarVisible ? assetsView.verticalThickness : 0)
|
||||
caption: dirName
|
||||
sectionHeight: 30
|
||||
sectionFontSize: 15
|
||||
contentLevel: dirDepth
|
||||
levelShift: 20
|
||||
leftPadding: 0
|
||||
hideHeader: dirDepth === 0
|
||||
showLeftBorder: true
|
||||
expanded: dirExpanded
|
||||
visible: dirVisible
|
||||
expandOnClick: false
|
||||
onToggleExpand: {
|
||||
dirExpanded = !dirExpanded
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 5
|
||||
leftPadding: 15
|
||||
|
||||
Repeater {
|
||||
model: dirsModel
|
||||
delegate: dirSection
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: filesModel
|
||||
delegate: fileSection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: fileSection
|
||||
|
||||
Rectangle {
|
||||
width: assetsView.width -
|
||||
(assetsView.verticalScrollBarVisible ? assetsView.verticalThickness : 0)
|
||||
height: img.height
|
||||
color: mouseArea.containsMouse ? "#444444" : "transparent"
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
|
||||
Image {
|
||||
id: img
|
||||
asynchronous: true
|
||||
width: 48
|
||||
height: 48
|
||||
source: "image://qmldesigner_assets/" + filePath
|
||||
}
|
||||
|
||||
Text {
|
||||
text: fileName
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: 14
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
readonly property string suffix: fileName.substr(-4)
|
||||
readonly property bool isFont: suffix === ".ttf" || suffix === ".otf"
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
onExited: tooltipBackend.hideTooltip()
|
||||
onCanceled: tooltipBackend.hideTooltip()
|
||||
onPositionChanged: tooltipBackend.reposition()
|
||||
onPressed: {
|
||||
forceActiveFocus()
|
||||
if (mouse.button === Qt.LeftButton)
|
||||
rootView.startDragAsset(filePath)
|
||||
else
|
||||
print("TODO: impl context menu")
|
||||
}
|
||||
|
||||
ToolTip {
|
||||
visible: !isFont && mouseArea.containsMouse
|
||||
text: filePath
|
||||
delay: 1000
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: mouseArea.containsMouse
|
||||
onTriggered: {
|
||||
if (suffix === ".ttf" || suffix === ".otf") {
|
||||
tooltipBackend.name = fileName
|
||||
tooltipBackend.path = filePath
|
||||
tooltipBackend.showTooltip()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -38,12 +38,14 @@ Item {
|
||||
property alias sectionFontSize: label.font.pixelSize
|
||||
property alias showTopSeparator: topSeparator.visible
|
||||
property alias showArrow: arrow.visible
|
||||
property alias showLeftBorder: leftBorder.visible
|
||||
|
||||
property int leftPadding: 8
|
||||
property int rightPadding: 0
|
||||
|
||||
property bool expanded: true
|
||||
property int level: 0
|
||||
property int level: 0 // affects arrow and title
|
||||
property int contentLevel: 0 // affects whole section
|
||||
property int levelShift: 10
|
||||
property bool hideHeader: false
|
||||
property bool expandOnClick: true // if false, toggleExpand signal will be emitted instead
|
||||
@@ -138,6 +140,14 @@ Item {
|
||||
anchors.top: topSpacer.bottom
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: leftBorder
|
||||
visible: false
|
||||
width: 1
|
||||
height: parent.height - 15
|
||||
color: header.color
|
||||
}
|
||||
|
||||
Item {
|
||||
id: bottomSpacer
|
||||
height: addBottomPadding && row.height > 0 ? StudioTheme.Values.sectionHeadSpacerHeight : 0
|
||||
@@ -160,12 +170,12 @@ Item {
|
||||
]
|
||||
|
||||
transitions: Transition {
|
||||
id: trans
|
||||
enabled: false
|
||||
NumberAnimation {
|
||||
properties: "implicitHeight,rotation";
|
||||
duration: 120;
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
id: trans
|
||||
enabled: false
|
||||
NumberAnimation {
|
||||
properties: "implicitHeight,rotation";
|
||||
duration: 120;
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -310,12 +310,10 @@ extend_qtc_plugin(QmlDesigner
|
||||
assetimportupdatetreeitemdelegate.cpp assetimportupdatetreeitemdelegate.h
|
||||
assetimportupdatetreemodel.cpp assetimportupdatetreemodel.h
|
||||
assetimportupdatetreeview.cpp assetimportupdatetreeview.h
|
||||
customfilesystemmodel.cpp customfilesystemmodel.h
|
||||
itemlibrary.qrc
|
||||
itemlibraryimageprovider.cpp itemlibraryimageprovider.h
|
||||
itemlibraryitem.cpp itemlibraryitem.h
|
||||
itemlibrarymodel.cpp itemlibrarymodel.h
|
||||
itemlibraryresourceview.cpp itemlibraryresourceview.h
|
||||
itemlibrarycategory.cpp itemlibrarycategory.h
|
||||
itemlibraryitemsmodel.cpp itemlibraryitemsmodel.h
|
||||
itemlibraryview.cpp itemlibraryview.h
|
||||
@@ -327,6 +325,11 @@ extend_qtc_plugin(QmlDesigner
|
||||
itemlibraryimport.cpp itemlibraryimport.h
|
||||
itemlibrarycategoriesmodel.cpp itemlibrarycategoriesmodel.h
|
||||
itemlibraryaddimportmodel.cpp itemlibraryaddimportmodel.h
|
||||
itemlibraryassetsmodel.cpp itemlibraryassetsmodel.h
|
||||
itemlibraryassetsiconprovider.cpp itemlibraryassetsiconprovider.h
|
||||
itemlibraryassetsdir.cpp itemlibraryassetsdir.h
|
||||
itemlibraryassetsdirsmodel.cpp itemlibraryassetsdirsmodel.h
|
||||
itemlibraryassetsfilesmodel.cpp itemlibraryassetsfilesmodel.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
|
@@ -1,437 +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 "customfilesystemmodel.h"
|
||||
|
||||
#include <synchronousimagecache.h>
|
||||
#include <theme.h>
|
||||
#include <hdrimage.h>
|
||||
|
||||
#include <utils/filesystemwatcher.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFileIconProvider>
|
||||
#include <QFileSystemModel>
|
||||
#include <QFont>
|
||||
#include <QImageReader>
|
||||
#include <QPainter>
|
||||
#include <QRawFont>
|
||||
#include <qmath.h>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
static const QStringList &supportedImageSuffixes()
|
||||
{
|
||||
static QStringList retList;
|
||||
if (retList.isEmpty()) {
|
||||
const QList<QByteArray> suffixes = QImageReader::supportedImageFormats();
|
||||
for (const QByteArray &suffix : suffixes)
|
||||
retList.append(QString::fromUtf8(suffix));
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
|
||||
static const QStringList &supportedFragmentShaderSuffixes()
|
||||
{
|
||||
static const QStringList retList {"frag", "glsl", "glslf", "fsh"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
static const QStringList &supportedShaderSuffixes()
|
||||
{
|
||||
static const QStringList retList {"frag", "vert",
|
||||
"glsl", "glslv", "glslf",
|
||||
"vsh", "fsh"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
static const QStringList &supportedFontSuffixes()
|
||||
{
|
||||
static const QStringList retList {"ttf", "otf"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
static const QStringList &supportedAudioSuffixes()
|
||||
{
|
||||
static const QStringList retList {"wav"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
static const QStringList &supportedTexture3DSuffixes()
|
||||
{
|
||||
// These are file types only supported by 3D textures
|
||||
static QStringList retList {"hdr"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
static QPixmap defaultPixmapForType(const QString &type, const QSize &size)
|
||||
{
|
||||
return QPixmap(QStringLiteral(":/ItemLibrary/images/asset_%1_%2.png").arg(type).arg(size.width()));
|
||||
}
|
||||
|
||||
static QPixmap texturePixmap(const QString &fileName)
|
||||
{
|
||||
return HdrImage{fileName}.toPixmap();
|
||||
}
|
||||
|
||||
QString fontFamily(const QFileInfo &info)
|
||||
{
|
||||
QRawFont font(info.absoluteFilePath(), 10);
|
||||
if (font.isValid())
|
||||
return font.familyName();
|
||||
return {};
|
||||
}
|
||||
|
||||
class ItemLibraryFileIconProvider : public QFileIconProvider
|
||||
{
|
||||
public:
|
||||
ItemLibraryFileIconProvider(SynchronousImageCache &fontImageCache,
|
||||
QHash<QString, QPair<QDateTime, QIcon>> &iconCache)
|
||||
: QFileIconProvider()
|
||||
, m_fontImageCache(fontImageCache)
|
||||
, m_iconCache(iconCache)
|
||||
{
|
||||
}
|
||||
|
||||
QIcon icon( const QFileInfo & info ) const override
|
||||
{
|
||||
const QString filePath = info.absoluteFilePath();
|
||||
QPair<QDateTime, QIcon> &cachedIcon = m_iconCache[filePath];
|
||||
if (!cachedIcon.second.isNull() && cachedIcon.first == info.lastModified())
|
||||
return cachedIcon.second;
|
||||
|
||||
QIcon icon;
|
||||
const QString suffix = info.suffix().toLower();
|
||||
|
||||
// Provide icon depending on suffix
|
||||
QPixmap origPixmap;
|
||||
|
||||
if (supportedFontSuffixes().contains(suffix))
|
||||
return generateFontIcons(filePath);
|
||||
else if (supportedImageSuffixes().contains(suffix))
|
||||
origPixmap.load(filePath);
|
||||
else if (supportedTexture3DSuffixes().contains(suffix))
|
||||
origPixmap = texturePixmap(filePath);
|
||||
|
||||
for (auto iconSize : iconSizes) {
|
||||
QPixmap pixmap = origPixmap;
|
||||
if (pixmap.isNull()) {
|
||||
if (supportedAudioSuffixes().contains(suffix))
|
||||
pixmap = defaultPixmapForType("sound", iconSize);
|
||||
else if (supportedShaderSuffixes().contains(suffix))
|
||||
pixmap = defaultPixmapForType("shader", iconSize);
|
||||
if (pixmap.isNull())
|
||||
return QFileIconProvider::icon(info);
|
||||
}
|
||||
|
||||
if ((pixmap.width() > iconSize.width()) || (pixmap.height() > iconSize.height()))
|
||||
pixmap = pixmap.scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
icon.addPixmap(pixmap);
|
||||
}
|
||||
|
||||
cachedIcon.first = info.lastModified();
|
||||
cachedIcon.second = icon;
|
||||
return icon;
|
||||
}
|
||||
|
||||
QIcon generateFontIcons(const QString &filePath) const
|
||||
{
|
||||
return m_fontImageCache.icon(
|
||||
filePath,
|
||||
{},
|
||||
ImageCache::FontCollectorSizesAuxiliaryData{Utils::span{iconSizes},
|
||||
Theme::getColor(Theme::DStextColor).name(),
|
||||
"Abc"});
|
||||
}
|
||||
|
||||
private:
|
||||
// Generated icon sizes should contain all ItemLibraryResourceView needed icon sizes, and their
|
||||
// x2 versions for HDPI sceens
|
||||
std::vector<QSize> iconSizes = {{384, 384},
|
||||
{192, 192}, // Large
|
||||
{256, 256},
|
||||
{128, 128}, // Drag
|
||||
{96, 96}, // Medium
|
||||
{48, 48}, // Small
|
||||
{64, 64},
|
||||
{32, 32}}; // List
|
||||
|
||||
SynchronousImageCache &m_fontImageCache;
|
||||
QHash<QString, QPair<QDateTime, QIcon>> &m_iconCache;
|
||||
};
|
||||
|
||||
CustomFileSystemModel::CustomFileSystemModel(SynchronousImageCache &fontImageCache, QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_fileSystemModel(new QFileSystemModel(this))
|
||||
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
||||
, m_fontImageCache(fontImageCache)
|
||||
{
|
||||
m_updatePathTimer.setInterval(200);
|
||||
m_updatePathTimer.setSingleShot(true);
|
||||
m_updatePathTimer.callOnTimeout([this]() {
|
||||
updatePath(m_fileSystemModel->rootPath());
|
||||
});
|
||||
|
||||
// If project directory contents change, or one of the asset files is modified, we must
|
||||
// reconstruct the model to update the icons
|
||||
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged, [this] {
|
||||
m_updatePathTimer.start();
|
||||
});
|
||||
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::fileChanged, [this] {
|
||||
m_updatePathTimer.start();
|
||||
});
|
||||
}
|
||||
|
||||
void CustomFileSystemModel::setFilter(QDir::Filters)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool filterMetaIcons(const QString &fileName)
|
||||
{
|
||||
|
||||
QFileInfo info(fileName);
|
||||
|
||||
if (info.dir().path().split("/").contains("designer")) {
|
||||
|
||||
QDir currentDir = info.dir();
|
||||
|
||||
int i = 0;
|
||||
while (!currentDir.isRoot() && i < 3) {
|
||||
if (currentDir.dirName() == "designer") {
|
||||
if (!currentDir.entryList({"*.metainfo"}).isEmpty())
|
||||
return false;
|
||||
}
|
||||
|
||||
currentDir.cdUp();
|
||||
++i;
|
||||
}
|
||||
|
||||
if (info.dir().dirName() == "designer")
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QModelIndex CustomFileSystemModel::setRootPath(const QString &newPath)
|
||||
{
|
||||
if (m_fileSystemModel->rootPath() == newPath)
|
||||
return QAbstractListModel::index(0, 0);
|
||||
|
||||
return updatePath(newPath);
|
||||
}
|
||||
|
||||
QVariant CustomFileSystemModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role == Qt::ToolTipRole)
|
||||
return fileInfo(index).filePath();
|
||||
|
||||
if (role == Qt::FontRole) {
|
||||
QFont font = m_fileSystemModel->data(fileSystemModelIndex(index), role).value<QFont>();
|
||||
font.setPixelSize(Theme::instance()->smallFontPixelSize());
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
return m_fileSystemModel->data(fileSystemModelIndex(index), role);
|
||||
}
|
||||
|
||||
int CustomFileSystemModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return m_files.count();
|
||||
}
|
||||
|
||||
int CustomFileSystemModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QModelIndex CustomFileSystemModel::indexForPath(const QString &path, int /*column*/) const
|
||||
{
|
||||
return QAbstractListModel::index(m_files.indexOf(path), 0);
|
||||
}
|
||||
|
||||
QIcon CustomFileSystemModel::fileIcon(const QModelIndex &index) const
|
||||
{
|
||||
return m_fileSystemModel->fileIcon(fileSystemModelIndex(index));
|
||||
}
|
||||
|
||||
QString CustomFileSystemModel::fileName(const QModelIndex &index) const
|
||||
{
|
||||
return m_fileSystemModel->fileName(fileSystemModelIndex(index));
|
||||
}
|
||||
|
||||
QFileInfo CustomFileSystemModel::fileInfo(const QModelIndex &index) const
|
||||
{
|
||||
return m_fileSystemModel->fileInfo(fileSystemModelIndex(index));
|
||||
}
|
||||
|
||||
Qt::ItemFlags CustomFileSystemModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
return m_fileSystemModel->flags (fileSystemModelIndex(index));
|
||||
}
|
||||
|
||||
void CustomFileSystemModel::setSearchFilter(const QString &nameFilterList)
|
||||
{
|
||||
m_searchFilter = nameFilterList;
|
||||
setRootPath(m_fileSystemModel->rootPath());
|
||||
}
|
||||
|
||||
QPair<QString, QByteArray> CustomFileSystemModel::resourceTypeAndData(const QModelIndex &index) const
|
||||
{
|
||||
QFileInfo fi = fileInfo(index);
|
||||
QString suffix = fi.suffix().toLower();
|
||||
if (!suffix.isEmpty()) {
|
||||
if (supportedImageSuffixes().contains(suffix)) {
|
||||
// Data: Image format (suffix)
|
||||
return {"application/vnd.bauhaus.libraryresource.image", suffix.toUtf8()};
|
||||
} else if (supportedFontSuffixes().contains(suffix)) {
|
||||
// Data: Font family name
|
||||
return {"application/vnd.bauhaus.libraryresource.font", fontFamily(fi).toUtf8()};
|
||||
} else if (supportedShaderSuffixes().contains(suffix)) {
|
||||
// Data: shader type, frament (f) or vertex (v)
|
||||
return {"application/vnd.bauhaus.libraryresource.shader",
|
||||
supportedFragmentShaderSuffixes().contains(suffix) ? "f" : "v"};
|
||||
} else if (supportedAudioSuffixes().contains(suffix)) {
|
||||
// No extra data for sounds
|
||||
return {"application/vnd.bauhaus.libraryresource.sound", {}};
|
||||
} else if (supportedTexture3DSuffixes().contains(suffix)) {
|
||||
// Data: Image format (suffix)
|
||||
return {"application/vnd.bauhaus.libraryresource.texture3d", suffix.toUtf8()};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
const QSet<QString> &CustomFileSystemModel::supportedSuffixes() const
|
||||
{
|
||||
static QSet<QString> allSuffixes;
|
||||
if (allSuffixes.isEmpty()) {
|
||||
auto insertSuffixes = [](const QStringList &suffixes) {
|
||||
for (const auto &suffix : suffixes)
|
||||
allSuffixes.insert(suffix);
|
||||
};
|
||||
insertSuffixes(supportedImageSuffixes());
|
||||
insertSuffixes(supportedShaderSuffixes());
|
||||
insertSuffixes(supportedFontSuffixes());
|
||||
insertSuffixes(supportedAudioSuffixes());
|
||||
insertSuffixes(supportedTexture3DSuffixes());
|
||||
}
|
||||
return allSuffixes;
|
||||
}
|
||||
|
||||
const QSet<QString> &CustomFileSystemModel::previewableSuffixes() const
|
||||
{
|
||||
static QSet<QString> previewableSuffixes;
|
||||
if (previewableSuffixes.isEmpty()) {
|
||||
auto insertSuffixes = [](const QStringList &suffixes) {
|
||||
for (const auto &suffix : suffixes)
|
||||
previewableSuffixes.insert(suffix);
|
||||
};
|
||||
insertSuffixes(supportedFontSuffixes());
|
||||
}
|
||||
return previewableSuffixes;
|
||||
|
||||
}
|
||||
|
||||
void CustomFileSystemModel::appendIfNotFiltered(const QString &file)
|
||||
{
|
||||
if (filterMetaIcons(file))
|
||||
m_files.append(file);
|
||||
}
|
||||
|
||||
QModelIndex CustomFileSystemModel::updatePath(const QString &newPath)
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
// We must recreate icon provider to ensure modified icons are recreated
|
||||
auto newProvider = new ItemLibraryFileIconProvider(m_fontImageCache, m_iconCache);
|
||||
m_fileSystemModel->setIconProvider(newProvider);
|
||||
delete m_fileIconProvider;
|
||||
m_fileIconProvider = newProvider;
|
||||
|
||||
m_fileSystemModel->setRootPath(newPath);
|
||||
|
||||
m_fileSystemWatcher->removeDirectories(m_fileSystemWatcher->directories());
|
||||
m_fileSystemWatcher->removeFiles(m_fileSystemWatcher->files());
|
||||
|
||||
m_fileSystemWatcher->addDirectory(newPath, Utils::FileSystemWatcher::WatchAllChanges);
|
||||
|
||||
QStringList nameFilterList;
|
||||
|
||||
const QString searchFilter = m_searchFilter;
|
||||
|
||||
if (searchFilter.contains(QLatin1Char('.'))) {
|
||||
nameFilterList.append(QString(QStringLiteral("*%1*")).arg(searchFilter));
|
||||
} else {
|
||||
const QString filterTemplate("*%1*.%2");
|
||||
auto appendFilters = [&](const QStringList &suffixes) {
|
||||
for (const QString &ext : suffixes) {
|
||||
nameFilterList.append(filterTemplate.arg(searchFilter, ext));
|
||||
nameFilterList.append(filterTemplate.arg(searchFilter, ext.toUpper()));
|
||||
}
|
||||
};
|
||||
appendFilters(supportedImageSuffixes());
|
||||
appendFilters(supportedShaderSuffixes());
|
||||
appendFilters(supportedFontSuffixes());
|
||||
appendFilters(supportedAudioSuffixes());
|
||||
appendFilters(supportedTexture3DSuffixes());
|
||||
}
|
||||
|
||||
m_files.clear();
|
||||
|
||||
QDirIterator fileIterator(newPath, nameFilterList, QDir::Files, QDirIterator::Subdirectories);
|
||||
|
||||
while (fileIterator.hasNext())
|
||||
appendIfNotFiltered(fileIterator.next());
|
||||
|
||||
QDirIterator dirIterator(newPath, {}, QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot,
|
||||
QDirIterator::Subdirectories);
|
||||
while (dirIterator.hasNext()) {
|
||||
const QString entry = dirIterator.next();
|
||||
QFileInfo fi{entry};
|
||||
if (fi.isDir())
|
||||
m_fileSystemWatcher->addDirectory(entry, Utils::FileSystemWatcher::WatchAllChanges);
|
||||
else if (supportedSuffixes().contains(fi.suffix()))
|
||||
m_fileSystemWatcher->addFile(entry, Utils::FileSystemWatcher::WatchAllChanges);
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
|
||||
return QAbstractListModel::index(0, 0);
|
||||
}
|
||||
|
||||
QModelIndex CustomFileSystemModel::fileSystemModelIndex(const QModelIndex &index) const
|
||||
{
|
||||
const int row = index.row();
|
||||
return m_fileSystemModel->index(m_files.at(row));
|
||||
}
|
||||
|
||||
} //QmlDesigner
|
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "itemlibraryassetsdir.h"
|
||||
#include "itemlibraryassetsdirsmodel.h"
|
||||
#include "itemlibraryassetsfilesmodel.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ItemLibraryAssetsDir::ItemLibraryAssetsDir(const QString &path, int depth, bool expanded, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_dirPath(path)
|
||||
, m_dirDepth(depth)
|
||||
, m_dirExpanded(expanded)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString ItemLibraryAssetsDir::dirName() const { return m_dirPath.split('/').last(); }
|
||||
QString ItemLibraryAssetsDir::dirPath() const { return m_dirPath; }
|
||||
int ItemLibraryAssetsDir::dirDepth() const { return m_dirDepth; }
|
||||
bool ItemLibraryAssetsDir::dirExpanded() const { return m_dirExpanded; }
|
||||
bool ItemLibraryAssetsDir::dirVisible() const { return m_dirVisible; }
|
||||
|
||||
void ItemLibraryAssetsDir::setDirExpanded(bool expand)
|
||||
{
|
||||
if (m_dirExpanded != expand) {
|
||||
m_dirExpanded = expand;
|
||||
emit dirExpandedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ItemLibraryAssetsDir::setDirVisible(bool visible)
|
||||
{
|
||||
if (m_dirVisible != visible) {
|
||||
m_dirVisible = visible;
|
||||
emit dirVisibleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QObject *ItemLibraryAssetsDir::filesModel() const
|
||||
{
|
||||
return m_filesModel;
|
||||
}
|
||||
|
||||
QObject *ItemLibraryAssetsDir::dirsModel() const
|
||||
{
|
||||
return m_dirsModel;
|
||||
}
|
||||
|
||||
void ItemLibraryAssetsDir::addDir(ItemLibraryAssetsDir *assetsDir)
|
||||
{
|
||||
if (!m_dirsModel)
|
||||
m_dirsModel = new ItemLibraryAssetsDirsModel(this);
|
||||
|
||||
m_dirsModel->addDir(assetsDir);
|
||||
}
|
||||
|
||||
void ItemLibraryAssetsDir::addFile(const QString &filePath)
|
||||
{
|
||||
if (!m_filesModel)
|
||||
m_filesModel = new ItemLibraryAssetsFilesModel(this);
|
||||
|
||||
m_filesModel->addFile(filePath);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QObject>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ItemLibraryAssetsDirsModel;
|
||||
class ItemLibraryAssetsFilesModel;
|
||||
|
||||
class ItemLibraryAssetsDir : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString dirName READ dirName NOTIFY dirNameChanged)
|
||||
Q_PROPERTY(QString dirPath READ dirPath NOTIFY dirPathChanged)
|
||||
Q_PROPERTY(bool dirExpanded READ dirExpanded WRITE setDirExpanded NOTIFY dirExpandedChanged)
|
||||
Q_PROPERTY(bool dirVisible READ dirVisible WRITE setDirVisible NOTIFY dirVisibleChanged)
|
||||
Q_PROPERTY(int dirDepth READ dirDepth NOTIFY dirDepthChanged)
|
||||
Q_PROPERTY(QObject *filesModel READ filesModel NOTIFY filesModelChanged)
|
||||
Q_PROPERTY(QObject *dirsModel READ dirsModel NOTIFY dirsModelChanged)
|
||||
|
||||
public:
|
||||
ItemLibraryAssetsDir(const QString &path, int depth, bool expanded = true, QObject *parent = nullptr);
|
||||
|
||||
QString dirName() const;
|
||||
QString dirPath() const;
|
||||
int dirDepth() const;
|
||||
|
||||
bool dirExpanded() const;
|
||||
bool dirVisible() const;
|
||||
void setDirExpanded(bool expand);
|
||||
void setDirVisible(bool visible);
|
||||
|
||||
QObject *filesModel() const;
|
||||
QObject *dirsModel() const;
|
||||
|
||||
void addDir(ItemLibraryAssetsDir *assetsDir);
|
||||
void addFile(const QString &filePath);
|
||||
|
||||
signals:
|
||||
void dirNameChanged();
|
||||
void dirPathChanged();
|
||||
void dirDepthChanged();
|
||||
void dirExpandedChanged();
|
||||
void dirVisibleChanged();
|
||||
void filesModelChanged();
|
||||
void dirsModelChanged();
|
||||
|
||||
private:
|
||||
QString m_dirPath;
|
||||
int m_dirDepth = 0;
|
||||
bool m_dirExpanded = true;
|
||||
bool m_dirVisible = true;
|
||||
ItemLibraryAssetsDirsModel *m_dirsModel = nullptr;
|
||||
ItemLibraryAssetsFilesModel *m_filesModel = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "itemlibraryassetsdirsmodel.h"
|
||||
#include "itemlibraryassetsmodel.h"
|
||||
|
||||
#include <QMetaProperty>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ItemLibraryAssetsDirsModel::ItemLibraryAssetsDirsModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
// add roles
|
||||
const QMetaObject meta = ItemLibraryAssetsDir::staticMetaObject;
|
||||
for (int i = meta.propertyOffset(); i < meta.propertyCount(); ++i)
|
||||
m_roleNames.insert(i, meta.property(i).name());
|
||||
}
|
||||
|
||||
QVariant ItemLibraryAssetsDirsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid index requested: " << QString::number(index.row());
|
||||
return {};
|
||||
}
|
||||
|
||||
if (m_roleNames.contains(role))
|
||||
return m_dirs[index.row()]->property(m_roleNames[role]);
|
||||
|
||||
qWarning() << Q_FUNC_INFO << "Invalid role requested: " << QString::number(role);
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ItemLibraryAssetsDirsModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
// currently only dirExpanded property is updatable
|
||||
if (index.isValid() && m_roleNames.contains(role)) {
|
||||
QVariant currValue = m_dirs.at(index.row())->property(m_roleNames.value(role));
|
||||
if (currValue != value) {
|
||||
m_dirs.at(index.row())->setProperty(m_roleNames.value(role), value);
|
||||
if (m_roleNames.value(role) == "dirExpanded")
|
||||
ItemLibraryAssetsModel::saveExpandedState(value.toBool(), m_dirs.at(index.row())->dirPath());
|
||||
emit dataChanged(index, index, {role});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ItemLibraryAssetsDirsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
return m_dirs.size();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ItemLibraryAssetsDirsModel::roleNames() const
|
||||
{
|
||||
return m_roleNames;
|
||||
}
|
||||
|
||||
void ItemLibraryAssetsDirsModel::addDir(ItemLibraryAssetsDir *assetsDir)
|
||||
{
|
||||
m_dirs.append(assetsDir);
|
||||
}
|
||||
|
||||
} // 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,32 +25,28 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <previewtooltip/previewtooltipbackend.h>
|
||||
|
||||
#include <QListView>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QActionGroup;
|
||||
QT_END_NAMESPACE
|
||||
#include <QAbstractListModel>
|
||||
#include "itemlibraryassetsdir.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class AsynchronousImageCache;
|
||||
|
||||
class ItemLibraryResourceView : public QListView {
|
||||
|
||||
class ItemLibraryAssetsDirsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ItemLibraryResourceView(AsynchronousImageCache &fontImageCache,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
void startDrag(Qt::DropActions supportedActions) override;
|
||||
bool viewportEvent(QEvent *event) override;
|
||||
public:
|
||||
ItemLibraryAssetsDirsModel(QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void addDir(ItemLibraryAssetsDir *assetsDir);
|
||||
|
||||
private:
|
||||
void addSizeAction(QActionGroup *group, const QString &text, int size, int iconSize);
|
||||
|
||||
std::unique_ptr<PreviewTooltipBackend> m_fontPreviewTooltipBackend;
|
||||
QList<ItemLibraryAssetsDir *> m_dirs;
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "itemlibraryassetsfilesmodel.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ItemLibraryAssetsFilesModel::ItemLibraryAssetsFilesModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
// add roles
|
||||
m_roleNames.insert(FileNameRole, "fileName");
|
||||
m_roleNames.insert(FilePathRole, "filePath");
|
||||
}
|
||||
|
||||
QVariant ItemLibraryAssetsFilesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid index requested: " << QString::number(index.row());
|
||||
return {};
|
||||
}
|
||||
|
||||
if (role == FileNameRole)
|
||||
return m_files[index.row()].split('/').last();
|
||||
|
||||
if (role == FilePathRole)
|
||||
return m_files[index.row()];
|
||||
|
||||
qWarning() << Q_FUNC_INFO << "Invalid role requested: " << QString::number(role);
|
||||
return {};
|
||||
}
|
||||
|
||||
int ItemLibraryAssetsFilesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
return m_files.size();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ItemLibraryAssetsFilesModel::roleNames() const
|
||||
{
|
||||
return m_roleNames;
|
||||
}
|
||||
|
||||
void ItemLibraryAssetsFilesModel::addFile(const QString &filePath)
|
||||
{
|
||||
m_files.append(filePath);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QAbstractListModel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ItemLibraryAssetsFilesModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ItemLibraryAssetsFilesModel(QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void addFile(const QString &filePath);
|
||||
|
||||
private:
|
||||
enum Roles {FileNameRole = Qt::UserRole + 1,
|
||||
FilePathRole};
|
||||
|
||||
QStringList m_files;
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
};
|
||||
|
||||
} // QmlDesigner
|
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "itemlibraryassetsiconprovider.h"
|
||||
#include "itemlibraryassetsmodel.h"
|
||||
|
||||
#include <hdrimage.h>
|
||||
#include <theme.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ItemLibraryAssetsIconProvider::ItemLibraryAssetsIconProvider(SynchronousImageCache &fontImageCache)
|
||||
: QQuickImageProvider(QQuickImageProvider::Pixmap)
|
||||
, m_fontImageCache(fontImageCache)
|
||||
{
|
||||
}
|
||||
|
||||
QPixmap ItemLibraryAssetsIconProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
|
||||
{
|
||||
QPixmap pixmap;
|
||||
const QString suffix = "*." + id.split('.').last();
|
||||
if (ItemLibraryAssetsModel::supportedFontSuffixes().contains(suffix))
|
||||
pixmap = generateFontIcons(id);
|
||||
else if (ItemLibraryAssetsModel::supportedImageSuffixes().contains(suffix))
|
||||
pixmap = Utils::StyleHelper::dpiSpecificImageFile(id);
|
||||
else if (ItemLibraryAssetsModel::supportedTexture3DSuffixes().contains(suffix))
|
||||
pixmap = HdrImage{id}.toPixmap();
|
||||
else if (ItemLibraryAssetsModel::supportedAudioSuffixes().contains(suffix))
|
||||
pixmap = QPixmap(Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_sound_48.png"));
|
||||
|
||||
if (size) {
|
||||
size->setWidth(pixmap.width());
|
||||
size->setHeight(pixmap.height());
|
||||
}
|
||||
|
||||
if (pixmap.isNull()) {
|
||||
pixmap = QPixmap(Utils::StyleHelper::dpiSpecificImageFile(
|
||||
QStringLiteral(":/ItemLibrary/images/item-default-icon.png")));
|
||||
}
|
||||
|
||||
if (requestedSize.isValid())
|
||||
return pixmap.scaled(requestedSize);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QPixmap ItemLibraryAssetsIconProvider::generateFontIcons(const QString &filePath) const
|
||||
{
|
||||
return m_fontImageCache.icon(filePath, {},
|
||||
ImageCache::FontCollectorSizesAuxiliaryData{Utils::span{iconSizes},
|
||||
Theme::getColor(Theme::DStextColor).name(),
|
||||
"Abc"}).pixmap({48, 48});
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <synchronousimagecache.h>
|
||||
|
||||
#include <QQuickImageProvider>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ItemLibraryAssetsIconProvider : public QQuickImageProvider
|
||||
{
|
||||
public:
|
||||
ItemLibraryAssetsIconProvider(SynchronousImageCache &fontImageCache);
|
||||
|
||||
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
|
||||
|
||||
private:
|
||||
QPixmap generateFontIcons(const QString &filePath) const;
|
||||
|
||||
SynchronousImageCache &m_fontImageCache;
|
||||
|
||||
// Generated icon sizes should contain all ItemLibraryResourceView needed icon sizes, and their
|
||||
// x2 versions for HDPI sceens
|
||||
std::vector<QSize> iconSizes = {{384, 384},
|
||||
{192, 192}, // Large
|
||||
{256, 256},
|
||||
{128, 128}, // Drag
|
||||
{96, 96}, // Medium
|
||||
{48, 48}, // Small
|
||||
{64, 64},
|
||||
{32, 32}}; // List
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,251 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "itemlibraryassetsmodel.h"
|
||||
#include "itemlibraryassetsdirsmodel.h"
|
||||
#include "itemlibraryassetsfilesmodel.h"
|
||||
|
||||
#include <synchronousimagecache.h>
|
||||
#include <theme.h>
|
||||
#include <hdrimage.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFont>
|
||||
#include <QImageReader>
|
||||
#include <QMetaProperty>
|
||||
#include <QPainter>
|
||||
#include <QRawFont>
|
||||
#include "qmldesignerplugin.h"
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <utils/stylehelper.h>
|
||||
#include <utils/filesystemwatcher.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
void ItemLibraryAssetsModel::saveExpandedState(bool expanded, const QString §ionName)
|
||||
{
|
||||
m_expandedStateHash.insert(sectionName, expanded);
|
||||
}
|
||||
|
||||
bool ItemLibraryAssetsModel::loadExpandedState(const QString §ionName)
|
||||
{
|
||||
return m_expandedStateHash.value(sectionName, true);
|
||||
}
|
||||
|
||||
const QStringList &ItemLibraryAssetsModel::supportedImageSuffixes()
|
||||
{
|
||||
static QStringList retList;
|
||||
if (retList.isEmpty()) {
|
||||
const QList<QByteArray> suffixes = QImageReader::supportedImageFormats();
|
||||
for (const QByteArray &suffix : suffixes)
|
||||
retList.append("*." + QString::fromUtf8(suffix));
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
|
||||
const QStringList &ItemLibraryAssetsModel::supportedFragmentShaderSuffixes()
|
||||
{
|
||||
static const QStringList retList {"*.frag", "*.glsl", "*.glslf", "*.fsh"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
const QStringList &ItemLibraryAssetsModel::supportedShaderSuffixes()
|
||||
{
|
||||
static const QStringList retList {"*.frag", "*.vert",
|
||||
"*.glsl", "*.glslv", "*.glslf",
|
||||
"*.vsh", "*.fsh"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
const QStringList &ItemLibraryAssetsModel::supportedFontSuffixes()
|
||||
{
|
||||
static const QStringList retList {"*.ttf", "*.otf"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
const QStringList &ItemLibraryAssetsModel::supportedAudioSuffixes()
|
||||
{
|
||||
static const QStringList retList {"*.wav"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
const QStringList &ItemLibraryAssetsModel::supportedTexture3DSuffixes()
|
||||
{
|
||||
// These are file types only supported by 3D textures
|
||||
static QStringList retList {"*.hdr"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
ItemLibraryAssetsModel::ItemLibraryAssetsModel(SynchronousImageCache &fontImageCache,
|
||||
Utils::FileSystemWatcher *fileSystemWatcher,
|
||||
QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_fontImageCache(fontImageCache)
|
||||
, m_fileSystemWatcher(fileSystemWatcher)
|
||||
{
|
||||
// add role names
|
||||
int role = 0;
|
||||
const QMetaObject meta = ItemLibraryAssetsDir::staticMetaObject;
|
||||
for (int i = meta.propertyOffset(); i < meta.propertyCount(); ++i)
|
||||
m_roleNames.insert(role++, meta.property(i).name());
|
||||
}
|
||||
|
||||
QVariant ItemLibraryAssetsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid index requested: " << QString::number(index.row());
|
||||
return {};
|
||||
}
|
||||
|
||||
if (m_assetsDir && m_roleNames.contains(role)) {
|
||||
return m_assetsDir->property(m_roleNames.value(role));
|
||||
}
|
||||
|
||||
qWarning() << Q_FUNC_INFO << "Invalid role requested: " << QString::number(role);
|
||||
return {};
|
||||
}
|
||||
|
||||
int ItemLibraryAssetsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ItemLibraryAssetsModel::roleNames() const
|
||||
{
|
||||
return m_roleNames;
|
||||
}
|
||||
|
||||
// called when a directory is changed to refresh the model for this directory
|
||||
void ItemLibraryAssetsModel::refresh()
|
||||
{
|
||||
setRootPath(m_assetsDir->dirPath());
|
||||
}
|
||||
|
||||
void ItemLibraryAssetsModel::setRootPath(const QString &path)
|
||||
{
|
||||
static const QStringList supportedTopLevelDirs {"images", "sounds", "fonts", "assets"};
|
||||
|
||||
m_fileSystemWatcher->removeDirectories(m_fileSystemWatcher->directories());
|
||||
m_fileSystemWatcher->removeFiles(m_fileSystemWatcher->files());
|
||||
|
||||
DesignDocument *currDesignDoc = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
if (!currDesignDoc) // happens sometimes on QDS shutdown
|
||||
return;
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile(currDesignDoc->fileName());
|
||||
QString projectName = project ? project->displayName() : "";
|
||||
|
||||
std::function<bool(ItemLibraryAssetsDir *, int)> parseDirRecursive;
|
||||
parseDirRecursive = [this, &parseDirRecursive, &projectName](ItemLibraryAssetsDir *currAssetsDir, int currDepth) {
|
||||
m_fileSystemWatcher->addDirectory(currAssetsDir->dirPath(), Utils::FileSystemWatcher::WatchAllChanges);
|
||||
|
||||
QDir dir(currAssetsDir->dirPath());
|
||||
dir.setNameFilters(supportedSuffixes().values());
|
||||
dir.setFilter(QDir::Files);
|
||||
QDirIterator itFiles(dir);
|
||||
bool isEmpty = true;
|
||||
while (itFiles.hasNext()) {
|
||||
QString filePath = itFiles.next();
|
||||
QString fileName = filePath.split('/').last();
|
||||
if (m_searchText.isEmpty() || fileName.contains(m_searchText, Qt::CaseInsensitive)) {
|
||||
currAssetsDir->addFile(filePath);
|
||||
m_fileSystemWatcher->addFile(filePath, Utils::FileSystemWatcher::WatchAllChanges);
|
||||
isEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
dir.setNameFilters({});
|
||||
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
QDirIterator itDirs(dir);
|
||||
|
||||
while (itDirs.hasNext()) {
|
||||
QDir subDir = itDirs.next();
|
||||
if (subDir.isEmpty() || projectName == subDir.dirName()
|
||||
|| (currDepth == 1 && !supportedTopLevelDirs.contains(subDir.dirName()))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemLibraryAssetsDir *assetsDir = new ItemLibraryAssetsDir(subDir.path(), currDepth, loadExpandedState(subDir.path()), currAssetsDir);
|
||||
currAssetsDir->addDir(assetsDir);
|
||||
isEmpty &= parseDirRecursive(assetsDir, currDepth + 1);
|
||||
}
|
||||
|
||||
if (isEmpty)
|
||||
currAssetsDir->setDirVisible(false);
|
||||
|
||||
return isEmpty;
|
||||
};
|
||||
|
||||
if (m_assetsDir)
|
||||
delete m_assetsDir;
|
||||
|
||||
beginResetModel();
|
||||
m_assetsDir = new ItemLibraryAssetsDir(path, 0, true, this);
|
||||
parseDirRecursive(m_assetsDir, 1);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ItemLibraryAssetsModel::setSearchText(const QString &searchText)
|
||||
{
|
||||
if (m_searchText != searchText) {
|
||||
m_searchText = searchText;
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
const QSet<QString> &ItemLibraryAssetsModel::supportedSuffixes() const
|
||||
{
|
||||
static QSet<QString> allSuffixes;
|
||||
if (allSuffixes.isEmpty()) {
|
||||
auto insertSuffixes = [](const QStringList &suffixes) {
|
||||
for (const auto &suffix : suffixes)
|
||||
allSuffixes.insert(suffix);
|
||||
};
|
||||
insertSuffixes(supportedImageSuffixes());
|
||||
insertSuffixes(supportedShaderSuffixes());
|
||||
insertSuffixes(supportedFontSuffixes());
|
||||
insertSuffixes(supportedAudioSuffixes());
|
||||
insertSuffixes(supportedTexture3DSuffixes());
|
||||
}
|
||||
return allSuffixes;
|
||||
}
|
||||
|
||||
const QSet<QString> &ItemLibraryAssetsModel::previewableSuffixes() const
|
||||
{
|
||||
static QSet<QString> previewableSuffixes;
|
||||
if (previewableSuffixes.isEmpty()) {
|
||||
auto insertSuffixes = [](const QStringList &suffixes) {
|
||||
for (const auto &suffix : suffixes)
|
||||
previewableSuffixes.insert(suffix);
|
||||
};
|
||||
insertSuffixes(supportedFontSuffixes());
|
||||
}
|
||||
return previewableSuffixes;
|
||||
}
|
||||
|
||||
} // 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,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractListModel>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QHash>
|
||||
@@ -34,59 +34,54 @@
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFileIconProvider;
|
||||
class QFileSystemModel;
|
||||
QT_END_NAMESPACE
|
||||
#include "itemlibraryassetsdir.h"
|
||||
|
||||
namespace Utils { class FileSystemWatcher; }
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class SynchronousImageCache;
|
||||
class ItemLibraryFileIconProvider;
|
||||
|
||||
class CustomFileSystemModel : public QAbstractListModel
|
||||
class ItemLibraryAssetsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CustomFileSystemModel(QmlDesigner::SynchronousImageCache &fontImageCache,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
void setFilter(QDir::Filters filters);
|
||||
QString rootPath() const;
|
||||
QModelIndex setRootPath(const QString &newPath);
|
||||
public:
|
||||
ItemLibraryAssetsModel(QmlDesigner::SynchronousImageCache &fontImageCache,
|
||||
Utils::FileSystemWatcher *fileSystemWatcher,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex & parent = QModelIndex()) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
QModelIndex indexForPath(const QString & path, int column = 0) const;
|
||||
void refresh();
|
||||
void setRootPath(const QString &path);
|
||||
void setSearchText(const QString &searchText);
|
||||
|
||||
QIcon fileIcon(const QModelIndex & index) const;
|
||||
QString fileName(const QModelIndex & index) const;
|
||||
QFileInfo fileInfo(const QModelIndex & index) const;
|
||||
static const QStringList &supportedImageSuffixes();
|
||||
static const QStringList &supportedFragmentShaderSuffixes();
|
||||
static const QStringList &supportedShaderSuffixes();
|
||||
static const QStringList &supportedFontSuffixes();
|
||||
static const QStringList &supportedAudioSuffixes();
|
||||
static const QStringList &supportedTexture3DSuffixes();
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
void setSearchFilter(const QString &nameFilterList);
|
||||
|
||||
QPair<QString, QByteArray> resourceTypeAndData(const QModelIndex &index) const;
|
||||
const QSet<QString> &supportedSuffixes() const;
|
||||
const QSet<QString> &previewableSuffixes() const;
|
||||
|
||||
private:
|
||||
QModelIndex updatePath(const QString &newPath);
|
||||
QModelIndex fileSystemModelIndex(const QModelIndex &index) const;
|
||||
void appendIfNotFiltered(const QString &file);
|
||||
static void saveExpandedState(bool expanded, const QString §ionName);
|
||||
static bool loadExpandedState(const QString §ionName);
|
||||
|
||||
QFileSystemModel *m_fileSystemModel;
|
||||
QStringList m_files;
|
||||
QString m_searchFilter;
|
||||
Utils::FileSystemWatcher *m_fileSystemWatcher;
|
||||
private:
|
||||
SynchronousImageCache &m_fontImageCache;
|
||||
ItemLibraryFileIconProvider *m_fileIconProvider = nullptr;
|
||||
QHash<QString, QPair<QDateTime, QIcon>> m_iconCache;
|
||||
QTimer m_updatePathTimer;
|
||||
|
||||
QString m_searchText;
|
||||
Utils::FileSystemWatcher *m_fileSystemWatcher = nullptr;
|
||||
ItemLibraryAssetsDir *m_assetsDir = nullptr;
|
||||
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
inline static QHash<QString, bool> m_expandedStateHash;
|
||||
};
|
||||
|
||||
} //QmlDesigner
|
||||
} // namespace QmlDesigner
|
@@ -1,206 +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 "itemlibraryresourceview.h"
|
||||
|
||||
#include "customfilesystemmodel.h"
|
||||
|
||||
#include <theme.h>
|
||||
#include <asynchronousimagecache.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QActionGroup>
|
||||
#include <QDebug>
|
||||
#include <QDrag>
|
||||
#include <QFileSystemModel>
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QProxyStyle>
|
||||
#include <QScrollBar>
|
||||
#include <QtGui/qevent.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
void ItemLibraryResourceView::addSizeAction(QActionGroup *group, const QString &text, int gridSize, int iconSize)
|
||||
{
|
||||
auto action = new QAction(text, group);
|
||||
group->addAction(action);
|
||||
action->setCheckable(true);
|
||||
QAction::connect(action, &QAction::triggered, this, [this, gridSize, iconSize]() {
|
||||
setViewMode(QListView::IconMode);
|
||||
setGridSize(QSize(gridSize, gridSize));
|
||||
setIconSize(QSize(iconSize, iconSize));
|
||||
verticalScrollBar()->setSingleStep(-1); //step auto-adjustment
|
||||
|
||||
setDragEnabled(true);
|
||||
setWrapping(true);
|
||||
});
|
||||
}
|
||||
|
||||
ItemLibraryResourceView::ItemLibraryResourceView(AsynchronousImageCache &fontImageCache,
|
||||
QWidget *parent)
|
||||
: QListView(parent)
|
||||
{
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
|
||||
setGridSize(QSize(128, 128));
|
||||
setIconSize(QSize(96, 96));
|
||||
setSpacing(4);
|
||||
|
||||
setViewMode(QListView::IconMode);
|
||||
setMovement(QListView::Snap);
|
||||
setResizeMode(QListView::Adjust);
|
||||
setSelectionRectVisible(false);
|
||||
setWrapping(true);
|
||||
setWordWrap(true);
|
||||
|
||||
setDragDropMode(QAbstractItemView::DragOnly);
|
||||
|
||||
setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
|
||||
auto actionGroup = new QActionGroup(this);
|
||||
actionGroup->setExclusive(true);
|
||||
|
||||
addSizeAction(actionGroup, tr("Large Icons"), 256, 192);
|
||||
addSizeAction(actionGroup, tr("Medium Icons"), 128, 96);
|
||||
addSizeAction(actionGroup, tr("Small Icons"), 96, 48);
|
||||
|
||||
QAction *action = new QAction(tr("List"), actionGroup);
|
||||
actionGroup->addAction(action);
|
||||
action->setCheckable(true);
|
||||
QAction::connect(action, &QAction::triggered, this, [this](){
|
||||
setViewMode(QListView::ListMode);
|
||||
setGridSize(QSize());
|
||||
setIconSize(QSize(32, 32));
|
||||
setDragEnabled(true);
|
||||
setWrapping(false);
|
||||
});
|
||||
|
||||
QAction *defaultAction = actionGroup->actions().at(1);
|
||||
defaultAction->toggle();
|
||||
|
||||
addActions(actionGroup->actions());
|
||||
|
||||
viewport()->setAttribute(Qt::WA_Hover);
|
||||
m_fontPreviewTooltipBackend = std::make_unique<PreviewTooltipBackend>(fontImageCache);
|
||||
// Note: Though the text specified here appears in UI, it shouldn't be translated, as it's
|
||||
// a commonly used sentence to preview the font glyphs in latin fonts.
|
||||
// For fonts that do not have latin glyphs, the font family name will have to
|
||||
// suffice for preview. Font family name is inserted into %1 at render time.
|
||||
m_fontPreviewTooltipBackend->setAuxiliaryData(
|
||||
ImageCache::FontCollectorSizeAuxiliaryData{QSize{300, 300},
|
||||
Theme::getColor(Theme::DStextColor).name(),
|
||||
QStringLiteral("The quick brown fox jumps\n"
|
||||
"over the lazy dog\n"
|
||||
"1234567890")});
|
||||
}
|
||||
|
||||
void ItemLibraryResourceView::startDrag(Qt::DropActions /* supportedActions */)
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
const auto indexes = selectedIndexes();
|
||||
if (indexes.isEmpty())
|
||||
return;
|
||||
|
||||
const QModelIndex &index = indexes.constFirst();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
auto fileSystemModel = qobject_cast<CustomFileSystemModel*>(model());
|
||||
Q_ASSERT(fileSystemModel);
|
||||
QPair<QString, QByteArray> typeAndData = fileSystemModel->resourceTypeAndData(index);
|
||||
|
||||
if (typeAndData.first.isEmpty())
|
||||
return;
|
||||
|
||||
QFileInfo fileInfo = fileSystemModel->fileInfo(index);
|
||||
|
||||
auto drag = new QDrag(this);
|
||||
drag->setPixmap(fileSystemModel->fileIcon(index).pixmap(128, 128));
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(QLatin1String("application/vnd.bauhaus.libraryresource"),
|
||||
fileInfo.absoluteFilePath().toUtf8());
|
||||
mimeData->setData(typeAndData.first, typeAndData.second);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec();
|
||||
}
|
||||
|
||||
bool ItemLibraryResourceView::viewportEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
auto fileSystemModel = qobject_cast<CustomFileSystemModel *>(model());
|
||||
Q_ASSERT(fileSystemModel);
|
||||
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
|
||||
QModelIndex index = indexAt(helpEvent->pos());
|
||||
if (index.isValid()) {
|
||||
QFileInfo fi = fileSystemModel->fileInfo(index);
|
||||
if (fileSystemModel->previewableSuffixes().contains(fi.suffix())) {
|
||||
QString filePath = fi.absoluteFilePath();
|
||||
if (!filePath.isEmpty()) {
|
||||
if (!m_fontPreviewTooltipBackend->isVisible()
|
||||
|| m_fontPreviewTooltipBackend->path() != filePath) {
|
||||
m_fontPreviewTooltipBackend->setPath(filePath);
|
||||
m_fontPreviewTooltipBackend->setName(fi.fileName());
|
||||
m_fontPreviewTooltipBackend->showTooltip();
|
||||
} else {
|
||||
m_fontPreviewTooltipBackend->reposition();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_fontPreviewTooltipBackend->hideTooltip();
|
||||
} else if (event->type() == QEvent::Leave) {
|
||||
m_fontPreviewTooltipBackend->hideTooltip();
|
||||
} else if (event->type() == QEvent::HoverMove) {
|
||||
if (m_fontPreviewTooltipBackend->isVisible()) {
|
||||
auto fileSystemModel = qobject_cast<CustomFileSystemModel *>(model());
|
||||
Q_ASSERT(fileSystemModel);
|
||||
auto *he = static_cast<QHoverEvent *>(event);
|
||||
QModelIndex index = indexAt(he->pos());
|
||||
if (index.isValid()) {
|
||||
QFileInfo fi = fileSystemModel->fileInfo(index);
|
||||
if (fi.absoluteFilePath() != m_fontPreviewTooltipBackend->path())
|
||||
m_fontPreviewTooltipBackend->hideTooltip();
|
||||
else
|
||||
m_fontPreviewTooltipBackend->reposition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QListView::viewportEvent(event);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "itemlibrarywidget.h"
|
||||
|
||||
#include "customfilesystemmodel.h"
|
||||
#include "itemlibraryassetsmodel.h"
|
||||
#include "itemlibraryiconimageprovider.h"
|
||||
#include "itemlibraryimport.h"
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <itemlibraryinfo.h>
|
||||
#include <itemlibrarymodel.h>
|
||||
#include <itemlibraryaddimportmodel.h>
|
||||
#include "itemlibraryassetsiconprovider.h"
|
||||
#include <metainfo.h>
|
||||
#include <model.h>
|
||||
#include <rewritingexception.h>
|
||||
@@ -46,6 +47,7 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/flowlayout.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/filesystemwatcher.h>
|
||||
#include <utils/stylehelper.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
@@ -125,13 +127,16 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
AsynchronousImageCache &asynchronousFontImageCache,
|
||||
SynchronousImageCache &synchronousFontImageCache)
|
||||
: m_itemIconSize(24, 24)
|
||||
, m_fontImageCache(synchronousFontImageCache)
|
||||
, m_itemLibraryModel(new ItemLibraryModel(this))
|
||||
, m_itemLibraryAddImportModel(new ItemLibraryAddImportModel(this))
|
||||
, m_resourcesFileSystemModel{new CustomFileSystemModel(synchronousFontImageCache, this)}
|
||||
, m_assetsIconProvider(new ItemLibraryAssetsIconProvider(synchronousFontImageCache))
|
||||
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
||||
, m_assetsModel(new ItemLibraryAssetsModel(synchronousFontImageCache, m_fileSystemWatcher, this))
|
||||
, m_headerWidget(new QQuickWidget(this))
|
||||
, m_addImportWidget(new QQuickWidget(this))
|
||||
, m_itemViewQuickWidget(new QQuickWidget(this))
|
||||
, m_resourcesView(new ItemLibraryResourceView(asynchronousFontImageCache, this))
|
||||
, m_assetsWidget(new QQuickWidget(this))
|
||||
, m_imageCache{imageCache}
|
||||
{
|
||||
m_compressionTimer.setInterval(200);
|
||||
@@ -180,12 +185,47 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
Theme::setupTheme(m_itemViewQuickWidget->engine());
|
||||
m_itemViewQuickWidget->installEventFilter(this);
|
||||
|
||||
// connect Resources view and its model
|
||||
m_resourcesView->setModel(m_resourcesFileSystemModel.data());
|
||||
m_fontPreviewTooltipBackend = std::make_unique<PreviewTooltipBackend>(asynchronousFontImageCache);
|
||||
// Note: Though the text specified here appears in UI, it shouldn't be translated, as it's
|
||||
// a commonly used sentence to preview the font glyphs in latin fonts.
|
||||
// For fonts that do not have latin glyphs, the font family name will have to suffice for preview.
|
||||
m_fontPreviewTooltipBackend->setAuxiliaryData(
|
||||
ImageCache::FontCollectorSizeAuxiliaryData{QSize{300, 300},
|
||||
Theme::getColor(Theme::DStextColor).name(),
|
||||
QStringLiteral("The quick brown fox jumps\n"
|
||||
"over the lazy dog\n"
|
||||
"1234567890")});
|
||||
// create assets widget
|
||||
m_assetsWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
Theme::setupTheme(m_assetsWidget->engine());
|
||||
m_assetsWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||
m_assetsWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||
m_assetsWidget->engine()->addImageProvider("qmldesigner_assets", m_assetsIconProvider);
|
||||
m_assetsWidget->rootContext()->setContextProperties(QVector<QQmlContext::PropertyPair>{
|
||||
{{"assetsModel"}, QVariant::fromValue(m_assetsModel.data())},
|
||||
{{"rootView"}, QVariant::fromValue(this)},
|
||||
{{"tooltipBackend"}, QVariant::fromValue(m_fontPreviewTooltipBackend.get())}
|
||||
});
|
||||
|
||||
// If project directory contents change, or one of the asset files is modified, we must
|
||||
// reconstruct the model to update the icons
|
||||
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged, [this](const QString & changedDirPath) {
|
||||
Q_UNUSED(changedDirPath)
|
||||
// TODO: find a clever way to only refresh the changed directory part of the model
|
||||
|
||||
m_assetsModel->refresh();
|
||||
|
||||
// reload assets qml so that an overridden file's image shows the new image
|
||||
QTimer::singleShot(100, [this] {
|
||||
const QString assetsQmlPath = qmlSourcesPath() + "/Assets.qml";
|
||||
m_assetsWidget->engine()->clearComponentCache();
|
||||
m_assetsWidget->setSource(QUrl::fromLocalFile(assetsQmlPath));
|
||||
});
|
||||
});
|
||||
|
||||
m_stackedWidget = new QStackedWidget(this);
|
||||
m_stackedWidget->addWidget(m_itemViewQuickWidget.data());
|
||||
m_stackedWidget->addWidget(m_resourcesView.data());
|
||||
m_stackedWidget->addWidget(m_assetsWidget.data());
|
||||
m_stackedWidget->addWidget(m_addImportWidget.data());
|
||||
m_stackedWidget->setMinimumHeight(30);
|
||||
m_stackedWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||||
@@ -201,34 +241,12 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
/* style sheets */
|
||||
setStyleSheet(Theme::replaceCssColors(
|
||||
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
|
||||
m_resourcesView->setStyleSheet(Theme::replaceCssColors(
|
||||
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css"))));
|
||||
|
||||
m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F5), this);
|
||||
connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &ItemLibraryWidget::reloadQmlSource);
|
||||
|
||||
connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel);
|
||||
|
||||
const auto dropSupport = new Utils::DropSupport(
|
||||
m_resourcesView.data(), [this](QDropEvent *event, Utils::DropSupport *) {
|
||||
// Accept supported file types
|
||||
if (event->type() == QDropEvent::DragEnter && !Utils::DropSupport::isFileDrop(event))
|
||||
return false; // do not accept drops without files
|
||||
bool accept = false;
|
||||
const QSet<QString> &suffixes = m_resourcesFileSystemModel->supportedSuffixes();
|
||||
const QList<QUrl> urls = event->mimeData()->urls();
|
||||
for (const QUrl &url : urls) {
|
||||
QFileInfo fi(url.toLocalFile());
|
||||
if (suffixes.contains(fi.suffix().toLower())) {
|
||||
accept = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return accept;
|
||||
});
|
||||
connect(dropSupport, &Utils::DropSupport::filesDropped,
|
||||
this, &ItemLibraryWidget::importDroppedFiles);
|
||||
|
||||
m_itemViewQuickWidget->engine()->addImageProvider("itemlibrary_preview",
|
||||
new ItemLibraryIconImageProvider{m_imageCache});
|
||||
|
||||
@@ -306,6 +324,11 @@ bool ItemLibraryWidget::isSearchActive() const
|
||||
return !m_filterText.isEmpty();
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::handleFilesDrop(const QStringList &filesPaths)
|
||||
{
|
||||
addResources(filesPaths);
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::delayedUpdateModel()
|
||||
{
|
||||
static bool disableTimer = DesignerSettings::getValue(DesignerSettingsKey::DISABLE_ITEM_LIBRARY_UPDATE_TIMER).toBool();
|
||||
@@ -356,6 +379,11 @@ void ItemLibraryWidget::reloadQmlSource()
|
||||
QTC_ASSERT(QFileInfo::exists(itemLibraryQmlPath), return);
|
||||
m_itemViewQuickWidget->engine()->clearComponentCache();
|
||||
m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlPath));
|
||||
|
||||
const QString assetsQmlPath = qmlSourcesPath() + "/Assets.qml";
|
||||
QTC_ASSERT(QFileInfo::exists(assetsQmlPath), return);
|
||||
m_assetsWidget->engine()->clearComponentCache();
|
||||
m_assetsWidget->setSource(QUrl::fromLocalFile(assetsQmlPath));
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::updateModel()
|
||||
@@ -395,9 +423,7 @@ void ItemLibraryWidget::updateSearch()
|
||||
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();
|
||||
m_assetsModel->setSearchText(m_filterText);
|
||||
} else if (m_stackedWidget->currentIndex() == 2) { // QML imports tab selected
|
||||
m_itemLibraryAddImportModel->setSearchText(m_filterText);
|
||||
}
|
||||
@@ -413,10 +439,7 @@ void ItemLibraryWidget::handlePriorityImportsChanged()
|
||||
|
||||
void ItemLibraryWidget::setResourcePath(const QString &resourcePath)
|
||||
{
|
||||
if (m_resourcesView->model() == m_resourcesFileSystemModel.data()) {
|
||||
m_resourcesFileSystemModel->setRootPath(resourcePath);
|
||||
m_resourcesView->setRootIndex(m_resourcesFileSystemModel->indexForPath(resourcePath));
|
||||
}
|
||||
m_assetsModel->setRootPath(resourcePath);
|
||||
updateSearch();
|
||||
}
|
||||
|
||||
@@ -429,6 +452,51 @@ void ItemLibraryWidget::startDragAndDrop(const QVariant &itemLibEntry, const QPo
|
||||
m_dragStartPoint = mousePos.toPoint();
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::startDragAsset(const QString &assetPath)
|
||||
{
|
||||
QFileInfo fileInfo(assetPath);
|
||||
QPair<QString, QByteArray> typeAndData = getAssetTypeAndData(fileInfo);
|
||||
|
||||
if (typeAndData.first.isEmpty())
|
||||
return;
|
||||
|
||||
auto drag = new QDrag(this);
|
||||
drag->setPixmap(m_assetsIconProvider->requestPixmap(assetPath, nullptr, {128, 128}));
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(QLatin1String("application/vnd.bauhaus.libraryresource"),
|
||||
fileInfo.absoluteFilePath().toUtf8());
|
||||
mimeData->setData(typeAndData.first, typeAndData.second);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec();
|
||||
}
|
||||
|
||||
QPair<QString, QByteArray> ItemLibraryWidget::getAssetTypeAndData(const QFileInfo &fi) const
|
||||
{
|
||||
QString suffix = "*." + fi.suffix().toLower();
|
||||
if (!suffix.isEmpty()) {
|
||||
if (ItemLibraryAssetsModel::supportedImageSuffixes().contains(suffix)) {
|
||||
// Data: Image format (suffix)
|
||||
return {"application/vnd.bauhaus.libraryresource.image", suffix.toUtf8()};
|
||||
} else if (ItemLibraryAssetsModel::supportedFontSuffixes().contains(suffix)) {
|
||||
// Data: Font family name
|
||||
QRawFont font(fi.absoluteFilePath(), 10);
|
||||
QString fontFamily = font.isValid() ? font.familyName() : "";
|
||||
return {"application/vnd.bauhaus.libraryresource.font", fontFamily.toUtf8()};
|
||||
} else if (ItemLibraryAssetsModel::supportedShaderSuffixes().contains(suffix)) {
|
||||
// Data: shader type, frament (f) or vertex (v)
|
||||
return {"application/vnd.bauhaus.libraryresource.shader",
|
||||
ItemLibraryAssetsModel::supportedFragmentShaderSuffixes().contains(suffix) ? "f" : "v"};
|
||||
} else if (ItemLibraryAssetsModel::supportedAudioSuffixes().contains(suffix)) {
|
||||
// No extra data for sounds
|
||||
return {"application/vnd.bauhaus.libraryresource.sound", {}};
|
||||
} else if (ItemLibraryAssetsModel::supportedTexture3DSuffixes().contains(suffix)) {
|
||||
// Data: Image format (suffix)
|
||||
return {"application/vnd.bauhaus.libraryresource.texture3d", suffix.toUtf8()};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::setFlowMode(bool b)
|
||||
{
|
||||
m_itemLibraryModel->setFlowMode(b);
|
||||
@@ -533,15 +601,4 @@ void ItemLibraryWidget::addResources(const QStringList &files)
|
||||
}
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::importDroppedFiles(const QList<Utils::DropSupport::FileSpec> &files)
|
||||
{
|
||||
QStringList fileNames;
|
||||
for (const auto &file : files) {
|
||||
QFileInfo fi(file.filePath);
|
||||
if (m_resourcesFileSystemModel->supportedSuffixes().contains(fi.suffix().toLower()))
|
||||
fileNames.append(fi.absoluteFilePath());
|
||||
}
|
||||
if (!fileNames.isEmpty())
|
||||
addResources(fileNames);
|
||||
}
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -26,12 +26,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "itemlibraryinfo.h"
|
||||
#include "itemlibraryresourceview.h"
|
||||
#include "import.h"
|
||||
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/dropsupport.h>
|
||||
#include <previewtooltip/previewtooltipbackend.h>
|
||||
#include "itemlibraryassetsmodel.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QToolButton>
|
||||
@@ -48,6 +48,8 @@ class QStackedWidget;
|
||||
class QShortcut;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils { class FileSystemWatcher; }
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class MetaInfo;
|
||||
@@ -55,8 +57,9 @@ class ItemLibraryEntry;
|
||||
class Model;
|
||||
class CustomFileSystemModel;
|
||||
|
||||
|
||||
class ItemLibraryModel;
|
||||
class ItemLibraryAssetsIconProvider;
|
||||
class ItemLibraryAssetsModel;
|
||||
class ItemLibraryAddImportModel;
|
||||
class ItemLibraryResourceView;
|
||||
class SynchronousImageCache;
|
||||
@@ -87,8 +90,10 @@ public:
|
||||
void setResourcePath(const QString &resourcePath);
|
||||
void setModel(Model *model);
|
||||
void setFlowMode(bool b);
|
||||
QPair<QString, QByteArray> getAssetTypeAndData(const QFileInfo &fi) const;
|
||||
|
||||
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos);
|
||||
Q_INVOKABLE void startDragAsset(const QString &assetPath);
|
||||
Q_INVOKABLE void removeImport(const QString &importUrl);
|
||||
Q_INVOKABLE void addImportForItem(const QString &importUrl);
|
||||
Q_INVOKABLE void handleTabChanged(int index);
|
||||
@@ -97,6 +102,8 @@ public:
|
||||
Q_INVOKABLE void handleSearchfilterChanged(const QString &filterText);
|
||||
Q_INVOKABLE void handleAddImport(int index);
|
||||
Q_INVOKABLE bool isSearchActive() const;
|
||||
Q_INVOKABLE void handleFilesDrop(const QStringList &filesPaths);
|
||||
Q_INVOKABLE QSet<QString> supportedSuffixes() const { return m_assetsModel->supportedSuffixes(); };
|
||||
|
||||
signals:
|
||||
void itemActivated(const QString& itemName);
|
||||
@@ -108,26 +115,29 @@ private:
|
||||
void reloadQmlSource();
|
||||
|
||||
void addResources(const QStringList &files);
|
||||
void importDroppedFiles(const QList<Utils::DropSupport::FileSpec> &files);
|
||||
void updateSearch();
|
||||
void handlePriorityImportsChanged();
|
||||
|
||||
QTimer m_compressionTimer;
|
||||
QSize m_itemIconSize;
|
||||
|
||||
SynchronousImageCache &m_fontImageCache;
|
||||
QPointer<ItemLibraryInfo> m_itemLibraryInfo;
|
||||
|
||||
QPointer<ItemLibraryModel> m_itemLibraryModel;
|
||||
QPointer<ItemLibraryAddImportModel> m_itemLibraryAddImportModel;
|
||||
QPointer<CustomFileSystemModel> m_resourcesFileSystemModel;
|
||||
ItemLibraryAssetsIconProvider *m_assetsIconProvider = nullptr;
|
||||
Utils::FileSystemWatcher *m_fileSystemWatcher = nullptr;
|
||||
QPointer<ItemLibraryAssetsModel> m_assetsModel;
|
||||
|
||||
QPointer<QStackedWidget> m_stackedWidget;
|
||||
|
||||
QScopedPointer<QQuickWidget> m_headerWidget;
|
||||
QScopedPointer<QQuickWidget> m_addImportWidget;
|
||||
QScopedPointer<QQuickWidget> m_itemViewQuickWidget;
|
||||
QScopedPointer<ItemLibraryResourceView> m_resourcesView;
|
||||
QScopedPointer<QQuickWidget> m_assetsWidget;
|
||||
std::unique_ptr<PreviewTooltipBackend> m_previewTooltipBackend;
|
||||
std::unique_ptr<PreviewTooltipBackend> m_fontPreviewTooltipBackend;
|
||||
|
||||
QShortcut *m_qmlSourceUpdateShortcut;
|
||||
AsynchronousImageCache &m_imageCache;
|
||||
|
Reference in New Issue
Block a user