[vlc-commits] [Git][videolan/vlc][master] 5 commits: qt: refactor getData of mlbasemodel
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Fri Jul 28 08:09:23 UTC 2023
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
5c802f1a by Prince Gupta at 2023-07-28T07:52:24+00:00
qt: refactor getData of mlbasemodel
- - - - -
0bab5aa0 by Prince Gupta at 2023-07-28T07:52:24+00:00
qt: implement addAndPlay in MLBaseModel
- - - - -
326f5c76 by Prince Gupta at 2023-07-28T07:52:24+00:00
qml: don't use getIdForIndex in MLContentMenu
first request data and only then show the data
- - - - -
c05a4605 by Prince Gupta at 2023-07-28T07:52:24+00:00
qml: remove usage of getIdsForIndexes/getIdForIndex
- - - - -
72d3fc2f by Prince Gupta at 2023-07-28T07:52:24+00:00
qml: remove getIdsForIndexes/getIdForIndex
- - - - -
15 changed files:
- modules/gui/qt/medialibrary/mlbasemodel.cpp
- modules/gui/qt/medialibrary/mlbasemodel.hpp
- modules/gui/qt/medialibrary/qml/MusicAlbums.qml
- modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
- modules/gui/qt/medialibrary/qml/MusicArtist.qml
- modules/gui/qt/medialibrary/qml/MusicGenres.qml
- modules/gui/qt/medialibrary/qml/MusicTrackListDisplay.qml
- modules/gui/qt/medialibrary/qml/PlaylistMedia.qml
- modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
- modules/gui/qt/medialibrary/qml/UrlListDisplay.qml
- modules/gui/qt/medialibrary/qml/VideoAll.qml
- modules/gui/qt/medialibrary/qml/VideoAllSubDisplay.qml
- modules/gui/qt/medialibrary/qml/VideoDisplayRecentVideos.qml
- modules/gui/qt/util/qml/MLContextMenu.qml
- modules/gui/qt/util/qml/NativeMenu.qml
Changes:
=====================================
modules/gui/qt/medialibrary/mlbasemodel.cpp
=====================================
@@ -79,28 +79,23 @@ void MLBaseModel::sortByColumn(QByteArray name, Qt::SortOrder order)
return getDataAt(index(idx));
}
-void MLBaseModel::getData(const QModelIndexList &indexes, QJSValue callback)
-{
- if (!callback.isCallable()) // invalid argument
- return;
-
- QVector<int> indx;
- std::transform(indexes.begin(), indexes.end(), std::back_inserter(indx),
- [](const auto &index) {
- return index.row();
- });
+quint64 MLBaseModel::loadItems(const QVector<int> &indexes, MLBaseModel::ItemCallback cb)
+{
QSharedPointer<BaseLoader> loader{ createLoader().release() };
- struct Ctx {
+
+ struct Ctx
+ {
std::vector<std::unique_ptr<MLItem>> items;
};
- m_mediaLib->runOnMLThread<Ctx>(this,
- //ML thread
- [loader, indx](vlc_medialibrary_t* ml, Ctx& ctx){
- if (indx.isEmpty())
+
+ const auto worker =
+ [loader, indexes](vlc_medialibrary_t* ml, Ctx& ctx)
+ {
+ if (indexes.isEmpty())
return;
- auto sortedIndexes = indx;
+ auto sortedIndexes = indexes;
std::sort(sortedIndexes.begin(), sortedIndexes.end());
struct Range
@@ -119,37 +114,56 @@ void MLBaseModel::getData(const QModelIndexList &indexes, QJSValue callback)
ranges.push_back(Range {index, index});
}
- ctx.items.resize(indx.size());
+ ctx.items.resize(indexes.size());
for (const auto range : ranges)
{
auto data = loader->load(ml, range.low, range.high - range.low + 1);
- for (int i = 0; i < indx.size(); ++i)
+ for (int i = 0; i < indexes.size(); ++i)
{
- const auto targetIndex = indx[i];
+ const auto targetIndex = indexes[i];
if (targetIndex >= range.low && targetIndex <= range.high)
{
ctx.items.at(i) = std::move(data.at(targetIndex - range.low));
}
}
}
+ };
- },
- //UI thread
- [this, indxSize = indx.size(), callback]
- (quint64, Ctx& ctx) mutable
+ return m_mediaLib->runOnMLThread<Ctx>(this
+ //ML thread
+ , worker
+ // UI thread
+ , [cb](quint64 id, Ctx &ctx) { if (cb) cb(id, ctx.items); });
+}
+
+
+void MLBaseModel::getData(const QModelIndexList &indexes, QJSValue callback)
+{
+ if (!callback.isCallable()) // invalid argument
+ return;
+
+ QVector<int> indx;
+ std::transform(indexes.begin(), indexes.end()
+ , std::back_inserter(indx)
+ , std::mem_fn(&QModelIndex::row));
+
+ std::shared_ptr<quint64> requestId = std::make_shared<quint64>();
+
+ ItemCallback cb = [this, indxSize = indx.size(), callback, requestId]
+ (quint64 id, std::vector<std::unique_ptr<MLItem>> &items) mutable
{
auto jsEngine = qjsEngine(this);
- if (!jsEngine)
+ if (!jsEngine || *requestId != id)
return;
- assert((int)ctx.items.size() == indxSize);
+ assert((int)items.size() == indxSize);
const QHash<int, QByteArray> roles = roleNames();
auto jsArray = jsEngine->newArray(indxSize);
for (int i = 0; i < indxSize; ++i)
{
- const auto &item = ctx.items[i];
+ const auto &item = items[i];
QMap<QString, QVariant> dataDict;
if (item) // item may fail to load
@@ -160,7 +174,9 @@ void MLBaseModel::getData(const QModelIndexList &indexes, QJSValue callback)
}
callback.call({jsArray});
- });
+ };
+
+ *requestId = loadItems(indx, cb);
}
QVariant MLBaseModel::data(const QModelIndex &index, int role) const
@@ -172,6 +188,27 @@ QVariant MLBaseModel::data(const QModelIndex &index, int role) const
return {};
}
+void MLBaseModel::addAndPlay(const QModelIndexList &list, const QStringList &options)
+{
+ QVector<int> indx;
+ std::transform(list.begin(), list.end(), std::back_inserter(indx), std::mem_fn(&QModelIndex::row));
+
+ ItemCallback play = [this, options](quint64, std::vector<std::unique_ptr<MLItem>> &items)
+ {
+ if (!m_mediaLib)
+ return;
+
+ QVariantList ids;
+ std::transform(items.begin(), items.end()
+ , std::back_inserter(ids)
+ , [](const std::unique_ptr<MLItem> &item) { return item ? QVariant::fromValue(item->getId()) : QVariant {}; });
+
+ m_mediaLib->addAndPlay(ids, options);
+ };
+
+ loadItems(indx, play);
+}
+
//-------------------------------------------------------------------------------------------------
void MLBaseModel::onResetRequested()
@@ -367,54 +404,6 @@ int MLBaseModel::rowCount(const QModelIndex &parent) const
return m_cache->count();
}
-MLItemId MLBaseModel::getIdForIndex(QVariant index) const
-{
- MLItem* obj = nullptr;
- if (index.canConvert<int>())
- obj = item( index.toInt() );
- else if ( index.canConvert<QModelIndex>() )
- obj = item( index.value<QModelIndex>().row() );
-
- if (!obj)
- return {};
-
- return obj->getId();
-}
-
-QVariantList MLBaseModel::getIdsForIndexes(const QModelIndexList & indexes) const
-{
- QVariantList idList;
- idList.reserve(indexes.length());
- std::transform( indexes.begin(), indexes.end(),std::back_inserter(idList), [this](const QModelIndex& index) -> QVariant {
- MLItem* obj = item( index.row() );
- if (!obj)
- return {};
- return QVariant::fromValue(obj->getId());
- });
- return idList;
-}
-
-QVariantList MLBaseModel::getIdsForIndexes(const QVariantList & indexes) const
-{
- QVariantList idList;
-
- idList.reserve(indexes.length());
- std::transform( indexes.begin(), indexes.end(),std::back_inserter(idList),
- [this](const QVariant& index) -> QVariant {
- MLItem* obj = nullptr;
- if (index.canConvert<int>())
- obj = item( index.toInt() );
- else if ( index.canConvert<QModelIndex>() )
- obj = item( index.value<QModelIndex>().row() );
-
- if (!obj)
- return {};
-
- return QVariant::fromValue(obj->getId());
- });
- return idList;
-}
-
//-------------------------------------------------------------------------------------------------
unsigned MLBaseModel::getCount() const
=====================================
modules/gui/qt/medialibrary/mlbasemodel.hpp
=====================================
@@ -77,11 +77,6 @@ public:
Q_INVOKABLE void sortByColumn(QByteArray name, Qt::SortOrder order);
- Q_INVOKABLE virtual MLItemId getIdForIndex(QVariant index) const;
-
- Q_INVOKABLE virtual QVariantList getIdsForIndexes(const QVariantList & indexes) const;
- Q_INVOKABLE virtual QVariantList getIdsForIndexes(const QModelIndexList & indexes) const;
-
Q_INVOKABLE QMap<QString, QVariant> getDataAt(const QModelIndex & index);
Q_INVOKABLE QMap<QString, QVariant> getDataAt(int idx);
@@ -114,6 +109,8 @@ public:
bool loading() const;
+ Q_INVOKABLE void addAndPlay(const QModelIndexList &list, const QStringList &options = {});
+
signals:
void parentIdChanged();
void mlChanged();
@@ -197,6 +194,11 @@ private:
void onCacheBeginRemoveRows(int first, int last);
void onCacheBeginMoveRows(int first, int last, int destination);
+ using ItemCallback = std::function<void (quint64 requestID
+ , std::vector<std::unique_ptr<MLItem>> &items)>;
+
+ quint64 loadItems(const QVector<int> &index, ItemCallback cb);
+
inline bool cachable() const { return m_mediaLib && !m_qmlInitializing; }
protected:
=====================================
modules/gui/qt/medialibrary/qml/MusicAlbums.qml
=====================================
@@ -61,9 +61,9 @@ MainInterface.MainViewLoader {
function _actionAtIndex(index) {
if (selectionModel.selectedIndexes.length > 1) {
- MediaLib.addAndPlay( model.getIdsForIndexes( selectionModel.selectedIndexes ) )
+ model.addAndPlay( selectionModel.selectedIndexes )
} else {
- MediaLib.addAndPlay( model.getIdForIndex(index) )
+ model.addAndPlay( new Array(index) )
}
}
=====================================
modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
=====================================
@@ -77,7 +77,7 @@ MainInterface.MainViewLoader {
onActionAtIndex: {
if (selectionModel.selectedIndexes.length > 1) {
- MediaLib.addAndPlay( artistModel.getIdsForIndexes( selectionModel.selectedIndexes ) )
+ artistModel.addAndPlay( selectionModel.selectedIndexes )
} else {
currentIndex = index
requestArtistAlbumView(Qt.TabFocusReason)
@@ -176,13 +176,9 @@ MainInterface.MainViewLoader {
Navigation.parentItem: root
onActionForSelection: {
- if (selection.length > 1) {
- MediaLib.addAndPlay( artistModel.getIdsForIndexes( selection ) )
- } else if ( selection.length === 1) {
+ artistModel.addAndPlay( selection )
+ if ( selection.length === 1)
requestArtistAlbumView(Qt.TabFocusReason)
- // FIX ME - requestArtistAlbumView will destroy this view
- MediaLib.addAndPlay( artistModel.getIdForIndex( selection[0] ) )
- }
}
sortModel: (availableRowWidth < VLCStyle.colWidth(4)) ? _modelSmall
=====================================
modules/gui/qt/medialibrary/qml/MusicArtist.qml
=====================================
@@ -181,7 +181,7 @@ FocusScope {
onSelectAll: albumSelectionModel.selectAll()
onSelectionUpdated: albumSelectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
- onActionAtIndex: MediaLib.addAndPlay( albumModel.getIdForIndex( index ) )
+ onActionAtIndex: albumModel.addAndPlay( new Array(index) )
}
Widgets.SubtitleLabel {
@@ -236,9 +236,9 @@ FocusScope {
function _actionAtIndex(index, model, selectionModel) {
if (selectionModel.selectedIndexes.length > 1) {
- MediaLib.addAndPlay( model.getIdsForIndexes( selectionModel.selectedIndexes ) )
+ model.addAndPlay( selectionModel.selectedIndexes )
} else {
- MediaLib.addAndPlay( model.getIdForIndex(index) )
+ model.addAndPlay( new Array(index) )
}
}
@@ -407,7 +407,7 @@ FocusScope {
model: trackModel
selectionDelegateModel: trackSelectionModel
onActionForSelection: {
- MediaLib.addAndPlay( model.getIdsForIndexes( selection ) )
+ model.addAndPlay(selection)
}
header: root.header
=====================================
modules/gui/qt/medialibrary/qml/MusicGenres.qml
=====================================
@@ -66,7 +66,7 @@ MainInterface.MainViewLoader {
function _actionAtIndex(index) {
if (selectionModel.selectedIndexes.length > 1) {
- MediaLib.addAndPlay(model.getIdsForIndexes(selectionModel.selectedIndexes))
+ model.addAndPlay( selectionModel.selectedIndexes )
} else if (selectionModel.selectedIndexes.length === 1) {
const sel = selectionModel.selectedIndexes[0]
const model = genreModel.getDataAt(sel)
=====================================
modules/gui/qt/medialibrary/qml/MusicTrackListDisplay.qml
=====================================
@@ -179,7 +179,7 @@ Widgets.KeyNavigableTableView {
selectionDelegateModel: selectionModel
rowHeight: VLCStyle.tableCoverRow_height
- onActionForSelection: MediaLib.addAndPlay(model.getIdsForIndexes( selection ))
+ onActionForSelection: model.addAndPlay(selection)
onItemDoubleClicked: MediaLib.addAndPlay(model.id)
onContextMenuButtonClicked: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
onRightClick: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
=====================================
modules/gui/qt/medialibrary/qml/PlaylistMedia.qml
=====================================
@@ -114,7 +114,7 @@ MainInterface.MainTableView {
// Events
//---------------------------------------------------------------------------------------------
- onActionForSelection: MediaLib.addAndPlay(model.getIdsForIndexes(selection))
+ onActionForSelection: model.addAndPlay( selection )
onItemDoubleClicked: MediaLib.addAndPlay(model.id)
=====================================
modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
=====================================
@@ -110,7 +110,7 @@ MainInterface.MainViewLoader {
function _actionAtIndex() {
if (root.selectionModel.selectedIndexes.length > 1) {
- MediaLib.addAndPlay(model.getIdsForIndexes(selectionModel.selectedIndexes));
+ model.addAndPlay( selectionModel.selectedIndexes );
} else if (root.selectionModel.selectedIndexes.length === 1) {
const index = selectionModel.selectedIndexes[0];
showList(model.getDataAt(index), Qt.TabFocusReason);
=====================================
modules/gui/qt/medialibrary/qml/UrlListDisplay.qml
=====================================
@@ -74,8 +74,7 @@ Widgets.KeyNavigableTableView {
rowHeight: VLCStyle.listAlbumCover_height + VLCStyle.margin_xxsmall * 2
- onActionForSelection: MediaLib.addAndPlay(model.getIdsForIndexes(
- selection))
+ onActionForSelection: model.addAndPlay( selection )
onItemDoubleClicked: MediaLib.addAndPlay(model.id)
onContextMenuButtonClicked: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
onRightClick: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
=====================================
modules/gui/qt/medialibrary/qml/VideoAll.qml
=====================================
@@ -86,7 +86,7 @@ MainInterface.MainViewLoader {
// Events
function onAction(indexes) {
- MediaLib.addAndPlay(model.getIdsForIndexes(indexes))
+ model.addAndPlay( indexes )
g_mainDisplay.showPlayer()
}
=====================================
modules/gui/qt/medialibrary/qml/VideoAllSubDisplay.qml
=====================================
@@ -132,7 +132,7 @@ VideoAll {
property var listLabels: root.getLabel
function onAction(indexes) {
- MediaLib.addAndPlay(model.getIdsForIndexes(indexes))
+ model.addAndPlay( indexes )
g_mainDisplay.showPlayer()
}
@@ -164,7 +164,7 @@ VideoAll {
const object = model.getDataAt(index);
if (object.isVideo) {
- MediaLib.addAndPlay(model.getIdsForIndexes(indexes))
+ model.addAndPlay( indexes )
g_mainDisplay.showPlayer()
return
=====================================
modules/gui/qt/medialibrary/qml/VideoDisplayRecentVideos.qml
=====================================
@@ -52,6 +52,11 @@ FocusScope {
g_mainDisplay.showPlayer()
}
+ function _playIndex(idx) {
+ recentModel.addAndPlay( [idx], [":restore-playback-pos=2"] )
+ g_mainDisplay.showPlayer()
+ }
+
// Childs
Util.MLContextMenu {
@@ -109,6 +114,8 @@ FocusScope {
visible: listView.count > 0
model: MLRecentsVideoModel {
+ id: recentModel
+
ml: MediaLib
}
@@ -165,7 +172,7 @@ FocusScope {
}
onActionAtIndex: {
- root._play(model.getIdForIndex(index))
+ root._playIndex(index)
}
}
=====================================
modules/gui/qt/util/qml/MLContextMenu.qml
=====================================
@@ -84,10 +84,11 @@ NativeMenu {
}, {
"text": I18n.qtr("Media Information"),
"action": function(dataList, options, indexes) {
- DialogsProvider.mediaInfoDialog(model.getIdForIndex(indexes[0]))
+ DialogsProvider.mediaInfoDialog(dataList[0][idDataRole])
},
- "visible": function(options, indexes) {
- return !(model.getIdForIndex(indexes[0]).hasParent())
+ "visible": function(dataList, options, indexes) {
+ return (dataList.length === 1)
+ && !(dataList[0][idDataRole].hasParent())
}
}
]
@@ -144,71 +145,45 @@ NativeMenu {
model.deleteStream(dataList[0][idDataRole])
}
- function showInformationAvailable(options, indexes) {
+ function showInformationAvailable(dataList, options, indexes) {
return indexes.length === 1
&& Helpers.isInteger(Helpers.get(options, "information", null))
}
// Private
- function _showAddFavorite(options, indexes) {
- if (indexes.length !== 1)
+ function _checkRole(dataList, role, expected) {
+ if (dataList.length !== 1)
return false
- const isFavorite = model.getDataAt(indexes[0]).isFavorite
-
- // NOTE: Strictly comparing 'isFavorite' given it might be undefined.
- return (isFavorite === false)
- }
-
- function _showRemoveFavorite(options, indexes) {
- if (indexes.length !== 1)
+ if (!(role in dataList[0]))
return false
- const isFavorite = model.getDataAt(indexes[0]).isFavorite
-
- // NOTE: Strictly comparing 'isFavorite' given it might be undefined.
- return (isFavorite === true)
+ return (dataList[0][role] === expected)
}
- function _showSeen(options, indexes) {
- if (indexes.length !== 1)
- return false
-
- const isNew = model.getDataAt(indexes[0]).isNew
-
- // NOTE: Strictly comparing 'isNew' given it might be undefined.
- return (isNew === true)
+ function _showAddFavorite(dataList, options, indexes) {
+ return _checkRole(dataList, "isFavorite", false)
}
- function _showUnseen(options, indexes) {
- if (indexes.length !== 1)
- return false
-
- const isNew = model.getDataAt(indexes[0]).isNew
-
- // NOTE: Strictly comparing 'isNew' given it might be undefined.
- return (isNew === false)
+ function _showRemoveFavorite(dataList, options, indexes) {
+ return _checkRole(dataList, "isFavorite", true)
}
- function _openContainingFolder(options, indexes) {
- if (indexes.length !== 1)
- return false
-
- const isLocal = model.getDataAt(indexes[0]).isLocal
-
- // NOTE: Strictly comparing 'isLocal' given it might be undefined.
- return (isLocal === true)
+ function _showSeen(dataList, options, indexes) {
+ return _checkRole(dataList, "isNew", true)
}
- function _deleteStream(options, indexes) {
- if (indexes.length !== 1)
- return false
+ function _showUnseen(dataList, options, indexes) {
+ return _checkRole(dataList, "isNew", false)
+ }
- const isDeletable = model.getDataAt(indexes[0]).isDeletable
+ function _openContainingFolder(dataList, options, indexes) {
+ return _checkRole(dataList, "isLocal", true)
+ }
- // NOTE: Strictly comparing 'isDeletable' given it might be undefined.
- return (isDeletable === true)
+ function _deleteStream(dataList,options, indexes) {
+ return _checkRole(dataList, "isDeletable", true)
}
function _signalShowInformation(dataList, options) {
=====================================
modules/gui/qt/util/qml/NativeMenu.qml
=====================================
@@ -35,7 +35,7 @@ VanillaObject {
"action" - (function(dataList, options, indexes)) a function that will be called when action is selected
- "visible" - (Boolean or function(options, indexes) -> Boolean) (optional) a boolean value or function which
+ "visible" - (Boolean or function(dataList,options, indexes) -> Boolean) (optional) a boolean value or function which
controls whether the action is shown in the menu following 'popup' call
e.g see MLContextMenu.qml
@@ -50,39 +50,23 @@ VanillaObject {
property var _indexes: []
- property bool _pendingData: false
-
property var _dataList: null
property int _currentRequest: 0
- property int _actionOnDataReceived: -1
-
property var _effectiveActions: null
+ property point _popupPoint: null
+
function popup(_indexes, point, _options) {
root._options = _options
root._indexes = _indexes
- _actionOnDataReceived = -1
- _pendingData = true
_dataList = null
+ _popupPoint = point
const requestID = ++_currentRequest
requestData(requestID, _indexes)
-
- const textStrings = []
- _effectiveActions = []
- for (let i in actions) {
- if (!actions[i].hasOwnProperty("visible")
- || (typeof actions[i].visible === "boolean" && actions[i].visible)
- || (typeof actions[i].visible === "function" && actions[i].visible(_options, _indexes))) {
- _effectiveActions.push(actions[i])
- textStrings.push(actions[i].text)
- }
- }
-
- menu.popup(point, textStrings)
}
function setData(id, data) {
@@ -90,10 +74,21 @@ VanillaObject {
return;
_dataList = data
- _pendingData = false
- if (_actionOnDataReceived !== -1)
- _executeAction(_actionOnDataReceived)
+ const textStrings = []
+ _effectiveActions = []
+ for (let i in actions) {
+ const action = actions[i]
+
+ if (!action.hasOwnProperty("visible")
+ || (typeof action.visible === "boolean" && action.visible)
+ || (typeof action.visible === "function" && action.visible(_dataList, _options, _indexes))) {
+ _effectiveActions.push(action)
+ textStrings.push(action.text)
+ }
+ }
+
+ menu.popup(_popupPoint, textStrings)
}
function _executeAction(index) {
@@ -106,10 +101,7 @@ VanillaObject {
id: menu
onSelected: {
- if (root._pendingData)
- root._actionOnDataReceived = index
- else
- root._executeAction(index)
+ root._executeAction(index)
}
}
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0cf4d52d30584ef9104f74ef3ea188667bb2e18f...72d3fc2f7dad56c81401a17d063b6c310507766b
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0cf4d52d30584ef9104f74ef3ea188667bb2e18f...72d3fc2f7dad56c81401a17d063b6c310507766b
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list