Welcome/Qt: Use separate model instances for examples and tutorials

And get rid of the need to filter the model in a special way.

Change-Id: I42dd80e3b8b122dcd2d5f454d0acde1facf556bd
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Eike Ziller
2023-01-16 18:44:54 +01:00
parent e8fdfd9e2c
commit ad643fdd30
3 changed files with 61 additions and 90 deletions

View File

@@ -263,16 +263,25 @@ static QPixmap fetchPixmapAndUpdatePixmapCache(const QString &url)
return pixmap; return pixmap;
} }
ExamplesListModel::ExamplesListModel(QObject *parent) ExamplesListModel::ExamplesListModel(ExampleSetModel *exampleSetModel,
bool isExamples,
QObject *parent)
: Core::ListModel(parent) : Core::ListModel(parent)
, m_exampleSetModel(exampleSetModel)
, m_isExamples(isExamples)
{ {
connect(&m_exampleSetModel, &ExampleSetModel::selectedExampleSetChanged, if (isExamples) {
this, &ExamplesListModel::updateExamples); connect(m_exampleSetModel,
&ExampleSetModel::selectedExampleSetChanged,
this,
&ExamplesListModel::updateExamples);
}
connect(Core::HelpManager::Signals::instance(), connect(Core::HelpManager::Signals::instance(),
&Core::HelpManager::Signals::documentationChanged, &Core::HelpManager::Signals::documentationChanged,
this, this,
&ExamplesListModel::updateExamples); &ExamplesListModel::updateExamples);
setPixmapFunction(fetchPixmapAndUpdatePixmapCache); setPixmapFunction(fetchPixmapAndUpdatePixmapCache);
updateExamples();
} }
static QString fixStringForTags(const QString &string) static QString fixStringForTags(const QString &string)
@@ -332,11 +341,11 @@ static bool isValidExampleOrDemo(ExampleItem *item)
return ok || debugExamples(); return ok || debugExamples();
} }
static QList<ListItem *> parseExamples(QXmlStreamReader *reader, static QList<ExampleItem *> parseExamples(QXmlStreamReader *reader,
const QString &projectsOffset, const QString &projectsOffset,
const QString &examplesInstallPath) const QString &examplesInstallPath)
{ {
QList<ListItem *> result; QList<ExampleItem *> result;
std::unique_ptr<ExampleItem> item; std::unique_ptr<ExampleItem> item;
const QChar slash = QLatin1Char('/'); const QChar slash = QLatin1Char('/');
while (!reader->atEnd()) { while (!reader->atEnd()) {
@@ -389,11 +398,11 @@ static QList<ListItem *> parseExamples(QXmlStreamReader *reader,
return result; return result;
} }
static QList<ListItem *> parseDemos(QXmlStreamReader *reader, static QList<ExampleItem *> parseDemos(QXmlStreamReader *reader,
const QString &projectsOffset, const QString &projectsOffset,
const QString &demosInstallPath) const QString &demosInstallPath)
{ {
QList<ListItem *> result; QList<ExampleItem *> result;
std::unique_ptr<ExampleItem> item; std::unique_ptr<ExampleItem> item;
const QChar slash = QLatin1Char('/'); const QChar slash = QLatin1Char('/');
while (!reader->atEnd()) { while (!reader->atEnd()) {
@@ -437,9 +446,9 @@ static QList<ListItem *> parseDemos(QXmlStreamReader *reader,
return result; return result;
} }
static QList<ListItem *> parseTutorials(QXmlStreamReader *reader, const QString &projectsOffset) static QList<ExampleItem *> parseTutorials(QXmlStreamReader *reader, const QString &projectsOffset)
{ {
QList<ListItem *> result; QList<ExampleItem *> result;
std::unique_ptr<ExampleItem> item; std::unique_ptr<ExampleItem> item;
const QChar slash = QLatin1Char('/'); const QChar slash = QLatin1Char('/');
while (!reader->atEnd()) { while (!reader->atEnd()) {
@@ -489,12 +498,12 @@ void ExamplesListModel::updateExamples()
QString examplesInstallPath; QString examplesInstallPath;
QString demosInstallPath; QString demosInstallPath;
const QStringList sources = m_exampleSetModel.exampleSources(&examplesInstallPath, const QStringList sources = m_exampleSetModel->exampleSources(&examplesInstallPath,
&demosInstallPath); &demosInstallPath);
clear(); clear();
QList<ListItem *> items; QList<ExampleItem *> items;
for (const QString &exampleSource : sources) { for (const QString &exampleSource : sources) {
QFile exampleFile(exampleSource); QFile exampleFile(exampleSource);
if (!exampleFile.open(QIODevice::ReadOnly)) { if (!exampleFile.open(QIODevice::ReadOnly)) {
@@ -514,11 +523,11 @@ void ExamplesListModel::updateExamples()
while (!reader.atEnd()) while (!reader.atEnd())
switch (reader.readNext()) { switch (reader.readNext()) {
case QXmlStreamReader::StartElement: case QXmlStreamReader::StartElement:
if (reader.name() == QLatin1String("examples")) if (m_isExamples && reader.name() == QLatin1String("examples"))
items += parseExamples(&reader, examplesDir.path(), examplesInstallPath); items += parseExamples(&reader, examplesDir.path(), examplesInstallPath);
else if (reader.name() == QLatin1String("demos")) else if (m_isExamples && reader.name() == QLatin1String("demos"))
items += parseDemos(&reader, demosDir.path(), demosInstallPath); items += parseDemos(&reader, demosDir.path(), demosInstallPath);
else if (reader.name() == QLatin1String("tutorials")) else if (!m_isExamples && reader.name() == QLatin1String("tutorials"))
items += parseTutorials(&reader, examplesDir.path()); items += parseTutorials(&reader, examplesDir.path());
break; break;
default: // nothing default: // nothing
@@ -531,7 +540,18 @@ void ExamplesListModel::updateExamples()
<< ": " << reader.errorString(); << ": " << reader.errorString();
} }
} }
appendItems(items); if (m_isExamples) {
if (m_exampleSetModel->selectedQtSupports(Android::Constants::ANDROID_DEVICE_TYPE)) {
items = Utils::filtered(items, [](ExampleItem *item) {
return item->tags.contains("android");
});
} else if (m_exampleSetModel->selectedQtSupports(Ios::Constants::IOS_DEVICE_TYPE)) {
items = Utils::filtered(items,
[](ExampleItem *item) { return item->tags.contains("ios"); });
}
}
appendItems(static_container_cast<ListItem *>(items));
} }
void ExampleSetModel::updateQtVersionList() void ExampleSetModel::updateQtVersionList()
@@ -694,45 +714,5 @@ void ExampleSetModel::tryToInitialize()
updateQtVersionList(); updateQtVersionList();
} }
ExamplesListModelFilter::ExamplesListModelFilter(ExamplesListModel *sourceModel, bool showTutorialsOnly, QObject *parent) :
Core::ListModelFilter(sourceModel, parent),
m_showTutorialsOnly(showTutorialsOnly),
m_examplesListModel(sourceModel)
{
}
bool ExamplesListModelFilter::leaveFilterAcceptsRowBeforeFiltering(const Core::ListItem *item,
bool *earlyExitResult) const
{
QTC_ASSERT(earlyExitResult, return false);
const bool isTutorial = static_cast<const ExampleItem *>(item)->type == Tutorial;
if (m_showTutorialsOnly) {
*earlyExitResult = isTutorial;
return !isTutorial;
}
if (isTutorial) {
*earlyExitResult = false;
return true;
}
if (m_examplesListModel->exampleSetModel()->selectedQtSupports(Android::Constants::ANDROID_DEVICE_TYPE)
&& !item->tags.contains("android")) {
*earlyExitResult = false;
return true;
}
if (m_examplesListModel->exampleSetModel()->selectedQtSupports(Ios::Constants::IOS_DEVICE_TYPE)
&& !item->tags.contains("ios")) {
*earlyExitResult = false;
return true;
}
return false;
}
} // namespace Internal } // namespace Internal
} // namespace QtSupport } // namespace QtSupport

View File

@@ -104,27 +104,13 @@ class ExamplesListModel : public Core::ListModel
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ExamplesListModel(QObject *parent); explicit ExamplesListModel(ExampleSetModel *exampleSetModel, bool isExamples, QObject *parent);
void updateExamples(); void updateExamples();
ExampleSetModel *exampleSetModel() { return &m_exampleSetModel; }
private: private:
ExampleSetModel m_exampleSetModel; ExampleSetModel *m_exampleSetModel;
}; bool m_isExamples;
class ExamplesListModelFilter : public Core::ListModelFilter
{
public:
ExamplesListModelFilter(ExamplesListModel *sourceModel, bool showTutorialsOnly, QObject *parent);
protected:
bool leaveFilterAcceptsRowBeforeFiltering(const Core::ListItem *item,
bool *earlyExitResult) const override;
private:
const bool m_showTutorialsOnly;
ExamplesListModel *m_examplesListModel = nullptr;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -46,6 +46,8 @@ namespace Internal {
const char C_FALLBACK_ROOT[] = "ProjectsFallbackRoot"; const char C_FALLBACK_ROOT[] = "ProjectsFallbackRoot";
Q_GLOBAL_STATIC(ExampleSetModel, s_exampleSetModel)
ExamplesWelcomePage::ExamplesWelcomePage(bool showExamples) ExamplesWelcomePage::ExamplesWelcomePage(bool showExamples)
: m_showExamples(showExamples) : m_showExamples(showExamples)
{ {
@@ -258,10 +260,9 @@ public:
: m_isExamples(isExamples) : m_isExamples(isExamples)
{ {
m_exampleDelegate.setShowExamples(isExamples); m_exampleDelegate.setShowExamples(isExamples);
static auto s_examplesModel = new ExamplesListModel(this);
m_examplesModel = s_examplesModel;
auto filteredModel = new ExamplesListModelFilter(m_examplesModel, !m_isExamples, this); auto examplesModel = new ExamplesListModel(s_exampleSetModel, isExamples, this);
auto filteredModel = new ListModelFilter(examplesModel, this);
auto searchBox = new SearchBox(this); auto searchBox = new SearchBox(this);
m_searcher = searchBox->m_lineEdit; m_searcher = searchBox->m_lineEdit;
@@ -284,13 +285,16 @@ public:
exampleSetSelector->setPalette(pal); exampleSetSelector->setPalette(pal);
exampleSetSelector->setMinimumWidth(Core::ListItemDelegate::GridItemWidth); exampleSetSelector->setMinimumWidth(Core::ListItemDelegate::GridItemWidth);
exampleSetSelector->setMaximumWidth(Core::ListItemDelegate::GridItemWidth); exampleSetSelector->setMaximumWidth(Core::ListItemDelegate::GridItemWidth);
ExampleSetModel *exampleSetModel = m_examplesModel->exampleSetModel(); exampleSetSelector->setModel(s_exampleSetModel);
exampleSetSelector->setModel(exampleSetModel); exampleSetSelector->setCurrentIndex(s_exampleSetModel->selectedExampleSet());
exampleSetSelector->setCurrentIndex(exampleSetModel->selectedExampleSet()); connect(exampleSetSelector,
connect(exampleSetSelector, &QComboBox::activated, &QComboBox::activated,
exampleSetModel, &ExampleSetModel::selectExampleSet); s_exampleSetModel,
connect(exampleSetModel, &ExampleSetModel::selectedExampleSetChanged, &ExampleSetModel::selectExampleSet);
exampleSetSelector, &QComboBox::setCurrentIndex); connect(s_exampleSetModel,
&ExampleSetModel::selectedExampleSetChanged,
exampleSetSelector,
&QComboBox::setCurrentIndex);
hbox->setSpacing(Core::WelcomePageHelpers::HSpacing); hbox->setSpacing(Core::WelcomePageHelpers::HSpacing);
hbox->addWidget(exampleSetSelector); hbox->addWidget(exampleSetSelector);
@@ -311,8 +315,10 @@ public:
connect(&m_exampleDelegate, &ExampleDelegate::tagClicked, connect(&m_exampleDelegate, &ExampleDelegate::tagClicked,
this, &ExamplesPageWidget::onTagClicked); this, &ExamplesPageWidget::onTagClicked);
connect(m_searcher, &QLineEdit::textChanged, connect(m_searcher,
filteredModel, &ExamplesListModelFilter::setSearchString); &QLineEdit::textChanged,
filteredModel,
&ListModelFilter::setSearchString);
} }
void onTagClicked(const QString &tag) void onTagClicked(const QString &tag)
@@ -324,7 +330,6 @@ public:
const bool m_isExamples; const bool m_isExamples;
ExampleDelegate m_exampleDelegate; ExampleDelegate m_exampleDelegate;
QPointer<ExamplesListModel> m_examplesModel;
QLineEdit *m_searcher; QLineEdit *m_searcher;
}; };