Merge lp:~dpm/ubuntu-filemanager-app/placesmodel-2 into lp:ubuntu-filemanager-app

Proposed by David Planella
Status: Merged
Approved by: David Planella
Approved revision: 216
Merged at revision: 213
Proposed branch: lp:~dpm/ubuntu-filemanager-app/placesmodel-2
Merge into: lp:ubuntu-filemanager-app
Diff against target: 1213 lines (+558/-263)
22 files modified
debian/control (+12/-1)
debian/qtdeclarative5-placesmodel0.1.install (+1/-0)
src/app/qml/components/FolderIconDelegate.qml (+1/-1)
src/app/qml/components/FolderListDelegate.qml (+1/-1)
src/app/qml/components/PathBar.qml (+2/-1)
src/app/qml/components/PlacesSidebar.qml (+15/-37)
src/app/qml/filemanager.qml (+7/-2)
src/app/qml/ui/FileDetailsPopover.qml (+2/-2)
src/app/qml/ui/FolderListPage.qml (+148/-165)
src/app/qml/ui/GoToDialog.qml (+1/-1)
src/app/qml/ui/PlacesPopover.qml (+5/-38)
src/app/qml/ui/ViewPopover.qml (+2/-2)
src/plugin/CMakeLists.txt (+1/-0)
src/plugin/placesmodel/CMakeLists.txt (+35/-0)
src/plugin/placesmodel/placesmodel.cpp (+174/-0)
src/plugin/placesmodel/placesmodel.h (+64/-0)
src/plugin/placesmodel/placesmodel_plugin.cpp (+34/-0)
src/plugin/placesmodel/placesmodel_plugin.h (+39/-0)
src/plugin/placesmodel/qmldir (+2/-0)
tests/autopilot/filemanager/tests/__init__.py (+6/-6)
tests/autopilot/filemanager/tests/test_filemanager.py (+5/-5)
tests/autopilot/filemanager/tests/test_places.py (+1/-1)
To merge this branch: bzr merge lp:~dpm/ubuntu-filemanager-app/placesmodel-2
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Michael Spencer Approve
Review via email: mp+224037@code.launchpad.net

Commit message

Add places model plugin

Description of the change

This is the re-submission of https://code.launchpad.net/~dpm/ubuntu-filemanager-app/placesmodel/+merge/223548

To cut a long story short: the branch was prematurely merged, and then it was accidentally reverted to fix an unrelated test failure. I'm resubmitting it again now, with the same changes plus the fix for bug 1331702. I've decided to address bug 1331699 as a separate branch [1] in order to minimize the changes on this branch.

In a nutshell, add a plugin to return:

a) User directories from the XDG spec
b) A model to retrieve and store user places

[1]: https://code.launchpad.net/~dpm/ubuntu-filemanager-app/readable-root-fix-1331699/+merge/224046

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Spencer (ibelieve) wrote :

Looks good on my end! Did you want balloons to review this too, or should I top-approve?

review: Approve
Revision history for this message
David Planella (dpm) wrote :

Awesome, thanks Michael for the review! As a File Manager developer, and given the fact it's passed both human and automated QA review, please feel free to top-approve. I'll take care of giving Nick a heads up too.

Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

I see it, and I'm happy.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
David Planella (dpm) wrote :

Hm, pep8 failures in the tests? Why are these triggered now and not before, has anything changed in the Jenkins jobs config since it last approved the branch?

Revision history for this message
David Planella (dpm) wrote :

Ah, here's what happened: https://launchpad.net/ubuntu/utopic/+source/pep8/+changelog

So 2 days ago pep8 1.5.6 was uploaded in utopic. This version, unlike the previous 1.4.6 version (which is the one that also trusty has) is more strict regarding E265, which is the error it's complaining about.

216. By David Planella

Make pep8 v1.5.6 happy

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
David Planella (dpm) wrote :

Top-approving as per previous reviews and top-approval.

Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

