[vlc-devel] [PATCH 16/16] qml: use ItemSelectionModel to handle selection instead of DelegateModel

Pierre Lamot pierre at videolabs.io
Wed May 27 17:06:57 CEST 2020


---
 .../gui/qt/medialibrary/qml/MusicAlbums.qml   | 54 +++++++-------
 .../medialibrary/qml/MusicArtistsDisplay.qml  | 28 ++++----
 .../gui/qt/medialibrary/qml/MusicGenres.qml   | 61 +++++++---------
 .../medialibrary/qml/MusicTracksDisplay.qml   |  4 +-
 .../gui/qt/medialibrary/qml/VideoDisplay.qml  | 39 +++++-----
 .../qt/network/qml/NetworkBrowseDisplay.qml   | 59 ++++++++-------
 .../gui/qt/network/qml/NetworkHomeDisplay.qml | 10 +++
 .../qt/util/qml/SelectableDelegateModel.qml   | 72 ++-----------------
 modules/gui/qt/widgets/qml/ExpandGridView.qml |  2 +-
 .../qt/widgets/qml/KeyNavigableTableView.qml  | 31 ++++----
 10 files changed, 143 insertions(+), 217 deletions(-)

diff --git a/modules/gui/qt/medialibrary/qml/MusicAlbums.qml b/modules/gui/qt/medialibrary/qml/MusicAlbums.qml
index 68e80ca8e0..b81275052a 100644
--- a/modules/gui/qt/medialibrary/qml/MusicAlbums.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicAlbums.qml
@@ -66,38 +66,32 @@ Widgets.NavigableFocusScope {
         var initialIndex = root.initialIndex
         if (initialIndex >= albumModelId.count)
             initialIndex = 0
-        delegateModelId.select(initialIndex, ItemSelectionModel.ClearAndSelect)
-        view.currentItem.currentIndex = initialIndex
+        selectionModel.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
         view.currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
     }
 
