diff --git a/modules/gui/qt/network/networkmediamodel.cpp b/modules/gui/qt/network/networkmediamodel.cpp index 9730d8574f..ad643e3f1e 100644 --- a/modules/gui/qt/network/networkmediamodel.cpp +++ b/modules/gui/qt/network/networkmediamodel.cpp @@ -34,6 +34,8 @@ #include #include #include +#include +#include namespace { @@ -861,53 +863,66 @@ bool NetworkMediaModel::addAndPlay(const QModelIndexList& itemIdList) } /* Q_INVOKABLE */ -QVariantList NetworkMediaModel::getItemsForIndexes(const QModelIndexList & indexes) const +void NetworkMediaModel::getItemsForIndexes(const QModelIndexList & indexes, QJSValue callback) { - Q_D(const NetworkMediaModel); - QVariantList items; - - bool allInCache = true; - for (const QModelIndex & modelIndex : indexes) - { - const NetworkMediaItem* item = d->getItemForRow(modelIndex.row()); - if (!item) - { - allInCache = false; - break; - } + if (!callback.isCallable()) + return; - const NetworkTreeItem & tree = item->tree; - items.append(QVariant::fromValue(SharedInputItem(tree.media.get(), true))); - } + getItemsForIndexes(indexes, [this, callback](const QVariantList& items) mutable { + auto engine = qjsEngine(this); + if (engine) + callback.call({engine->toScriptValue(items)}); + }); +} - if (allInCache) - return items; +void NetworkMediaModel::getItemsForIndexes(const QModelIndexList & indexes, std::function callback) +{ + Q_D(NetworkMediaModel); - // Sometimes if there are many items selected, some are not in cache so we need to rebuild the list - items.clear(); - std::vector modelData = d->getModelData(d->m_searchPattern); + if (!callback) + return; - auto sortFunc = d->getSortFunction(); - if (sortFunc) - std::sort(modelData.begin(), modelData.end(), sortFunc); + if (indexes.isEmpty()) + { + callback(QVariantList()); + return; + } + int maxIndex = 0; for (const QModelIndex & modelIndex : indexes) { - int index = modelIndex.row(); + if (modelIndex.row() > maxIndex) + maxIndex = modelIndex.row(); + } - if (index < 0 || index >= static_cast(modelData.size())) - continue; + // check if we have loaded all items we need in the cache + unsigned int loaded = getLoadedCount(); + unsigned int maximum = getMaximumCount(); + unsigned int needed = static_cast(maxIndex) + 1; - const NetworkMediaItemPtr& item = modelData[index]; - if (!item) - continue; + if (loaded >= needed || loaded >= maximum) + { + QVariantList items; + for (const QModelIndex & modelIndex : indexes) + { + const NetworkMediaItem* item = d->getItemForRow(modelIndex.row()); + if (!item) + continue; - const NetworkTreeItem & tree = item->tree; + const NetworkTreeItem & tree = item->tree; + items.append(QVariant::fromValue(SharedInputItem(tree.media.get(), true))); + } - items.append(QVariant::fromValue(SharedInputItem(tree.media.get(), true))); + callback(items); + return; } - return items; + // item() internally calls refer() to trigger cache loading for all items till the max index + d->item(maxIndex); + + connect(this, &NetworkMediaModel::dataChanged, this, [this, indexes, callback]() { + getItemsForIndexes(indexes, callback); + }, Qt::SingleShotConnection); } MainCtx* NetworkMediaModel::getCtx() const { diff --git a/modules/gui/qt/network/networkmediamodel.hpp b/modules/gui/qt/network/networkmediamodel.hpp index 49ea5c8deb..4a45752de1 100644 --- a/modules/gui/qt/network/networkmediamodel.hpp +++ b/modules/gui/qt/network/networkmediamodel.hpp @@ -29,9 +29,11 @@ #include "networkbasemodel.hpp" #include +#include Q_MOC_INCLUDE( "maininterface/mainctx.hpp" ) +class QJSValue; class MainCtx; class NetworkTreeItem @@ -164,7 +166,8 @@ public: Q_INVOKABLE bool addAndPlay(const QVariantList& itemIdList); Q_INVOKABLE bool addAndPlay(const QModelIndexList& itemIdList); - Q_INVOKABLE QVariantList getItemsForIndexes(const QModelIndexList & indexes) const; + Q_INVOKABLE void getItemsForIndexes(const QModelIndexList & indexes, QJSValue callback); + void getItemsForIndexes(const QModelIndexList & indexes, std::function callback); signals: void nameChanged();