config.qml 18 KB
Newer Older
1
2
/*
 *  Copyright 2013 Marco Martin <mart@kde.org>
3
 *  Copyright 2014 Kai Uwe Broulik <kde@privat.broulik.de>
4
 *  Copyright 2019 David Redondo <kde@david-redondo.de>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  2.010-1301, USA.
 */

21
import QtQuick 2.5
22
import QtQuick.Controls 2.3 as QtControls2
23
import QtQuick.Layouts 1.0
24
import QtQuick.Window 2.0 // for Screen
25
import org.kde.plasma.wallpapers.image 2.0 as Wallpaper
26
import org.kde.kquickcontrols 2.0 as KQuickControls
27
import org.kde.kquickcontrolsaddons 2.0
28
import org.kde.newstuff 1.62 as NewStuff
29
import org.kde.draganddrop 2.0 as DragDrop
30
import org.kde.kcm 1.1 as KCM
31
import org.kde.kirigami 2.12 as Kirigami
32
33
34

ColumnLayout {
    id: root
35
    property alias cfg_Color: colorButton.color
36
37
    property string cfg_Image
    property int cfg_FillMode
38
    property int cfg_SlideshowMode
39
    property alias cfg_Blur: blurRadioButton.checked
40
41
    property var cfg_SlidePaths: ""
    property int cfg_SlideInterval: 0
42
    property var cfg_UncheckedSlides: []
43

44
45
46
47
    function saveConfig() {
        imageWallpaper.commitDeletion();
    }

48
49
50
51
    SystemPalette {
        id: syspal
    }

52
53
    Wallpaper.Image {
        id: imageWallpaper
54
55
56
57
58
59
60
        targetSize: {
            if (typeof plasmoid !== "undefined") {
                return Qt.size(plasmoid.width, plasmoid.height)
            }
            // Lock screen configuration case
            return Qt.size(Screen.width, Screen.height)
        }
61
        onSlidePathsChanged: cfg_SlidePaths = slidePaths
62
        onUncheckedSlidesChanged: cfg_UncheckedSlides = uncheckedSlides
63
        onSlideshowModeChanged: cfg_SlideshowMode = slideshowMode
64
65
    }

66
67
68
69
    onCfg_FillModeChanged: {
        resizeComboBox.setMethod()
    }

70
71
72
    onCfg_SlidePathsChanged: {
        imageWallpaper.slidePaths = cfg_SlidePaths
    }
73
74
75
    onCfg_UncheckedSlidesChanged: {
        imageWallpaper.uncheckedSlides = cfg_UncheckedSlides
    }
76

77
78
79
80
    onCfg_SlideshowModeChanged: {
        imageWallpaper.slideshowMode = cfg_SlideshowMode
    }

81
82
83
    property int hoursIntervalValue: Math.floor(cfg_SlideInterval / 3600)
    property int minutesIntervalValue: Math.floor(cfg_SlideInterval % 3600) / 60
    property int secondsIntervalValue: cfg_SlideInterval % 3600 % 60
84

85
86
    //Rectangle { color: "orange"; x: formAlignment; width: formAlignment; height: 20 }

87
88
89
    Kirigami.FormLayout {
        twinFormLayouts: parentLayout
        QtControls2.ComboBox {
90
            id: resizeComboBox
91
            Kirigami.FormData.label: i18nd("plasma_wallpaper_org.kde.image", "Positioning:")
92
93
            model: [
                        {
94
                            'label': i18nd("plasma_wallpaper_org.kde.image", "Scaled and Cropped"),
95
96
97
                            'fillMode': Image.PreserveAspectCrop
                        },
                        {
98
                            'label': i18nd("plasma_wallpaper_org.kde.image","Scaled"),
99
100
101
                            'fillMode': Image.Stretch
                        },
                        {
102
                            'label': i18nd("plasma_wallpaper_org.kde.image","Scaled, Keep Proportions"),
103
104
105
                            'fillMode': Image.PreserveAspectFit
                        },
                        {
106
                            'label': i18nd("plasma_wallpaper_org.kde.image", "Centered"),
107
108
109
                            'fillMode': Image.Pad
                        },
                        {
110
                            'label': i18nd("plasma_wallpaper_org.kde.image","Tiled"),
111
112
113
114
115
116
117
118
119
120
                            'fillMode': Image.Tile
                        }
                    ]

            textRole: "label"
            onCurrentIndexChanged: cfg_FillMode = model[currentIndex]["fillMode"]
            Component.onCompleted: setMethod();

            function setMethod() {
                for (var i = 0; i < model.length; i++) {
121
                    if (model[i]["fillMode"] === root.cfg_FillMode) {
122
123
124
125
126
127
128
129
                        resizeComboBox.currentIndex = i;
                        var tl = model[i]["label"].length;
                        //resizeComboBox.textLength = Math.max(resizeComboBox.textLength, tl+5);
                    }
                }
            }
        }

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
        QtControls2.ComboBox {
            id: slideshowComboBox
            visible: configDialog.currentWallpaper == "org.kde.slideshow"
            Kirigami.FormData.label: i18nd("plasma_wallpaper_org.kde.image", "Order:")
            model: [
                {
                    'label': i18nd("plasma_wallpaper_org.kde.image", "Random"),
                    'slideshowMode':  Wallpaper.Image.Random
                },
                {
                    'label': i18nd("plasma_wallpaper_org.kde.image", "A to Z"),
                    'slideshowMode':  Wallpaper.Image.Alphabetical
                },
                {
                    'label': i18nd("plasma_wallpaper_org.kde.image", "Z to A"),
                    'slideshowMode':  Wallpaper.Image.AlphabeticalReversed
                },
                {
                    'label': i18nd("plasma_wallpaper_org.kde.image", "Date modified (newest first)"),
                    'slideshowMode':  Wallpaper.Image.ModifiedReversed
                },
                {
                    'label': i18nd("plasma_wallpaper_org.kde.image", "Date modified (oldest first)"),
                    'slideshowMode':  Wallpaper.Image.Modified
                }
            ]
            textRole: "label"
            onCurrentIndexChanged: {
                cfg_SlideshowMode = model[currentIndex]["slideshowMode"];
            }
            Component.onCompleted: setMethod();
            function setMethod() {
                for (var i = 0; i < model.length; i++) {
                    if (model[i]["slideshowMode"] === wallpaper.configuration.SlideshowMode) {
                        slideshowComboBox.currentIndex = i;
                    }
                }
            }
        }

170
        QtControls2.ButtonGroup { id: backgroundGroup }
171

172
        QtControls2.RadioButton {
173
            id: blurRadioButton
174
175
            visible: cfg_FillMode === Image.PreserveAspectFit || cfg_FillMode === Image.Pad
            Kirigami.FormData.label: i18nd("plasma_wallpaper_org.kde.image", "Background:")
176
            text: i18nd("plasma_wallpaper_org.kde.image", "Blur")
177
            QtControls2.ButtonGroup.group: backgroundGroup
178
179
        }

180
181
182
183
184
185
186
187
188
189
190
191
192
        RowLayout {
            id: colorRow
            visible: cfg_FillMode === Image.PreserveAspectFit || cfg_FillMode === Image.Pad
            QtControls2.RadioButton {
                id: colorRadioButton
                text: i18nd("plasma_wallpaper_org.kde.image", "Solid color")
                checked: !cfg_Blur
                QtControls2.ButtonGroup.group: backgroundGroup
            }
            KQuickControls.ColorButton {
                id: colorButton
                dialogTitle: i18nd("plasma_wallpaper_org.kde.image", "Select Background Color")
            }
193
        }
194
195
196
197
198
199
200
    }

    Component {
        id: foldersComponent
        ColumnLayout {
            Connections {
                target: root
Konrad Materka's avatar
Konrad Materka committed
201
202
203
                function onHoursIntervalValueChanged() {hoursInterval.value = root.hoursIntervalValue}
                function onMinutesIntervalValueChanged() {minutesInterval.value = root.minutesIntervalValue}
                function onSecondsIntervalValueChanged() {secondsInterval.value = root.secondsIntervalValue}
204
205
            }
            //FIXME: there should be only one spinbox: QtControls spinboxes are still too limited for it tough
206
207
208
209
210
211
212
213
214
215
216
            Kirigami.FormLayout {
                twinFormLayouts: parentLayout
                RowLayout {
                    Kirigami.FormData.label: i18nd("plasma_wallpaper_org.kde.image","Change every:")
                    QtControls2.SpinBox {
                        id: hoursInterval
                        value: root.hoursIntervalValue
                        from: 0
                        to: 24
                        editable: true
                        onValueChanged: cfg_SlideInterval = hoursInterval.value * 3600 + minutesInterval.value * 60 + secondsInterval.value
217
218

                        textFromValue: function(value, locale) {
219
                            return i18ndp("plasma_wallpaper_org.kde.image","%1 hour", "%1 hours", value)
220
221
222
223
                        }
                        valueFromText: function(text, locale) {
                            return parseInt(text);
                        }
224
225
226
227
228
229
230
231
                    }
                    QtControls2.SpinBox {
                        id: minutesInterval
                        value: root.minutesIntervalValue
                        from: 0
                        to: 60
                        editable: true
                        onValueChanged: cfg_SlideInterval = hoursInterval.value * 3600 + minutesInterval.value * 60 + secondsInterval.value
232
233

                        textFromValue: function(value, locale) {
234
                            return i18ndp("plasma_wallpaper_org.kde.image","%1 minute", "%1 minutes", value)
235
236
237
238
                        }
                        valueFromText: function(text, locale) {
                            return parseInt(text);
                        }
239
240
241
242
243
244
245
246
                    }
                    QtControls2.SpinBox {
                        id: secondsInterval
                        value: root.secondsIntervalValue
                        from: root.hoursIntervalValue === 0 && root.minutesIntervalValue === 0 ? 1 : 0
                        to: 60
                        editable: true
                        onValueChanged: cfg_SlideInterval = hoursInterval.value * 3600 + minutesInterval.value * 60 + secondsInterval.value
247
248

                        textFromValue: function(value, locale) {
249
                            return i18ndp("plasma_wallpaper_org.kde.image","%1 second", "%1 seconds", value)
250
251
252
253
                        }
                        valueFromText: function(text, locale) {
                            return parseInt(text);
                        }
254
                    }
255
256
                }
            }
257
            Kirigami.Heading {
258
                text: i18nd("plasma_wallpaper_org.kde.image","Folders")
259
260
261
262
                level: 2
            }
            GridLayout {
                columns: 2
263
                Layout.fillWidth: true
264
265
266
267
268
269
270
271
272
273
274
275
                Layout.fillHeight: true
                columnSpacing: Kirigami.Units.largeSpacing
                QtControls2.ScrollView {
                    id: foldersScroll
                    Layout.fillHeight: true
                    Layout.preferredWidth: 0.25 * parent.width
                    Component.onCompleted: foldersScroll.background.visible = true;
                    ListView {
                        id: slidePathsView
                        model: imageWallpaper.slidePaths
                        delegate: Kirigami.SwipeListItem {
                            id: folderDelegate
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
                            width: slidePathsView.width
                            contentItem: Kirigami.BasicListItem {
                                // The parent item already has a highlight
                                activeBackgroundColor: "transparent"
                                // Otherwise there are unnecessary margins
                                anchors.top: parent.top
                                anchors.bottom: parent.bottom
                                anchors.left: parent.left
                                // No right anchor so text can be elided by actions

                                // Header: the folder
                                label: {
                                    var strippedPath = modelData.replace(/\/+$/, "");
                                    return strippedPath.split('/').pop()
                                }
                                // Subtitle: the path to the folder
                                subtitle: {
                                    var strippedPath = modelData.replace(/\/+$/, "");
                                    return strippedPath.replace(/\/[^\/]*$/, '');;
                                }

                                QtControls2.ToolTip.text: modelData
                                QtControls2.ToolTip.visible: hovered
                                QtControls2.ToolTip.delay: 1000
                                QtControls2.ToolTip.timeout: 5000
                            }
302
303
304
305
306
307
308
309
310
311
312
313
                            actions: [
                                Kirigami.Action {
                                    iconName: "list-remove"
                                    tooltip: i18nd("plasma_wallpaper_org.kde.image", "Remove Folder")
                                    onTriggered: imageWallpaper.removeSlidePath(modelData)
                                },
                                Kirigami.Action {
                                    icon.name: "document-open-folder"
                                    tooltip: i18nd("plasma_wallpaper_org.kde.image", "Open Folder")
                                    onTriggered: imageWallpaper.openFolder(modelData)
                                }
                            ]
314
                        }
315

316
317
318
                        Kirigami.PlaceholderMessage {
                            anchors.centerIn: parent
                            width: parent.width - (Kirigami.Units.largeSpacing * 4)
319
                            visible: slidePathsView.count === 0
320
                            text: i18nd("plasma_wallpaper_org.kde.image", "There are no wallpaper locations configured")
321
                        }
322
323
                    }
                }
324
325
326
327
328
329
330
331
332
333
334
335
                Loader {
                    sourceComponent: thumbnailsComponent
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    anchors.fill: undefined
                }
                QtControls2.Button {
                    Layout.alignment: Qt.AlignRight
                    icon.name: "list-add"
                    text: i18nd("plasma_wallpaper_org.kde.image","Add Folder...")
                    onClicked: imageWallpaper.showAddSlidePathsDialog()
                }
336
                NewStuff.Button {
337
                    Layout.alignment: Qt.AlignRight
338
                    configFile: "wallpaper.knsrc"
339
                    text: i18nd("plasma_wallpaper_org.kde.image", "Get New Wallpapers...")
340
341
                    viewMode: NewStuff.Page.ViewMode.Preview
                    onChangedEntriesChanged: imageWallpaper.newStuffFinished();
342
                }
343
344
345
346
347
348
            }
        }
    }

    Component {
        id: thumbnailsComponent
349
350
        KCM.GridView {
            id: wallpapersGrid
351
            property var imageModel: (configDialog.currentWallpaper == "org.kde.image")? imageWallpaper.wallpaperModel : imageWallpaper.slideFilterModel
352
353
354
355

            function resetCurrentIndex() {
                //that min is needed as the module will be populated in an async way
                //and only on demand so we can't ensure it already exists
356
                view.currentIndex = Qt.binding(function() { return Math.min(imageModel.indexOf(cfg_Image), imageModel.count - 1) });
357
358
            }

359
            //kill the space for label under thumbnails
360
            view.model: imageModel
361
362
            Component.onCompleted: {
                imageModel.usedInConfig = true;
363
                resetCurrentIndex()
364
            }
365
366
            view.delegate: WallpaperDelegate {
                color: cfg_Color
367
            }
368

369
            Kirigami.PlaceholderMessage {
370
                anchors.fill: parent
371
                anchors.margins: Kirigami.Units.largeSpacing * 2
372
                // FIXME: this is needed to vertically center it in the grid for some reason
373
                anchors.topMargin: wallpapersGrid.height / 2
374
                visible: wallpapersGrid.view.count === 0
375
                text: i18nd("plasma_wallpaper_org.kde.image", "There are no wallpapers in this slideshow")
376
            }
377
378
379
        }
    }

380
    DragDrop.DropArea {
Kai Uwe Broulik's avatar
Kai Uwe Broulik committed
381
382
        Layout.fillWidth: true
        Layout.fillHeight: true
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

        onDragEnter: {
            if (!event.mimeData.hasUrls) {
                event.ignore();
            }
        }
        onDrop: {
            event.mimeData.urls.forEach(function (url) {
                if (url.indexOf("file://") === 0) {
                    var path = url.substr(7); // 7 is length of "file://"
                    if (configDialog.currentWallpaper === "org.kde.image") {
                        imageWallpaper.addUsersWallpaper(path);
                    } else {
                        imageWallpaper.addSlidePath(path);
                    }
                }
            });
        }

        Loader {
            anchors.fill: parent
404
405
            sourceComponent: (configDialog.currentWallpaper == "org.kde.image") ? thumbnailsComponent :
                ((configDialog.currentWallpaper == "org.kde.slideshow") ? foldersComponent : undefined)
406
        }
407
408
409
410
    }

    RowLayout {
        id: buttonsRow
411
        Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
412
        visible: configDialog.currentWallpaper == "org.kde.image"
413
414
        QtControls2.Button {
            icon.name: "list-add"
415
            text: i18nd("plasma_wallpaper_org.kde.image","Add Image...")
416
417
            onClicked: imageWallpaper.showFileDialog();
        }
418
419
420
        NewStuff.Button {
            Layout.alignment: Qt.AlignRight
            configFile: "wallpaper.knsrc"
421
            text: i18nd("plasma_wallpaper_org.kde.image", "Get New Wallpapers...")
422
423
            viewMode: NewStuff.Page.ViewMode.Preview
            onChangedEntriesChanged: imageWallpaper.newStuffFinished();
424
425
        }
    }
426
}