forked from qt-creator/qt-creator
QmlDesigner: Allow partially overwriting 3D imports
When importing a 3D scene, if an existing import with the same name is found, allow partially overwriting an existing import by selecting the files to overwrite. Task-number: QDS-3738 Change-Id: I8969da9bd03ef47ede4768cc2c7eb033bee3cb66 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -300,6 +300,12 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
SOURCES_PREFIX components/itemlibrary
|
SOURCES_PREFIX components/itemlibrary
|
||||||
SOURCES
|
SOURCES
|
||||||
|
assetimportupdatedialog.cpp assetimportupdatedialog.h
|
||||||
|
assetimportupdatedialog.ui
|
||||||
|
assetimportupdatetreeitem.cpp assetimportupdatetreeitem.h
|
||||||
|
assetimportupdatetreeitemdelegate.cpp assetimportupdatetreeitemdelegate.h
|
||||||
|
assetimportupdatetreemodel.cpp assetimportupdatetreemodel.h
|
||||||
|
assetimportupdatetreeview.cpp assetimportupdatetreeview.h
|
||||||
customfilesystemmodel.cpp customfilesystemmodel.h
|
customfilesystemmodel.cpp customfilesystemmodel.h
|
||||||
itemlibrary.qrc
|
itemlibrary.qrc
|
||||||
itemlibraryimageprovider.cpp itemlibraryimageprovider.h
|
itemlibraryimageprovider.cpp itemlibraryimageprovider.h
|
||||||
|
@@ -0,0 +1,94 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetimportupdatedialog.h"
|
||||||
|
#include "ui_assetimportupdatedialog.h"
|
||||||
|
#include "assetimportupdatetreeview.h"
|
||||||
|
#include "assetimportupdatetreemodel.h"
|
||||||
|
|
||||||
|
#include <QDirIterator>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QModelIndex>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
AssetImportUpdateDialog::AssetImportUpdateDialog(
|
||||||
|
const QString &importPath, const QSet<QString> &preSelectedFiles,
|
||||||
|
const QSet<QString> &hiddenEntries, QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, ui(new Ui::AssetImportUpdateDialog)
|
||||||
|
{
|
||||||
|
setModal(true);
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked,
|
||||||
|
this, &AssetImportUpdateDialog::accept);
|
||||||
|
connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked,
|
||||||
|
this, &AssetImportUpdateDialog::reject);
|
||||||
|
connect(ui->expandButton, &QPushButton::clicked,
|
||||||
|
this, &AssetImportUpdateDialog::expandAll);
|
||||||
|
connect(ui->collapseButton, &QPushButton::clicked,
|
||||||
|
this, &AssetImportUpdateDialog::collapseAll);
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
||||||
|
|
||||||
|
QList<QFileInfo> infos;
|
||||||
|
infos.append(QFileInfo{importPath});
|
||||||
|
QDirIterator it(importPath, {"*"}, QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot,
|
||||||
|
QDirIterator::Subdirectories);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
const QString absFile = it.fileInfo().absoluteFilePath();
|
||||||
|
if (!hiddenEntries.contains(absFile))
|
||||||
|
infos.append(it.fileInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->treeView->model()->createItems(infos, preSelectedFiles);
|
||||||
|
ui->treeView->expandAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetImportUpdateDialog::~AssetImportUpdateDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList AssetImportUpdateDialog::selectedFiles() const
|
||||||
|
{
|
||||||
|
return ui->treeView->model()->checkedFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateDialog::collapseAll()
|
||||||
|
{
|
||||||
|
ui->treeView->collapseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateDialog::expandAll()
|
||||||
|
{
|
||||||
|
ui->treeView->expandAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,59 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <QDialog>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AssetImportUpdateDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AssetImportUpdateDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AssetImportUpdateDialog(const QString &importPath,
|
||||||
|
const QSet<QString> &preSelectedFiles,
|
||||||
|
const QSet<QString> &hiddenEntries,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
|
~AssetImportUpdateDialog();
|
||||||
|
|
||||||
|
QStringList selectedFiles() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void collapseAll();
|
||||||
|
void expandAll();
|
||||||
|
|
||||||
|
Ui::AssetImportUpdateDialog *ui = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>QmlDesigner::Internal::AssetImportUpdateDialog</class>
|
||||||
|
<widget class="QDialog" name="QmlDesigner::Internal::AssetImportUpdateDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>472</width>
|
||||||
|
<height>360</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Select Files to Update</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="AssetImportUpdateTreeView" name="treeView">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::NoSelection</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="expandButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Expand All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="collapseButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Collapse All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>77</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>AssetImportUpdateTreeView</class>
|
||||||
|
<extends>QTreeView</extends>
|
||||||
|
<header>assetimportupdatetreeview.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@@ -0,0 +1,87 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetimportupdatetreeitem.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItem::AssetImportUpdateTreeItem(const QFileInfo &info,
|
||||||
|
AssetImportUpdateTreeItem *parent)
|
||||||
|
: m_parent(parent)
|
||||||
|
, m_fileInfo(info)
|
||||||
|
{
|
||||||
|
if (parent)
|
||||||
|
parent->appendChild(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItem::~AssetImportUpdateTreeItem()
|
||||||
|
{
|
||||||
|
if (m_parent)
|
||||||
|
m_parent->removeChild(this);
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateTreeItem::clear()
|
||||||
|
{
|
||||||
|
qDeleteAll(m_children);
|
||||||
|
m_children.clear();
|
||||||
|
m_fileInfo = {};
|
||||||
|
m_parent = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AssetImportUpdateTreeItem::childCount() const
|
||||||
|
{
|
||||||
|
return m_children.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AssetImportUpdateTreeItem::rowOfItem() const
|
||||||
|
{
|
||||||
|
return m_parent ? m_parent->m_children.indexOf(const_cast<AssetImportUpdateTreeItem *>(this))
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItem *AssetImportUpdateTreeItem::childAt(int index) const
|
||||||
|
{
|
||||||
|
return m_children.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItem *AssetImportUpdateTreeItem::parent() const
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateTreeItem::removeChild(AssetImportUpdateTreeItem *item)
|
||||||
|
{
|
||||||
|
m_children.removeOne(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateTreeItem::appendChild(AssetImportUpdateTreeItem *item)
|
||||||
|
{
|
||||||
|
m_children.append(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,65 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <QString>
|
||||||
|
#include <QList>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class AssetImportUpdateTreeItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit AssetImportUpdateTreeItem(const QFileInfo &info,
|
||||||
|
AssetImportUpdateTreeItem *parent = nullptr);
|
||||||
|
virtual ~AssetImportUpdateTreeItem();
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItem *parent() const;
|
||||||
|
AssetImportUpdateTreeItem *childAt(int index) const;
|
||||||
|
int childCount() const;
|
||||||
|
int rowOfItem() const;
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
Qt::CheckState checkState() const { return m_checkState; }
|
||||||
|
void setCheckState(Qt::CheckState checkState) { m_checkState = checkState; }
|
||||||
|
const QFileInfo &fileInfo() const { return m_fileInfo; }
|
||||||
|
void setFileInfo(const QFileInfo &info) { m_fileInfo = info; }
|
||||||
|
void removeChild(AssetImportUpdateTreeItem *item);
|
||||||
|
const QList<AssetImportUpdateTreeItem *> &children() const { return m_children; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void appendChild(AssetImportUpdateTreeItem *item);
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItem *m_parent;
|
||||||
|
QList<AssetImportUpdateTreeItem *> m_children;
|
||||||
|
Qt::CheckState m_checkState = Qt::Unchecked;
|
||||||
|
QFileInfo m_fileInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,101 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetimportupdatetreeitemdelegate.h"
|
||||||
|
#include "assetimportupdatetreemodel.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QModelIndex>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItemDelegate::AssetImportUpdateTreeItemDelegate(QObject *parent)
|
||||||
|
: QItemDelegate(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItemDelegate::LayoutInfo AssetImportUpdateTreeItemDelegate::getLayoutInfo(
|
||||||
|
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
LayoutInfo info;
|
||||||
|
info.option = setOptions(index, option);
|
||||||
|
|
||||||
|
const bool checkable = (index.model()->flags(index) & Qt::ItemIsUserCheckable);
|
||||||
|
info.checkState = Qt::Unchecked;
|
||||||
|
if (checkable) {
|
||||||
|
QVariant checkStateData = index.data(Qt::CheckStateRole);
|
||||||
|
info.checkState = static_cast<Qt::CheckState>(checkStateData.toInt());
|
||||||
|
info.checkRect = doCheck(info.option, info.option.rect, checkStateData);
|
||||||
|
}
|
||||||
|
|
||||||
|
info.textRect = info.option.rect.adjusted(0, 0, info.checkRect.width(), 0);
|
||||||
|
|
||||||
|
doLayout(info.option, &info.checkRect, &info.iconRect, &info.textRect, false);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
painter->save();
|
||||||
|
|
||||||
|
const LayoutInfo info = getLayoutInfo(option, index);
|
||||||
|
|
||||||
|
painter->setFont(info.option.font);
|
||||||
|
|
||||||
|
drawBackground(painter, info.option, index);
|
||||||
|
drawText(painter, info.option, info.textRect, index);
|
||||||
|
drawCheck(painter, info.option, info.checkRect, info.checkState);
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize AssetImportUpdateTreeItemDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
const LayoutInfo info = getLayoutInfo(option, index);
|
||||||
|
const int height = index.data(Qt::SizeHintRole).value<QSize>().height();
|
||||||
|
// get text width, see QItemDelegatePrivate::displayRect
|
||||||
|
const QString text = index.data(Qt::DisplayRole).toString();
|
||||||
|
const QRect textMaxRect(0, 0, INT_MAX / 256, height);
|
||||||
|
const QRect textLayoutRect = textRectangle(nullptr, textMaxRect, info.option.font, text);
|
||||||
|
const QRect textRect(info.textRect.x(), info.textRect.y(), textLayoutRect.width(), height);
|
||||||
|
const QRect layoutRect = info.checkRect | textRect;
|
||||||
|
return QSize(layoutRect.x(), layoutRect.y()) + layoutRect.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateTreeItemDelegate::drawText(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QRect &rect,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
const QString text = index.data(Qt::DisplayRole).toString();
|
||||||
|
drawDisplay(painter, option, rect, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <QItemDelegate>
|
||||||
|
#include <QStyleOptionViewItem>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class AssetImportUpdateTreeItemDelegate : public QItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AssetImportUpdateTreeItemDelegate(QObject *parent = nullptr);
|
||||||
|
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const override;
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
|
private:
|
||||||
|
struct LayoutInfo
|
||||||
|
{
|
||||||
|
QRect checkRect;
|
||||||
|
QRect textRect;
|
||||||
|
QRect iconRect;
|
||||||
|
Qt::CheckState checkState;
|
||||||
|
QStyleOptionViewItem option;
|
||||||
|
};
|
||||||
|
|
||||||
|
LayoutInfo getLayoutInfo(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
void drawText(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
|
const QRect &rect, const QModelIndex &index) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,262 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetimportupdatetreemodel.h"
|
||||||
|
#include "assetimportupdatetreeitem.h"
|
||||||
|
|
||||||
|
#include <QSize>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
AssetImportUpdateTreeModel::AssetImportUpdateTreeModel(QObject *parent)
|
||||||
|
: QAbstractItemModel(parent)
|
||||||
|
{
|
||||||
|
m_rootItem = new AssetImportUpdateTreeItem {{}};
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetImportUpdateTreeModel::~AssetImportUpdateTreeModel()
|
||||||
|
{
|
||||||
|
delete m_rootItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags AssetImportUpdateTreeModel::flags(const QModelIndex &idx) const
|
||||||
|
{
|
||||||
|
Qt::ItemFlags flags = QAbstractItemModel::flags(idx);
|
||||||
|
|
||||||
|
if (idx.isValid())
|
||||||
|
flags |= Qt::ItemIsUserCheckable;
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex AssetImportUpdateTreeModel::index(int row, int column,
|
||||||
|
const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (!hasIndex(row, column, parent))
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
const AssetImportUpdateTreeItem *parentItem;
|
||||||
|
|
||||||
|
parentItem = parent.isValid() ? treeItemAtIndex(parent) : m_rootItem;
|
||||||
|
|
||||||
|
const AssetImportUpdateTreeItem *childItem = parentItem->childAt(row);
|
||||||
|
if (childItem)
|
||||||
|
return createIndex(row, column, const_cast<AssetImportUpdateTreeItem *>(childItem));
|
||||||
|
else
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex AssetImportUpdateTreeModel::index(AssetImportUpdateTreeItem *item) const
|
||||||
|
{
|
||||||
|
return createIndex(item->rowOfItem(), 0, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant AssetImportUpdateTreeModel::data(const AssetImportUpdateTreeItem *row, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return row->fileInfo().fileName();
|
||||||
|
if (role == Qt::CheckStateRole)
|
||||||
|
return row->checkState();
|
||||||
|
if (role == Qt::ToolTipRole)
|
||||||
|
return row->fileInfo().absoluteFilePath();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex AssetImportUpdateTreeModel::parent(const QModelIndex &idx) const
|
||||||
|
{
|
||||||
|
if (!idx.isValid())
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
const AssetImportUpdateTreeItem *childItem = treeItemAtIndex(idx);
|
||||||
|
const AssetImportUpdateTreeItem *parentItem = childItem->parent();
|
||||||
|
|
||||||
|
if (parentItem == m_rootItem)
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
return createIndex(parentItem->rowOfItem(), 0, const_cast<AssetImportUpdateTreeItem *>(parentItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
int AssetImportUpdateTreeModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (parent.column() > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return parent.isValid() ? treeItemAtIndex(parent)->childCount()
|
||||||
|
: m_rootItem->childCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AssetImportUpdateTreeModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItem *AssetImportUpdateTreeModel::treeItemAtIndex(const QModelIndex &idx)
|
||||||
|
{
|
||||||
|
return static_cast<AssetImportUpdateTreeItem*>(idx.internalPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant AssetImportUpdateTreeModel::data(const QModelIndex &idx, int role) const
|
||||||
|
{
|
||||||
|
if (!idx.isValid())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (role == Qt::SizeHintRole)
|
||||||
|
return QSize(0, 20);
|
||||||
|
|
||||||
|
return data(treeItemAtIndex(idx), role);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetImportUpdateTreeModel::setData(const QModelIndex &idx, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (role == Qt::CheckStateRole) {
|
||||||
|
auto checkState = static_cast<Qt::CheckState>(value.toInt());
|
||||||
|
return setCheckState(idx, checkState);
|
||||||
|
}
|
||||||
|
return QAbstractItemModel::setData(idx, value, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetImportUpdateTreeModel::setCheckState(const QModelIndex &idx, Qt::CheckState checkState,
|
||||||
|
bool firstCall)
|
||||||
|
{
|
||||||
|
AssetImportUpdateTreeItem *item = treeItemAtIndex(idx);
|
||||||
|
if (item->checkState() == checkState)
|
||||||
|
return false;
|
||||||
|
item->setCheckState(checkState);
|
||||||
|
if (firstCall) {
|
||||||
|
emit dataChanged(idx, idx);
|
||||||
|
// check parents
|
||||||
|
AssetImportUpdateTreeItem *parent = item->parent();
|
||||||
|
QModelIndex parentIdx = idx.parent();
|
||||||
|
while (parent) {
|
||||||
|
bool hasChecked = false;
|
||||||
|
bool hasUnchecked = false;
|
||||||
|
for (const auto child : parent->children()) {
|
||||||
|
if (child->checkState() == Qt::Checked) {
|
||||||
|
hasChecked = true;
|
||||||
|
} else if (child->checkState() == Qt::Unchecked) {
|
||||||
|
hasUnchecked = true;
|
||||||
|
} else if (child->checkState() == Qt::PartiallyChecked) {
|
||||||
|
hasChecked = true;
|
||||||
|
hasUnchecked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasChecked && hasUnchecked)
|
||||||
|
parent->setCheckState(Qt::PartiallyChecked);
|
||||||
|
else if (hasChecked)
|
||||||
|
parent->setCheckState(Qt::Checked);
|
||||||
|
else
|
||||||
|
parent->setCheckState(Qt::Unchecked);
|
||||||
|
emit dataChanged(parentIdx, parentIdx);
|
||||||
|
parent = parent->parent();
|
||||||
|
parentIdx = parentIdx.parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check children
|
||||||
|
if (int children = item->childCount()) {
|
||||||
|
for (int i = 0; i < children; ++i)
|
||||||
|
setCheckState(index(i, 0, idx), checkState, false);
|
||||||
|
emit dataChanged(index(0, 0, idx), index(children - 1, 0, idx));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateTreeModel::createItems(const QList<QFileInfo> &infos,
|
||||||
|
const QSet<QString> &preselectedFiles)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
if (!infos.isEmpty()) {
|
||||||
|
QHash<QString, AssetImportUpdateTreeItem *> dirItems;
|
||||||
|
for (const auto &info : infos) {
|
||||||
|
auto parent = dirItems.value(info.absolutePath());
|
||||||
|
if (!parent)
|
||||||
|
parent = m_rootItem;
|
||||||
|
auto item = new AssetImportUpdateTreeItem(info, parent);
|
||||||
|
if (info.isDir()) {
|
||||||
|
dirItems.insert(info.absoluteFilePath(), item);
|
||||||
|
} else {
|
||||||
|
m_fileItems.append(item);
|
||||||
|
if (preselectedFiles.contains(info.absoluteFilePath()))
|
||||||
|
item->setCheckState(Qt::Checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove dir items that have no children from the model
|
||||||
|
for (auto dirItem : qAsConst(dirItems)) {
|
||||||
|
if (dirItem->childCount() == 0)
|
||||||
|
delete dirItem;
|
||||||
|
}
|
||||||
|
std::function<Qt::CheckState (AssetImportUpdateTreeItem *)> updateDirCheckStatesRecursive;
|
||||||
|
updateDirCheckStatesRecursive = [&](AssetImportUpdateTreeItem *item) -> Qt::CheckState {
|
||||||
|
bool hasChecked = false;
|
||||||
|
bool hasUnchecked = false;
|
||||||
|
for (const auto child : item->children()) {
|
||||||
|
Qt::CheckState childState = child->childCount() > 0
|
||||||
|
? updateDirCheckStatesRecursive(child)
|
||||||
|
: child->checkState();
|
||||||
|
if (childState == Qt::Checked) {
|
||||||
|
hasChecked = true;
|
||||||
|
} else if (childState == Qt::Unchecked) {
|
||||||
|
hasUnchecked = true;
|
||||||
|
} else {
|
||||||
|
hasChecked = true;
|
||||||
|
hasUnchecked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Qt::CheckState retval = Qt::Unchecked;
|
||||||
|
if (hasChecked && hasUnchecked)
|
||||||
|
retval = Qt::PartiallyChecked;
|
||||||
|
else if (hasChecked)
|
||||||
|
retval = Qt::Checked;
|
||||||
|
item->setCheckState(retval);
|
||||||
|
return retval;
|
||||||
|
};
|
||||||
|
m_rootItem->setCheckState(updateDirCheckStatesRecursive(m_rootItem));
|
||||||
|
}
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList AssetImportUpdateTreeModel::checkedFiles() const
|
||||||
|
{
|
||||||
|
QStringList retList;
|
||||||
|
|
||||||
|
for (const auto item : qAsConst(m_fileItems)) {
|
||||||
|
if (item->checkState() == Qt::Checked)
|
||||||
|
retList.append(item->fileInfo().absoluteFilePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
return retList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateTreeModel::clear()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_fileItems.clear();
|
||||||
|
m_rootItem->clear(); // Deletes all children
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,73 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <QAbstractItemModel>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QList>
|
||||||
|
#include <QSet>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class AssetImportUpdateTreeItem;
|
||||||
|
|
||||||
|
class AssetImportUpdateTreeModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AssetImportUpdateTreeModel(QObject *parent = nullptr);
|
||||||
|
~AssetImportUpdateTreeModel() override;
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QModelIndex parent(const QModelIndex &child) const override;
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||||
|
|
||||||
|
void createItems(const QList<QFileInfo> &infos, const QSet<QString> &preselectedFiles);
|
||||||
|
QStringList checkedFiles() const;
|
||||||
|
|
||||||
|
static AssetImportUpdateTreeItem *treeItemAtIndex(const QModelIndex &idx);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QModelIndex index(AssetImportUpdateTreeItem *item) const;
|
||||||
|
QVariant data(const AssetImportUpdateTreeItem *row, int role) const;
|
||||||
|
bool setCheckState(const QModelIndex &idx, Qt::CheckState checkState, bool firstCall = true);
|
||||||
|
|
||||||
|
AssetImportUpdateTreeItem *m_rootItem;
|
||||||
|
QList<AssetImportUpdateTreeItem *> m_fileItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetimportupdatetreeview.h"
|
||||||
|
#include "assetimportupdatetreemodel.h"
|
||||||
|
#include "assetimportupdatetreeitemdelegate.h"
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
AssetImportUpdateTreeView::AssetImportUpdateTreeView(QWidget *parent)
|
||||||
|
: Utils::TreeView(parent)
|
||||||
|
, m_model(new AssetImportUpdateTreeModel(this))
|
||||||
|
{
|
||||||
|
setModel(m_model);
|
||||||
|
setItemDelegate(new AssetImportUpdateTreeItemDelegate(this));
|
||||||
|
setUniformRowHeights(true);
|
||||||
|
setExpandsOnDoubleClick(true);
|
||||||
|
header()->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetImportUpdateTreeView::clear()
|
||||||
|
{
|
||||||
|
m_model->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetImportUpdateTreeModel *AssetImportUpdateTreeView::model() const
|
||||||
|
{
|
||||||
|
return m_model;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetimportupdatetreeitem.h"
|
||||||
|
|
||||||
|
#include <utils/itemviews.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class AssetImportUpdateTreeModel;
|
||||||
|
|
||||||
|
class AssetImportUpdateTreeView : public Utils::TreeView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AssetImportUpdateTreeView(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
AssetImportUpdateTreeModel *model() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AssetImportUpdateTreeModel *m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace QmlDesigner
|
@@ -15,7 +15,12 @@ HEADERS += itemlibraryview.h \
|
|||||||
itemlibraryaddimportmodel.h \
|
itemlibraryaddimportmodel.h \
|
||||||
itemlibraryassetimportdialog.h \
|
itemlibraryassetimportdialog.h \
|
||||||
itemlibraryassetimporter.h \
|
itemlibraryassetimporter.h \
|
||||||
customfilesystemmodel.h
|
customfilesystemmodel.h \
|
||||||
|
assetimportupdatedialog.h \
|
||||||
|
assetimportupdatetreeitem.h \
|
||||||
|
assetimportupdatetreeitemdelegate.h \
|
||||||
|
assetimportupdatetreemodel.h \
|
||||||
|
assetimportupdatetreeview.h
|
||||||
|
|
||||||
SOURCES += itemlibraryview.cpp \
|
SOURCES += itemlibraryview.cpp \
|
||||||
$$PWD/itemlibraryiconimageprovider.cpp \
|
$$PWD/itemlibraryiconimageprovider.cpp \
|
||||||
@@ -31,7 +36,13 @@ SOURCES += itemlibraryview.cpp \
|
|||||||
itemlibraryaddimportmodel.cpp \
|
itemlibraryaddimportmodel.cpp \
|
||||||
itemlibraryassetimportdialog.cpp \
|
itemlibraryassetimportdialog.cpp \
|
||||||
itemlibraryassetimporter.cpp \
|
itemlibraryassetimporter.cpp \
|
||||||
customfilesystemmodel.cpp
|
customfilesystemmodel.cpp \
|
||||||
|
assetimportupdatedialog.cpp \
|
||||||
|
assetimportupdatetreeitem.cpp \
|
||||||
|
assetimportupdatetreeitemdelegate.cpp \
|
||||||
|
assetimportupdatetreemodel.cpp \
|
||||||
|
assetimportupdatetreeview.cpp
|
||||||
RESOURCES += itemlibrary.qrc
|
RESOURCES += itemlibrary.qrc
|
||||||
|
|
||||||
FORMS += itemlibraryassetimportdialog.ui
|
FORMS += itemlibraryassetimportdialog.ui \
|
||||||
|
assetimportupdatedialog.ui
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "itemlibraryassetimporter.h"
|
#include "itemlibraryassetimporter.h"
|
||||||
|
#include "assetimportupdatedialog.h"
|
||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
#include "qmldesignerconstants.h"
|
#include "qmldesignerconstants.h"
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -262,11 +264,43 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa
|
|||||||
pd.assetName = assetDirs[0];
|
pd.assetName = assetDirs[0];
|
||||||
pd.targetDirPath = pd.targetDir.filePath(pd.assetName);
|
pd.targetDirPath = pd.targetDir.filePath(pd.assetName);
|
||||||
}
|
}
|
||||||
if (!confirmAssetOverwrite(pd.assetName)) {
|
OverwriteResult result = confirmAssetOverwrite(pd.assetName);
|
||||||
|
if (result == OverwriteResult::Skip) {
|
||||||
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(pd.assetName));
|
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(pd.assetName));
|
||||||
return false;
|
return false;
|
||||||
|
} else if (result == OverwriteResult::Update) {
|
||||||
|
// Add generated icons and existing source asset file, as those will always need
|
||||||
|
// to be overwritten
|
||||||
|
QSet<QString> alwaysOverwrite;
|
||||||
|
QString iconPath = pd.targetDirPath + '/' + Constants::QUICK_3D_ASSET_ICON_DIR;
|
||||||
|
// Note: Despite the name, QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX is not a traditional file
|
||||||
|
// suffix. It's guaranteed to be in the generated icon filename, though.
|
||||||
|
QStringList filters {QStringLiteral("*%1*").arg(Constants::QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX)};
|
||||||
|
QDirIterator iconIt(iconPath, filters, QDir::Files);
|
||||||
|
while (iconIt.hasNext()) {
|
||||||
|
iconIt.next();
|
||||||
|
alwaysOverwrite.insert(iconIt.fileInfo().absoluteFilePath());
|
||||||
|
}
|
||||||
|
alwaysOverwrite.insert(sourceSceneTargetFilePath(pd));
|
||||||
|
|
||||||
|
Internal::AssetImportUpdateDialog dlg {pd.targetDirPath, {}, alwaysOverwrite,
|
||||||
|
qobject_cast<QWidget *>(parent())};
|
||||||
|
int exitVal = dlg.exec();
|
||||||
|
|
||||||
|
QStringList overwriteFiles;
|
||||||
|
if (exitVal == QDialog::Accepted)
|
||||||
|
overwriteFiles = dlg.selectedFiles();
|
||||||
|
if (!overwriteFiles.isEmpty()) {
|
||||||
|
overwriteFiles.append(QStringList::fromSet(alwaysOverwrite));
|
||||||
|
m_overwrittenImports.insert(pd.targetDirPath, overwriteFiles);
|
||||||
|
} else {
|
||||||
|
addWarning(tr("No files selected for overwrite, skipping import: \"%1\"").arg(pd.assetName));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
m_overwrittenImports.insert(pd.targetDirPath, {});
|
||||||
}
|
}
|
||||||
m_overwrittenImports << pd.targetDirPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pd.outDir.mkpath(pd.assetName);
|
pd.outDir.mkpath(pd.assetName);
|
||||||
@@ -395,8 +429,7 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy the original asset into a subdirectory
|
// Copy the original asset into a subdirectory
|
||||||
assetFiles.insert(pd.sourceInfo.absoluteFilePath(),
|
assetFiles.insert(pd.sourceInfo.absoluteFilePath(), sourceSceneTargetFilePath(pd));
|
||||||
pd.targetDirPath + QStringLiteral("/source scene/") + pd.sourceInfo.fileName());
|
|
||||||
m_importFiles.insert(assetFiles);
|
m_importFiles.insert(assetFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,11 +441,22 @@ void ItemLibraryAssetImporter::copyImportedFiles()
|
|||||||
notifyProgress(0, progressTitle);
|
notifyProgress(0, progressTitle);
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
for (const QString &dirPath : qAsConst(m_overwrittenImports)) {
|
auto it = m_overwrittenImports.constBegin();
|
||||||
QDir dir(dirPath);
|
while (it != m_overwrittenImports.constEnd()) {
|
||||||
if (dir.exists())
|
QDir dir(it.key());
|
||||||
|
if (dir.exists()) {
|
||||||
|
const auto &overwrittenFiles = it.value();
|
||||||
|
if (overwrittenFiles.isEmpty()) {
|
||||||
|
// Overwrite entire import
|
||||||
dir.removeRecursively();
|
dir.removeRecursively();
|
||||||
|
} else {
|
||||||
|
// Overwrite just selected files
|
||||||
|
for (const auto &fileName : overwrittenFiles)
|
||||||
|
QFile::remove(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
notifyProgress((100 * ++counter) / m_overwrittenImports.size(), progressTitle);
|
notifyProgress((100 * ++counter) / m_overwrittenImports.size(), progressTitle);
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +474,7 @@ void ItemLibraryAssetImporter::copyImportedFiles()
|
|||||||
// by filesystem watchers.
|
// by filesystem watchers.
|
||||||
QHash<QString, QString>::const_iterator it = assetFiles.begin();
|
QHash<QString, QString>::const_iterator it = assetFiles.begin();
|
||||||
while (it != assetFiles.end()) {
|
while (it != assetFiles.end()) {
|
||||||
if (QFileInfo::exists(it.key())) {
|
if (QFileInfo::exists(it.key()) && !QFileInfo::exists(it.value())) {
|
||||||
QDir targetDir = QFileInfo(it.value()).dir();
|
QDir targetDir = QFileInfo(it.value()).dir();
|
||||||
if (!targetDir.exists())
|
if (!targetDir.exists())
|
||||||
targetDir.mkpath(".");
|
targetDir.mkpath(".");
|
||||||
@@ -461,13 +505,26 @@ void ItemLibraryAssetImporter::keepUiAlive() const
|
|||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName)
|
ItemLibraryAssetImporter::OverwriteResult ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName)
|
||||||
{
|
{
|
||||||
const QString title = tr("Overwrite Existing Asset?");
|
const QString title = tr("Overwrite Existing Asset?");
|
||||||
const QString question = tr("Asset already exists. Overwrite?\n\"%1\"").arg(assetName);
|
const QString question = tr("Asset already exists. Overwrite existing or skip?\n\"%1\"").arg(assetName);
|
||||||
return QMessageBox::question(qobject_cast<QWidget *>(parent()),
|
|
||||||
title, question,
|
QMessageBox msgBox {QMessageBox::Question, title, question, QMessageBox::NoButton,
|
||||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes;
|
qobject_cast<QWidget *>(parent())};
|
||||||
|
QPushButton *updateButton = msgBox.addButton(tr("Overwrite Selected Files"), QMessageBox::NoRole);
|
||||||
|
QPushButton *overwriteButton = msgBox.addButton(tr("Overwrite All Files"), QMessageBox::NoRole);
|
||||||
|
QPushButton *skipButton = msgBox.addButton(tr("Skip"), QMessageBox::NoRole);
|
||||||
|
msgBox.setDefaultButton(overwriteButton);
|
||||||
|
msgBox.setEscapeButton(skipButton);
|
||||||
|
|
||||||
|
msgBox.exec();
|
||||||
|
|
||||||
|
if (msgBox.clickedButton() == updateButton)
|
||||||
|
return OverwriteResult::Update;
|
||||||
|
else if (msgBox.clickedButton() == overwriteButton)
|
||||||
|
return OverwriteResult::Overwrite;
|
||||||
|
return OverwriteResult::Skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemLibraryAssetImporter::startImportProcess(const ParseData &pd)
|
bool ItemLibraryAssetImporter::startImportProcess(const ParseData &pd)
|
||||||
@@ -623,6 +680,11 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ItemLibraryAssetImporter::sourceSceneTargetFilePath(const ParseData &pd)
|
||||||
|
{
|
||||||
|
return pd.targetDirPath + QStringLiteral("/source scene/") + pd.sourceInfo.fileName();
|
||||||
|
}
|
||||||
|
|
||||||
bool ItemLibraryAssetImporter::isCancelled() const
|
bool ItemLibraryAssetImporter::isCancelled() const
|
||||||
{
|
{
|
||||||
keepUiAlive();
|
keepUiAlive();
|
||||||
|
@@ -99,14 +99,22 @@ private:
|
|||||||
void notifyProgress(int value, const QString &text);
|
void notifyProgress(int value, const QString &text);
|
||||||
void notifyProgress(int value);
|
void notifyProgress(int value);
|
||||||
void keepUiAlive() const;
|
void keepUiAlive() const;
|
||||||
bool confirmAssetOverwrite(const QString &assetName);
|
|
||||||
|
enum class OverwriteResult {
|
||||||
|
Skip,
|
||||||
|
Overwrite,
|
||||||
|
Update
|
||||||
|
};
|
||||||
|
|
||||||
|
OverwriteResult confirmAssetOverwrite(const QString &assetName);
|
||||||
bool startImportProcess(const ParseData &pd);
|
bool startImportProcess(const ParseData &pd);
|
||||||
bool startIconProcess(int size, const QString &iconFile, const QString &iconSource);
|
bool startIconProcess(int size, const QString &iconFile, const QString &iconSource);
|
||||||
void postImport();
|
void postImport();
|
||||||
void finalizeQuick3DImport();
|
void finalizeQuick3DImport();
|
||||||
|
QString sourceSceneTargetFilePath(const ParseData &pd);
|
||||||
|
|
||||||
QSet<QHash<QString, QString>> m_importFiles;
|
QSet<QHash<QString, QString>> m_importFiles;
|
||||||
QSet<QString> m_overwrittenImports;
|
QHash<QString, QStringList> m_overwrittenImports;
|
||||||
bool m_isImporting = false;
|
bool m_isImporting = false;
|
||||||
bool m_cancelled = false;
|
bool m_cancelled = false;
|
||||||
QString m_importPath;
|
QString m_importPath;
|
||||||
|
@@ -603,6 +603,17 @@ Project {
|
|||||||
"integration/stackedutilitypanelcontroller.h",
|
"integration/stackedutilitypanelcontroller.h",
|
||||||
"integration/utilitypanelcontroller.cpp",
|
"integration/utilitypanelcontroller.cpp",
|
||||||
"integration/utilitypanelcontroller.h",
|
"integration/utilitypanelcontroller.h",
|
||||||
|
"itemlibrary/assetimportupdatedialog.cpp",
|
||||||
|
"itemlibrary/assetimportupdatedialog.h",
|
||||||
|
"itemlibrary/assetimportupdatedialog.ui",
|
||||||
|
"itemlibrary/assetimportupdatetreeitem.cpp",
|
||||||
|
"itemlibrary/assetimportupdatetreeitem.h",
|
||||||
|
"itemlibrary/assetimportupdatetreeitemdelegate.cpp",
|
||||||
|
"itemlibrary/assetimportupdatetreeitemdelegate.h",
|
||||||
|
"itemlibrary/assetimportupdatetreemodel.cpp",
|
||||||
|
"itemlibrary/assetimportupdatetreemodel.h",
|
||||||
|
"itemlibrary/assetimportupdatetreeview.cpp",
|
||||||
|
"itemlibrary/assetimportupdatetreeview.h",
|
||||||
"itemlibrary/itemlibrary.qrc",
|
"itemlibrary/itemlibrary.qrc",
|
||||||
"itemlibrary/itemlibraryaddimportmodel.cpp",
|
"itemlibrary/itemlibraryaddimportmodel.cpp",
|
||||||
"itemlibrary/itemlibraryaddimportmodel.h",
|
"itemlibrary/itemlibraryaddimportmodel.h",
|
||||||
|
Reference in New Issue
Block a user