forked from qt-creator/qt-creator
QmlDesigner: Implement sort for the Collection Details View
Task-number: QDS-10986 Change-Id: Iba10830436d58cecb3bd2dba1afc1ac95779123d Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -13,6 +13,7 @@ Rectangle {
|
|||||||
|
|
||||||
required property var model
|
required property var model
|
||||||
required property var backend
|
required property var backend
|
||||||
|
required property var sortedModel
|
||||||
|
|
||||||
implicitWidth: 600
|
implicitWidth: 600
|
||||||
implicitHeight: 400
|
implicitHeight: 400
|
||||||
@@ -80,7 +81,7 @@ Rectangle {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
clip: true
|
clip: true
|
||||||
visible: root.model.isEmpty === false
|
visible: !tableView.model.isEmpty
|
||||||
color: StudioTheme.Values.themeControlBackground
|
color: StudioTheme.Values.themeControlBackground
|
||||||
border.color: StudioTheme.Values.themeControlOutline
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
border.width: 2
|
border.width: 2
|
||||||
@@ -112,14 +113,14 @@ Rectangle {
|
|||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
delegate: HeaderDelegate {
|
delegate: HeaderDelegate {
|
||||||
selectedItem: root.model.selectedColumn
|
selectedItem: tableView.model.selectedColumn
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 5
|
anchors.margins: 5
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
onClicked: (mouse) => {
|
onClicked: (mouse) => {
|
||||||
root.model.selectColumn(index)
|
tableView.model.selectColumn(index)
|
||||||
|
|
||||||
if (mouse.button === Qt.RightButton)
|
if (mouse.button === Qt.RightButton)
|
||||||
headerMenu.popIndex(index)
|
headerMenu.popIndex(index)
|
||||||
@@ -151,6 +152,16 @@ Rectangle {
|
|||||||
text: qsTr("Delete")
|
text: qsTr("Delete")
|
||||||
onTriggered: deleteColumnDialog.popUp(headerMenu.clickedHeader)
|
onTriggered: deleteColumnDialog.popUp(headerMenu.clickedHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StudioControls.MenuItem {
|
||||||
|
text: qsTr("Sort Ascending")
|
||||||
|
onTriggered: sortedModel.sort(headerMenu.clickedHeader, Qt.AscendingOrder)
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.MenuItem {
|
||||||
|
text: qsTr("Sort Descending")
|
||||||
|
onTriggered: sortedModel.sort(headerMenu.clickedHeader, Qt.DescendingOrder)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,22 +176,21 @@ Rectangle {
|
|||||||
Layout.alignment: Qt.AlignTop + Qt.AlignLeft
|
Layout.alignment: Qt.AlignTop + Qt.AlignLeft
|
||||||
|
|
||||||
delegate: HeaderDelegate {
|
delegate: HeaderDelegate {
|
||||||
selectedItem: root.model.selectedRow
|
selectedItem: tableView.model.selectedRow
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 5
|
anchors.margins: 5
|
||||||
acceptedButtons: Qt.LeftButton
|
acceptedButtons: Qt.LeftButton
|
||||||
onClicked: root.model.selectRow(index)
|
onClicked: tableView.model.selectRow(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TableView {
|
TableView {
|
||||||
id: tableView
|
id: tableView
|
||||||
|
|
||||||
model: root.model
|
model: root.sortedModel
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Layout.preferredWidth: tableView.contentWidth
|
Layout.preferredWidth: tableView.contentWidth
|
||||||
|
@@ -15,6 +15,7 @@ Item {
|
|||||||
property var rootView: CollectionEditorBackend.rootView
|
property var rootView: CollectionEditorBackend.rootView
|
||||||
property var model: CollectionEditorBackend.model
|
property var model: CollectionEditorBackend.model
|
||||||
property var collectionDetailsModel: CollectionEditorBackend.collectionDetailsModel
|
property var collectionDetailsModel: CollectionEditorBackend.collectionDetailsModel
|
||||||
|
property var collectionDetailsSortFilterModel: CollectionEditorBackend.collectionDetailsSortFilterModel
|
||||||
|
|
||||||
function showWarning(title, message) {
|
function showWarning(title, message) {
|
||||||
warningDialog.title = title
|
warningDialog.title = title
|
||||||
@@ -145,6 +146,7 @@ Item {
|
|||||||
CollectionDetailsView {
|
CollectionDetailsView {
|
||||||
model: root.collectionDetailsModel
|
model: root.collectionDetailsModel
|
||||||
backend: root.model
|
backend: root.model
|
||||||
|
sortedModel: root.collectionDetailsSortFilterModel
|
||||||
anchors {
|
anchors {
|
||||||
left: collectionsRect.right
|
left: collectionsRect.right
|
||||||
right: parent.right
|
right: parent.right
|
||||||
|
@@ -841,7 +841,9 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
SOURCES
|
SOURCES
|
||||||
collectiondetails.cpp collectiondetails.h
|
collectiondetails.cpp collectiondetails.h
|
||||||
collectiondetailsmodel.cpp collectiondetailsmodel.h
|
collectiondetailsmodel.cpp collectiondetailsmodel.h
|
||||||
|
collectiondetailssortfiltermodel.cpp collectiondetailssortfiltermodel.h
|
||||||
collectioneditorconstants.h
|
collectioneditorconstants.h
|
||||||
|
collectioneditorutils.cpp collectioneditorutils.h
|
||||||
collectionlistmodel.cpp collectionlistmodel.h
|
collectionlistmodel.cpp collectionlistmodel.h
|
||||||
collectionsourcemodel.cpp collectionsourcemodel.h
|
collectionsourcemodel.cpp collectionsourcemodel.h
|
||||||
collectionview.cpp collectionview.h
|
collectionview.cpp collectionview.h
|
||||||
|
@@ -233,6 +233,11 @@ QVariant CollectionDetailsModel::headerData(int section, Qt::Orientation orienta
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CollectionDetails::DataType CollectionDetailsModel::propertyDataType(int column) const
|
||||||
|
{
|
||||||
|
return m_currentCollection.typeAt(column);
|
||||||
|
}
|
||||||
|
|
||||||
int CollectionDetailsModel::selectedColumn() const
|
int CollectionDetailsModel::selectedColumn() const
|
||||||
{
|
{
|
||||||
return m_selectedColumn;
|
return m_selectedColumn;
|
||||||
|
@@ -43,6 +43,9 @@ public:
|
|||||||
QVariant headerData(int section,
|
QVariant headerData(int section,
|
||||||
Qt::Orientation orientation,
|
Qt::Orientation orientation,
|
||||||
int role = Qt::DisplayRole) const override;
|
int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
CollectionDetails::DataType propertyDataType(int column) const;
|
||||||
|
|
||||||
int selectedColumn() const;
|
int selectedColumn() const;
|
||||||
int selectedRow() const;
|
int selectedRow() const;
|
||||||
Q_INVOKABLE QString propertyName(int column) const;
|
Q_INVOKABLE QString propertyName(int column) const;
|
||||||
|
@@ -0,0 +1,96 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "collectiondetailssortfiltermodel.h"
|
||||||
|
|
||||||
|
#include "collectiondetailsmodel.h"
|
||||||
|
#include "collectioneditorutils.h"
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
CollectionDetailsSortFilterModel::CollectionDetailsSortFilterModel(QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
connect(this, &CollectionDetailsSortFilterModel::rowsInserted,
|
||||||
|
this, &CollectionDetailsSortFilterModel::updateEmpty);
|
||||||
|
connect(this, &CollectionDetailsSortFilterModel::rowsRemoved,
|
||||||
|
this, &CollectionDetailsSortFilterModel::updateEmpty);
|
||||||
|
connect(this, &CollectionDetailsSortFilterModel::modelReset,
|
||||||
|
this, &CollectionDetailsSortFilterModel::updateEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectionDetailsSortFilterModel::setSourceModel(CollectionDetailsModel *model)
|
||||||
|
{
|
||||||
|
m_source = model;
|
||||||
|
Super::setSourceModel(model);
|
||||||
|
connect(m_source, &CollectionDetailsModel::selectedColumnChanged, this, [this](int sourceColumn) {
|
||||||
|
emit selectedColumnChanged(mapFromSource(m_source->index(0, sourceColumn)).column());
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_source, &CollectionDetailsModel::selectedRowChanged, this, [this](int sourceRow) {
|
||||||
|
emit selectedRowChanged(mapFromSource(m_source->index(sourceRow, 0)).row());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int CollectionDetailsSortFilterModel::selectedRow() const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_source, return -1);
|
||||||
|
|
||||||
|
return mapFromSource(m_source->index(m_source->selectedRow(), 0)).row();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CollectionDetailsSortFilterModel::selectedColumn() const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_source, return -1);
|
||||||
|
|
||||||
|
return mapFromSource(m_source->index(0, m_source->selectedColumn())).column();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollectionDetailsSortFilterModel::selectRow(int row)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_source, return false);
|
||||||
|
|
||||||
|
return m_source->selectRow(mapToSource(index(row, 0)).row());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollectionDetailsSortFilterModel::selectColumn(int column)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_source, return false);
|
||||||
|
|
||||||
|
return m_source->selectColumn(mapToSource(index(0, column)).column());
|
||||||
|
}
|
||||||
|
|
||||||
|
CollectionDetailsSortFilterModel::~CollectionDetailsSortFilterModel() = default;
|
||||||
|
|
||||||
|
bool CollectionDetailsSortFilterModel::filterAcceptsRow(int sourceRow,
|
||||||
|
const QModelIndex &sourceParent) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollectionDetailsSortFilterModel::lessThan(const QModelIndex &sourceleft,
|
||||||
|
const QModelIndex &sourceRight) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_source, return false);
|
||||||
|
|
||||||
|
if (sourceleft.column() == sourceRight.column()) {
|
||||||
|
int column = sourceleft.column();
|
||||||
|
CollectionDetails::DataType columnType = m_source->propertyDataType(column);
|
||||||
|
return CollectionEditor::variantIslessThan(sourceleft.data(), sourceRight.data(), columnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectionDetailsSortFilterModel::updateEmpty()
|
||||||
|
{
|
||||||
|
bool newValue = rowCount() == 0;
|
||||||
|
if (m_isEmpty != newValue) {
|
||||||
|
m_isEmpty = newValue;
|
||||||
|
emit isEmptyChanged(m_isEmpty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,51 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class CollectionDetailsModel;
|
||||||
|
|
||||||
|
class CollectionDetailsSortFilterModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(int selectedColumn READ selectedColumn WRITE selectColumn NOTIFY selectedColumnChanged)
|
||||||
|
Q_PROPERTY(int selectedRow READ selectedRow WRITE selectRow NOTIFY selectedRowChanged)
|
||||||
|
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
||||||
|
|
||||||
|
using Super = QSortFilterProxyModel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CollectionDetailsSortFilterModel(QObject *parent = nullptr);
|
||||||
|
virtual ~CollectionDetailsSortFilterModel();
|
||||||
|
|
||||||
|
void setSourceModel(CollectionDetailsModel *model);
|
||||||
|
|
||||||
|
int selectedRow() const;
|
||||||
|
int selectedColumn() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE bool selectRow(int row);
|
||||||
|
Q_INVOKABLE bool selectColumn(int column);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void selectedColumnChanged(int);
|
||||||
|
void selectedRowChanged(int);
|
||||||
|
void isEmptyChanged(bool);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using Super::setSourceModel;
|
||||||
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||||
|
bool lessThan(const QModelIndex &sourceleft, const QModelIndex &sourceRight) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateEmpty();
|
||||||
|
|
||||||
|
QPointer<CollectionDetailsModel> m_source;
|
||||||
|
bool m_isEmpty = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "collectioneditorutils.h"
|
||||||
|
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using CollectionDataVariant = std::variant<QString, bool, double, QUrl, QColor>;
|
||||||
|
|
||||||
|
inline CollectionDataVariant valueToVariant(const QVariant &value,
|
||||||
|
QmlDesigner::CollectionDetails::DataType type)
|
||||||
|
{
|
||||||
|
using DataType = QmlDesigner::CollectionDetails::DataType;
|
||||||
|
switch (type) {
|
||||||
|
case DataType::String:
|
||||||
|
return value.toString();
|
||||||
|
case DataType::Number:
|
||||||
|
return value.toDouble();
|
||||||
|
case DataType::Boolean:
|
||||||
|
return value.toBool();
|
||||||
|
case DataType::Color:
|
||||||
|
return value.value<QColor>();
|
||||||
|
case DataType::Url:
|
||||||
|
return value.value<QUrl>();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LessThanVisitor
|
||||||
|
{
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
bool operator()(const T1 &a, const T2 &b) const
|
||||||
|
{
|
||||||
|
return CollectionDataVariant(a).index() < CollectionDataVariant(b).index();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator()(const T &a, const T &b) const
|
||||||
|
{
|
||||||
|
return a < b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool operator()(const QColor &a, const QColor &b) const
|
||||||
|
{
|
||||||
|
return a.name(QColor::HexArgb) < b.name(QColor::HexArgb);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace QmlDesigner::CollectionEditor {
|
||||||
|
|
||||||
|
bool variantIslessThan(const QVariant &a, const QVariant &b, CollectionDetails::DataType type)
|
||||||
|
{
|
||||||
|
return std::visit(LessThanVisitor{}, valueToVariant(a, type), valueToVariant(b, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner::CollectionEditor
|
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "collectiondetails.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner::CollectionEditor {
|
||||||
|
|
||||||
|
bool variantIslessThan(const QVariant &a, const QVariant &b, CollectionDetails::DataType type);
|
||||||
|
|
||||||
|
} // namespace QmlDesigner::CollectionEditor
|
@@ -4,6 +4,7 @@
|
|||||||
#include "collectionwidget.h"
|
#include "collectionwidget.h"
|
||||||
|
|
||||||
#include "collectiondetailsmodel.h"
|
#include "collectiondetailsmodel.h"
|
||||||
|
#include "collectiondetailssortfiltermodel.h"
|
||||||
#include "collectionsourcemodel.h"
|
#include "collectionsourcemodel.h"
|
||||||
#include "collectionview.h"
|
#include "collectionview.h"
|
||||||
#include "qmldesignerconstants.h"
|
#include "qmldesignerconstants.h"
|
||||||
@@ -40,6 +41,7 @@ CollectionWidget::CollectionWidget(CollectionView *view)
|
|||||||
, m_view(view)
|
, m_view(view)
|
||||||
, m_sourceModel(new CollectionSourceModel)
|
, m_sourceModel(new CollectionSourceModel)
|
||||||
, m_collectionDetailsModel(new CollectionDetailsModel)
|
, m_collectionDetailsModel(new CollectionDetailsModel)
|
||||||
|
, m_collectionDetailsSortFilterModel(std::make_unique<CollectionDetailsSortFilterModel>())
|
||||||
, m_quickWidget(new StudioQuickWidget(this))
|
, m_quickWidget(new StudioQuickWidget(this))
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Collection View", "Title of collection view widget"));
|
setWindowTitle(tr("Collection View", "Title of collection view widget"));
|
||||||
@@ -50,6 +52,8 @@ CollectionWidget::CollectionWidget(CollectionView *view)
|
|||||||
icontext->setContext(context);
|
icontext->setContext(context);
|
||||||
icontext->setWidget(this);
|
icontext->setWidget(this);
|
||||||
|
|
||||||
|
m_collectionDetailsSortFilterModel->setSourceModel(m_collectionDetailsModel);
|
||||||
|
|
||||||
m_quickWidget->quickWidget()->setObjectName(Constants::OBJECT_NAME_COLLECTION_EDITOR);
|
m_quickWidget->quickWidget()->setObjectName(Constants::OBJECT_NAME_COLLECTION_EDITOR);
|
||||||
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
m_quickWidget->engine()->addImportPath(collectionViewResourcesPath() + "/imports");
|
m_quickWidget->engine()->addImportPath(collectionViewResourcesPath() + "/imports");
|
||||||
@@ -65,10 +69,13 @@ CollectionWidget::CollectionWidget(CollectionView *view)
|
|||||||
|
|
||||||
qmlRegisterAnonymousType<CollectionWidget>("CollectionEditorBackend", 1);
|
qmlRegisterAnonymousType<CollectionWidget>("CollectionEditorBackend", 1);
|
||||||
auto map = m_quickWidget->registerPropertyMap("CollectionEditorBackend");
|
auto map = m_quickWidget->registerPropertyMap("CollectionEditorBackend");
|
||||||
map->setProperties(
|
map->setProperties({
|
||||||
{{"rootView", QVariant::fromValue(this)},
|
{"rootView", QVariant::fromValue(this)},
|
||||||
{"model", QVariant::fromValue(m_sourceModel.data())},
|
{"model", QVariant::fromValue(m_sourceModel.data())},
|
||||||
{"collectionDetailsModel", QVariant::fromValue(m_collectionDetailsModel.data())}});
|
{"collectionDetailsModel", QVariant::fromValue(m_collectionDetailsModel.data())},
|
||||||
|
{"collectionDetailsSortFilterModel",
|
||||||
|
QVariant::fromValue(m_collectionDetailsSortFilterModel.get())},
|
||||||
|
});
|
||||||
|
|
||||||
auto hotReloadShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F4), this);
|
auto hotReloadShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F4), this);
|
||||||
connect(hotReloadShortcut, &QShortcut::activated, this, &CollectionWidget::reloadQmlSource);
|
connect(hotReloadShortcut, &QShortcut::activated, this, &CollectionWidget::reloadQmlSource);
|
||||||
|
@@ -12,6 +12,7 @@ class StudioQuickWidget;
|
|||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class CollectionDetailsModel;
|
class CollectionDetailsModel;
|
||||||
|
class CollectionDetailsSortFilterModel;
|
||||||
class CollectionSourceModel;
|
class CollectionSourceModel;
|
||||||
class CollectionView;
|
class CollectionView;
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ private:
|
|||||||
QPointer<CollectionView> m_view;
|
QPointer<CollectionView> m_view;
|
||||||
QPointer<CollectionSourceModel> m_sourceModel;
|
QPointer<CollectionSourceModel> m_sourceModel;
|
||||||
QPointer<CollectionDetailsModel> m_collectionDetailsModel;
|
QPointer<CollectionDetailsModel> m_collectionDetailsModel;
|
||||||
|
std::unique_ptr<CollectionDetailsSortFilterModel> m_collectionDetailsSortFilterModel;
|
||||||
QScopedPointer<StudioQuickWidget> m_quickWidget;
|
QScopedPointer<StudioQuickWidget> m_quickWidget;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user