+    function _actionAtIndex(index) {
+        if (selectionModel.selectedGroup.count > 1) {
+            medialib.addAndPlay( model.getIdsForIndexes( selectionModel.selectedIndexes ) )
+        } else {
+            medialib.addAndPlay( model.getIdForIndex(index) )
+        }
+    }
+
     MLAlbumModel {
         id: albumModelId
         ml: medialib
 
         onCountChanged: {
-            if (albumModelId.count > 0 && !delegateModelId.hasSelection) {
+            if (albumModelId.count > 0 && !selectionModel.hasSelection) {
                 root.resetFocus()
             }
         }
     }
 
     Util.SelectableDelegateModel {
-        id: delegateModelId
-        property alias parentId: albumModelId.parentId
-
+        id: selectionModel
         model: albumModelId
-
-        delegate: Item {
-        }
-
-        function actionAtIndex(index) {
-            if (delegateModelId.selectedGroup.count > 1) {
-                medialib.addAndPlay( model.getIdsForIndexes( delegateModelId.selectedIndexes() ) )
-            } else {
-                medialib.addAndPlay( model.getIdForIndex(index) )
-            }
-        }
     }
 
     Component {
@@ -113,14 +107,14 @@ Widgets.NavigableFocusScope {
 
             headerDelegate: root.header
 
-            delegateModel: delegateModelId
+            delegateModel: selectionModel
             model: albumModelId
 
             delegate: AudioGridItem {
                 id: audioGridItem
 
                 onItemClicked : {
-                    delegateModelId.updateSelection( modifier , root.currentIndex, index)
+                    selectionModel.updateSelection( modifier , root.currentIndex, index)
                     gridView_id.currentIndex = index
                     gridView_id.forceActiveFocus()
                 }
@@ -144,14 +138,14 @@ Widgets.NavigableFocusScope {
             }
 
             onActionAtIndex: {
-                if (delegateModelId.selectedGroup.count === 1) {
+                if (selectionModel.selectedIndexes.length === 1) {
                     view._switchExpandItem(index)
                 } else {
-                    delegateModelId.actionAtIndex(index)
+                    _actionAtIndex(index)
                 }
             }
-            onSelectAll: delegateModelId.selectAll()
-            onSelectionUpdated: delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
+            onSelectAll: selectionModel.selectAll()
+            onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
 
             navigationParent: root
         }
@@ -175,10 +169,10 @@ Widgets.NavigableFocusScope {
                 width: root.width
                 height: VLCStyle.icon_normal + VLCStyle.margin_small
 
-                selected: delegateModelId.isSelected(index)
+                selected: selectionModel.isSelected(root.model.index(index, 0))
                 Connections {
-                   target: delegateModelId
-                   onSelectionChanged: listDelegate.selected = delegateModelId.isSelected(index)
+                   target: selectionModel
+                   onSelectionChanged: listDelegate.selected = selectionModel.isSelected(root.model.index(index, 0))
                 }
 
                 cover: Image {
@@ -191,7 +185,7 @@ Widgets.NavigableFocusScope {
                 line2: model.main_artist || i18n.qtr("Unknown artist")
 
                 onItemClicked : {
-                    delegateModelId.updateSelection( modifier, view.currentItem.currentIndex, index )
+                    selectionModel.updateSelection( modifier, view.currentItem.currentIndex, index )
                     view.currentItem.currentIndex = index
                     this.forceActiveFocus()
                 }
@@ -199,9 +193,9 @@ Widgets.NavigableFocusScope {
                 onAddToPlaylistClicked : medialib.addToPlaylist( model.id )
             }
 
-            onActionAtIndex: delegateModelId.actionAtIndex(index)
-            onSelectAll: delegateModelId.selectAll()
-            onSelectionUpdated: delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
+            onActionAtIndex: _actionAtIndex(index)
+            onSelectAll: selectionModel.selectAll()
+            onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
 
             navigationParent: root
             navigationCancel: function() {
diff --git a/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml b/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
index a097092061..7a675d7fa8 100644
--- a/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
@@ -54,18 +54,22 @@ Widgets.NavigableFocusScope {
         if (initialIndex >= artistModel.count)
             initialIndex = 0
         if (initialIndex !== artistList.currentIndex) {
-            delegateModelId.select(initialIndex, ItemSelectionModel.ClearAndSelect)
+            selectionModel.select(artistModel.index(initialIndex), ItemSelectionModel.ClearAndSelect)
             artistList.currentIndex = initialIndex
             artistList.positionViewAtIndex(initialIndex, ItemView.Contain)
         }
     }
 
+    function _actionAtIndex(index) {
+        view.forceActiveFocus()
+    }
+
     MLArtistModel {
         id: artistModel
         ml: medialib
 
         onCountChanged: {
-            if (artistModel.count > 0 && !delegateModel.hasSelection) {
+            if (artistModel.count > 0 && !selectionModel.hasSelection) {
                 var initialIndex = root.initialIndex
                 if (initialIndex >= artistModel.count)
                     initialIndex = 0
@@ -75,14 +79,8 @@ Widgets.NavigableFocusScope {
     }
 
     Util.SelectableDelegateModel {
-        id: delegateModel
+        id: selectionModel
         model: artistModel
-
-        delegate: Item {}
-
-        function actionAtIndex(index) {
-            view.forceActiveFocus()
-        }
     }
 
     FocusScope {
@@ -105,8 +103,8 @@ Widgets.NavigableFocusScope {
 
             focus: true
 
-            onSelectAll: delegateModel.selectAll()
-            onSelectionUpdated: delegateModel.updateSelection( keyModifiers, oldIndex, newIndex )
+            onSelectAll: selectionModel.selectAll()
+            onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
             onCurrentIndexChanged: {
                 if (artistList.currentIndex < artistModel.count) {
                     root.artistId =  artistModel.getIdForIndex(artistList.currentIndex)
@@ -128,10 +126,10 @@ Widgets.NavigableFocusScope {
                 height: VLCStyle.icon_normal + VLCStyle.margin_small
                 width: artistList.width
 
-                property bool selected: delegateModel.isSelected(index)
+                property bool selected: selectionModel.isSelected(artistModel.index(index, 0))
                 Connections {
-                   target: delegateModel
-                   onSelectionChanged: selected = delegateModel.isSelected(index)
+                   target: selectionModel
+                   onSelectionChanged: selected = selectionModel.isSelected(artistModel.index(index, 0))
                 }
 
                 color: VLCStyle.colors.getBgColor(selected, this.hovered, this.activeFocus)
@@ -149,7 +147,7 @@ Widgets.NavigableFocusScope {
 
                 onItemClicked: {
                     artistId = model.id
-                    delegateModel.updateSelection( modifier , artistList.currentIndex, index)
+                    selectionModel.updateSelection( modifier , artistList.currentIndex, index)
                     artistList.currentIndex = index
                     artistList.forceActiveFocus()
                 }
diff --git a/modules/gui/qt/medialibrary/qml/MusicGenres.qml b/modules/gui/qt/medialibrary/qml/MusicGenres.qml
index 15ba25b560..b608c70556 100644
--- a/modules/gui/qt/medialibrary/qml/MusicGenres.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicGenres.qml
@@ -66,8 +66,7 @@ Widgets.NavigableFocusScope {
         var initialIndex = root.initialIndex
         if (initialIndex >= genreModel.count)
             initialIndex = 0
-        delegateModelId.select(initialIndex, ItemSelectionModel.ClearAndSelect)
-        view.currentItem.currentIndex = initialIndex
+        selectionModel.select(genreModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
         view.currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
     }
 
@@ -88,42 +87,38 @@ Widgets.NavigableFocusScope {
         ml: medialib
 
         onCountChanged: {
-            if (genreModel.count > 0 && !delegateModelId.hasSelection) {
+            if (genreModel.count > 0 && !selectionModel.hasSelection) {
                 root.resetFocus()
             }
         }
     }
 
-    Util.SelectableDelegateModel {
-        id: delegateModelId
-
-        model: genreModel
-
-        delegate: Item {
+    function _actionAtIndex(index) {
+        if (selectionModel.selectedIndexes.length > 1) {
+            medialib.addAndPlay(model.getIdsForIndexes(selectionModel.selectedIndexes))
+        } else if (selectionModel.selectedIndexes.length === 1) {
+            var sel = selectionModel.selectedIndexes[0]
+            showAlbumView( genreModel.getDataAt(sel) )
         }
+    }
 
+    Util.SelectableDelegateModel {
+        id: selectionModel
 
-        function actionAtIndex(index) {
-            if (delegateModelId.selectedGroup.count > 1) {
-                medialib.addAndPlay(model.getIdsForIndexes(delegateModelId.selectedIndexes()))
-            } else if (delegateModelId.selectedGroup.count === 1) {
-                var sel = delegateModelId.selectedIndexes()[0]
-                showAlbumView( genreModel.getDataAt(sel) )
-            }
-        }
+        model: genreModel
     }
 
     /*
      *define the intial position/selection
-     * This is done on activeFocus rather than Component.onCompleted because delegateModelId.
+     * This is done on activeFocus rather than Component.onCompleted because selectionModel.
      * selectedGroup update itself after this event
      */
     onActiveFocusChanged: {
-        if (activeFocus && genreModel.count > 0 && !delegateModelId.hasSelection) {
+        if (activeFocus && genreModel.count > 0 && !selectionModel.hasSelection) {
             var initialIndex = 0
             if (view.currentItem.currentIndex !== -1)
                 initialIndex = view.currentItem.currentIndex
-            delegateModelId.select(initialIndex, ItemSelectionModel.ClearAndSelect)
+            selectionModel.select(genreModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
             view.currentItem.currentIndex = initialIndex
         }
     }
@@ -134,7 +129,7 @@ Widgets.NavigableFocusScope {
         Widgets.ExpandGridView {
             id: gridView_id
 
-            delegateModel: delegateModelId
+            delegateModel: selectionModel
             model: genreModel
 
             headerDelegate: headerComponent
@@ -147,7 +142,7 @@ Widgets.NavigableFocusScope {
                 subtitle: ""
 
                 onItemClicked: {
-                    delegateModelId.updateSelection( modifier , view.currentItem.currentIndex, index)
+                    selectionModel.updateSelection( modifier , view.currentItem.currentIndex, index)
                     view.currentItem.currentIndex = index
                     view.currentItem.forceActiveFocus()
                 }
@@ -160,11 +155,9 @@ Widgets.NavigableFocusScope {
             cellWidth: VLCStyle.gridItem_music_width
             cellHeight: VLCStyle.gridItem_music_height
 
-            onSelectAll: delegateModelId.selectAll()
-            onSelectionUpdated:  delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
-            onActionAtIndex: {
-                delegateModelId.actionAtIndex(index)
-            }
+            onSelectAll: selectionModel.selectAll()
+            onSelectionUpdated:  selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
+            onActionAtIndex: _actionAtIndex(index)
 
             navigationParent: root
         }
@@ -183,9 +176,9 @@ Widgets.NavigableFocusScope {
             focus: true
             spacing: VLCStyle.margin_xxxsmall
 
-            onSelectAll: delegateModelId.selectAll()
-            onSelectionUpdated: delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
-            onActionAtIndex: delegateModelId.actionAtIndex(index)
+            onSelectAll: selectionModel.selectAll()
+            onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
+            onActionAtIndex: _actionAtIndex(index)
 
             navigationParent: root
 
@@ -194,10 +187,10 @@ Widgets.NavigableFocusScope {
 
                 width: root.width
                 height: VLCStyle.icon_normal + VLCStyle.margin_small
-                selected: delegateModelId.isSelected(index)
+                selected: selectionModel.isSelected(genreModel.index(index, 0))
                 Connections {
-                   target: delegateModelId
-                   onSelectionChanged: listDelegate.selected = delegateModelId.isSelected(index)
+                   target: selectionModel
+                   onSelectionChanged: listDelegate.selected = selectionModel.isSelected(genreModel.index(index, 0))
                 }
 
 
@@ -211,7 +204,7 @@ Widgets.NavigableFocusScope {
                 line1: (model.name || "Unknown genre")+" - "+model.nb_tracks+" tracks"
 
                 onItemClicked: {
-                    delegateModelId.updateSelection( modifier, view.currentItem.currentIndex, index )
+                    selectionModel.updateSelection( modifier, view.currentItem.currentIndex, index )
                     view.currentItem.currentIndex = index
                     this.forceActiveFocus()
                 }
diff --git a/modules/gui/qt/medialibrary/qml/MusicTracksDisplay.qml b/modules/gui/qt/medialibrary/qml/MusicTracksDisplay.qml
index 5d9b02c3a1..79213d8859 100644
--- a/modules/gui/qt/medialibrary/qml/MusicTracksDisplay.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicTracksDisplay.qml
@@ -28,7 +28,7 @@ Widgets.NavigableFocusScope {
     MusicTrackListDisplay {
         id: tracklistdisplay_id
         anchors.fill: parent
-        visible: tracklistdisplay_id.delegateModel.count > 0
+        visible: model.count > 0
         focus: visible
         navigationParent: root
         navigationCancel: function() {
@@ -41,7 +41,7 @@ Widgets.NavigableFocusScope {
 
     EmptyLabel {
         anchors.fill: parent
-        visible: tracklistdisplay_id.delegateModel.count === 0
+        visible: tracklistdisplay_id.model.count === 0
         focus: visible
         text: i18n.qtr("No tracks found\nPlease try adding sources, by going to the Network tab")
         navigationParent: root
diff --git a/modules/gui/qt/medialibrary/qml/VideoDisplay.qml b/modules/gui/qt/medialibrary/qml/VideoDisplay.qml
index 9a819e46c6..856bfb370c 100644
--- a/modules/gui/qt/medialibrary/qml/VideoDisplay.qml
+++ b/modules/gui/qt/medialibrary/qml/VideoDisplay.qml
@@ -57,11 +57,15 @@ Widgets.NavigableFocusScope {
         var initialIndex = root.initialIndex
         if (initialIndex >= videoModel.count)
             initialIndex = 0
-        videosDelegate.select(initialIndex, ItemSelectionModel.ClearAndSelect)
-        view.currentItem.currentIndex = initialIndex
+        selectionModel.select(videoModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
         view.currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
     }
 
+    function _actionAtIndex(index) {
+        medialib.addAndPlay( videoModel.getIdsForIndexes( selectionModel.selectedIndexes ) )
+        history.push(["player"])
+    }
+
     Widgets.MenuExt {
         id: contextMenu
         property var model: ({})
@@ -118,24 +122,15 @@ Widgets.NavigableFocusScope {
         ml: medialib
 
         onCountChanged: {
-            if (videoModel.count > 0 && !videosDelegate.hasSelection) {
+            if (videoModel.count > 0 && !selectionModel.hasSelection) {
                 root.resetFocus()
             }
         }
     }
 
     Util.SelectableDelegateModel {
-        id: videosDelegate
-
+        id: selectionModel
         model: videoModel
-
-        delegate: Item{
-        }
-
-        function actionAtIndex(index) {
-            medialib.addAndPlay( videoModel.getIdsForIndexes( videosDelegate.selectedIndexes() ) )
-            history.push(["player"])
-        }
     }
 
     Component {
@@ -146,7 +141,7 @@ Widgets.NavigableFocusScope {
             property Item currentItem: Item{}
 
             activeFocusOnTab:true
-            delegateModel: videosDelegate
+            delegateModel: selectionModel
             model: videoModel
 
             headerDelegate: Widgets.LabelSeparator {
@@ -155,7 +150,6 @@ Widgets.NavigableFocusScope {
                 text: i18n.qtr("Videos")
             }
 
-
             delegate: VideoGridItem {
                 id: videoGridItem
 
@@ -165,7 +159,7 @@ Widgets.NavigableFocusScope {
                 }
 
                 onItemClicked : {
-                    videosDelegate.updateSelection( modifier , videosGV.currentIndex, index)
+                    selectionModel.updateSelection( modifier , videosGV.currentIndex, index)
                     videosGV.currentIndex = index
                     videosGV.forceActiveFocus()
                 }
@@ -190,21 +184,21 @@ Widgets.NavigableFocusScope {
 
             /*
              *define the intial position/selection
-             * This is done on activeFocus rather than Component.onCompleted because videosDelegate.
+             * This is done on activeFocus rather than Component.onCompleted because selectionModel.
              * selectedGroup update itself after this event
              */
             onActiveFocusChanged: {
-                if (activeFocus && videoModel.count > 0 && !videosDelegate.hasSelection) {
-                    videosDelegate.select(0, ItemSelectionModel.ClearAndSelect)
+                if (activeFocus && videoModel.count > 0 && !selectionModel.hasSelection) {
+                    selectionModel.select(videoModel.index(0,0), ItemSelectionModel.ClearAndSelect)
                 }
             }
 
             cellWidth: VLCStyle.gridItem_video_width
             cellHeight: VLCStyle.gridItem_video_height
 
-            onSelectAll:videosDelegate.selectAll()
-            onSelectionUpdated: videosDelegate.updateSelection( keyModifiers, oldIndex, newIndex )
-            onActionAtIndex: videosDelegate.actionAtIndex( index )
+            onSelectAll:selectionModel.selectAll()
+            onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
+            onActionAtIndex: _actionAtIndex( index )
         }
 
     }
@@ -215,6 +209,7 @@ Widgets.NavigableFocusScope {
         VideoListDisplay {
             height: view.height
             width: view.width
+            model: videoModel
             onContextMenuButtonClicked:{
                 contextMenu.model = menuModel
                 contextMenu.popup(menuParent)
diff --git a/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml b/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
index ef976c6829..0336c0c09e 100644
--- a/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
+++ b/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
@@ -32,7 +32,7 @@ Widgets.NavigableFocusScope {
     id: root
 
     property alias tree: providerModel.tree
-    readonly property var currentIndex: delegateModelId.currentIndex
+    readonly property var currentIndex: view.currentItem.currentIndex
     //the index to "go to" when the view is loaded
     property var initialIndex: 0
 
@@ -40,41 +40,41 @@ Widgets.NavigableFocusScope {
         id: providerModel
         ctx: mainctx
         tree: undefined
+        onCountChanged: resetFocus()
     }
 
     Util.SelectableDelegateModel{
-        id: delegateModelId
+        id: selectionModel
         model: providerModel
-        onCountChanged: resetFocus()
     }
 
     function resetFocus() {
         var initialIndex = root.initialIndex
         if (initialIndex >= providerModel.count)
             initialIndex = 0
-        delegateModelId.select(initialIndex, ItemSelectionModel.ClearAndSelect)
+        selectionModel.select(providerModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
         view.currentItem.currentIndex = initialIndex
         view.currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
     }
 
 
     function _actionAtIndex(index) {
-        if ( delegateModelId.selectedIndexes().length > 1 ) {
-            providerModel.addAndPlay( delegateModelId.selectedIndexes() )
+        if ( selectionModel.selectedIndexes.length > 1 ) {
+            providerModel.addAndPlay( selectionModel.selectedIndexes )
         } else {
             var data = providerModel.getDataAt(index)
             if (data.type === NetworkMediaModel.TYPE_DIRECTORY
                     || data.type === NetworkMediaModel.TYPE_NODE)  {
                 history.push(["mc", "network", { tree: data.tree }]);
             } else {
-                providerModel.addAndPlay( delegateModelId.selectedIndexes() )
+                providerModel.addAndPlay( selectionModel.selectedIndexes )
             }
         }
     }
 
     Widgets.MenuExt {
         id: contextMenu
-        property var delegateModelId: undefined
+        property var selectionModel: undefined
         property var model: ({})
         closePolicy: Popup.CloseOnReleaseOutside | Popup.CloseOnEscape
         focus:true
@@ -83,14 +83,14 @@ Widgets.NavigableFocusScope {
             id: instanciator
             property var modelActions: {
                 "play": function() {
-                    if (delegateModelId) {
-                        providerModel.addAndPlay(delegateModelId.selectedIndexes())
+                    if (selectionModel) {
+                        providerModel.addAndPlay(selectionModel.selectedIndexes )
                     }
                     contextMenu.close()
                 },
                 "enqueue": function() {
-                    if (delegateModelId) {
-                        providerModel.addToPlaylist(delegateModelId.selectedIndexes())
+                    if (selectionModel) {
+                        providerModel.addToPlaylist(selectionModel.selectedIndexes )
                     }
                     contextMenu.close()
                 },
@@ -138,7 +138,7 @@ Widgets.NavigableFocusScope {
         Widgets.ExpandGridView {
             id: gridView
 
-            delegateModel: delegateModelId
+            delegateModel: selectionModel
             model: providerModel
 
             headerDelegate: Widgets.LabelSeparator {
@@ -175,8 +175,8 @@ Widgets.NavigableFocusScope {
                 subtitle: ""
 
                 onItemClicked : {
-                    delegateModelId.updateSelection( modifier ,  delegateModelId.currentIndex, index)
-                    delegateModelId.currentIndex = index
+                    selectionModel.updateSelection( modifier ,  view.currentItem.currentIndex, index)
+                    view.currentItem.currentIndex = index
                     delegateGrid.forceActiveFocus()
                 }
 
@@ -184,19 +184,19 @@ Widgets.NavigableFocusScope {
                     if (model.type === NetworkMediaModel.TYPE_NODE || model.type === NetworkMediaModel.TYPE_DIRECTORY)
                         history.push( ["mc", "network", { tree: model.tree } ])
                     else
-                        delegateModelId.model.addAndPlay( index )
+                        selectionModel.model.addAndPlay( index )
                 }
 
                 onContextMenuButtonClicked: {
                     contextMenu.model = providerModel
-                    contextMenu.delegateModelId = delegateModelId
+                    contextMenu.selectionModel = selectionModel
                     contextMenu.popup()
                 }
             }
 
-            onSelectAll: delegateModelId.selectAll()
-            onSelectionUpdated: delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
-            onActionAtIndex: delegateModelId.actionAtIndex(index)
+            onSelectAll: selectionModel.selectAll()
+            onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
+            onActionAtIndex: _actionAtIndex(index)
 
             navigationParent: root
             navigationUpItem: gridView.headerItem
@@ -213,21 +213,20 @@ Widgets.NavigableFocusScope {
             height: view.height
             width: view.width
             model: providerModel
-            currentIndex: delegateModelId.currentIndex
 
             delegate: NetworkListItem {
                 id: delegateList
                 focus: true
 
-                selected: delegateModelId.isSelected( index )
+                selected: selectionModel.isSelected( providerModel.index(index, 0) )
                 Connections {
-                    target: delegateModelId
-                    onSelectionChanged: selected = delegateModelId.isSelected(index)
+                    target: selectionModel
+                    onSelectionChanged: delegateList.selected = selectionModel.isSelected(providerModel.index(index, 0))
                 }
 
                 onItemClicked : {
-                    delegateModelId.updateSelection( modifier, delegateModelId.currentIndex, index )
-                    delegateModelId.currentIndex = index
+                    selectionModel.updateSelection( modifier, view.currentItem.currentIndex, index )
+                    view.currentItem.currentIndex = index
                     delegateList.forceActiveFocus()
                 }
 
@@ -240,7 +239,7 @@ Widgets.NavigableFocusScope {
 
                 onContextMenuButtonClicked: {
                     contextMenu.model = providerModel
-                    contextMenu.delegateModelId = delegateModelId
+                    contextMenu.selectionModel = selectionModel
                     contextMenu.popup(menuParent)
                 }
 
@@ -251,9 +250,9 @@ Widgets.NavigableFocusScope {
             focus: true
             spacing: VLCStyle.margin_xxxsmall
 
-            onSelectAll: delegateModelId.selectAll()
-            onSelectionUpdated: delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
-            onActionAtIndex: delegateModelId.actionAtIndex(index)
+            onSelectAll: selectionModel.selectAll()
+            onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
+            onActionAtIndex: _actionAtIndex(index)
 
             navigationParent: root
             navigationUpItem: listView.headerItem
diff --git a/modules/gui/qt/network/qml/NetworkHomeDisplay.qml b/modules/gui/qt/network/qml/NetworkHomeDisplay.qml
index 0b42aeefed..4218ee249b 100644
--- a/modules/gui/qt/network/qml/NetworkHomeDisplay.qml
+++ b/modules/gui/qt/network/qml/NetworkHomeDisplay.qml
@@ -23,6 +23,7 @@ import QtQml 2.11
 import org.videolan.medialib 0.1
 
 import "qrc:///widgets/" as Widgets
+import "qrc:///util/" as Util
 import "qrc:///style/"
 
 Widgets.NavigableFocusScope {
@@ -37,6 +38,15 @@ Widgets.NavigableFocusScope {
         }
     }
 
+    function _actionAtIndex(index, model, selectionModel) {
+        if (selectionModel.items.get(index).model.type === NetworkMediaModel.TYPE_DIRECTORY
+                || selectionModel.items.get(index).model.type === NetworkMediaModel.TYPE_NODE)  {
+            history.push(["mc", "network", { tree: selectionModel.items.get(index).model.tree }]);
+        } else {
+            model.addAndPlay( selectionModel.selectedIndexes )
+        }
+    }
+
     Label {
         anchors.centerIn: parent
         visible: (deviceSection.model.count === 0 && lanSection.model.count === 0 )
diff --git a/modules/gui/qt/util/qml/SelectableDelegateModel.qml b/modules/gui/qt/util/qml/SelectableDelegateModel.qml
index f5abbfcace..37fd235cf6 100644
--- a/modules/gui/qt/util/qml/SelectableDelegateModel.qml
+++ b/modules/gui/qt/util/qml/SelectableDelegateModel.qml
@@ -16,82 +16,26 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 import QtQuick 2.11
-import QtQml.Models 2.2
+import QtQml.Models 2.11
 
-DelegateModel {
+ItemSelectionModel {
     id: delegateModel
 
-    property int currentIndex: -1
     property int shiftIndex: -1
-    property alias selectedGroup: selectedGroup
-    readonly property bool hasSelection: selectedGroup.count > 0
-
-    signal selectionChanged()
-
-    groups: [
-        DelegateModelGroup { id: selectedGroup; name: "selected"; includeByDefault: false }
-    ]
 
     function _addRange(from, to) {
         for (var i = from; i <= to; i++) {
-            delegateModel.items.get(i).inSelected = true
+            select(model.index(i, 0), ItemSelectionModel.Select)
         }
-        selectionChanged()
     }
     function _delRange(from, to) {
         for (var i = from; i <= to; i++) {
-            delegateModel.items.get(i).inSelected = false
-        }
-        selectionChanged()
-    }
-
-    function selectNone() {
-        if (hasSelection) {
-            selectedGroup.remove(0,selectedGroup.count)
-            selectionChanged()
+            select(model.index(i, 0), ItemSelectionModel.Deselect)
         }
     }
 
     function selectAll() {
-        delegateModel.items.addGroups(0, delegateModel.items.count, ["selected"])
-        selectionChanged()
-    }
-
-    function selectedIndexes() {
-        var list = []
-        for (var i = 0; i < delegateModel.selectedGroup.count; i++) {
-            var index = delegateModel.selectedGroup.get(i).itemsIndex;
-            list.push(index)
-        }
-        return list
-    }
-
-    function isSelected( index ) {
-        if (index < 0 || index >= delegateModel.count)
-            return false
-        return items.get(index).inSelected
-    }
-
-    function select( index, command ) {
-        switch (command) {
-            case ItemSelectionModel.Select:
-                items.get(index).inSelected = true
-                break;
-            case ItemSelectionModel.Deselect:
-                items.get(index).inSelected = false
-                break;
-            case ItemSelectionModel.Toggle:
-                items.get(index).inSelected = !items.get(index).inSelected
-                break;
-            case ItemSelectionModel.Clear:
-                selectNone()
-                break;
-            case ItemSelectionModel.ClearAndSelect:
-                selectNone()
-                items.get(index).inSelected = true
-                selectionChanged()
-                break;
-        }
+        select(model.index(0, 0), ItemSelectionModel.Select | ItemSelectionModel.Columns)
     }
 
     function updateSelection( keymodifiers, oldIndex, newIndex ) {
@@ -117,12 +61,10 @@ DelegateModel {
                 _delRange(oldIndex, newIndex - 1)
             }
         } else {
-            var e = delegateModel.items.get(newIndex)
             if ((keymodifiers & Qt.ControlModifier) == Qt.ControlModifier) {
-                e.inSelected = !e.inSelected
+                select(model.index(newIndex, 0), ItemSelectionModel.Toggle)
             } else {
-                selectNone()
-                e.inSelected = true
+                select(model.index(newIndex, 0), ItemSelectionModel.ClearAndSelect)
             }
             shiftIndex = newIndex
         }
diff --git a/modules/gui/qt/widgets/qml/ExpandGridView.qml b/modules/gui/qt/widgets/qml/ExpandGridView.qml
index eb7332eaf9..c83a2ca8dc 100644
--- a/modules/gui/qt/widgets/qml/ExpandGridView.qml
+++ b/modules/gui/qt/widgets/qml/ExpandGridView.qml
@@ -155,7 +155,7 @@ NavigableFocusScope {
     function _updateSelected() {
         for (var id in _idChildrenMap) {
             var item = _idChildrenMap[id]
-            item.selected = delegateModel.isSelected(id)
+            item.selected = delegateModel.isSelected(model.index(id, 0))
         }
     }
 
diff --git a/modules/gui/qt/widgets/qml/KeyNavigableTableView.qml b/modules/gui/qt/widgets/qml/KeyNavigableTableView.qml
index 9c0bf7ecad..1fbd0f693f 100644
--- a/modules/gui/qt/widgets/qml/KeyNavigableTableView.qml
+++ b/modules/gui/qt/widgets/qml/KeyNavigableTableView.qml
@@ -35,7 +35,7 @@ NavigableFocusScope {
 
     property var sortModel: []
     property Component colDelegate: Item { }
-    property var model: []
+    property alias model: view.model
 
     property alias contentHeight: view.contentHeight
 
@@ -49,7 +49,7 @@ NavigableFocusScope {
     property alias headerItem: view.headerItem
     property color headerColor
 
-    property alias delegateModel: delegateModel
+    property alias selectionModel: selectionModel
     property real rowHeight: VLCStyle.fontHeight_normal + VLCStyle.margin_large
     property alias spacing: view.spacing
 
@@ -60,12 +60,9 @@ NavigableFocusScope {
     }
 
     Util.SelectableDelegateModel {
-        id: delegateModel
+        id: selectionModel
 
         model: root.model
-
-        delegate: Item {
-        }
     }
 
 
@@ -76,8 +73,6 @@ NavigableFocusScope {
 
         focus: true
 
-        model : root.model
-
         headerPositioning: ListView.OverlayHeader
 
         header: Rectangle {
@@ -156,10 +151,10 @@ NavigableFocusScope {
             color: VLCStyle.colors.getBgColor(selected, hoverArea.containsMouse, lineView.activeFocus)
 
             property var rowModel: model
-            property bool selected: delegateModel.isSelected(index)
+            property bool selected: selectionModel.isSelected(root.model.index(index, 0))
             Connections {
-                target: delegateModel
-                onSelectionChanged: lineView.selected = delegateModel.isSelected(index)
+                target: selectionModel
+                onSelectionChanged: lineView.selected = selectionModel.isSelected(root.model.index(index, 0))
             }
 
             MouseArea {
@@ -170,7 +165,7 @@ NavigableFocusScope {
                 acceptedButtons: Qt.RightButton | Qt.LeftButton
 
                 onClicked: {
-                    delegateModel.updateSelection( mouse.modifiers , view.currentIndex, index)
+                    selectionModel.updateSelection( mouse.modifiers , view.currentIndex, index)
                     view.currentIndex = rowModel.index
                     lineView.forceActiveFocus()
 
@@ -180,7 +175,7 @@ NavigableFocusScope {
                 }
 
                 onDoubleClicked: {
-                    actionForSelection(delegateModel.selectedIndexes())
+                    actionForSelection(selectionModel.selectedIndexes)
                 }
 
                 Row {
@@ -211,9 +206,9 @@ NavigableFocusScope {
             }
         }
 
-        onSelectAll: delegateModel.selectAll()
-        onSelectionUpdated: delegateModel.updateSelection( keyModifiers, oldIndex, newIndex )
-        onActionAtIndex: root.actionForSelection( delegateModel.selectedIndexes() )
+        onSelectAll: selectionModel.selectAll()
+        onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
+        onActionAtIndex: root.actionForSelection( selectionModel.selectedIndexes )
 
         navigationParent: root
     }
@@ -224,11 +219,11 @@ NavigableFocusScope {
      * selectedGroup update itself after this event
      */
     onActiveFocusChanged: {
-        if (activeFocus && view.count > 0 && !delegateModel.hasSelection) {
+        if (activeFocus && view.count > 0 && !selectionModel.hasSelection) {
             var initialIndex = 0
             if (view.currentIndex !== -1)
                 initialIndex = view.currentIndex
-            delegateModel.select(initialIndex, ItemSelectionModel.ClearAndSelect)
+            selectionModel.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
             view.currentIndex = initialIndex
         }
     }
-- 
2.25.1



More information about the vlc-devel mailing list