[vlc-commits] [Git][videolan/vlc][master] 5 commits: qt: make MLPlaylistListModel::getItemId() invokable

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun May 5 18:29:59 UTC 2024



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
7fd37aac by Fatih Uzunoglu at 2024-05-05T18:00:33+00:00
qt: make MLPlaylistListModel::getItemId() invokable

- - - - -
e13f300d by Fatih Uzunoglu at 2024-05-05T18:00:33+00:00
qt: asynchronous method should not return a boolean in MLPlaylistListModel

- - - - -
6b1622d0 by Fatih Uzunoglu at 2024-05-05T18:00:33+00:00
qt: allow appending input item into MLPlaylistListModel

- - - - -
e2d32aeb by Fatih Uzunoglu at 2024-05-05T18:00:33+00:00
qml: enable dropping in PlaylistMediaList

With this patch, it is now possible to drag
media library and input items directly
into a playlist.

New input item is created for an unknown
source. So, actions such as dragging from
file browser should also be supported as long
as the drag event contains URLs.

It is also possible to append a playlist into
another playlist.

Previously, it was only possible to first
load the playlist in order to add items.
Now, in the playlist view (the view where
all the playlists are listed) items can be
dropped in to the playlists.

- - - - -
d5c19a4f by Fatih Uzunoglu at 2024-05-05T18:00:33+00:00
qml: allow dropping items to background in PlaylistMediaList

If items are dropped to background rather than into a
playlist that is available, then a new playlist is created
with the dropped items as its sole content.

- - - - -


3 changed files:

- modules/gui/qt/medialibrary/mlplaylistlistmodel.cpp
- modules/gui/qt/medialibrary/mlplaylistlistmodel.hpp
- modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml


Changes:

=====================================
modules/gui/qt/medialibrary/mlplaylistlistmodel.cpp
=====================================
@@ -27,6 +27,7 @@
 #include "qt.hpp"
 #include "util/vlctick.hpp"
 #include "dialogs/dialogs_provider.hpp"
+#include "playlist/playlist_controller.hpp"
 
 // MediaLibrary includes
 #include "mlhelper.hpp"
@@ -116,48 +117,64 @@ void appendMediaIntoPlaylist(vlc_medialibrary_t* ml, int64_t playlistId, const s
     });
 }
 
