1/*
2   SPDX-FileCopyrightText: 2018 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
3
4   SPDX-License-Identifier: LGPL-3.0-or-later
5 */
6
7import QtQuick 2.10
8import QtQuick.Controls 2.3
9import org.kde.kirigami 2.5 as Kirigami
10import org.kde.elisa 1.0
11
12FocusScope {
13    id: viewHeader
14
15    property var filterType
16    property alias isSubPage: listView.isSubPage
17    property alias mainTitle: listView.mainTitle
18    property alias secondaryTitle: listView.secondaryTitle
19    property alias showSection: listView.showSection
20    property alias expandedFilterView: listView.expandedFilterView
21    property alias haveTreeModel: listView.haveTreeModel
22    property var filter
23    property alias image: listView.image
24    property var modelType
25    property AbstractItemModel realModel
26    property AbstractProxyModel proxyModel
27    property alias sortRole: listView.sortRole
28    property alias sortRoles: listView.sortRoles
29    property alias sortRoleNames: listView.sortRoleNames
30    property alias sortOrderNames: listView.sortOrderNames
31    property alias sortOrder: listView.sortOrder
32    property bool displaySingleAlbum: false
33    property alias radioCase: listView.showCreateRadioButton
34    property bool modelIsInitialized: false
35    property alias viewManager: listView.viewManager
36
37    function openMetaDataView(databaseId, url, entryType) {
38        metadataLoader.setSource(Kirigami.Settings.isMobile ? "mobile/MobileMediaTrackMetadataView.qml" : "MediaTrackMetadataView.qml",
39                                 {
40                                     "fileName": url,
41                                     "modelType": entryType,
42                                     "showImage": entryType !== ElisaUtils.Radio,
43                                     "showTrackFileName": entryType !== ElisaUtils.Radio,
44                                     "showDeleteButton": entryType === ElisaUtils.Radio,
45                                     "editableMetadata": true,
46                                     "canAddMoreMetadata": entryType !== ElisaUtils.Radio,
47                                 });
48        metadataLoader.active = true
49    }
50    function openCreateRadioView()
51    {
52        metadataLoader.setSource(Kirigami.Settings.isMobile ? "mobile/MobileMediaTrackMetadataView.qml" : "MediaTrackMetadataView.qml",
53                                 {
54                                     "modelType": ElisaUtils.Radio,
55                                     "isCreating": true,
56                                     "showImage": false,
57                                     "showTrackFileName": false,
58                                     "showDeleteButton": true,
59                                     "editableMetadata": true,
60                                     "canAddMoreMetadata": false,
61                                 });
62        metadataLoader.active = true
63    }
64
65    function initializeModel()
66    {
67        if (!proxyModel) {
68            return
69        }
70
71        if (!realModel) {
72            return
73        }
74
75        if (!ElisaApplication.musicManager) {
76            return
77        }
78
79        if (modelIsInitialized) {
80            return
81        }
82
83        proxyModel.sourceModel = realModel
84        proxyModel.dataType = modelType
85        proxyModel.playList = Qt.binding(function() { return ElisaApplication.mediaPlayListProxyModel })
86        listView.contentModel = proxyModel
87
88        if (!displaySingleAlbum) {
89            proxyModel.sortModel(sortOrder)
90        }
91
92        realModel.initializeByData(ElisaApplication.musicManager, ElisaApplication.musicManager.viewDatabase,
93                                   modelType, filterType, filter)
94    }
95
96    function goToBack() {
97        listView.goToBack()
98    }
99
100    Loader {
101        id: metadataLoader
102        active: false
103        onLoaded: {
104            // on mobile, the metadata loader is a page
105            // on desktop, it's a window
106            if (Kirigami.Settings.isMobile) {
107                mainWindow.pageStack.layers.push(item);
108            } else {
109                item.show();
110            }
111        }
112    }
113
114    // desktop delegates
115    Component {
116        id: trackDelegate
117
118        ListBrowserDelegate {
119            id: entry
120
121            width: listView.delegateWidth
122
123            focus: true
124
125            trackUrl: model.url
126            dataType: model.dataType
127            title: model.display ? model.display : ''
128            artist: model.artist ? model.artist : ''
129            album: model.album ? model.album : ''
130            albumArtist: model.albumArtist ? model.albumArtist : ''
131            duration: model.duration ? model.duration : ''
132            imageUrl: model.imageUrl ? model.imageUrl : ''
133            trackNumber: model.trackNumber ? model.trackNumber : -1
134            discNumber: model.discNumber ? model.discNumber : -1
135            rating: model.rating
136            hideDiscNumber: !viewHeader.displaySingleAlbum && model.isSingleDiscAlbum
137            isSelected: listView.currentIndex === index
138            isAlternateColor: (index % 2) === 1
139            detailedView: !viewHeader.displaySingleAlbum
140
141            onTrackRatingChanged: {
142                ElisaApplication.musicManager.updateSingleFileMetaData(url, DataTypes.RatingRole, rating)
143            }
144
145            onEnqueue: ElisaApplication.mediaPlayListProxyModel.enqueue(model.fullData, model.display,
146                                                             ElisaUtils.AppendPlayList,
147                                                             ElisaUtils.DoNotTriggerPlay)
148
149            onReplaceAndPlay: ElisaApplication.mediaPlayListProxyModel.enqueue(model.fullData, model.display,
150                                                                    ElisaUtils.ReplacePlayList,
151                                                                    ElisaUtils.TriggerPlay)
152
153            onClicked: {
154                listView.currentIndex = index;
155                entry.forceActiveFocus();
156            }
157
158            onActiveFocusChanged: {
159                if (activeFocus && listView.currentIndex !== index) {
160                    listView.currentIndex = index
161                }
162            }
163
164            onCallOpenMetaDataView: {
165                openMetaDataView(databaseId, url, entryType)
166            }
167        }
168    }
169
170    ListBrowserView {
171        id: listView
172
173        focus: true
174
175        anchors.fill: parent
176
177        contentModel: proxyModel
178
179        delegate: trackDelegate
180
181        enableSorting: !displaySingleAlbum
182
183        allowArtistNavigation: isSubPage
184
185        showCreateRadioButton: modelType === ElisaUtils.Radio
186        showEnqueueButton: modelType !== ElisaUtils.Radio
187
188        onShowArtist: {
189            viewManager.openArtistView(secondaryTitle)
190        }
191
192        onGoBackRequested: viewManager.goBack()
193
194        suppressNoDataPlaceholderMessage: busyIndicatorLoader.active
195
196        Loader {
197            id: busyIndicatorLoader
198            anchors.centerIn: parent
199            height: Kirigami.Units.gridUnit * 5
200            width: height
201
202            visible: realModel ? realModel.isBusy : true
203            active: realModel ? realModel.isBusy : true
204
205            sourceComponent: BusyIndicator {
206                anchors.centerIn: parent
207            }
208        }
209    }
210
211    Connections {
212        target: ElisaApplication
213
214        function onMusicManagerChanged() {
215            initializeModel()
216        }
217    }
218
219    Connections {
220        target: listView.navigationBar
221
222        function onCreateRadio() {
223            openCreateRadioView()
224        }
225    }
226
227    Component.onCompleted: {
228        initializeModel()
229    }
230}
231