Merge lp:~jonas-drange/ubuntu-settings-components/filepicker into lp:ubuntu-settings-components

Proposed by Jonas G. Drange
Status: Approved
Approved by: Ken VanDine
Approved revision: 167
Proposed branch: lp:~jonas-drange/ubuntu-settings-components/filepicker
Merge into: lp:ubuntu-settings-components
Diff against target: 1665 lines (+1174/-226)
27 files modified
debian/changelog (+6/-0)
debian/control (+1/-0)
examples/FilePickerComponent.qml (+91/-0)
plugins/Ubuntu/Settings/Components/CMakeLists.txt (+7/-0)
plugins/Ubuntu/Settings/Components/FilePicker.qml (+197/-0)
plugins/Ubuntu/Settings/Components/FilePickerProperties.qml (+22/-0)
plugins/Ubuntu/Settings/Components/filepickerhelper.cpp (+59/-0)
plugins/Ubuntu/Settings/Components/filepickerhelper.h (+36/-0)
plugins/Ubuntu/Settings/Components/plugin.cpp (+7/-0)
plugins/Ubuntu/Settings/Components/qmldir (+3/-0)
plugins/Ubuntu/Settings/Vpn/DialogFile.qml (+0/-176)
plugins/Ubuntu/Settings/Vpn/DialogFileProperties.qml (+0/-22)
plugins/Ubuntu/Settings/Vpn/FileSelector.qml (+7/-1)
plugins/Ubuntu/Settings/Vpn/VpnEditor.qml (+0/-7)
plugins/Ubuntu/Settings/Vpn/qmldir (+0/-4)
po/ubuntu-settings-components.pot (+28/-16)
tests/qmltests/CMakeLists.txt (+1/-0)
tests/qmltests/Components/tst_FilePicker.qml (+215/-0)
tests/qmltests/mocks/CMakeLists.txt (+1/-0)
tests/qmltests/mocks/Qt/CMakeLists.txt (+1/-0)
tests/qmltests/mocks/Qt/labs/CMakeLists.txt (+1/-0)
tests/qmltests/mocks/Qt/labs/folderlistmodel/CMakeLists.txt (+20/-0)
tests/qmltests/mocks/Qt/labs/folderlistmodel/MockFolderListModel.cpp (+241/-0)
tests/qmltests/mocks/Qt/labs/folderlistmodel/MockFolderListModel.h (+171/-0)
tests/qmltests/mocks/Qt/labs/folderlistmodel/plugin.cpp (+26/-0)
tests/qmltests/mocks/Qt/labs/folderlistmodel/plugin.h (+31/-0)
tests/qmltests/mocks/Qt/labs/folderlistmodel/qmldir (+2/-0)
To merge this branch: bzr merge lp:~jonas-drange/ubuntu-settings-components/filepicker
Reviewer Review Type Date Requested Status
Ken VanDine Approve
Lukáš Tinkl (community) Needs Information
PS Jenkins bot continuous-integration Pending
Review via email: mp+300180@code.launchpad.net

Commit message

create file picker component for export

To post a comment you must log in.
Revision history for this message
Ken VanDine (ken-vandine) wrote :

One copyright question inline

review: Needs Information
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Two other minor points inline

review: Needs Information
Revision history for this message
Ken VanDine (ken-vandine) wrote :

Looks fine to me

review: Approve
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Is this something we still want to land?

Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

It's scheduled to land after silo 2078.

On 27 October 2016 at 18:16, Marco Trevisan (Treviño) <mail@3v1n0.net>
wrote:

> Is this something we still want to land?
> --
> https://code.launchpad.net/~jonas-drange/ubuntu-settings-
> components/filepicker/+merge/300180
> You are the owner of lp:~jonas-drange/ubuntu-settings-components/
> filepicker.
>

166. By Jonas G. Drange

bumps filepicker change

167. By Jonas G. Drange

syncs with trunk

Revision history for this message
Ken VanDine (ken-vandine) wrote :

I'll reviewed the commits since my last approval, looks fine.

review: Approve

Unmerged revisions

167. By Jonas G. Drange

syncs with trunk

166. By Jonas G. Drange

bumps filepicker change

165. By Jonas G. Drange

sync with trunk

164. By Jonas G. Drange

bump version

163. By Jonas G. Drange

drop bump

162. By Jonas G. Drange

merge trunk

161. By Jonas G. Drange

update pot

160. By Jonas G. Drange

address comments, use glib to format size

159. By Jonas G. Drange

update pot

158. By Jonas G. Drange