-/* Q_INVOKABLE */ bool MLPlaylistListModel::append(const MLItemId     & playlistId,
+/* Q_INVOKABLE */ void MLPlaylistListModel::append(const MLItemId     & playlistId,
                                                    const QVariantList & ids)
 {
     assert(m_mediaLib);
+    assert(ids.size() > 0);
 
     if (unlikely(m_transactionPending))
-        return false;
+        return;
 
     m_transactionPending = true;
 
-    bool result = true;
-    std::vector<MLItemId> itemList;
-    for (const QVariant & id : ids)
-    {
-        if (id.canConvert<MLItemId>() == false)
+    m_mediaLib->runOnMLThread(this,
+    //ML thread
+    [playlistId, ids](vlc_medialibrary_t* ml) {
+        std::vector<MLItemId> mlItemIdVector;
+        mlItemIdVector.reserve(ids.size());
+
+        if (ids.at(0).canConvert<MLItemId>())
         {
-            result = false;
-            continue;
-        }
+            for (const QVariant& id : ids)
+            {
+                // Do not mix types. This is currently not possible
+                // in the application anyway.
+                assert(id.canConvert<MLItemId>());
 
-        const MLItemId & itemId = id.value<MLItemId>();
+                mlItemIdVector.push_back(id.value<MLItemId>());
+            }
 
-        if (itemId.id == 0)
-        {
-            result = false;
-            continue;
+            appendMediaIntoPlaylist(ml, playlistId.id, mlItemIdVector);
         }
-        itemList.push_back(itemId);
-    }
+        else
+        {
+            QVector<vlc::playlist::Media> medias = vlc::playlist::toMediaList(ids);
 
-    m_mediaLib->runOnMLThread(this,
-    //ML thread
-    [playlistId, itemList](vlc_medialibrary_t* ml)
-    {
-        appendMediaIntoPlaylist(ml, playlistId.id, itemList);
+            for (const auto& media : medias)
+            {
+                assert(media.raw());
+
+                const char * const uri = media.raw()->psz_uri;
+
+                vlc_ml_media_t * ml_media = vlc_ml_get_media_by_mrl(ml, uri);
+
+                if (ml_media == nullptr)
+                {
+                    ml_media = vlc_ml_new_external_media(ml, uri);
+                    if (ml_media == nullptr)
+                        continue;
+                }
+
+                vlc_ml_playlist_append(ml, playlistId.id, ml_media->i_id);
+                vlc_ml_media_release(ml_media);
+            }
+        }
     },
     //UI thread
     [this]() {
         endTransaction();
     });
-
-    return result;
 }
 
 /* Q_INVOKABLE */ bool MLPlaylistListModel::deletePlaylists(const QVariantList & ids)


=====================================
modules/gui/qt/medialibrary/mlplaylistlistmodel.hpp
=====================================
@@ -64,13 +64,13 @@ public:
 public: // Interface
     Q_INVOKABLE void create(const QString & name, const QVariantList& initialItems);
 
-    Q_INVOKABLE bool append(const MLItemId & playlistId, const QVariantList & ids);
+    Q_INVOKABLE void append(const MLItemId & playlistId, const QVariantList & ids);
 
     Q_INVOKABLE bool deletePlaylists(const QVariantList & ids);
 
     Q_INVOKABLE bool showDialogRename(const QModelIndex & index);
 
-    MLItemId getItemId(int index) const;
+    Q_INVOKABLE MLItemId getItemId(int index) const;
 
 public: // QAbstractItemModel implementation
     QHash<int, QByteArray> roleNames() const override;


=====================================
modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
=====================================
@@ -138,14 +138,61 @@ MainInterface.MainViewLoader {
             return qsTr("99+");
     }
 
+    function _adjustDragAccepted(drag) {
+        if (drag.source !== dragItemPlaylist && Helpers.isValidInstanceOf(drag.source, Widgets.DragItem))
+            drag.accepted = true
+        else if (drag.hasUrls)
+            drag.accepted = true
+        else {
+            drag.accepted = false
+        }
+    }
+
+    function _dropAction(drop, index) {
+        const item = drop.source
+        if (Helpers.isValidInstanceOf(item, Widgets.DragItem)) {
+            item.getSelectedInputItem().then(inputItems => {
+                if (index === undefined)
+                    DialogsProvider.playlistsDialog(inputItems)
+                else
+                    root.model.append(root.model.getItemId(index), inputItems)
+            })
+            drop.accepted = true
+        } else if (drop.hasUrls) {
+            const urlList = []
+            for (let url in drop.urls)
+                urlList.push(drop.urls[url])
+            if (index === undefined)
+                DialogsProvider.playlistsDialog(inputItems)
+            else
+                root.model.append(root.model.getItemId(index), urlList)
+            drop.accepted = true
+        } else {
+            drop.accepted = false
+        }
+    }
+
     //---------------------------------------------------------------------------------------------
     // Childs
     //---------------------------------------------------------------------------------------------
 
+    DropArea {
+        anchors.fill: parent
+
+        onEntered: function(drag) {
+            root._adjustDragAccepted(drag)
+        }
+
+        onDropped: function(drop) {
+            root._dropAction(drop)
+        }
+    }
 
     Widgets.MLDragItem {
         id: dragItemPlaylist
 
+        objectName: "PlaylistMediaListDragItem"
+
         mlModel: model
 
         indexes: indexesFlat ? root.selectionModel.selectedIndexesFlat
@@ -226,6 +273,18 @@ MainInterface.MainViewLoader {
                 // Animations
 
                 Behavior on opacity { NumberAnimation { duration: VLCStyle.duration_short } }
+
+                DropArea {
+                    anchors.fill: parent
+
+                    onEntered: function(drag) {
+                        root._adjustDragAccepted(drag)
+                    }
+
+                    onDropped: function(drop) {
+                        root._dropAction(drop, index)
+                    }
+                }
             }
 
             //-------------------------------------------------------------------------------------
@@ -324,6 +383,8 @@ MainInterface.MainViewLoader {
 
             header: root.header
 
+            acceptDrop: true
+
             Navigation.parentItem: root
 
             //-------------------------------------------------------------------------------------
@@ -341,6 +402,14 @@ MainInterface.MainViewLoader {
                 contextMenu.popup(selectionModel.selectedRows(), globalMousePos)
             }
 
+            onDropEntered: (_, _, drag, _) => {
+                root._adjustDragAccepted(drag)
+            }
+
+            onDropEvent: (_, index, _, drop, _) => {
+                root._dropAction(drop, index)
+            }
+
             //-------------------------------------------------------------------------------------
             // Childs
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3634ea930bf00008e18ba203f85188529897b1b8...d5c19a4fed49b88876149b12a225c7b43efa480b

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3634ea930bf00008e18ba203f85188529897b1b8...d5c19a4fed49b88876149b12a225c7b43efa480b
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