diff --git a/src/qtquick/quickitemsmodel.cpp b/src/qtquick/quickitemsmodel.cpp index 90f08228..98343eba 100644 --- a/src/qtquick/quickitemsmodel.cpp +++ b/src/qtquick/quickitemsmodel.cpp @@ -1,367 +1,367 @@ /* * Copyright (C) 2016 Dan Leinir Turthra Jensen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * */ #include "quickitemsmodel.h" #include "quickengine.h" #include "itemsmodel.h" #include "engine.h" #include "downloadlinkinfo.h" class ItemsModel::Private { public: Private(ItemsModel* qq) : q(qq) , model(nullptr) , engine(nullptr) {} ItemsModel* q; KNSCore::ItemsModel* model; KNSCore::Engine* engine; bool initModel() { if(model) { return true; } if(!engine) { return false; } model = new KNSCore::ItemsModel(engine, q); q->connect(engine, &KNSCore::Engine::signalProvidersLoaded, engine, &KNSCore::Engine::reloadEntries); // Entries have been fetched and should be shown: q->connect(engine, &KNSCore::Engine::signalEntriesLoaded, model, &KNSCore::ItemsModel::slotEntriesLoaded); // An entry has changes - eg because it was installed q->connect(engine, &KNSCore::Engine::signalEntryChanged, model, &KNSCore::ItemsModel::slotEntryChanged); q->connect(engine, &KNSCore::Engine::signalResetView, model, &KNSCore::ItemsModel::clearEntries); q->connect(engine, &KNSCore::Engine::signalEntryPreviewLoaded, model, &KNSCore::ItemsModel::slotEntryPreviewLoaded); q->connect(model, &KNSCore::ItemsModel::rowsInserted, q, &ItemsModel::rowsInserted); q->connect(model, &KNSCore::ItemsModel::rowsRemoved, q, &ItemsModel::rowsRemoved); q->connect(model, &KNSCore::ItemsModel::dataChanged, q, &ItemsModel::dataChanged); q->connect(model, &KNSCore::ItemsModel::modelReset, q, &ItemsModel::modelReset); return true; } }; ItemsModel::ItemsModel(QObject* parent) : QAbstractListModel(parent) , d(new Private(this)) { } ItemsModel::~ItemsModel() { delete d; } QHash ItemsModel::roleNames() const { static const QHash roles = QHash{ {Qt::DisplayRole, "display"}, {NameRole, "name"}, {UniqueIdRole, "uniqueId"}, {CategoryRole, "category"}, {HomepageRole, "homepage"}, {AuthorRole, "author"}, {LicenseRole, "license"}, {ShortSummaryRole, "shortSummary"}, {SummaryRole, "summary"}, {ChangelogRole, "changelog"}, {VersionRole, "version"}, {ReleaseDateRole, "releaseDate"}, {UpdateVersionRole, "updateVersion"}, {UpdateReleaseDateRole, "updateReleaseDate"}, {PayloadRole, "payload"}, {Qt::DecorationRole, "decoration"}, {PreviewsSmallRole, "previewsSmall"}, {PreviewsRole, "previews"}, {InstalledFilesRole, "installedFiles"}, {UnInstalledFilesRole, "uninstalledFiles"}, {RatingRole, "rating"}, {NumberOfCommentsRole, "numberOfComments"}, {DownloadCountRole, "downloadCount"}, {NumberFansRole, "numberFans"}, {NumberKnowledgebaseEntriesRole, "numberKnowledgebaseEntries"}, {KnowledgebaseLinkRole, "knowledgebaseLink"}, {DownloadLinksRole, "downloadLinks"}, {DonationLinkRole, "donationLink"}, {ProviderIdRole, "providerId"}, {SourceRole, "source"}, {StatusRole, "status"} }; return roles; } int ItemsModel::rowCount(const QModelIndex& parent) const { if(parent.isValid()) return 0; if(d->initModel()) return d->model->rowCount(QModelIndex()); return 0; } QVariant ItemsModel::data(const QModelIndex& index, int role) const { QVariant data; if(index.isValid() && d->initModel()) { KNSCore::EntryInternal entry = d->model->data(d->model->index(index.row()), Qt::UserRole).value(); switch(role) { case NameRole: case Qt::DisplayRole: data.setValue(entry.name()); break; case UniqueIdRole: data.setValue(entry.uniqueId()); break; case CategoryRole: data.setValue(entry.category()); break; case HomepageRole: data.setValue(entry.homepage()); break; case AuthorRole: { KNSCore::Author author = entry.author(); QVariantMap returnAuthor; returnAuthor[QStringLiteral("name")] = author.name(); returnAuthor[QStringLiteral("email")] = author.email(); returnAuthor[QStringLiteral("homepage")] = author.homepage(); returnAuthor[QStringLiteral("jabber")] = author.jabber(); data.setValue<>(returnAuthor); } break; case LicenseRole: data.setValue(entry.license()); break; case ShortSummaryRole: data.setValue(entry.shortSummary()); break; case SummaryRole: data.setValue(entry.summary()); break; case ChangelogRole: data.setValue(entry.changelog()); break; case VersionRole: data.setValue(entry.version()); break; case ReleaseDateRole: data.setValue(entry.releaseDate()); break; case UpdateVersionRole: data.setValue(entry.updateVersion()); break; case UpdateReleaseDateRole: data.setValue(entry.updateReleaseDate()); break; case PayloadRole: data.setValue(entry.payload()); break; case Qt::DecorationRole: data.setValue(entry.previewUrl(KNSCore::EntryInternal::PreviewSmall1)); break; case PreviewsSmallRole: { QStringList previews; previews << entry.previewUrl(KNSCore::EntryInternal::PreviewSmall1); previews << entry.previewUrl(KNSCore::EntryInternal::PreviewSmall2); previews << entry.previewUrl(KNSCore::EntryInternal::PreviewSmall3); - while(previews.last().isEmpty()) { + while(!previews.isEmpty() && previews.last().isEmpty()) { previews.takeLast(); } data.setValue(previews); } break; case PreviewsRole: { QStringList previews; previews << entry.previewUrl(KNSCore::EntryInternal::PreviewBig1); previews << entry.previewUrl(KNSCore::EntryInternal::PreviewBig2); previews << entry.previewUrl(KNSCore::EntryInternal::PreviewBig3); - while(previews.last().isEmpty()) { + while(!previews.isEmpty() && previews.last().isEmpty()) { previews.takeLast(); } data.setValue(previews); } break; case InstalledFilesRole: data.setValue(entry.installedFiles()); break; case UnInstalledFilesRole: data.setValue(entry.uninstalledFiles()); break; case RatingRole: data.setValue(entry.rating()); break; case NumberOfCommentsRole: data.setValue(entry.numberOfComments()); break; case DownloadCountRole: data.setValue(entry.downloadCount()); break; case NumberFansRole: data.setValue(entry.numberFans()); break; case NumberKnowledgebaseEntriesRole: data.setValue(entry.numberKnowledgebaseEntries()); break; case KnowledgebaseLinkRole: data.setValue(entry.knowledgebaseLink()); break; case DownloadLinksRole: { // This would be good to cache... but it also needs marking as dirty, somehow... QList dllinks = entry.downloadLinkInformationList(); QObjectList list; Q_FOREACH(const KNSCore::EntryInternal::DownloadLinkInformation& link, dllinks) { DownloadLinkInfo* info = new DownloadLinkInfo(); info->setData(link); list.append(info); } data.setValue(list); } break; case DonationLinkRole: data.setValue(entry.donationLink()); break; case ProviderIdRole: data.setValue(entry.providerId()); break; case SourceRole: { KNSCore::EntryInternal::Source src = entry.source(); switch(src) { case KNSCore::EntryInternal::Cache: data.setValue(QStringLiteral("Cache")); break; case KNSCore::EntryInternal::Online: data.setValue(QStringLiteral("Online")); break; case KNSCore::EntryInternal::Registry: data.setValue(QStringLiteral("Registry")); break; default: data.setValue(QStringLiteral("Unknown source - shouldn't be possible")); break; } } break; case StatusRole: { KNS3::Entry::Status status = entry.status(); switch(status) { case KNS3::Entry::Downloadable: data.setValue(ItemsModel::DownloadableStatus); break; case KNS3::Entry::Installed: data.setValue(ItemsModel::InstalledStatus); break; case KNS3::Entry::Updateable: data.setValue(ItemsModel::UpdateableStatus); break; case KNS3::Entry::Deleted: data.setValue(ItemsModel::DeletedStatus); break; case KNS3::Entry::Installing: data.setValue(ItemsModel::InstallingStatus); break; case KNS3::Entry::Updating: data.setValue(ItemsModel::UpdatingStatus); break; case KNS3::Entry::Invalid: default: data.setValue(ItemsModel::InvalidStatus); break; } } break; default: data.setValue(QStringLiteral("Unknown role")); break; } } return data; } bool ItemsModel::canFetchMore(const QModelIndex& parent) const { if(parent.isValid()) { return false; } return true; } void ItemsModel::fetchMore(const QModelIndex& parent) { if(parent.isValid()) { return; } d->engine->requestMoreData(); } QObject * ItemsModel::engine() const { return d->engine; } void ItemsModel::setEngine(QObject* newEngine) { beginResetModel(); Engine* test = qobject_cast(newEngine); if(test) { d->engine = qobject_cast(test->engine()); } else { d->engine = qobject_cast(newEngine); } emit engineChanged(); endResetModel(); } void ItemsModel::installItem(int index) { if(d->engine) { KNSCore::EntryInternal entry = d->model->data(d->model->index(index), Qt::UserRole).value(); if(entry.isValid()) { d->engine->install(entry); } } } void ItemsModel::uninstallItem(int index) { if(d->engine) { KNSCore::EntryInternal entry = d->model->data(d->model->index(index), Qt::UserRole).value(); if(entry.isValid()) { d->engine->uninstall(entry); } } }