Yes, fm is not the only project to suffer from pep8 changes :-)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2014-06-19 15:58:49 +0000
3+++ debian/control 2014-06-26 06:20:10 +0000
4@@ -38,9 +38,19 @@
5 Qt is a cross-platform C++ application framework. Qt's primary feature
6 is its rich set of widgets that provide standard GUI functionality.
7 .
8- This package contains the Folder List model plugin of the Nemo QML
9+ This package contains the Folder List model plugin of the Nemo QML
10 plugins collection.
11
12+Package: qtdeclarative5-placesmodel0.1
13+Architecture: any
14+Multi-Arch: same
15+Depends: ${misc:Depends},
16+ ${shlibs:Depends},
17+ ${misc:Pre-Depends},
18+Description: Places model QML plugin
19+ This package contains a plugin that enables QML apps to list and
20+ modify a set of places (bookmarks) in the file system.
21+
22 Package: ubuntu-filemanager-app-autopilot
23 Architecture: all
24 Depends: ${misc:Depends},
25@@ -49,5 +59,6 @@
26 ubuntu-filemanager-app (>= ${source:Version}),
27 ubuntu-ui-toolkit-autopilot,
28 python3-autopilot,
29+ python3-fixtures,
30 Description: Autopilot tests for File Manager Application
31 This package contains the autopilot tests for the File Manager
32
33=== added file 'debian/qtdeclarative5-placesmodel0.1.install'
34--- debian/qtdeclarative5-placesmodel0.1.install 1970-01-01 00:00:00 +0000
35+++ debian/qtdeclarative5-placesmodel0.1.install 2014-06-26 06:20:10 +0000
36@@ -0,0 +1,1 @@
37+usr/lib/*/qt5/qml/com/ubuntu/PlacesModel/
38
39=== modified file 'src/app/qml/components/FolderIconDelegate.qml'
40--- src/app/qml/components/FolderIconDelegate.qml 2014-03-29 09:20:11 +0000
41+++ src/app/qml/components/FolderIconDelegate.qml 2014-06-26 06:20:10 +0000
42@@ -47,7 +47,7 @@
43 objectName: "folder" + index
44
45 property string fileName: model.fileName
46- property string filePath: fileView.path + '/' + fileName
47+ property string filePath: fileView.folder + '/' + fileName
48
49 property string text: fileName
50 property string subText: Qt.formatDateTime(model.modifiedDate, Qt.DefaultLocaleShortDate) + (!model.isDir ? ", " + fileSize : "")
51
52=== modified file 'src/app/qml/components/FolderListDelegate.qml'
53--- src/app/qml/components/FolderListDelegate.qml 2014-03-29 09:20:11 +0000
54+++ src/app/qml/components/FolderListDelegate.qml 2014-06-26 06:20:10 +0000
55@@ -29,7 +29,7 @@
56 text: model.fileName
57 subText: Qt.formatDateTime(model.modifiedDate, Qt.DefaultLocaleShortDate) + (!model.isDir ? ", " + fileSize : "")
58
59- property string path: fileView.path + '/' + model.fileName
60+ property string path: fileView.folder + '/' + model.fileName
61 iconSource: fileIcon(path, model.isDir)
62
63 progression: model.isDir
64
65=== modified file 'src/app/qml/components/PathBar.qml'
66--- src/app/qml/components/PathBar.qml 2014-06-19 15:58:49 +0000
67+++ src/app/qml/components/PathBar.qml 2014-06-26 06:20:10 +0000
68@@ -87,6 +87,7 @@
69
70 Repeater {
71 id: repeater
72+ // This refers to a parent FolderListPage.folder
73 model: folder === "/" ? [""] : folder.split("/")
74 delegate: Rectangle {
75 MouseArea {
76@@ -117,7 +118,7 @@
77 Label {
78 id: label
79 anchors.centerIn: parent
80- text: modelData === "" ? "/" : modelData === "~" ? i18n.tr("Home") : modelData
81+ text: modelData === "" ? "/" : modelData
82 color: UbuntuColors.coolGrey
83 }
84
85
86=== modified file 'src/app/qml/components/PlacesSidebar.qml'
87--- src/app/qml/components/PlacesSidebar.qml 2014-06-19 15:58:49 +0000
88+++ src/app/qml/components/PlacesSidebar.qml 2014-06-26 06:20:10 +0000
89@@ -20,6 +20,7 @@
90 import Ubuntu.Components 0.1
91 import Ubuntu.Components.ListItems 0.1
92 import Ubuntu.Components.Popups 0.1
93+import com.ubuntu.PlacesModel 0.1
94
95 Sidebar {
96 id: root
97@@ -42,40 +43,6 @@
98 UbuntuNumberAnimation {}
99 }
100
101- ListModel {
102- id: places
103-
104- ListElement {
105- objectName: "placeHome"
106- path: "~"
107- }
108-
109- ListElement {
110- path: "~/Documents"
111- }
112-
113- ListElement {
114- path: "~/Downloads"
115- }
116-
117- ListElement {
118- path: "~/Music"
119- }
120-
121- ListElement {
122- path: "~/Pictures"
123- }
124-
125- ListElement {
126- path: "~/Videos"
127- }
128-
129- ListElement {
130- objectName: "placeRoot"
131- path: "/"
132- }
133- }
134-
135 Column {
136 anchors {
137 left: parent.left
138@@ -87,15 +54,25 @@
139 text: i18n.tr("Places")
140 }
141
142+ PlacesModel {
143+ id: userplaces
144+
145+ // By default, the model only contains the
146+ // user directories. Add the file system location too
147+ Component.onCompleted: {
148+ addLocation("/");
149+ }
150+ }
151+
152 Repeater {
153 id: placesList
154 objectName: "placesList"
155
156- model: places
157+ model: userplaces
158
159 delegate: Standard {
160- objectName: model.objectName
161- text: folderName(path)
162+ objectName: "place" + folderDisplayName(path).replace(/ /g,'')
163+ text: folderDisplayName(path)
164
165 Image {
166 anchors {
167@@ -123,6 +100,7 @@
168 height: units.gu(5)
169 showDivider: !collapsed
170
171+ // This refers to a parent FolderListPage.folder
172 selected: folder === path
173 iconFrame: false
174 }
175
176=== modified file 'src/app/qml/filemanager.qml'
177--- src/app/qml/filemanager.qml 2014-06-19 15:58:49 +0000
178+++ src/app/qml/filemanager.qml 2014-06-26 06:20:10 +0000
179@@ -21,6 +21,7 @@
180 import Ubuntu.Components.Popups 0.1
181 import Ubuntu.Unity.Action 1.0 as UnityActions
182 import U1db 1.0 as U1db
183+import com.ubuntu.PlacesModel 0.1
184
185 import "ui"
186
187@@ -60,6 +61,10 @@
188 backgroundColor: "#797979"
189 footerColor: "#808080"
190
191+ PlacesModel {
192+ id: userplaces
193+ }
194+
195 // HUD Actions
196 Action {
197 id: settingsAction
198@@ -72,7 +77,7 @@
199
200 property var pageStack: pageStack
201
202- property var folderTabs: ["~"]
203+ property var folderTabs: [userplaces.locationHome]
204
205 function openTab(folder) {
206 var list = folderTabs
207@@ -100,7 +105,7 @@
208 page: FolderListPage {
209 objectName: "folderPage"
210
211- folder: "~"//modelData
212+ folder: userplaces.locationHome //modelData
213 }
214 }
215
216
217=== modified file 'src/app/qml/ui/FileDetailsPopover.qml'
218--- src/app/qml/ui/FileDetailsPopover.qml 2014-02-19 00:00:15 +0000
219+++ src/app/qml/ui/FileDetailsPopover.qml 2014-06-26 06:20:10 +0000
220@@ -23,7 +23,7 @@
221 id: root
222 property var model
223
224- property string path: model.path || (fileView.path + '/' + model.fileName)
225+ property string path: model.path || (fileView.folder + '/' + model.fileName)
226
227 contentHeight: contents.height + 2 * contents.anchors.margins
228
229@@ -77,7 +77,7 @@
230 Label {
231 anchors.verticalCenter: parent.verticalCenter
232
233- text: folderName(root.path)
234+ text: folderDisplayName(root.path)
235 color: Theme.palette.normal.overlayText
236 font.bold: true
237 }
238
239=== modified file 'src/app/qml/ui/FolderListPage.qml'
240--- src/app/qml/ui/FolderListPage.qml 2014-06-19 15:58:49 +0000
241+++ src/app/qml/ui/FolderListPage.qml 2014-06-26 06:20:10 +0000
242@@ -20,25 +20,27 @@
243 import Ubuntu.Components.Popups 0.1
244 import Ubuntu.Components.ListItems 0.1
245 import org.nemomobile.folderlistmodel 1.0
246+import com.ubuntu.PlacesModel 0.1
247 import "../components"
248
249 Page {
250 id: folderListPage
251-
252- title: folderName(folder)
253+ title: folderDisplayName(folder)
254+ flickable: !sidebar.expanded ?
255+ (folderListView.visible ? folderListView : folderIconView.flickable) : null
256
257 property variant fileView: folderListPage
258-
259 property bool showHiddenFiles: false
260-
261 property bool showingListView: folderListView.visible
262+ property string sortingMethod: "Name"
263+ property bool sortAscending: true
264+ property string folder
265+ property bool loading: pageModel.awaitingResults
266
267 onShowHiddenFilesChanged: {
268 pageModel.showHiddenFiles = folderListPage.showHiddenFiles
269 }
270
271- property string sortingMethod: "Name"
272-
273 onSortingMethodChanged: {
274 console.log("Sorting by: " + sortingMethod)
275 if (sortingMethod === "Name") {
276@@ -51,154 +53,39 @@
277 }
278 }
279
280- property bool sortAccending: true
281-
282- onSortAccendingChanged: {
283- console.log("Sorting accending: " + sortAccending)
284-
285- if (sortAccending) {
286+ onSortAscendingChanged: {
287+ console.log("Sorting ascending: " + sortAscending)
288+
289+ if (sortAscending) {
290 pageModel.sortOrder = FolderListModel.SortAscending
291 } else {
292 pageModel.sortOrder = FolderListModel.SortDescending
293 }
294 }
295
296- // This stores the location using ~ to represent home
297- property string folder
298- property string homeFolder: "~"
299-
300- // This replaces ~ with the actual home folder, since the
301- // plugin doesn't recognize the ~
302- property string path: folder.replace("~", pageModel.homePath())
303-
304- function goHome() {
305- goTo(folderListPage.homeFolder)
306- }
307-
308- function goTo(location) {
309- // Since the FolderListModel returns paths using the actual
310- // home folder, this replaces with ~ before actually going
311- // to the specified folder
312- while (location !== '/' && location.substring(location.lastIndexOf('/')+1) === "") {
313- location = location.substring(0, location.length - 1)
314- }
315-
316- folderListPage.folder = location.replace(pageModel.homePath(), "~")
317- refresh()
318- }
319-
320- function refresh() {
321- pageModel.refresh()
322- }
323-
324- function pathAccessedDate() {
325- console.log("calling method pageModel.curPathAccessedDate()")
326- return pageModel.curPathAccessedDate()
327- }
328-
329- function pathModifiedDate() {
330- console.log("calling method pageModel.curPathModifiedDate()")
331- return pageModel.curPathModifiedDate()
332- }
333-
334- function pathIsWritable() {
335- console.log("calling method pageModel.curPathIsWritable()")
336- return pageModel.curPathIsWritable()
337- }
338-
339- // FIXME: hard coded path for icon, assumes Ubuntu desktop icon available.
340- // Nemo mobile has icon provider. Have to figure out what's the proper way
341- // to get "system wide" icons in Ubuntu Touch, or if we have to use
342- // icons packaged into the application. Both folder and individual
343- // files will need an icon.
344- // TODO: Remove isDir parameter and use new model functions
345- function fileIcon(file, isDir) {
346- file = file.replace(pageModel.homePath(), "~")
347- var iconPath = isDir ? "/usr/share/icons/Humanity/places/48/folder.svg"
348- : "/usr/share/icons/Humanity/mimes/48/empty.svg"
349-
350- if (file === "~") {
351- iconPath = "../icons/folder-home.svg"
352- } else if (file === i18n.tr("~/Desktop")) {
353- iconPath = "/usr/share/icons/Humanity/places/48/user-desktop.svg"
354- } else if (file === i18n.tr("~/Documents")) {
355- iconPath = "/usr/share/icons/Humanity/places/48/folder-documents.svg"
356- } else if (file === i18n.tr("~/Downloads")) {
357- iconPath = "/usr/share/icons/Humanity/places/48/folder-downloads.svg"
358- } else if (file === i18n.tr("~/Music")) {
359- iconPath = "/usr/share/icons/Humanity/places/48/folder-music.svg"
360- } else if (file === i18n.tr("~/Pictures")) {
361- iconPath = "/usr/share/icons/Humanity/places/48/folder-pictures.svg"
362- } else if (file === i18n.tr("~/Public")) {
363- iconPath = "/usr/share/icons/Humanity/places/48/folder-publicshare.svg"
364- } else if (file === i18n.tr("~/Programs")) {
365- iconPath = "/usr/share/icons/Humanity/places/48/folder-system.svg"
366- } else if (file === i18n.tr("~/Templates")) {
367- iconPath = "/usr/share/icons/Humanity/places/48/folder-templates.svg"
368- } else if (file === i18n.tr("~/Videos")) {
369- iconPath = "/usr/share/icons/Humanity/places/48/folder-videos.svg"
370- } else if (file === "/") {
371- iconPath = "/usr/share/icons/Humanity/devices/48/drive-harddisk.svg"
372- }
373-
374- return Qt.resolvedUrl(iconPath)
375- }
376-
377- function folderName(folder) {
378- folder = folder.replace(pageModel.homePath(), "~")
379-
380- if (folder === folderListPage.homeFolder) {
381- return i18n.tr("Home")
382- } else if (folder === "/") {
383- return i18n.tr("File System")
384- } else {
385- return folder.substr(folder.lastIndexOf('/') + 1)
386- }
387- }
388-
389- function pathName(folder) {
390- if (folder === "/") {
391- return "/"
392- } else {
393- return folder.substr(folder.lastIndexOf('/') + 1)
394- }
395- }
396-
397- function pathExists(path) {
398- path = path.replace("~", pageModel.homePath())
399-
400- if (path === '/')
401- return true
402-
403- if(path.charAt(0) === '/') {
404- console.log("Directory: " + path.substring(0, path.lastIndexOf('/')+1))
405- repeaterModel.path = path.substring(0, path.lastIndexOf('/')+1)
406- console.log("Sub dir: " + path.substring(path.lastIndexOf('/')+1))
407- if (path.substring(path.lastIndexOf('/')+1) !== "" && !repeaterModel.cdIntoPath(path.substring(path.lastIndexOf('/')+1))) {
408- return false
409- } else {
410- return true
411- }
412- } else {
413- return false
414- }
415- }
416-
417- property bool loading: pageModel.awaitingResults
418+ onFlickableChanged: {
419+ if (flickable === null) {
420+ folderListView.topMargin = 0
421+ folderIconView.flickable.topMargin = 0
422+ } else {
423+ folderListView.topMargin = units.gu(9.5)
424+ folderIconView.flickable.topMargin = units.gu(9.5)
425+ }
426+ }
427+
428+
429+
430+ PlacesModel { id: userplaces }
431
432 FolderListModel {
433 id: pageModel
434-
435- path: folderListPage.path
436-
437+ path: folderListPage.folder
438 enableExternalFSWatcher: true
439
440 // Properties to emulate a model entry for use by FileDetailsPopover
441 property bool isDir: true
442 property string fileName: pathName(pageModel.path)
443- property string fileSize: (folderListView.count === 1
444- ? i18n.tr("1 file")
445- : i18n.tr("%1 files").arg(folderListView.count))
446+ property string fileSize: i18n.tr("%1 file", "%1 files", folderListView.count).arg(folderListView.count)
447 property bool isReadable: true
448 property bool isExecutable: true
449 }
450@@ -208,7 +95,7 @@
451 path: folderListPage.folder
452
453 onPathChanged: {
454- console.log("Path: " + repeaterModel.path)
455+ console.log("Path changed to: " + repeaterModel.path)
456 }
457 }
458
459@@ -270,11 +157,9 @@
460 // }
461
462 Action {
463- text: pageModel.clipboardUrlsCounter === 0
464- ? i18n.tr("Paste")
465- : pageModel.clipboardUrlsCounter === 1
466- ? i18n.tr("Paste %1 File").arg(pageModel.clipboardUrlsCounter)
467- : i18n.tr("Paste %1 Files").arg(pageModel.clipboardUrlsCounter)
468+ text: pageModel.clipboardUrlsCounter === 0 ?
469+ i18n.tr("Paste") :
470+ i18n.tr("Paste %1 File", "Paste %1 Files", pageModel.clipboardUrlsCounter).arg(pageModel.clipboardUrlsCounter)
471 onTriggered: {
472 console.log("Pasting to current folder items of count " + pageModel.clipboardUrlsCounter)
473 fileOperationDialog.startOperation(i18n.tr("Paste files"))
474@@ -349,12 +234,6 @@
475 }
476 }
477
478- function openFile(filePath) {
479- if (!pageModel.openPath(filePath)) {
480- error(i18n.tr("File operation error"), i18n.tr("Unable to open '%11").arg(filePath))
481- }
482- }
483-
484 tools: ToolbarItems {
485 id: toolbar
486 locked: showToolbar
487@@ -364,7 +243,7 @@
488
489 back: ToolbarButton {
490 objectName: "up"
491- text: "Up"
492+ text: i18n.tr("Up")
493 iconSource: getIcon("keyboard-caps")
494 enabled: folder != "/"
495 onTriggered: {
496@@ -451,18 +330,6 @@
497 }
498 }
499
500- flickable: !sidebar.expanded ? folderListView.visible ? folderListView : folderIconView.flickable : null
501-
502- onFlickableChanged: {
503- if (flickable === null) {
504- folderListView.topMargin = 0
505- folderIconView.flickable.topMargin = 0
506- } else {
507- folderListView.topMargin = units.gu(9.5)
508- folderIconView.flickable.topMargin = units.gu(9.5)
509- }
510- }
511-
512 PlacesSidebar {
513 id: sidebar
514 objectName: "placesSidebar"
515@@ -677,6 +544,122 @@
516 model: pageModel
517 }
518
519+ function goTo(location) {
520+ // This allows us to enter "~" as a shortcut to the home folder
521+ // when entering a location on the Go To dialog
522+ folderListPage.folder = location.replace("~", userplaces.locationHome)
523+ refresh()
524+ }
525+
526+ function refresh() {
527+ pageModel.refresh()
528+ }
529+
530+ function pathAccessedDate() {
531+ console.log("calling method pageModel.curPathAccessedDate()")
532+ return pageModel.curPathAccessedDate()
533+ }
534+
535+ function pathModifiedDate() {
536+ console.log("calling method pageModel.curPathModifiedDate()")
537+ return pageModel.curPathModifiedDate()
538+ }
539+
540+ function pathIsWritable() {
541+ console.log("calling method pageModel.curPathIsWritable()")
542+ return pageModel.curPathIsWritable()
543+ }
544+
545+ // FIXME: hard coded path for icon, assumes Ubuntu desktop icon available.
546+ // Nemo mobile has icon provider. Have to figure out what's the proper way
547+ // to get "system wide" icons in Ubuntu Touch, or if we have to use
548+ // icons packaged into the application. Both folder and individual
549+ // files will need an icon.
550+ // TODO: Remove isDir parameter and use new model functions
551+ function fileIcon(file, isDir) {
552+ var iconPath = isDir ? "/usr/share/icons/Humanity/places/48/folder.svg"
553+ : "/usr/share/icons/Humanity/mimes/48/empty.svg"
554+
555+ if (file === userplaces.locationHome) {
556+ iconPath = "../icons/folder-home.svg"
557+ } else if (file === i18n.tr("~/Desktop")) {
558+ iconPath = "/usr/share/icons/Humanity/places/48/user-desktop.svg"
559+ } else if (file === userplaces.locationDocuments) {
560+ iconPath = "/usr/share/icons/Humanity/places/48/folder-documents.svg"
561+ } else if (file === userplaces.locationDownloads) {
562+ iconPath = "/usr/share/icons/Humanity/places/48/folder-downloads.svg"
563+ } else if (file === userplaces.locationMusic) {
564+ iconPath = "/usr/share/icons/Humanity/places/48/folder-music.svg"
565+ } else if (file === userplaces.locationPictures) {
566+ iconPath = "/usr/share/icons/Humanity/places/48/folder-pictures.svg"
567+ } else if (file === i18n.tr("~/Public")) {
568+ iconPath = "/usr/share/icons/Humanity/places/48/folder-publicshare.svg"
569+ } else if (file === i18n.tr("~/Programs")) {
570+ iconPath = "/usr/share/icons/Humanity/places/48/folder-system.svg"
571+ } else if (file === i18n.tr("~/Templates")) {
572+ iconPath = "/usr/share/icons/Humanity/places/48/folder-templates.svg"
573+ } else if (file === userplaces.locationVideos) {
574+ iconPath = "/usr/share/icons/Humanity/places/48/folder-videos.svg"
575+ } else if (file === "/") {
576+ iconPath = "/usr/share/icons/Humanity/devices/48/drive-harddisk.svg"
577+ }
578+
579+ return Qt.resolvedUrl(iconPath)
580+ }
581+
582+ function folderDisplayName(folder) {
583+ if (folder === userplaces.locationHome) {
584+ return i18n.tr("Home")
585+ } else if (folder === "/") {
586+ return i18n.tr("File System")
587+ } else {
588+ return basename(folder)
589+ }
590+ }
591+
592+ function pathName(folder) {
593+ if (folder === "/") {
594+ return "/"
595+ } else {
596+ return basename(folder)
597+ }
598+ }
599+
600+ function basename(folder) {
601+ // Returns the latest component (folder) of an absolute path
602+ // E.g. basename('/home/phablet/Música') returns 'Música'
603+
604+ // Remove the last trailing '/' if there is one
605+ folder.replace(/\/$/, "")
606+ return folder.substr(folder.lastIndexOf('/') + 1)
607+ }
608+
609+ function pathExists(path) {
610+ path = path.replace("~", pageModel.homePath())
611+
612+ if (path === '/')
613+ return true
614+
615+ if(path.charAt(0) === '/') {
616+ console.log("Directory: " + path.substring(0, path.lastIndexOf('/')+1))
617+ repeaterModel.path = path.substring(0, path.lastIndexOf('/')+1)
618+ console.log("Sub dir: " + path.substring(path.lastIndexOf('/')+1))
619+ if (path.substring(path.lastIndexOf('/')+1) !== "" && !repeaterModel.cdIntoPath(path.substring(path.lastIndexOf('/')+1))) {
620+ return false
621+ } else {
622+ return true
623+ }
624+ } else {
625+ return false
626+ }
627+ }
628+
629+ function openFile(filePath) {
630+ if (!pageModel.openPath(filePath)) {
631+ error(i18n.tr("File operation error"), i18n.tr("Unable to open '%1'").arg(filePath))
632+ }
633+ }
634+
635 function itemClicked(model) {
636 if (model.isDir) {
637 if (model.isReadable && model.isExecutable) {
638
639=== modified file 'src/app/qml/ui/GoToDialog.qml'
640--- src/app/qml/ui/GoToDialog.qml 2014-02-19 00:00:15 +0000
641+++ src/app/qml/ui/GoToDialog.qml 2014-06-26 06:20:10 +0000
642@@ -39,7 +39,7 @@
643
644 property bool valid: pathExists(text)
645
646- text: fileView.path
647+ text: fileView.folder
648
649 placeholderText: i18n.tr("Location...")
650
651
652=== modified file 'src/app/qml/ui/PlacesPopover.qml'
653--- src/app/qml/ui/PlacesPopover.qml 2014-06-19 15:58:49 +0000
654+++ src/app/qml/ui/PlacesPopover.qml 2014-06-26 06:20:10 +0000
655@@ -19,45 +19,12 @@
656 import Ubuntu.Components 0.1
657 import Ubuntu.Components.Popups 0.1
658 import Ubuntu.Components.ListItems 0.1
659+import com.ubuntu.PlacesModel 0.1
660
661 Popover {
662 id: root
663 objectName: "placesPopover"
664
665- ListModel {
666- id: places
667-
668- ListElement {
669- objectName: 'placeHome'
670- path: "~"
671- }
672-
673- ListElement {
674- path: "~/Documents"
675- }
676-
677- ListElement {
678- path: "~/Downloads"
679- }
680-
681- ListElement {
682- path: "~/Music"
683- }
684-
685- ListElement {
686- path: "~/Pictures"
687- }
688-
689- ListElement {
690- path: "~/Videos"
691- }
692-
693- ListElement {
694- objectName: "placeRoot"
695- path: "/"
696- }
697- }
698-
699 Column {
700 anchors {
701 left: parent.left
702@@ -81,7 +48,7 @@
703
704 property bool valid: pathExists(text)
705
706- text: fileView.path
707+ text: fileView.folder
708
709 placeholderText: i18n.tr("Location...")
710
711@@ -113,17 +80,17 @@
712 id: placesList
713 objectName: "placesList"
714
715- model: places
716+ model: PlacesModel {}
717
718 delegate: Standard {
719 objectName: model.objectName
720- property string name: folderName(path)
721+ property string name: folderDisplayName(path)
722
723 Label {
724 anchors.left: parent.left
725 anchors.leftMargin: units.gu(8)
726 anchors.verticalCenter: parent.verticalCenter
727- text: folderName(path)
728+ text: folderDisplayName(path)
729 color: selected ? UbuntuColors.orange : Theme.palette.normal.overlayText
730 }
731
732
733=== modified file 'src/app/qml/ui/ViewPopover.qml'
734--- src/app/qml/ui/ViewPopover.qml 2014-02-19 00:00:15 +0000
735+++ src/app/qml/ui/ViewPopover.qml 2014-06-26 06:20:10 +0000
736@@ -109,14 +109,14 @@
737 anchors.topMargin: units.gu(1.7)
738 }
739
740- selectedIndex: sortAccending ? 0 : 1
741+ selectedIndex: sortAscending ? 0 : 1
742 values: [
743 i18n.tr("Ascending"),
744 i18n.tr("Descending")
745 ]
746
747 onSelectedIndexChanged: {
748- fileView.sortAccending = (values[selectedIndex] === i18n.tr("Ascending"))
749+ fileView.sortAscending = (values[selectedIndex] === i18n.tr("Ascending"))
750 }
751 }
752
753
754=== modified file 'src/plugin/CMakeLists.txt'
755--- src/plugin/CMakeLists.txt 2014-06-19 15:58:49 +0000
756+++ src/plugin/CMakeLists.txt 2014-06-26 06:20:10 +0000
757@@ -5,3 +5,4 @@
758 find_package(Qt5Widgets)
759
760 add_subdirectory(folderlistmodel)
761+add_subdirectory(placesmodel)
762
763=== added directory 'src/plugin/placesmodel'
764=== added file 'src/plugin/placesmodel/CMakeLists.txt'
765--- src/plugin/placesmodel/CMakeLists.txt 1970-01-01 00:00:00 +0000
766+++ src/plugin/placesmodel/CMakeLists.txt 2014-06-26 06:20:10 +0000
767@@ -0,0 +1,35 @@
768+include_directories(
769+ ${CMAKE_CURRENT_SOURCE_DIR}
770+)
771+
772+set(PLUGIN_DIR com/ubuntu/PlacesModel)
773+
774+set(placesmodel_SRCS
775+ placesmodel.cpp
776+ placesmodel.h
777+ placesmodel_plugin.cpp
778+ placesmodel_plugin.h
779+)
780+
781+add_library(PlacesModel MODULE
782+ ${placesmodel_SRCS}
783+)
784+
785+qt5_use_modules(PlacesModel Gui Qml Quick Widgets)
786+
787+# Copy the plugin, the qmldir file and other assets to the build dir for running in QtCreator
788+if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
789+ add_custom_command(TARGET PlacesModel POST_BUILD
790+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
791+ COMMENT "Creating plugin directory layout in the build directory"
792+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
793+ COMMENT "Copying the qmldir file to the build directory"
794+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:PlacesModel> ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
795+ COMMENT "Copying the plugin binary to the build directory"
796+ )
797+endif(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
798+
799+# Install plugin file
800+install(TARGETS PlacesModel DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
801+install(FILES qmldir DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
802+
803
804=== added file 'src/plugin/placesmodel/placesmodel.cpp'
805--- src/plugin/placesmodel/placesmodel.cpp 1970-01-01 00:00:00 +0000
806+++ src/plugin/placesmodel/placesmodel.cpp 2014-06-26 06:20:10 +0000
807@@ -0,0 +1,174 @@
808+/*
809+ * Copyright (C) 2013 Canonical Ltd
810+ *
811+ * This program is free software: you can redistribute it and/or modify
812+ * it under the terms of the GNU General Public License version 3 as
813+ * published by the Free Software Foundation.
814+ *
815+ * This program is distributed in the hope that it will be useful,
816+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
817+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
818+ * GNU General Public License for more details.
819+ *
820+ * You should have received a copy of the GNU General Public License
821+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
822+ *
823+ * Author : David Planella <david.planella@ubuntu.com>
824+ */
825+
826+#include "placesmodel.h"
827+#include <QDebug>
828+#include <QDir>
829+#include <QAbstractItemModel>
830+#include <QCoreApplication>
831+#include <QStandardPaths>
832+#include <QDebug>
833+
834+PlacesModel::PlacesModel(QAbstractListModel *parent) :
835+ QAbstractListModel(parent)
836+{
837+
838+ QStringList defaultLocations;
839+ // Set the storage location to a path that works well
840+ // with app isolation
841+ QString settingsLocation =
842+ QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first()
843+ + "/" + QCoreApplication::applicationName() + "/" + "places.conf";
844+ m_settings = new QSettings(settingsLocation, QSettings::IniFormat, this);
845+
846+ // Prepopulate the model with the user locations
847+ // for the first time it's used
848+ defaultLocations.append(locationHome());
849+ defaultLocations.append(locationDocuments());
850+ defaultLocations.append(locationDownloads());
851+ defaultLocations.append(locationMusic());
852+ defaultLocations.append(locationPictures());
853+ defaultLocations.append(locationVideos());
854+
855+ if (!m_settings->contains("storedLocations")) {
856+ m_locations.append(defaultLocations);
857+ } else {
858+ m_locations = m_settings->value("storedLocations").toStringList();
859+ }
860+
861+ foreach (const QString &location, m_locations) {
862+ qDebug() << "Location: " << location;
863+ }
864+
865+}
866+
867+PlacesModel::~PlacesModel() {
868+
869+}
870+
871+QString PlacesModel::standardLocation(QStandardPaths::StandardLocation location) const
872+{
873+ QStringList locations = QStandardPaths::standardLocations(location);
874+ QString standardLocation = "";
875+
876+ foreach (const QString &location, locations) {
877+ // We always return the first location or an empty string
878+ // The frontend should check out that it exists
879+ if (QDir(location).exists()) {
880+ standardLocation = location;
881+ break;
882+ }
883+ }
884+
885+ return standardLocation;
886+}
887+
888+QString PlacesModel::locationHome() const
889+{
890+ return standardLocation(QStandardPaths::HomeLocation);
891+}
892+
893+QString PlacesModel::locationDocuments() const
894+{
895+ return standardLocation(QStandardPaths::DocumentsLocation);
896+}
897+
898+QString PlacesModel::locationDownloads() const
899+{
900+ return standardLocation(QStandardPaths::DownloadLocation);
901+}
902+
903+QString PlacesModel::locationMusic() const
904+{
905+ return standardLocation(QStandardPaths::MusicLocation);
906+}
907+
908+QString PlacesModel::locationPictures() const
909+{
910+ return standardLocation(QStandardPaths::PicturesLocation);
911+}
912+
913+QString PlacesModel::locationVideos() const
914+{
915+ return standardLocation(QStandardPaths::MoviesLocation);
916+}
917+
918+int PlacesModel::rowCount(const QModelIndex &parent) const
919+{
920+ Q_UNUSED(parent)
921+
922+ return m_locations.count();
923+}
924+
925+QVariant PlacesModel::data(const QModelIndex &index, int role) const
926+{
927+ Q_UNUSED(role)
928+
929+ return m_locations.at(index.row());
930+}
931+
932+QHash<int, QByteArray> PlacesModel::roleNames() const
933+{
934+ QHash<int, QByteArray> roles;
935+ roles.insert(Qt::UserRole, "path");
936+
937+ return roles;
938+}
939+
940+void PlacesModel::removeItem(int indexToRemove)
941+{
942+
943+ // Tell Qt that we're going to be changing the model
944+ // There's no tree-parent, first new item will be at
945+ // indexToRemove, and the last one too
946+ beginRemoveRows(QModelIndex(), indexToRemove, indexToRemove);
947+
948+ // Remove the actual location
949+ m_locations.removeAt(indexToRemove);
950+
951+ // Tell Qt we're done with modifying the model so that
952+ // it can update the UI and everything else to reflect
953+ // the new state
954+ endRemoveRows();
955+
956+ // Remove the location permanently
957+ m_settings->setValue("storedLocations", m_locations);
958+}
959+
960+void PlacesModel::addLocation(const QString &location)
961+{
962+ // Do not allow for duplicates
963+ if (!m_locations.contains(location)) {
964+ // Tell Qt that we're going to be changing the model
965+ // There's no tree-parent, first new item will be at
966+ // m_locations.count(), and the last one too
967+ beginInsertRows(QModelIndex(), m_locations.count(), m_locations.count());
968+
969+ // Append the actual location
970+ m_locations.append(location);
971+
972+
973+ // Tell Qt we're done with modifying the model so that
974+ // it can update the UI and everything else to reflect
975+ // the new state
976+ endInsertRows();
977+
978+ // Store the location permanently
979+ m_settings->setValue("storedLocations", m_locations);
980+ }
981+}
982
983=== added file 'src/plugin/placesmodel/placesmodel.h'
984--- src/plugin/placesmodel/placesmodel.h 1970-01-01 00:00:00 +0000
985+++ src/plugin/placesmodel/placesmodel.h 2014-06-26 06:20:10 +0000
986@@ -0,0 +1,64 @@
987+/*
988+ * Copyright (C) 2013 Canonical Ltd
989+ *
990+ * This program is free software: you can redistribute it and/or modify
991+ * it under the terms of the GNU General Public License version 3 as
992+ * published by the Free Software Foundation.
993+ *
994+ * This program is distributed in the hope that it will be useful,
995+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
996+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
997+ * GNU General Public License for more details.
998+ *
999+ * You should have received a copy of the GNU General Public License
1000+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1001+ *
1002+ * Author : David Planella <david.planella@ubuntu.com>
1003+ */
1004+
1005+#ifndef PLACESMODEL_H
1006+#define PLACESMODEL_H
1007+
1008+#include <QObject>
1009+#include <QAbstractListModel>
1010+#include <QStandardPaths>
1011+#include <QSettings>
1012+
1013+class PlacesModel : public QAbstractListModel
1014+{
1015+ Q_OBJECT
1016+
1017+ Q_PROPERTY(QString locationHome READ locationHome CONSTANT)
1018+ Q_PROPERTY(QString locationDocuments READ locationDocuments CONSTANT)
1019+ Q_PROPERTY(QString locationDownloads READ locationDownloads CONSTANT)
1020+ Q_PROPERTY(QString locationMusic READ locationMusic CONSTANT)
1021+ Q_PROPERTY(QString locationPictures READ locationPictures CONSTANT)
1022+ Q_PROPERTY(QString locationVideos READ locationVideos CONSTANT)
1023+
1024+public:
1025+ explicit PlacesModel(QAbstractListModel *parent = 0);
1026+ ~PlacesModel();
1027+ QString locationHome() const;
1028+ QString locationDocuments() const;
1029+ QString locationDownloads() const;
1030+ QString locationMusic() const;
1031+ QString locationPictures() const;
1032+ QString locationVideos() const;
1033+ int rowCount(const QModelIndex &parent) const override;
1034+ QVariant data(const QModelIndex &index, int role) const override;
1035+ QHash<int, QByteArray> roleNames() const override;
1036+
1037+public slots:
1038+ void addLocation(const QString &location);
1039+ void removeItem(int indexToRemove);
1040+
1041+private:
1042+ QString standardLocation(QStandardPaths::StandardLocation location) const;
1043+ QStringList m_locations;
1044+ QSettings *m_settings;
1045+};
1046+
1047+#endif // PLACESMODEL_H
1048+
1049+
1050+
1051
1052=== added file 'src/plugin/placesmodel/placesmodel_plugin.cpp'
1053--- src/plugin/placesmodel/placesmodel_plugin.cpp 1970-01-01 00:00:00 +0000
1054+++ src/plugin/placesmodel/placesmodel_plugin.cpp 2014-06-26 06:20:10 +0000
1055@@ -0,0 +1,34 @@
1056+/*
1057+ * Copyright (C) 2013 Canonical Ltd
1058+ *
1059+ * This program is free software: you can redistribute it and/or modify
1060+ * it under the terms of the GNU General Public License version 3 as
1061+ * published by the Free Software Foundation.
1062+ *
1063+ * This program is distributed in the hope that it will be useful,
1064+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1065+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1066+ * GNU General Public License for more details.
1067+ *
1068+ * You should have received a copy of the GNU General Public License
1069+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1070+ *
1071+ * Author : David Planella <david.planella@ubuntu.com>
1072+ */
1073+
1074+#include <QtQml>
1075+#include <QtQml/QQmlContext>
1076+#include "placesmodel_plugin.h"
1077+#include "placesmodel.h"
1078+
1079+void BackendPlugin::registerTypes(const char *uri)
1080+{
1081+ Q_ASSERT(uri == QLatin1String(QUOTES(PLUGIN_URI)));
1082+
1083+ qmlRegisterType<PlacesModel>(uri, 0, 1, "PlacesModel");
1084+}
1085+
1086+void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
1087+{
1088+ QQmlExtensionPlugin::initializeEngine(engine, uri);
1089+}
1090
1091=== added file 'src/plugin/placesmodel/placesmodel_plugin.h'
1092--- src/plugin/placesmodel/placesmodel_plugin.h 1970-01-01 00:00:00 +0000
1093+++ src/plugin/placesmodel/placesmodel_plugin.h 2014-06-26 06:20:10 +0000
1094@@ -0,0 +1,39 @@
1095+/*
1096+ * Copyright (C) 2013 Canonical Ltd
1097+ *
1098+ * This program is free software: you can redistribute it and/or modify
1099+ * it under the terms of the GNU General Public License version 3 as
1100+ * published by the Free Software Foundation.
1101+ *
1102+ * This program is distributed in the hope that it will be useful,
1103+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1104+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1105+ * GNU General Public License for more details.
1106+ *
1107+ * You should have received a copy of the GNU General Public License
1108+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1109+ *
1110+ * Author : David Planella <david.planella@ubuntu.com>
1111+ */
1112+
1113+#ifndef PLACESMODEL_PLUGIN_H
1114+#define PLACESMODEL_PLUGIN_H
1115+
1116+#include <QtQml/QQmlEngine>
1117+#include <QtQml/QQmlExtensionPlugin>
1118+
1119+class BackendPlugin : public QQmlExtensionPlugin
1120+{
1121+ Q_OBJECT
1122+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
1123+
1124+public:
1125+ void registerTypes(const char *uri);
1126+ void initializeEngine(QQmlEngine *engine, const char *uri);
1127+};
1128+#endif // PLACESMODEL_PLUGIN_H
1129+
1130+
1131+
1132+
1133+
1134
1135=== added file 'src/plugin/placesmodel/qmldir'
1136--- src/plugin/placesmodel/qmldir 1970-01-01 00:00:00 +0000
1137+++ src/plugin/placesmodel/qmldir 2014-06-26 06:20:10 +0000
1138@@ -0,0 +1,2 @@
1139+module com.ubuntu.PlacesModel
1140+plugin PlacesModel
1141
1142=== modified file 'tests/autopilot/filemanager/tests/__init__.py'
1143--- tests/autopilot/filemanager/tests/__init__.py 2014-06-19 15:59:52 +0000
1144+++ tests/autopilot/filemanager/tests/__init__.py 2014-06-26 06:20:10 +0000
1145@@ -125,14 +125,14 @@
1146 self.useFixture(temp_dir_fixture)
1147 temp_dir = temp_dir_fixture.path
1148
1149- #If running under xvfb, as jenkins does,
1150- #xsession will fail to start without xauthority file
1151- #Thus if the Xauthority file is in the home directory
1152- #make sure we copy it to our temp home directory
1153+ # If running under xvfb, as jenkins does,
1154+ # xsession will fail to start without xauthority file
1155+ # Thus if the Xauthority file is in the home directory
1156+ # make sure we copy it to our temp home directory
1157 self._copy_xauthority_file(temp_dir)
1158
1159- #click requires using initctl env (upstart), but the desktop can set
1160- #an environment variable instead
1161+ # click requires using initctl env (upstart), but the desktop can set
1162+ # an environment variable instead
1163 if self.test_type == 'click':
1164 self.useFixture(toolkit_fixtures.InitctlEnvironmentVariable(
1165 HOME=temp_dir))
1166
1167=== modified file 'tests/autopilot/filemanager/tests/test_filemanager.py'
1168--- tests/autopilot/filemanager/tests/test_filemanager.py 2014-06-19 15:59:52 +0000
1169+++ tests/autopilot/filemanager/tests/test_filemanager.py 2014-06-26 06:20:10 +0000
1170@@ -50,9 +50,9 @@
1171 return folder_list_page.get_file_by_index(index)
1172
1173 def _go_to_location(self, location):
1174- #go to specified location
1175- #on wide UI display, we get the location dialog
1176- #on phone UI display, we get places popover
1177+ # go to specified location
1178+ # on wide UI display, we get the location dialog
1179+ # on phone UI display, we get places popover
1180 device = model()
1181 if self.main_view.showSidebar:
1182 logger.debug("Using goto to goto %s on %s" % (location, device))
1183@@ -70,7 +70,7 @@
1184 expected_path = item.filePath
1185 list_view = item.list_view
1186
1187- #item.open_directory()
1188+ # item.open_directory()
1189 self.pointing_device.click_object(item)
1190 self.assertThat(
1191 list_view.get_current_path, Eventually(Equals(expected_path)))
1192@@ -131,7 +131,7 @@
1193 original_apps = process_manager.get_running_applications()
1194
1195 dialog.open()
1196- #make sure the dialog is open
1197+ # make sure the dialog is open
1198 self.main_view.get_file_action_dialog()
1199 # Filtering copied from
1200 # AutopilotTestCase._compare_system_with_app_snapshot.
1201
1202=== modified file 'tests/autopilot/filemanager/tests/test_places.py'
1203--- tests/autopilot/filemanager/tests/test_places.py 2014-06-19 16:03:37 +0000
1204+++ tests/autopilot/filemanager/tests/test_places.py 2014-06-26 06:20:10 +0000
1205@@ -34,7 +34,7 @@
1206
1207 def test_go_to_root_must_open_the_root_directory(self):
1208 """Test that opens the File System bookmark from the places section."""
1209- self.main_view.go_to_place('placeRoot')
1210+ self.main_view.go_to_place('placeFileSystem')
1211
1212 folder_list_page = self.main_view.get_folder_list_page()
1213 self.assertThat(

Subscribers

People subscribed via source and target branches