Welcome: Remove requirement for subclassing ListModel

By using aggregation for the pixmap fetching.

Change-Id: I6647cc6fa7995581c692050af32e41ba9aa86491
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Eike Ziller
2023-01-12 16:10:09 +01:00
parent ab9935af73
commit aff6c4b2d2
6 changed files with 58 additions and 59 deletions

View File

@@ -150,8 +150,8 @@ QVariant ListModel::data(const QModelIndex &index, int role) const
QPixmap pixmap;
if (QPixmapCache::find(item->imageUrl, &pixmap))
return pixmap;
if (pixmap.isNull())
pixmap = fetchPixmapAndUpdatePixmapCache(item->imageUrl);
if (pixmap.isNull() && m_fetchPixmapAndUpdatePixmapCache)
pixmap = m_fetchPixmapAndUpdatePixmapCache(item->imageUrl);
return pixmap;
}
case ItemTagsRole:
@@ -161,6 +161,11 @@ QVariant ListModel::data(const QModelIndex &index, int role) const
}
}
void ListModel::setPixmapFunction(const PixmapFunction &fetchPixmapAndUpdatePixmapCache)
{
m_fetchPixmapAndUpdatePixmapCache = fetchPixmapAndUpdatePixmapCache;
}
ListModelFilter::ListModelFilter(ListModel *sourceModel, QObject *parent) :
QSortFilterProxyModel(parent)
{

View File

@@ -12,6 +12,7 @@
#include <QStyledItemDelegate>
#include <QListView>
#include <functional>
#include <optional>
namespace Utils { class FancyLineEdit; }
@@ -58,23 +59,22 @@ public:
class CORE_EXPORT ListModel : public QAbstractListModel
{
public:
enum ListDataRole {
ItemRole = Qt::UserRole,
ItemImageRole,
ItemTagsRole
};
enum ListDataRole { ItemRole = Qt::UserRole, ItemImageRole, ItemTagsRole };
using PixmapFunction = std::function<QPixmap(QString)>;
explicit ListModel(QObject *parent);
~ListModel() override;
int rowCount(const QModelIndex &parent = QModelIndex()) const final;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
virtual QPixmap fetchPixmapAndUpdatePixmapCache(const QString &url) const = 0;
void setPixmapFunction(const PixmapFunction &fetchPixmapAndUpdatePixmapCache);
static const QSize defaultImageSize;
protected:
QList<ListItem *> m_items;
PixmapFunction m_fetchPixmapAndUpdatePixmapCache;
};
class CORE_EXPORT ListModelFilter : public QSortFilterProxyModel

View File

@@ -72,6 +72,11 @@ public:
ProductListModel::ProductListModel(QObject *parent)
: Core::ListModel(parent)
{
setPixmapFunction([this](const QString &url) -> QPixmap {
if (auto sectionedProducts = qobject_cast<SectionedProducts *>(this->parent()))
sectionedProducts->queueImageForDownload(url);
return {};
});
}
void ProductListModel::appendItems(const QList<Core::ListItem *> &items)
@@ -165,13 +170,6 @@ void SectionedProducts::updateCollections()
this, [this, reply]() { onFetchCollectionsFinished(reply); });
}
QPixmap ProductListModel::fetchPixmapAndUpdatePixmapCache(const QString &url) const
{
if (auto sectionedProducts = qobject_cast<SectionedProducts *>(parent()))
sectionedProducts->queueImageForDownload(url);
return QPixmap();
}
void SectionedProducts::onFetchCollectionsFinished(QNetworkReply *reply)
{
QTC_ASSERT(reply, return);

View File

@@ -31,9 +31,6 @@ public:
void appendItems(const QList<Core::ListItem *> &items);
const QList<Core::ListItem *> items() const;
void updateModelIndexesForUrl(const QString &url);
protected:
QPixmap fetchPixmapAndUpdatePixmapCache(const QString &url) const override;
};
struct Section

View File