make file name elide in the middle

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2017-01-18 15:20:00 +0000
3+++ debian/changelog 2017-01-25 13:04:17 +0000
4@@ -1,3 +1,9 @@
5+ubuntu-settings-components (0.13+17.04.20170104-0ubuntu2) UNRELEASED; urgency=medium
6+
7+ * create file picker component for export
8+
9+ -- Jonas G. Drange <jonas.drange@canonical.com> Tue, 24 Jan 2017 15:01:25 +0100
10+
11 ubuntu-settings-components (0.12+17.04.20170118-0ubuntu1) zesty; urgency=medium
12
13 [ Pete Woods ]
14
15=== modified file 'debian/control'
16--- debian/control 2016-12-07 17:02:20 +0000
17+++ debian/control 2017-01-25 13:04:17 +0000
18@@ -5,6 +5,7 @@
19 Build-Depends: cmake,
20 cmake-extras (>= 0.10),
21 debhelper (>= 9),
22+ libglib2.0-dev (>= 2.37.92),
23 pkg-config,
24 python3:any,
25 qml-module-qt-labs-folderlistmodel,
26
27=== added file 'examples/FilePickerComponent.qml'
28--- examples/FilePickerComponent.qml 1970-01-01 00:00:00 +0000
29+++ examples/FilePickerComponent.qml 2017-01-25 13:04:17 +0000
30@@ -0,0 +1,91 @@
31+/*
32+ * Copyright 2016 Canonical Ltd.
33+ *
34+ * This program is free software; you can redistribute it and/or modify
35+ * it under the terms of the GNU Lesser General Public License as published by
36+ * the Free Software Foundation; version 3.
37+ *
38+ * This program is distributed in the hope that it will be useful,
39+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
40+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41+ * GNU Lesser General Public License for more details.
42+ *
43+ * You should have received a copy of the GNU Lesser General Public License
44+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
45+ *
46+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
47+ */
48+
49+import QtQuick 2.4
50+import Ubuntu.Components 1.3
51+import Ubuntu.Settings.Components 0.1
52+import Ubuntu.Components.Popups 1.3
53+
54+MainView {
55+ id: mainView
56+ // Note! applicationName needs to match the .desktop filename
57+ applicationName: "SettingsComponents"
58+
59+ width: units.gu(42)
60+ height: units.gu(75)
61+
62+ property var _diag
63+ property alias _accepted: acceptedLabel.acceptedPath
64+
65+ Component {
66+ id: fp
67+ FilePicker {
68+ onReject: {
69+ if (_diag) {
70+ PopupUtils.close(_diag)
71+ }
72+ _accepted = ""
73+ }
74+ onAccept: {
75+ _accepted = path
76+ if (_diag) {
77+ PopupUtils.close(_diag)
78+ }
79+ }
80+ }
81+ }
82+
83+ Page {
84+ header: PageHeader {
85+ id: pageHeader
86+ title: "FilePicker"
87+ }
88+
89+ Column {
90+ spacing: units.gu(2)
91+ anchors {
92+ top: pageHeader.bottom
93+ left: parent.left
94+ right: parent.right
95+ bottom: parent.bottom
96+ margins: units.gu(2)
97+ }
98+
99+ Button {
100+ anchors { left: parent.left; right: parent.right }
101+ text: i18n.tr("Select dark theme")
102+ onClicked: theme.name = "Ubuntu.Components.Themes.SuruDark"
103+ }
104+
105+ Button {
106+ anchors { left: parent.left; right: parent.right }
107+ text: i18n.tr("Open file picker")
108+ onClicked: _diag = PopupUtils.open(fp)
109+ }
110+
111+ Label {
112+ id: acceptedLabel
113+ property string acceptedPath
114+ visible: acceptedPath
115+ anchors { left: parent.left; right: parent.right }
116+ text: i18n.tr("Accepted path: %1").arg(acceptedPath)
117+ elide: Text.ElideMiddle
118+ }
119+ }
120+ }
121+}
122
123=== modified file 'plugins/Ubuntu/Settings/Components/CMakeLists.txt'
124--- plugins/Ubuntu/Settings/Components/CMakeLists.txt 2016-01-29 00:44:43 +0000
125+++ plugins/Ubuntu/Settings/Components/CMakeLists.txt 2017-01-25 13:04:17 +0000
126@@ -1,9 +1,15 @@
127 project(UbuntuSettingsComponentsQml)
128
129+pkg_search_module(GLIB REQUIRED glib-2.0)
130+include_directories(
131+ ${GLIB_INCLUDE_DIRS}
132+)
133+
134 add_definitions(-DUBUNTUSETTINGSCOMPONENTS_LIBRARY)
135
136 add_library(UbuntuSettingsComponentsQml MODULE
137 plugin.cpp
138+ filepickerhelper.cpp
139 serverpropertysynchroniser.cpp
140 )
141
142@@ -11,6 +17,7 @@
143 Qt5::Core
144 Qt5::Qml
145 Qt5::Quick
146+ ${GLIB_LDFLAGS}
147 )
148
149 add_usc_plugin(Ubuntu.Settings.Components 0.1 Ubuntu/Settings/Components TARGETS UbuntuSettingsComponentsQml)
150
151=== added file 'plugins/Ubuntu/Settings/Components/FilePicker.qml'
152--- plugins/Ubuntu/Settings/Components/FilePicker.qml 1970-01-01 00:00:00 +0000
153+++ plugins/Ubuntu/Settings/Components/FilePicker.qml 2017-01-25 13:04:17 +0000
154@@ -0,0 +1,197 @@
155+/*
156+ * Copyright (C) 2016 Canonical Ltd.
157+ *
158+ * This program is free software: you can redistribute it and/or modify it
159+ * under the terms of the GNU Lesser General Public License version 3,
160+ * as published by the Free Software Foundation.
161+ *
162+ * This program is distributed in the hope that it will be useful,
163+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
164+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
165+ * GNU Lesser General Public License for more details.
166+ *
167+ * You should have received a copy of the GNU Lesser General Public License
168+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
169+ */
170+
171+import Qt.labs.folderlistmodel 2.1
172+import QtQuick 2.4
173+import QtQuick.Layouts 1.1
174+import Ubuntu.Components 1.3
175+import Ubuntu.Components.ListItems 1.3 as ListItems
176+import Ubuntu.Components.Popups 1.3
177+import Ubuntu.Settings.Components 0.1
178+
179+Dialog {
180+ id: root
181+ objectName: "filePicker"
182+
183+ property string currentFilePath: ""
184+
185+ signal accept(string path)
186+ signal reject()
187+
188+ function hideFunc() {
189+ FilePickerProperties.lastFolder = fsModel.folder
190+ currentFilePath = ""
191+ }
192+
193+ function rejectFunc() {
194+ hideFunc()
195+ root.reject()
196+ }
197+
198+ function acceptFunc() {
199+ var path = currentFilePath
200+ hideFunc()
201+ root.accept(path)
202+ }
203+
204+ property var fsModel: FolderListModel {
205+ showDirs: true
206+ showFiles: true
207+ showHidden: true
208+ showDirsFirst: true
209+ showDotAndDotDot: false
210+ showOnlyReadable: false
211+ sortField: FolderListModel.Name
212+
213+ folder: (FilePickerProperties.lastFolder === "") ?
214+ FilePickerHelper.homeDirUrl() :
215+ FilePickerProperties.lastFolder
216+ }
217+
218+ ColumnLayout {
219+ spacing: units.gu(1)
220+ anchors {
221+ left: parent.left
222+ right: parent.right
223+ }
224+ height: root.height - units.gu(10)
225+
226+ RowLayout {
227+ anchors { left: parent.left; right: parent.right }
228+ spacing: units.gu(1)
229+
230+ Icon {
231+ objectName: "filePickerBackButton"
232+ name: "back"
233+ Layout.alignment: Qt.AlignVCenter
234+ width: units.gu(2.5)
235+ height: width
236+
237+ enabled: (FilePickerHelper.pathFromUrl(fsModel.folder)
238+ !== FilePickerHelper.rootPath())
239+ opacity: enabled ? 1 : 0.5
240+
241+ MouseArea {
242+ anchors {
243+ fill: parent
244+ margins: -units.gu(2)
245+ }
246+ onClicked: {
247+ if (parent.enabled) {
248+ fsModel.folder = fsModel.parentFolder
249+ }
250+ }
251+ }
252+ }
253+
254+ Label {
255+ objectName: "filePickerBreadcrumb"
256+ Layout.alignment: Qt.AlignVCenter
257+ text: {
258+ var prettyTree = [
259+ i18n.dtr("ubuntu-settings-components", "Device")
260+ ];
261+ var paths = FilePickerHelper.pathsFromUrl(fsModel.folder);
262+ for (var i = 0; i < paths.length; i++) {
263+ prettyTree.push(paths[i]);
264+ }
265+ return i18n.dtr("ubuntu-settings-components",
266+ "%1 (%2 file)",
267+ "%1 (%2 files)",
268+ fsModel.count
269+ ).arg(prettyTree.join("/"))
270+ .arg(fsModel.count)
271+ }
272+ Layout.fillWidth: true
273+ elide: Text.ElideMiddle
274+ }
275+ }
276+
277+ Rectangle {
278+ Layout.fillWidth: true
279+ Layout.fillHeight: true
280+ color: theme.palette.normal.background
281+
282+ border {
283+ width: 1
284+ color: theme.palette.normal.overlaySecondaryText
285+ }
286+
287+ ListView {
288+ id: list
289+ objectName: "filePickerList"
290+ anchors.fill: parent
291+ clip: true
292+ model: fsModel
293+
294+ delegate: ListItem {
295+ objectName: "filePickerFileItem_" + index
296+ height: fileLayout.height + divider.height
297+ color: (filePath === currentFilePath) ? highlightColor : "transparent"
298+
299+ onClicked: {
300+ if (fileIsDir) {
301+ fsModel.folder = fileURL
302+ } else {
303+ currentFilePath = filePath
304+ }
305+ }
306+
307+ ListItemLayout {
308+ id: fileLayout
309+
310+ title.text: fileName
311+ title.elide: Text.ElideMiddle
312+ title.wrapMode: Text.NoWrap
313+ subtitle.text: fileIsDir ?
314+ "" : FilePickerHelper.formatSize(fileSize)
315+
316+ Icon {
317+ name: fileIsDir ? "folder" : "empty"
318+ SlotsLayout.position: SlotsLayout.Leading;
319+ width: units.gu(4)
320+ }
321+ }
322+ }
323+ }
324+
325+ Scrollbar {
326+ flickableItem: list
327+ align: Qt.AlignTrailing
328+ }
329+ }
330+
331+ RowLayout {
332+ spacing: units.gu(1)
333+
334+ Button {
335+ objectName: "filePickerCancel"
336+ Layout.fillWidth: true
337+ text: i18n.dtr("ubuntu-settings-components", "Cancel")
338+ onClicked: rejectFunc()
339+ }
340+
341+ Button {
342+ objectName: "filePickerAccept"
343+ Layout.fillWidth: true
344+ enabled: currentFilePath !== ""
345+ text: i18n.dtr("ubuntu-settings-components", "Accept")
346+ onClicked: acceptFunc()
347+ color: theme.palette.normal.positive
348+ }
349+ }
350+ }
351+}
352
353=== added file 'plugins/Ubuntu/Settings/Components/FilePickerProperties.qml'
354--- plugins/Ubuntu/Settings/Components/FilePickerProperties.qml 1970-01-01 00:00:00 +0000
355+++ plugins/Ubuntu/Settings/Components/FilePickerProperties.qml 2017-01-25 13:04:17 +0000
356@@ -0,0 +1,22 @@
357+/*
358+ * Copyright (C) 2016 Canonical Ltd.
359+ *
360+ * This program is free software: you can redistribute it and/or modify it
361+ * under the terms of the GNU Lesser General Public License version 3,
362+ * as published by the Free Software Foundation.
363+ *
364+ * This program is distributed in the hope that it will be useful,
365+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
366+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
367+ * GNU Lesser General Public License for more details.
368+ *
369+ * You should have received a copy of the GNU Lesser General Public License
370+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
371+ */
372+
373+pragma Singleton
374+import QtQuick 2.4
375+
376+QtObject {
377+ property string lastFolder
378+}
379
380=== added file 'plugins/Ubuntu/Settings/Components/filepickerhelper.cpp'
381--- plugins/Ubuntu/Settings/Components/filepickerhelper.cpp 1970-01-01 00:00:00 +0000
382+++ plugins/Ubuntu/Settings/Components/filepickerhelper.cpp 2017-01-25 13:04:17 +0000
383@@ -0,0 +1,59 @@
384+/*
385+ * Copyright (C) 2016 Canonical, Ltd.
386+ *
387+ * This program is free software; you can redistribute it and/or modify
388+ * it under the terms of the GNU Lesser General Public License as published by
389+ * the Free Software Foundation; version 3.
390+ *
391+ * This program is distributed in the hope that it will be useful,
392+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
393+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
394+ * GNU Lesser General Public License for more details.
395+ *
396+ * You should have received a copy of the GNU Lesser General Public License
397+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
398+ */
399+
400+#include "filepickerhelper.h"
401+
402+#include <glib.h>
403+
404+#include <QDir>
405+#include <QDebug>
406+
407+FilePickerHelper::FilePickerHelper(QObject* parent)
408+ : QObject(parent)
409+{
410+}
411+
412+QUrl FilePickerHelper::homeDirUrl()
413+{
414+ return QUrl::fromLocalFile(QDir::homePath());
415+}
416+
417+QString FilePickerHelper::pathFromUrl(const QUrl &url)
418+{
419+ return url.path();
420+}
421+
422+QString FilePickerHelper::rootPath()
423+{
424+ return QDir::rootPath();
425+}
426+
427+QStringList FilePickerHelper::pathsFromUrl(const QUrl &url)
428+{
429+ QString path = url.path();
430+ return path.split(QDir::separator(), QString::SkipEmptyParts);
431+}
432+
433+QString FilePickerHelper::formatSize(const quint64 &size)
434+{
435+ guint64 g_size = size;
436+
437+ gchar * formatted_size = g_format_size (g_size);
438+ QString q_formatted_size = QString::fromLocal8Bit(formatted_size);
439+ g_free (formatted_size);
440+
441+ return q_formatted_size;
442+}
443
444=== added file 'plugins/Ubuntu/Settings/Components/filepickerhelper.h'
445--- plugins/Ubuntu/Settings/Components/filepickerhelper.h 1970-01-01 00:00:00 +0000
446+++ plugins/Ubuntu/Settings/Components/filepickerhelper.h 2017-01-25 13:04:17 +0000
447@@ -0,0 +1,36 @@
448+/*
449+ * Copyright (C) 2016 Canonical, Ltd.
450+ *
451+ * This program is free software; you can redistribute it and/or modify
452+ * it under the terms of the GNU Lesser General Public License as published by
453+ * the Free Software Foundation; version 3.
454+ *
455+ * This program is distributed in the hope that it will be useful,
456+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
457+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
458+ * GNU Lesser General Public License for more details.
459+ *
460+ * You should have received a copy of the GNU Lesser General Public License
461+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
462+ */
463+
464+#ifndef FILEPICKERHELPER_H
465+#define FILEPICKERHELPER_H
466+
467+#include <QObject>
468+#include <QUrl>
469+#include <QStringList>
470+
471+class FilePickerHelper : public QObject
472+{
473+ Q_OBJECT
474+public:
475+ FilePickerHelper(QObject* parent = nullptr);
476+ Q_INVOKABLE static QUrl homeDirUrl();
477+ Q_INVOKABLE static QString rootPath();
478+ Q_INVOKABLE static QString pathFromUrl(const QUrl &url);
479+ Q_INVOKABLE static QStringList pathsFromUrl(const QUrl &url);
480+ Q_INVOKABLE static QString formatSize(const quint64 &size);
481+};
482+
483+#endif // FILEPICKERHELPER_H
484
485=== modified file 'plugins/Ubuntu/Settings/Components/plugin.cpp'
486--- plugins/Ubuntu/Settings/Components/plugin.cpp 2016-10-26 17:09:16 +0000
487+++ plugins/Ubuntu/Settings/Components/plugin.cpp 2017-01-25 13:04:17 +0000
488@@ -17,6 +17,7 @@
489 // local
490 #include "plugin.h"
491 #include "serverpropertysynchroniser.h"
492+#include "filepickerhelper.h"
493
494 // Qt
495 #include <QtQml/qqml.h>
496@@ -33,9 +34,15 @@
497 Q_INVOKABLE QString formattedWeekNumber(const QDate &date) const { return QString("%1").arg(date.weekNumber(), 2, 10, QChar('0')); }
498 };
499
500+static QObject* filepickerhelperProvider(QQmlEngine*, QJSEngine*)
501+{
502+ return new FilePickerHelper;
503+}
504+
505 void UbuntuSettingsComponentsPlugin::registerTypes(const char *uri)
506 {
507 qmlRegisterType<ServerPropertySynchroniser>(uri, 0, 1, "ServerPropertySynchroniser");
508+ qmlRegisterSingletonType<FilePickerHelper>(uri, 0, 1, "FilePickerHelper", filepickerhelperProvider);
509 qmlRegisterSingletonType<QtDateFunctions>(uri, 0, 1, "QtDateFunctions",
510 [](QQmlEngine*, QJSEngine*) -> QObject* { return new QtDateFunctions; });
511 }
512
513=== modified file 'plugins/Ubuntu/Settings/Components/qmldir'
514--- plugins/Ubuntu/Settings/Components/qmldir 2016-09-16 23:17:00 +0000
515+++ plugins/Ubuntu/Settings/Components/qmldir 2017-01-25 13:04:17 +0000
516@@ -4,5 +4,8 @@
517
518 ActionTextField 0.1 ActionTextField.qml
519 Calendar 0.1 Calendar.qml
520+FilePicker 0.1 FilePicker.qml
521 MessageHeader 0.1 MessageHeader.qml
522 UbuntuShapeForItem 0.1 UbuntuShapeForItem.qml
523+
524+singleton FilePickerProperties 0.1 FilePickerProperties.qml
525
526=== removed file 'plugins/Ubuntu/Settings/Vpn/DialogFile.qml'
527--- plugins/Ubuntu/Settings/Vpn/DialogFile.qml 2016-03-14 15:01:48 +0000
528+++ plugins/Ubuntu/Settings/Vpn/DialogFile.qml 1970-01-01 00:00:00 +0000
529@@ -1,176 +0,0 @@
530-/*
531- * Copyright (C) 2016 Canonical Ltd.
532- *
533- * This program is free software: you can redistribute it and/or modify it
534- * under the terms of the GNU Lesser General Public License version 3,
535- * as published by the Free Software Foundation.
536- *
537- * This program is distributed in the hope that it will be useful,
538- * but WITHOUT ANY WARRANTY; without even the implied warranty of
539- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
540- * GNU Lesser General Public License for more details.
541- *
542- * You should have received a copy of the GNU Lesser General Public License
543- * along with this program. If not, see <http://www.gnu.org/licenses/>.
544- */
545-
546-import QtQuick 2.4
547-import QtQuick.Layouts 1.1
548-import Ubuntu.Components 1.3
549-import Ubuntu.Components.ListItems 1.3 as ListItems
550-import Ubuntu.Components.Popups 1.3
551-import Ubuntu.Settings.Vpn 0.1
552-import Qt.labs.folderlistmodel 2.1
553-
554-Dialog {
555- objectName: "vpnDialogFile"
556- id: dialog
557-
558- property string currentFilePath: ""
559-
560- signal accept(string path)
561- signal reject
562-
563- function hideFunc() {
564- DialogFileProperties.lastFolder = modelFs.folder
565- currentFilePath = ""
566- }
567-
568- function rejectFunc() {
569- hideFunc()
570- dialog.reject()
571- }
572-
573- function acceptFunc() {
574- var path = currentFilePath
575- hideFunc()
576- dialog.accept(path)
577- }
578-
579- FolderListModel {
580- id: modelFs
581- showDirs: true
582- showFiles: true
583- showHidden: true
584- showDirsFirst: true
585- showDotAndDotDot: false
586- showOnlyReadable: false
587- sortField: FolderListModel.Name
588-
589- folder: (DialogFileProperties.lastFolder === "")? "file:///home/" : DialogFileProperties.lastFolder
590- }
591-
592- ColumnLayout {
593- height: root.height - units.gu(10)
594- spacing: units.gu(1)
595-
596- Flow {
597- spacing: units.gu(1)
598- Layout.fillWidth: true
599-
600- Repeater {
601- model: {
602- var ret = []
603- var path = "file:///"
604- ret.push({ "name" : "/", "url" : path })
605- var tmp = modelFs.folder.toString().replace("file:///", "").split("/")
606- for (var idx = 0; idx < tmp.length; idx++) {
607- var name = tmp[idx] + "/"
608- if (name !== "/") {
609- path += name
610- ret.push({ "name" : name, "url" : path })
611- }
612- }
613- return ret
614- }
615- delegate: Row {
616- spacing: units.gu(0.7)
617-
618- property bool isCurrent : Positioner.isLastItem
619-
620- Rectangle {
621- width: units.gu(0.7)
622- height: width
623- color: "gray"
624- rotation: 45
625- visible: (model.index > 0)
626- anchors.verticalCenter: parent.verticalCenter
627- }
628- Label {
629- objectName: "vpnFilePathItem_" + model.modelData["name"]
630- text: model.modelData["name"]
631- font.weight: (isCurrent ? Font.Bold : Font.Normal)
632- font.underline: hoverDetector.containsMouse
633- color: "darkblue"
634- anchors.verticalCenter: parent.verticalCenter
635-
636- MouseArea {
637- id: hoverDetector
638- enabled: !isCurrent
639- hoverEnabled: true
640- anchors.fill: parent
641- onClicked: modelFs.folder = model.modelData["url"]
642- }
643- }
644- }
645- }
646- }
647-
648- Rectangle {
649- Layout.fillWidth: true
650- Layout.fillHeight: true
651-
652- border {
653- width: 1
654- color: "lightgrey"
655- }
656-
657- ListView {
658- objectName: "vpnFileList"
659- anchors.fill: parent
660- anchors.margins: 1
661- clip: true
662- model: modelFs
663-
664- delegate: ListItems.Standard {
665- objectName: "vpnFileItem_" + model.fileName
666- text: model.fileName
667- iconFrame: false
668- iconName: model.fileIsDir ? "folder" : "empty"
669-
670- selected: (model.filePath === currentFilePath)
671-
672- onClicked: {
673- if (model.fileIsDir) {
674- modelFs.folder = model.fileURL
675- } else {
676- currentFilePath = model.filePath
677- }
678- }
679- }
680- }
681- }
682-
683- RowLayout {
684- spacing: units.gu(1)
685- Layout.fillWidth: true
686-
687- Button {
688- objectName: "vpnFileCancel"
689- Layout.fillWidth: true
690- text: i18n.dtr("ubuntu-settings-components", "Cancel")
691- onClicked: rejectFunc()
692- color: UbuntuColors.red
693- }
694-
695- Button {
696- objectName: "vpnFileAccept"
697- Layout.fillWidth: true
698- enabled: currentFilePath !== ""
699- text: i18n.dtr("ubuntu-settings-components", "Accept")
700- onClicked: acceptFunc()
701- color: UbuntuColors.green
702- }
703- }
704- }
705-}
706
707=== removed file 'plugins/Ubuntu/Settings/Vpn/DialogFileProperties.qml'
708--- plugins/Ubuntu/Settings/Vpn/DialogFileProperties.qml 2016-03-07 15:46:28 +0000
709+++ plugins/Ubuntu/Settings/Vpn/DialogFileProperties.qml 1970-01-01 00:00:00 +0000
710@@ -1,22 +0,0 @@
711-/*
712- * Copyright (C) 2016 Canonical Ltd.
713- *
714- * This program is free software: you can redistribute it and/or modify it
715- * under the terms of the GNU Lesser General Public License version 3,
716- * as published by the Free Software Foundation.
717- *
718- * This program is distributed in the hope that it will be useful,
719- * but WITHOUT ANY WARRANTY; without even the implied warranty of
720- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
721- * GNU Lesser General Public License for more details.
722- *
723- * You should have received a copy of the GNU Lesser General Public License
724- * along with this program. If not, see <http://www.gnu.org/licenses/>.
725- */
726-
727-pragma Singleton
728-import QtQuick 2.4
729-
730-QtObject {
731- property string lastFolder
732-}
733
734=== modified file 'plugins/Ubuntu/Settings/Vpn/FileSelector.qml'
735--- plugins/Ubuntu/Settings/Vpn/FileSelector.qml 2016-03-14 15:01:48 +0000
736+++ plugins/Ubuntu/Settings/Vpn/FileSelector.qml 2017-01-25 13:04:17 +0000
737@@ -19,6 +19,7 @@
738 import Ubuntu.Components 1.3
739 import Ubuntu.Components.Popups 1.3
740 import Ubuntu.Components.ListItems 1.3 as ListItems
741+import Ubuntu.Settings.Components 0.1
742
743 ListItems.ItemSelector {
744 property string path
745@@ -47,7 +48,7 @@
746 }
747
748 function createDialog() {
749- __dialog = PopupUtils.open(fileDialogComponent)
750+ __dialog = PopupUtils.open(filePickerComponent)
751 __dialog.accept.connect(pathAccepted)
752 __dialog.reject.connect(pathRejected)
753 }
754@@ -91,4 +92,9 @@
755 path = model[index];
756 }
757 }
758+
759+ Component {
760+ id: filePickerComponent
761+ FilePicker {}
762+ }
763 }
764
765=== modified file 'plugins/Ubuntu/Settings/Vpn/VpnEditor.qml'
766--- plugins/Ubuntu/Settings/Vpn/VpnEditor.qml 2016-12-16 13:32:35 +0000
767+++ plugins/Ubuntu/Settings/Vpn/VpnEditor.qml 2017-01-25 13:04:17 +0000
768@@ -68,13 +68,6 @@
769 leadingActionBar.actions: []
770 }
771
772- Component {
773- id: fileDialogComponent
774- DialogFile {
775- id: fileDialog
776- }
777- }
778-
779 Flickable {
780 id: scrollWidget
781 anchors {
782
783=== modified file 'plugins/Ubuntu/Settings/Vpn/qmldir'
784--- plugins/Ubuntu/Settings/Vpn/qmldir 2016-02-29 13:52:35 +0000
785+++ plugins/Ubuntu/Settings/Vpn/qmldir 2017-01-25 13:04:17 +0000
786@@ -1,10 +1,6 @@
787 module Ubuntu.Settings.Vpn
788 plugin UbuntuSettingsVpn
789
790-singleton DialogFileProperties 0.1 DialogFileProperties.qml
791-
792-internal DialogFile DialogFile.qml
793-
794 VpnList 0.1 VpnList.qml
795 VpnEditor 0.1 VpnEditor.qml
796 VpnPreviewDialog 0.1 VpnPreviewDialog.qml
797
798=== modified file 'po/ubuntu-settings-components.pot'
799--- po/ubuntu-settings-components.pot 2017-01-18 15:20:00 +0000
800+++ po/ubuntu-settings-components.pot 2017-01-25 13:04:17 +0000
801@@ -8,7 +8,7 @@
802 msgstr ""
803 "Project-Id-Version: ubuntu-settings-components\n"
804 "Report-Msgid-Bugs-To: \n"
805-"POT-Creation-Date: 2017-01-18 15:20+0000\n"
806+"POT-Creation-Date: 2017-01-25 14:03+0100\n"
807 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
808 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
809 "Language-Team: LANGUAGE <LL@li.org>\n"
810@@ -16,12 +16,36 @@
811 "MIME-Version: 1.0\n"
812 "Content-Type: text/plain; charset=UTF-8\n"
813 "Content-Transfer-Encoding: 8bit\n"
814+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
815
816 #: plugins/Ubuntu/Settings/Components/Calendar.qml:232
817 msgctxt "Header text: keep it short and upper case"
818 msgid "WEEK"
819 msgstr ""
820
821+#: plugins/Ubuntu/Settings/Components/FilePicker.qml:105
822+msgid "Device"
823+msgstr ""
824+
825+#: plugins/Ubuntu/Settings/Components/FilePicker.qml:112
826+#, qt-format
827+msgid "%1 (%2 file)"
828+msgid_plural "%1 (%2 files)"
829+msgstr[0] ""
830+msgstr[1] ""
831+
832+#: plugins/Ubuntu/Settings/Components/FilePicker.qml:183
833+#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:336
834+#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:355
835+#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:129
836+#: plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml:104
837+msgid "Cancel"
838+msgstr ""
839+
840+#: plugins/Ubuntu/Settings/Components/FilePicker.qml:191
841+msgid "Accept"
842+msgstr ""
843+
844 #: plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml:82
845 msgid "Fingerprint Name"
846 msgstr ""
847@@ -37,7 +61,7 @@
848 #: plugins/Ubuntu/Settings/Fingerprint/Fingerprint.qml:131
849 #: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:362
850 #: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:138
851-#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:149
852+#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:142
853 msgid "OK"
854 msgstr ""
855
856@@ -74,14 +98,6 @@
857 msgid "Are you sure you want to forget all stored fingerprints?"
858 msgstr ""
859
860-#: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:336
861-#: plugins/Ubuntu/Settings/Fingerprint/Setup.qml:355
862-#: plugins/Ubuntu/Settings/Vpn/DialogFile.qml:161
863-#: plugins/Ubuntu/Settings/Vpn/VpnEditor.qml:136
864-#: plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml:104
865-msgid "Cancel"
866-msgstr ""
867-
868 #: plugins/Ubuntu/Settings/Fingerprint/Fingerprints.qml:343
869 #: plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml:84
870 msgid "Remove"
871@@ -148,15 +164,11 @@
872 msgid "Send"
873 msgstr ""
874
875-#: plugins/Ubuntu/Settings/Vpn/DialogFile.qml:170
876-msgid "Accept"
877-msgstr ""
878-
879-#: plugins/Ubuntu/Settings/Vpn/FileSelector.qml:25
880+#: plugins/Ubuntu/Settings/Vpn/FileSelector.qml:26
881 msgid "Choose…"
882 msgstr ""
883
884-#: plugins/Ubuntu/Settings/Vpn/FileSelector.qml:34
885+#: plugins/Ubuntu/Settings/Vpn/FileSelector.qml:35
886 #: plugins/Ubuntu/Settings/Vpn/Openvpn/Editor.qml:431
887 #: plugins/Ubuntu/Settings/Vpn/Openvpn/Editor.qml:513
888 msgid "None"
889
890=== modified file 'tests/qmltests/CMakeLists.txt'
891--- tests/qmltests/CMakeLists.txt 2016-10-11 13:51:11 +0000
892+++ tests/qmltests/CMakeLists.txt 2017-01-25 13:04:17 +0000
893@@ -2,6 +2,7 @@
894
895 add_usc_qmltest(Components ActionTextField)
896 add_usc_qmltest(Components Calendar)
897+add_usc_qmltest(Components FilePicker)
898 add_usc_qmltest(Components ServerPropertySynchroniser)
899
900 add_usc_qmltest(Menus AccessPointMenu)
901
902=== added file 'tests/qmltests/Components/tst_FilePicker.qml'
903--- tests/qmltests/Components/tst_FilePicker.qml 1970-01-01 00:00:00 +0000
904+++ tests/qmltests/Components/tst_FilePicker.qml 2017-01-25 13:04:17 +0000
905@@ -0,0 +1,215 @@
906+/*
907+ * Copyright 2016 Canonical Ltd.
908+ *
909+ * This program is free software; you can redistribute it and/or modify
910+ * it under the terms of the GNU Lesser General Public License as published by
911+ * the Free Software Foundation; version 3.
912+ *
913+ * This program is distributed in the hope that it will be useful,
914+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
915+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
916+ * GNU Lesser General Public License for more details.
917+ *
918+ * You should have received a copy of the GNU Lesser General Public License
919+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
920+ *
921+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
922+ */
923+
924+import Qt.labs.folderlistmodel 2.1
925+import QtQuick 2.4
926+import QtTest 1.0
927+import Ubuntu.Components 1.3
928+import Ubuntu.Components.Popups 1.3
929+import Ubuntu.Settings.Components 0.1
930+import Ubuntu.Test 0.1
931+
932+MainView {
933+ id: testRoot
934+ width: units.gu(42)
935+ height: units.gu(75)
936+
937+ Component {
938+ id: filePickerComp
939+
940+ FilePicker {}
941+ }
942+
943+ Component {
944+ id: fsModelComp
945+
946+ FolderListModel {}
947+ }
948+
949+ SignalSpy {
950+ id: spy
951+ }
952+
953+ UbuntuTestCase {
954+ name: "FilePicker"
955+ when: windowShown
956+
957+ property var instance: null
958+ property var fsModel: null
959+
960+ function init() {
961+ fsModel = fsModelComp.createObject(testRoot);
962+ }
963+
964+ function cleanup() {
965+ PopupUtils.close(instance);
966+ tryCompareFunction(function () {
967+ return !!findChild(testRoot, "filePicker");
968+ }, false);
969+ fsModel.destroy();
970+ spy.clear();
971+ spy.target = null;
972+ spy.signalName = "";
973+ }
974+
975+ function test_breadCrumb_data() {
976+ return [
977+ {
978+ folder: "file:///home/user/",
979+ parentFolder: "file:///home",
980+ count: 0,
981+ targetText: i18n.dtr("ubuntu-settings-components", "%1 (%2 files)")
982+ .arg(i18n.tr("Device") + "/home/user")
983+ .arg(0)
984+ },
985+ {
986+ folder: "file:///",
987+ parentFolder: "file:///",
988+ count: 10,
989+ targetText: i18n.dtr("ubuntu-settings-components", "%1 (%2 files)")
990+ .arg(i18n.tr("Device"))
991+ .arg(10)
992+ },
993+ {
994+ folder: "file:///bar/baz",
995+ parentFolder: "file:///bar",
996+ count: 1,
997+ targetText: i18n.dtr("ubuntu-settings-components", "%1 (%2 file)")
998+ .arg(i18n.tr("Device") + "/bar/baz")
999+ .arg(1)
1000+ },
1001+ ]
1002+ }
1003+
1004+ function test_breadCrumb(data) {
1005+ fsModel.folder = data.folder;
1006+ fsModel.parentFolder = data.parentFolder;
1007+ fsModel.count = data.count;
1008+ instance = PopupUtils.open(filePickerComp, null, { "fsModel": fsModel });
1009+ waitForRendering(instance);
1010+
1011+ var crumbs = findChild(instance, "filePickerBreadcrumb");
1012+ compare(crumbs.text, data.targetText)
1013+ }
1014+
1015+ function test_backButtonEnabled_data() {
1016+ return [
1017+ { folder: "file:///", parentFolder: "file:///", targetEnabled: false },
1018+ { folder: "file:///bar", parentFolder: "file:///", targetEnabled: true },
1019+ { folder: "file:///bar/baz", parentFolder: "file:///bar", targetEnabled: true },
1020+ ]
1021+ }
1022+
1023+ function test_backButtonEnabled(data) {
1024+ fsModel.folder = data.folder;
1025+ fsModel.parentFolder = data.parentFolder;
1026+ instance = PopupUtils.open(filePickerComp, null, { "fsModel": fsModel });
1027+ waitForRendering(instance);
1028+
1029+ var button = findChild(instance, "filePickerBackButton");
1030+ compare(button.enabled, data.targetEnabled);
1031+ }
1032+
1033+ function test_backButtonAction_data() {
1034+ return [
1035+ { folder: "file:///", parentFolder: "file:///" },
1036+ { folder: "file:///bar", parentFolder: "file:///" },
1037+ { folder: "file:///bar/baz", parentFolder: "file:///bar" }
1038+ ]
1039+ }
1040+
1041+ function test_backButtonAction(data) {
1042+ fsModel.folder = data.folder;
1043+ fsModel.parentFolder = data.parentFolder;
1044+ instance = PopupUtils.open(filePickerComp, null, { "fsModel": fsModel });
1045+ waitForRendering(instance);
1046+
1047+ var button = findChild(instance, "filePickerBackButton");
1048+ mouseClick(button, button.width / 2, button.height / 2);
1049+ compare(fsModel.folder, fsModel.parentFolder);
1050+ }
1051+
1052+ function test_renderFiles_data() {
1053+ return [
1054+ { files: [ ["fileA.txt", "/home/user/fileA.txt", "", 5000, "txt", false, true] ] },
1055+ { files: [
1056+ ["fileA.txt", "/home/user/fileA.txt", "", 5000, "txt", false, true],
1057+ ["fileB.txt", "/fileB.txt", "", 5000, "txt", false, true],
1058+ ["somedir", "/somedir", "somedir", 4001, "", true, false]
1059+ ]}
1060+ ]
1061+ }
1062+
1063+ function test_renderFiles(data) {
1064+ for (var i = 0; i < data.files.length; i++) {
1065+ fsModel.mockAddFile.apply(fsModel, data.files[i]);
1066+ }
1067+ instance = PopupUtils.open(filePickerComp, null, { "fsModel": fsModel });
1068+ waitForRendering(instance);
1069+
1070+ // Make sure each file was rendered.
1071+ for (var i = 0; i < data.files.length; i++) {
1072+ verify(findChild(instance, "filePickerFileItem_" + i));
1073+ }
1074+ }
1075+
1076+ function test_accept_data() {
1077+ var files = [
1078+ ["fileA.txt", "file:///home/user/fileA.txt", "", 5000, "txt", false, true],
1079+ ["fileB.txt", "file:///fileB.txt", "", 5000, "txt", false, true]
1080+ ]
1081+ return [
1082+ { "files": files, accept: 0, targetAcceptPath: "file:///home/user/fileA.txt" },
1083+ { "files": files, accept: 1, targetAcceptPath: "file:///fileB.txt" },
1084+ ]
1085+ }
1086+
1087+ function test_accept(data) {
1088+ for (var i = 0; i < data.files.length; i++) {
1089+ fsModel.mockAddFile.apply(fsModel, data.files[i]);
1090+ }
1091+ instance = PopupUtils.open(filePickerComp, null, { "fsModel": fsModel });
1092+ waitForRendering(instance);
1093+
1094+ var item = findChild(instance, "filePickerFileItem_" + data.accept);
1095+ mouseClick(item, item.width / 2, item.height / 2);
1096+
1097+ spy.target = instance;
1098+ spy.signalName = "accept";
1099+
1100+ var btn = findChild(instance, "filePickerAccept");
1101+ mouseClick(btn, btn.width / 2, btn.height / 2);
1102+ spy.wait();
1103+ compare(spy.count, 1);
1104+ compare(spy.signalArguments[0][0], data.targetAcceptPath);
1105+ }
1106+
1107+ function test_reject() {
1108+ instance = PopupUtils.open(filePickerComp, null, { "fsModel": fsModel });
1109+ waitForRendering(instance);
1110+
1111+ spy.target = instance;
1112+ spy.signalName = "reject";
1113+
1114+ var btn = findChild(instance, "filePickerCancel");
1115+ mouseClick(btn, btn.width / 2, btn.height / 2);
1116+ spy.wait();
1117+ compare(spy.count, 1);
1118+ }
1119+ }
1120+}
1121
1122=== modified file 'tests/qmltests/mocks/CMakeLists.txt'
1123--- tests/qmltests/mocks/CMakeLists.txt 2016-12-22 14:35:38 +0000
1124+++ tests/qmltests/mocks/CMakeLists.txt 2017-01-25 13:04:17 +0000
1125@@ -30,3 +30,4 @@
1126
1127 add_subdirectory(Biometryd)
1128 add_subdirectory(GSettings.1.0)
1129+add_subdirectory(Qt)
1130
1131=== added directory 'tests/qmltests/mocks/Qt'
1132=== added file 'tests/qmltests/mocks/Qt/CMakeLists.txt'
1133--- tests/qmltests/mocks/Qt/CMakeLists.txt 1970-01-01 00:00:00 +0000
1134+++ tests/qmltests/mocks/Qt/CMakeLists.txt 2017-01-25 13:04:17 +0000
1135@@ -0,0 +1,1 @@
1136+add_subdirectory(labs)
1137
1138=== added directory 'tests/qmltests/mocks/Qt/labs'
1139=== added file 'tests/qmltests/mocks/Qt/labs/CMakeLists.txt'
1140--- tests/qmltests/mocks/Qt/labs/CMakeLists.txt 1970-01-01 00:00:00 +0000
1141+++ tests/qmltests/mocks/Qt/labs/CMakeLists.txt 2017-01-25 13:04:17 +0000
1142@@ -0,0 +1,1 @@
1143+add_subdirectory(folderlistmodel)
1144
1145=== added directory 'tests/qmltests/mocks/Qt/labs/folderlistmodel'
1146=== added file 'tests/qmltests/mocks/Qt/labs/folderlistmodel/CMakeLists.txt'
1147--- tests/qmltests/mocks/Qt/labs/folderlistmodel/CMakeLists.txt 1970-01-01 00:00:00 +0000
1148+++ tests/qmltests/mocks/Qt/labs/folderlistmodel/CMakeLists.txt 2017-01-25 13:04:17 +0000
1149@@ -0,0 +1,20 @@
1150+include_directories(
1151+ ${CMAKE_CURRENT_BINARY_DIR}
1152+ ${Qt5Core_INCLUDE_DIRS}
1153+ ${Qt5Quick_INCLUDE_DIRS}
1154+)
1155+
1156+set(Qtlabs_folderlistmodel_SRCS
1157+ MockFolderListModel.cpp
1158+ plugin.cpp
1159+)
1160+
1161+add_library(QtLabsFolderListModelQml MODULE ${Qtlabs_folderlistmodel_SRCS})
1162+target_link_libraries(QtLabsFolderListModelQml
1163+ ${Qt5Core_LIBRARIES}
1164+ ${Qt5Quick_LIBRARIES}
1165+)
1166+
1167+qt5_use_modules(QtLabsFolderListModelQml Qml)
1168+
1169+add_usc_mock(Qt.labs.folderlistmodel 2.1 Qt.labs.folderlistmodel TARGETS QtLabsFolderListModelQml)
1170
1171=== added file 'tests/qmltests/mocks/Qt/labs/folderlistmodel/MockFolderListModel.cpp'
1172--- tests/qmltests/mocks/Qt/labs/folderlistmodel/MockFolderListModel.cpp 1970-01-01 00:00:00 +0000
1173+++ tests/qmltests/mocks/Qt/labs/folderlistmodel/MockFolderListModel.cpp 2017-01-25 13:04:17 +0000
1174@@ -0,0 +1,241 @@
1175+/*
1176+ * Copyright (C) 2016 Canonical, Ltd.
1177+ *
1178+ * This program is free software; you can redistribute it and/or modify
1179+ * it under the terms of the GNU General Public License as published by
1180+ * the Free Software Foundation; version 3.
1181+ *
1182+ * This program is distributed in the hope that it will be useful,
1183+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1184+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1185+ * GNU General Public License for more details.
1186+ *
1187+ * You should have received a copy of the GNU General Public License
1188+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1189+ */
1190+
1191+#include "MockFolderListModel.h"
1192+
1193+#include <QDateTime>
1194+
1195+MockFolderListModel::MockFolderListModel(QObject *parent)
1196+ : QAbstractListModel(parent)
1197+ , m_files()
1198+{
1199+}
1200+
1201+QUrl MockFolderListModel::folder() const { return m_folder; }
1202+bool MockFolderListModel::caseSensitive() const { return m_caseSensitive; }
1203+int MockFolderListModel::count() const { return m_count; }
1204+QStringList MockFolderListModel::nameFilters() const { return m_nameFilters; }
1205+QUrl MockFolderListModel::parentFolder() const { return m_parentFolder; }
1206+QUrl MockFolderListModel::rootFolder() const { return m_rootFolder; }
1207+bool MockFolderListModel::showDirs() const { return m_showDirs; }
1208+bool MockFolderListModel::showDirsFirst() const { return m_showDirsFirst; }
1209+bool MockFolderListModel::showDotAndDotDot() const { return m_showDotAndDotDot; }
1210+bool MockFolderListModel::showFiles() const { return m_showFiles; }
1211+bool MockFolderListModel::showHidden() const { return m_showHidden; }
1212+bool MockFolderListModel::showOnlyReadable() const { return m_showOnlyReadable; }
1213+MockFolderListModel::Sort MockFolderListModel::sortField() const { return m_sortField; }
1214+bool MockFolderListModel::sortReversed() const { return m_sortReversed; }
1215+
1216+void MockFolderListModel::setCaseSensitive(const bool caseSensitive)
1217+{
1218+ if (caseSensitive != m_caseSensitive) {
1219+ m_caseSensitive = caseSensitive;
1220+ Q_EMIT caseSensitiveChanged();
1221+ }
1222+}
1223+
1224+void MockFolderListModel::setCount(const int &count)
1225+{
1226+ if (count != m_count) {
1227+ m_count = count;
1228+ Q_EMIT countChanged();
1229+ }
1230+}
1231+
1232+void MockFolderListModel::setFolder(const QUrl &folder)
1233+{
1234+ if (folder != m_folder) {
1235+ m_folder = folder;
1236+ Q_EMIT folderChanged();
1237+ }
1238+}
1239+
1240+void MockFolderListModel::setNameFilters(const QStringList &nameFilters)
1241+{
1242+ if (nameFilters != m_nameFilters) {
1243+ m_nameFilters = nameFilters;
1244+ Q_EMIT nameFiltersChanged();
1245+ }
1246+}
1247+
1248+void MockFolderListModel::setParentFolder(const QUrl &parentFolder)
1249+{
1250+ if (parentFolder != m_parentFolder) {
1251+ m_parentFolder = parentFolder;
1252+ Q_EMIT parentFolderChanged();
1253+ }
1254+}
1255+
1256+void MockFolderListModel::setRootFolder(const QUrl &rootFolder)
1257+{
1258+ if (rootFolder != m_rootFolder) {
1259+ m_rootFolder = rootFolder;
1260+ Q_EMIT rootFolderChanged();
1261+ }
1262+}
1263+
1264+void MockFolderListModel::setShowDirs(const bool showDirs)
1265+{
1266+ if (showDirs != m_showDirs) {
1267+ m_showDirs = showDirs;
1268+ Q_EMIT showDirsChanged();
1269+ }
1270+}
1271+
1272+void MockFolderListModel::setShowDirsFirst(const bool showDirsFirst)
1273+{
1274+ if (showDirsFirst != m_showDirsFirst) {
1275+ m_showDirsFirst = showDirsFirst;
1276+ Q_EMIT showDirsFirstChanged();
1277+ }
1278+}
1279+
1280+void MockFolderListModel::setShowDotAndDotDot(const bool showDotAndDotDot)
1281+{
1282+ if (showDotAndDotDot != m_showDotAndDotDot) {
1283+ m_showDotAndDotDot = showDotAndDotDot;
1284+ Q_EMIT showDotAndDotDotChanged();
1285+ }
1286+}
1287+
1288+void MockFolderListModel::setShowFiles(const bool showFiles)
1289+{
1290+ if (showFiles != m_showFiles) {
1291+ m_showFiles = showFiles;
1292+ Q_EMIT showFilesChanged();
1293+ }
1294+}
1295+
1296+void MockFolderListModel::setShowHidden(const bool showHidden)
1297+{
1298+ if (showHidden != m_showHidden) {
1299+ m_showHidden = showHidden;
1300+ Q_EMIT showHiddenChanged();
1301+ }
1302+}
1303+
1304+void MockFolderListModel::setShowOnlyReadable(const bool showOnlyReadable)
1305+{
1306+ if (showOnlyReadable != m_showOnlyReadable) {
1307+ m_showOnlyReadable = showOnlyReadable;
1308+ Q_EMIT showOnlyReadableChanged();
1309+ }
1310+}
1311+
1312+void MockFolderListModel::setSortField(const Sort &sortField)
1313+{
1314+ if (sortField != m_sortField) {
1315+ m_sortField = sortField;
1316+ Q_EMIT sortFieldChanged();
1317+ }
1318+}
1319+
1320+void MockFolderListModel::setSortReversed(const bool sortReversed)
1321+{
1322+ if (sortReversed != m_sortReversed) {
1323+ m_sortReversed = sortReversed;
1324+ Q_EMIT sortReversedChanged();
1325+ }
1326+}
1327+
1328+QHash<int, QByteArray> MockFolderListModel::roleNames() const
1329+{
1330+ QHash<int, QByteArray> names;
1331+
1332+ names[Roles::FileNameRole] = "fileName";
1333+ names[Roles::FilePathRole] = "filePath";
1334+ names[Roles::FileURLRole] = "fileURL";
1335+ names[Roles::FileBaseNameRole] = "fileBaseName";
1336+ names[Roles::FileSuffixRole] = "fileSuffix";
1337+ names[Roles::FileSizeRole] = "fileSize";
1338+ names[Roles::FileModifiedRole] = "fileModified";
1339+ names[Roles::FileAccessedRole] = "fileAccessed";
1340+ names[Roles::FileIsDirRole] = "fileIsDir";
1341+
1342+ return names;
1343+}
1344+
1345+
1346+int MockFolderListModel::rowCount(const QModelIndex&) const
1347+{
1348+ return m_files.count();
1349+}
1350+
1351+QVariant MockFolderListModel::data(const QModelIndex &index, int role) const
1352+{
1353+ QVariant rv;
1354+
1355+ if (index.row() >= m_files.size())
1356+ return rv;
1357+
1358+ switch (role)
1359+ {
1360+ case Roles::FileNameRole:
1361+ rv = m_files.at(index.row()).fileName;
1362+ break;
1363+ case Roles::FilePathRole:
1364+ rv = m_files.at(index.row()).filePath;
1365+ break;
1366+ case Roles::FileBaseNameRole:
1367+ rv = m_files.at(index.row()).baseName;
1368+ break;
1369+ case Roles::FileSuffixRole:
1370+ rv = m_files.at(index.row()).suffix;
1371+ break;
1372+ case Roles::FileSizeRole:
1373+ rv = m_files.at(index.row()).size;
1374+ break;
1375+ case Roles::FileModifiedRole:
1376+ rv = QDateTime();
1377+ break;
1378+ case Roles::FileAccessedRole:
1379+ rv = QDateTime();
1380+ break;
1381+ case Roles::FileIsDirRole:
1382+ rv = m_files.at(index.row()).isDir;
1383+ break;
1384+ case Roles::FileURLRole:
1385+ rv = QUrl::fromLocalFile(m_files.at(index.row()).filePath);
1386+ break;
1387+ default:
1388+ break;
1389+ }
1390+ return rv;
1391+}
1392+
1393+QModelIndex MockFolderListModel::index(int row, int column, const QModelIndex&) const
1394+{
1395+ return createIndex(row, column);
1396+}
1397+
1398+void MockFolderListModel::mockAddFile(const QString &fileName,
1399+ const QString &filePath,
1400+ const QString &baseName,
1401+ const qint64 &size,
1402+ const QString &suffix,
1403+ const bool isDir,
1404+ const bool isFile)
1405+{
1406+ MockFile m;
1407+ m.fileName = fileName;
1408+ m.filePath = filePath;
1409+ m.baseName = baseName;
1410+ m.size = size;
1411+ m.suffix = suffix;
1412+ m.isDir = isDir;
1413+ m.isFile = isFile;
1414+ m_files.append(m);
1415+}
1416
1417=== added file 'tests/qmltests/mocks/Qt/labs/folderlistmodel/MockFolderListModel.h'
1418--- tests/qmltests/mocks/Qt/labs/folderlistmodel/MockFolderListModel.h 1970-01-01 00:00:00 +0000
1419+++ tests/qmltests/mocks/Qt/labs/folderlistmodel/MockFolderListModel.h 2017-01-25 13:04:17 +0000
1420@@ -0,0 +1,171 @@
1421+/*
1422+ * Copyright (C) 2016 Canonical, Ltd.
1423+ *
1424+ * This program is free software; you can redistribute it and/or modify
1425+ * it under the terms of the GNU General Public License as published by
1426+ * the Free Software Foundation; version 3.
1427+ *
1428+ * This program is distributed in the hope that it will be useful,
1429+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1430+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1431+ * GNU General Public License for more details.
1432+ *
1433+ * You should have received a copy of the GNU General Public License
1434+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1435+ */
1436+
1437+#ifndef MOCK_FOLDERLISTMODEL_H
1438+#define MOCK_FOLDERLISTMODEL_H
1439+
1440+#include <QAbstractListModel>
1441+#include <QObject>
1442+#include <QString>
1443+#include <QUrl>
1444+#include <QStringList>
1445+
1446+struct MockFile {
1447+ QString fileName;
1448+ QString filePath;
1449+ QString baseName;
1450+ qint64 size;
1451+ QString suffix;
1452+ bool isDir;
1453+ bool isFile;
1454+};
1455+
1456+class MockFolderListModel : public QAbstractListModel
1457+{
1458+ Q_OBJECT
1459+ Q_ENUMS(Sort)
1460+ Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged)
1461+ Q_PROPERTY(bool caseSensitive READ caseSensitive
1462+ WRITE setCaseSensitive NOTIFY caseSensitiveChanged)
1463+ Q_PROPERTY(int count READ count
1464+ WRITE setCount NOTIFY countChanged)
1465+ Q_PROPERTY(QStringList nameFilters READ nameFilters
1466+ WRITE setNameFilters NOTIFY nameFiltersChanged)
1467+ Q_PROPERTY(QUrl parentFolder READ parentFolder
1468+ WRITE setParentFolder NOTIFY parentFolderChanged)
1469+ Q_PROPERTY(QUrl rootFolder READ rootFolder
1470+ WRITE setRootFolder NOTIFY rootFolderChanged)
1471+ Q_PROPERTY(bool showDirs READ showDirs
1472+ WRITE setShowDirs NOTIFY showDirsChanged)
1473+ Q_PROPERTY(bool showDirsFirst READ showDirsFirst
1474+ WRITE setShowDirsFirst NOTIFY showDirsFirstChanged)
1475+ Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot
1476+ WRITE setShowDotAndDotDot NOTIFY showDotAndDotDotChanged)
1477+ Q_PROPERTY(bool showFiles READ showFiles
1478+ WRITE setShowFiles NOTIFY showFilesChanged)
1479+ Q_PROPERTY(bool showHidden READ showHidden
1480+ WRITE setShowHidden NOTIFY showHiddenChanged)
1481+ Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable
1482+ WRITE setShowOnlyReadable NOTIFY showOnlyReadableChanged)
1483+ Q_PROPERTY(Sort sortField READ sortField
1484+ WRITE setSortField NOTIFY sortFieldChanged)
1485+ Q_PROPERTY(bool sortReversed READ sortReversed
1486+ WRITE setSortReversed NOTIFY sortReversedChanged)
1487+
1488+public:
1489+ explicit MockFolderListModel(QObject *parent = 0);
1490+
1491+ enum Roles {
1492+ FileNameRole = Qt::DisplayRole + 1,
1493+ FilePathRole,
1494+ FileURLRole,
1495+ FileBaseNameRole,
1496+ FileSuffixRole,
1497+ FileSizeRole,
1498+ FileModifiedRole,
1499+ FileAccessedRole,
1500+ FileIsDirRole
1501+ };
1502+
1503+ enum class Sort : uint
1504+ {
1505+ Unsorted = 0,
1506+ Name,
1507+ Time,
1508+ Size,
1509+ Type
1510+ };
1511+
1512+ QUrl folder() const;
1513+ bool caseSensitive() const;
1514+ int count() const;
1515+ QStringList nameFilters() const;
1516+ QUrl parentFolder() const;
1517+ QUrl rootFolder() const;
1518+ bool showDirs() const;
1519+ bool showDirsFirst() const;
1520+ bool showDotAndDotDot() const;
1521+ bool showFiles() const;
1522+ bool showHidden() const;
1523+ bool showOnlyReadable() const;
1524+ Sort sortField() const;
1525+ bool sortReversed() const;
1526+
1527+ void setCaseSensitive(const QUrl &folder);
1528+ void setCaseSensitive(const bool caseSensitive);
1529+ void setCount(const int &count);
1530+ void setFolder(const QUrl &folder);
1531+ void setNameFilters(const QStringList &nameFilters);
1532+ void setParentFolder(const QUrl &parentFolder);
1533+ void setRootFolder(const QUrl &rootFolder);
1534+ void setShowDirs(const bool showDirs);
1535+ void setShowDirsFirst(const bool showDirsFirst);
1536+ void setShowDotAndDotDot(const bool showDotAndDotDot);
1537+ void setShowFiles(const bool showFiles);
1538+ void setShowHidden(const bool showHidden);
1539+ void setShowOnlyReadable(const bool showOnlyReadable);
1540+ void setSortField(const Sort &sortField);
1541+ void setSortReversed(const bool sortReversed);
1542+
1543+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
1544+ QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
1545+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
1546+ QHash<int, QByteArray> roleNames() const override;
1547+
1548+ Q_INVOKABLE void mockAddFile(const QString &fileName,
1549+ const QString &filePath,
1550+ const QString &baseName,
1551+ const qint64 &size,
1552+ const QString &suffix,
1553+ const bool isDir,
1554+ const bool isFile);
1555+
1556+Q_SIGNALS:
1557+ void caseSensitiveChanged();
1558+ void countChanged();
1559+ void folderChanged();
1560+ void nameFiltersChanged();
1561+ void parentFolderChanged();
1562+ void rootFolderChanged();
1563+ void showDirsChanged();
1564+ void showDirsFirstChanged();
1565+ void showDotAndDotDotChanged();
1566+ void showFilesChanged();
1567+ void showHiddenChanged();
1568+ void showOnlyReadableChanged();
1569+ void sortFieldChanged();
1570+ void sortReversedChanged();
1571+
1572+private:
1573+ QUrl m_folder = QUrl();
1574+ bool m_caseSensitive = false;
1575+ int m_count = false;
1576+ QStringList m_nameFilters = QStringList();
1577+ QUrl m_parentFolder = QUrl();
1578+ QUrl m_rootFolder = QUrl();
1579+ bool m_showDirs = false;
1580+ bool m_showDirsFirst = false;
1581+ bool m_showDotAndDotDot = false;
1582+ bool m_showFiles = false;
1583+ bool m_showHidden = false;
1584+ bool m_showOnlyReadable = false;
1585+ Sort m_sortField = Sort::Unsorted;
1586+ bool m_sortReversed = false;
1587+
1588+ QList<MockFile> m_files;
1589+};
1590+
1591+#endif // MOCK_FOLDERLISTMODEL_H
1592
1593=== added file 'tests/qmltests/mocks/Qt/labs/folderlistmodel/plugin.cpp'
1594--- tests/qmltests/mocks/Qt/labs/folderlistmodel/plugin.cpp 1970-01-01 00:00:00 +0000
1595+++ tests/qmltests/mocks/Qt/labs/folderlistmodel/plugin.cpp 2017-01-25 13:04:17 +0000
1596@@ -0,0 +1,26 @@
1597+/*
1598+ * Copyright (C) 2016 Canonical, Ltd.
1599+ *
1600+ * This program is free software; you can redistribute it and/or modify
1601+ * it under the terms of the GNU General Public License as published by
1602+ * the Free Software Foundation; version 3.
1603+ *
1604+ * This program is distributed in the hope that it will be useful,
1605+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1606+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1607+ * GNU General Public License for more details.
1608+ *
1609+ * You should have received a copy of the GNU General Public License
1610+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1611+ */
1612+
1613+#include "plugin.h"
1614+#include "MockFolderListModel.h"
1615+
1616+#include <QtQml/qqml.h>
1617+
1618+void MockQtLabsFolderListModelPlugin::registerTypes(const char *uri)
1619+{
1620+ Q_ASSERT(uri == QLatin1String("Qt.labs.folderlistmodel"));
1621+ qmlRegisterType<MockFolderListModel>(uri, 2, 1, "FolderListModel");
1622+}
1623
1624=== added file 'tests/qmltests/mocks/Qt/labs/folderlistmodel/plugin.h'
1625--- tests/qmltests/mocks/Qt/labs/folderlistmodel/plugin.h 1970-01-01 00:00:00 +0000
1626+++ tests/qmltests/mocks/Qt/labs/folderlistmodel/plugin.h 2017-01-25 13:04:17 +0000
1627@@ -0,0 +1,31 @@
1628+/*
1629+ * Copyright (C) 2016 Canonical, Ltd.
1630+ *
1631+ * This program is free software; you can redistribute it and/or modify
1632+ * it under the terms of the GNU General Public License as published by
1633+ * the Free Software Foundation; version 3.
1634+ *
1635+ * This program is distributed in the hope that it will be useful,
1636+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1637+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1638+ * GNU General Public License for more details.
1639+ *
1640+ * You should have received a copy of the GNU General Public License
1641+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1642+ */
1643+
1644+#ifndef QTLABS_FOLDERLISTMODEL_PLUGIN_H
1645+#define QTLABS_FOLDERLISTMODEL_PLUGIN_H
1646+
1647+#include <QtQml/QQmlExtensionPlugin>
1648+
1649+class MockQtLabsFolderListModelPlugin : public QQmlExtensionPlugin
1650+{
1651+ Q_OBJECT
1652+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
1653+
1654+public:
1655+ void registerTypes(const char *uri) override;
1656+};
1657+
1658+#endif // QTLABS_FOLDERLISTMODEL_PLUGIN_H
1659
1660=== added file 'tests/qmltests/mocks/Qt/labs/folderlistmodel/qmldir'
1661--- tests/qmltests/mocks/Qt/labs/folderlistmodel/qmldir 1970-01-01 00:00:00 +0000
1662+++ tests/qmltests/mocks/Qt/labs/folderlistmodel/qmldir 2017-01-25 13:04:17 +0000
1663@@ -0,0 +1,2 @@
1664+module Qt.labs.folderlistmodel
1665+plugin QtLabsFolderListModelQml

Subscribers

People subscribed via source and target branches

to all changes: