diff --git a/modules/gui/qt/medialibrary/mlbasemodel.cpp b/modules/gui/qt/medialibrary/mlbasemodel.cpp index 997bc3a0fa..54237b6a8c 100644 --- a/modules/gui/qt/medialibrary/mlbasemodel.cpp +++ b/modules/gui/qt/medialibrary/mlbasemodel.cpp @@ -502,6 +502,62 @@ MLItem *MLBaseModel::findInCache(const MLItemId& id, int *index) const return item ? item->get() : nullptr; } +void MLBaseModel::updateItemInCache(const MLItemId& mlid) +{ + if (!m_cache) + { + emit resetRequested(); + return; + } + MLItem* item = findInCache(mlid, nullptr); + if (!item) // items isn't loaded + return; + + if (!m_itemLoader) + m_itemLoader = createLoader(); + struct Ctx { + std::unique_ptr item; + }; + m_mediaLib->runOnMLThread(this, + //ML thread + [mlid, itemLoader = m_itemLoader](vlc_medialibrary_t* ml, Ctx& ctx){ + ctx.item = itemLoader->loadItemById(ml, mlid); + }, + //UI thread + [this](qint64, Ctx& ctx) { + if (!ctx.item) + return; + + int row = m_cache->updateItem(std::move(ctx.item)); + if (row != -1) + { + //notify every roles + emit dataChanged(index(row), index(row)); + } + //otherwise don't notify, it will be updated when the cache reload the corresponding segment + }); +} + +void MLBaseModel::deleteItemInCache(const MLItemId& mlid) +{ + if (!m_cache) + { + emit resetRequested(); + return; + } + int row = m_cache->deleteItem(mlid); + if (row < 0) + { + // items isn't in cache, we don't know if it's before or after our cache, request a reset + emit resetRequested(); + } + else + { + beginRemoveRows({}, row, row); + endRemoveRows(); + } +} + //------------------------------------------------------------------------------------------------- MLBaseModel::BaseLoader::BaseLoader(MLItemId parent, QString searchPattern, diff --git a/modules/gui/qt/medialibrary/mlbasemodel.hpp b/modules/gui/qt/medialibrary/mlbasemodel.hpp index 81ed7764f8..df0ae28784 100644 --- a/modules/gui/qt/medialibrary/mlbasemodel.hpp +++ b/modules/gui/qt/medialibrary/mlbasemodel.hpp @@ -118,6 +118,13 @@ protected: MLItem *findInCache(const MLItemId& id, int *index) const; + //update and notify changes on an item if this item is in the cache + void updateItemInCache(const MLItemId& id); + + //delete and notify deletion of an item if this item is in the cache + //this is only to reflect changes from the ML, it won't alter the database + void deleteItemInCache(const MLItemId& mlid); + virtual void onVlcMlEvent( const MLEvent &event ); @@ -177,6 +184,9 @@ protected: mutable std::unique_ptr m_cache; + //loader used to load single items + std::shared_ptr m_itemLoader; + private: // Friends friend QString getVideoListCover(const MLBaseModel*, MLItemCover*, int, int, int); }; diff --git a/modules/gui/qt/medialibrary/mllistcache.cpp b/modules/gui/qt/medialibrary/mllistcache.cpp index e0a9b865cf..78c7a7ff09 100644 --- a/modules/gui/qt/medialibrary/mllistcache.cpp +++ b/modules/gui/qt/medialibrary/mllistcache.cpp @@ -46,6 +46,35 @@ const MLListCache::ItemType* MLListCache::find(const std::function&& newItem) +{ + MLItemId mlid = newItem->getId(); + auto it = std::find_if(m_list.begin(), m_list.end(), [mlid](const ItemType& item) { + return (item->getId() == mlid); + }); + //item not found + if (it == m_list.end()) + return -1; + + int pos = m_offset + std::distance(m_list.begin(), it); + *it = std::move(newItem); + return pos; +} + +int MLListCache::deleteItem(const MLItemId& mlid) +{ + auto it = std::find_if(m_list.begin(), m_list.end(), [mlid](const ItemType& item) { + return (item->getId() == mlid); + }); + //item not found + if (it == m_list.end()) + return -1; + int pos = m_offset + std::distance(m_list.begin(), it); + m_list.erase(it, it); + m_total_count -= 1; + return pos; +} + ssize_t MLListCache::count() const { return m_total_count; diff --git a/modules/gui/qt/medialibrary/mllistcache.hpp b/modules/gui/qt/medialibrary/mllistcache.hpp index fcd022d96c..96e23a2286 100644 --- a/modules/gui/qt/medialibrary/mllistcache.hpp +++ b/modules/gui/qt/medialibrary/mllistcache.hpp @@ -112,6 +112,19 @@ public: */ const ItemType *find(const std::function &&f, int *index = nullptr) const; + /** + * replace item in the cache with the one provided. replacement is based on newItem MLItemId + * + * this returns the index of the replaced item, or -1 if the item is not in the cache + */ + int updateItem(std::unique_ptr&& newItem); + + /** + * Removes from the cache list given its item id + * + * it returns the index row when the id is found and removed, -1 otherwise + */ + int deleteItem(const MLItemId& mlid); /** * Return the number of items or `COUNT_UNINITIALIZED`