@@ -223,6 +223,45 @@ int ExampleSetModel::getExtraExampleSetIndex(int i) const
return variant.toInt();
}
static QString resourcePath()
{
// normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows
return Core::ICore::resourcePath().normalizedPathName().toString();
}
static QPixmap fetchPixmapAndUpdatePixmapCache(const QString &url)
{
QPixmap pixmap;
if (QPixmapCache::find(url, &pixmap))
return pixmap;
if (url.startsWith("qthelp://")) {
QByteArray fetchedData = Core::HelpManager::fileData(url);
if (!fetchedData.isEmpty()) {
QBuffer imgBuffer(&fetchedData);
imgBuffer.open(QIODevice::ReadOnly);
QImageReader reader(&imgBuffer, QFileInfo(url).suffix().toLatin1());
QImage img = reader.read();
img.convertTo(QImage::Format_RGB32);
const int dpr = qApp->devicePixelRatio();
// boundedTo -> don't scale thumbnails up
const QSize scaledSize = Core::ListModel::defaultImageSize.boundedTo(img.size()) * dpr;
pixmap = QPixmap::fromImage(
img.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
pixmap.setDevicePixelRatio(dpr);
}
} else {
pixmap.load(url);
if (pixmap.isNull())
pixmap.load(resourcePath() + "/welcomescreen/widgets/" + url);
}
QPixmapCache::insert(url, pixmap);
return pixmap;
}
ExamplesListModel::ExamplesListModel(QObject *parent)
: Core::ListModel(parent)
{
@@ -232,6 +271,7 @@ ExamplesListModel::ExamplesListModel(QObject *parent)
&Core::HelpManager::Signals::documentationChanged,
this,
&ExamplesListModel::updateExamples);
setPixmapFunction(fetchPixmapAndUpdatePixmapCache);
}
static QString fixStringForTags(const QString &string)
@@ -435,12 +475,6 @@ void ExamplesListModel::parseTutorials(QXmlStreamReader *reader, const QString &
}
}
static QString resourcePath()
{
// normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows
return Core::ICore::resourcePath().normalizedPathName().toString();
}
void ExamplesListModel::updateExamples()
{
QString examplesInstallPath;
@@ -491,39 +525,6 @@ void ExamplesListModel::updateExamples()
endResetModel();
}
QPixmap ExamplesListModel::fetchPixmapAndUpdatePixmapCache(const QString &url) const
{
QPixmap pixmap;
if (QPixmapCache::find(url, &pixmap))
return pixmap;
if (url.startsWith("qthelp://")) {
QByteArray fetchedData = Core::HelpManager::fileData(url);
if (!fetchedData.isEmpty()) {
QBuffer imgBuffer(&fetchedData);
imgBuffer.open(QIODevice::ReadOnly);
QImageReader reader(&imgBuffer, QFileInfo(url).suffix().toLatin1());
QImage img = reader.read();
img.convertTo(QImage::Format_RGB32);
const int dpr = qApp->devicePixelRatio();
// boundedTo -> don't scale thumbnails up
const QSize scaledSize = ListModel::defaultImageSize.boundedTo(img.size()) * dpr;
pixmap = QPixmap::fromImage(
img.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
pixmap.setDevicePixelRatio(dpr);
}
} else {
pixmap.load(url);
if (pixmap.isNull())
pixmap.load(resourcePath() + "/welcomescreen/widgets/" + url);
}
QPixmapCache::insert(url, pixmap);
return pixmap;
}
void ExampleSetModel::updateQtVersionList()
{
QtVersions versions = QtVersionManager::sortVersions(QtVersionManager::versions(

View File

@@ -111,8 +111,6 @@ public:
QStringList exampleSets() const;
ExampleSetModel *exampleSetModel() { return &m_exampleSetModel; }
QPixmap fetchPixmapAndUpdatePixmapCache(const QString &url) const override;
signals:
void selectedExampleSetChanged(int);