← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

[Merge] lp:~verzegnassi-stefano/ubuntu-docviewer-app/document-page-filters into lp:ubuntu-docviewer-app

 

Stefano Verzegnassi has proposed merging lp:~verzegnassi-stefano/ubuntu-docviewer-app/document-page-filters into lp:ubuntu-docviewer-app.

Commit message:
Added a search mode for the DocumentPage and a list of sorting options.

Requested reviews:
  Ubuntu Document Viewer Developers (ubuntu-docviewer-dev)
Related bugs:
  Bug #1450837 in Ubuntu Document Viewer App: "[documentPage] Add new sort options and a search feature"
  https://bugs.launchpad.net/ubuntu-docviewer-app/+bug/1450837

For more details, see:
https://code.launchpad.net/~verzegnassi-stefano/ubuntu-docviewer-app/document-page-filters/+merge/261858

This MP adds a "search" mode for the DocumentPage and a list of sorting options.

The available options are:
- Sort by name
- Sort by date (default)
- Sort by size

The search filter is reset when docviewer receives a request for exporting a document via Content Hub.

A further empty state is shown when the search returns no result.

----------
I'm also interested in getting some opinion about the following questions:

1) Is it ok to use a Dialog to provide these settings?
2) I reused an earlier "settings" icon from the Suru icon theme, since there's no icon for "sort". Is there anything better out there that we can use?
3) Is my English good? :-P Please check for any error in the dialog or in the empty state.
-- 
Your team Ubuntu Document Viewer Developers is requested to review the proposed merge of lp:~verzegnassi-stefano/ubuntu-docviewer-app/document-page-filters into lp:ubuntu-docviewer-app.
=== modified file 'po/com.ubuntu.docviewer.pot'
--- po/com.ubuntu.docviewer.pot	2015-05-19 12:06:27 +0000
+++ po/com.ubuntu.docviewer.pot	2015-06-12 14:48:32 +0000
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-05-19 14:05+0200\n"
+"POT-Creation-Date: 2015-06-12 16:46+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -33,8 +33,8 @@
 msgstr ""
 
 #: ../src/app/docviewer-application.cpp:171
-#: ../src/app/qml/documentPage/DocumentPage.qml:25
-#: /home/stefano/tmp/build-sdcard-read-support-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1
+#: ../src/app/qml/documentPage/DocumentPage.qml:24
+#: /home/stefano/Progetti/docviewer/build-document-page-filters-UbuntuSDK_for_armhf_GCC_ubuntu_sdk_14_10_utopic-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1
 msgid "Document Viewer"
 msgstr ""
 
@@ -76,6 +76,7 @@
 #: ../src/app/qml/common/PickImportedDialog.qml:47
 #: ../src/app/qml/common/RejectedImportDialog.qml:38
 #: ../src/app/qml/documentPage/DocumentPageSelectionModeHeader.qml:32
+#: ../src/app/qml/documentPage/SortSettingsDialog.qml:53
 #: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:61
 #: ../src/app/qml/textView/TextViewDefaultHeader.qml:61
 msgid "Close"
@@ -214,32 +215,40 @@
 msgid "dd-MM-yyyy hh:mm"
 msgstr ""
 
-#: ../src/app/qml/documentPage/DocumentListView.qml:136
+#: ../src/app/qml/documentPage/DocumentListView.qml:157
 msgid "Today"
 msgstr ""
 
-#: ../src/app/qml/documentPage/DocumentListView.qml:139
+#: ../src/app/qml/documentPage/DocumentListView.qml:160
 msgid "Yesterday"
 msgstr ""
 
-#: ../src/app/qml/documentPage/DocumentListView.qml:142
+#: ../src/app/qml/documentPage/DocumentListView.qml:163
 msgid "Earlier this week"
 msgstr ""
 
-#: ../src/app/qml/documentPage/DocumentListView.qml:145
+#: ../src/app/qml/documentPage/DocumentListView.qml:166
 msgid "Earlier this month"
 msgstr ""
 
-#: ../src/app/qml/documentPage/DocumentListView.qml:147
+#: ../src/app/qml/documentPage/DocumentListView.qml:168
 msgid "Even earlier..."
 msgstr ""
 
-#: ../src/app/qml/documentPage/DocumentPageDefaultHeader.qml:28
+#: ../src/app/qml/documentPage/DocumentPageDefaultHeader.qml:29
+msgid "Search..."
+msgstr ""
+
+#: ../src/app/qml/documentPage/DocumentPageDefaultHeader.qml:37
+msgid "Sorting settings..."
+msgstr ""
+
+#: ../src/app/qml/documentPage/DocumentPageDefaultHeader.qml:46
 #: ../src/app/qml/documentPage/DocumentPagePickModeHeader.qml:35
 msgid "Switch to single column list"
 msgstr ""
 
-#: ../src/app/qml/documentPage/DocumentPageDefaultHeader.qml:28
+#: ../src/app/qml/documentPage/DocumentPageDefaultHeader.qml:46
 #: ../src/app/qml/documentPage/DocumentPagePickModeHeader.qml:35
 msgid "Switch to grid"
 msgstr ""
@@ -248,6 +257,16 @@
 msgid "Pick"
 msgstr ""
 
+#: ../src/app/qml/documentPage/DocumentPageSearchHeader.qml:27
+#: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:61
+#: ../src/app/qml/textView/TextViewDefaultHeader.qml:61
+msgid "Back"
+msgstr ""
+
+#: ../src/app/qml/documentPage/DocumentPageSearchHeader.qml:47
+msgid "search in documents..."
+msgstr ""
+
 #: ../src/app/qml/documentPage/DocumentPageSelectionModeHeader.qml:52
 msgid "Select None"
 msgstr ""
@@ -256,6 +275,35 @@
 msgid "Select All"
 msgstr ""
 
+#: ../src/app/qml/documentPage/SearchEmptyState.qml:24
+msgid "No matching document found"
+msgstr ""
+
+#: ../src/app/qml/documentPage/SearchEmptyState.qml:26
+msgid ""
+"Please ensure that your query is not misspelled and/or try a different query."
+msgstr ""
+
+#: ../src/app/qml/documentPage/SortSettingsDialog.qml:26
+msgid "Sorting settings"
+msgstr ""
+
+#: ../src/app/qml/documentPage/SortSettingsDialog.qml:31
+msgid "Sort by date (Latest first)"
+msgstr ""
+
+#: ../src/app/qml/documentPage/SortSettingsDialog.qml:32
+msgid "Sort by name (A-Z)"
+msgstr ""
+
+#: ../src/app/qml/documentPage/SortSettingsDialog.qml:33
+msgid "Sort by size (Smaller first)"
+msgstr ""
+
+#: ../src/app/qml/documentPage/SortSettingsDialog.qml:47
+msgid "Reverse order"
+msgstr ""
+
 #. TRANSLATORS: "Contents" refers to the "Table of Contents" of a PDF document.
 #: ../src/app/qml/pdfView/PdfContentsPage.qml:32
 #: ../src/app/qml/pdfView/PdfView.qml:37
@@ -273,11 +321,6 @@
 msgid "Page %1 of %2"
 msgstr ""
 
-#: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:61
-#: ../src/app/qml/textView/TextViewDefaultHeader.qml:61
-msgid "Back"
-msgstr ""
-
 #: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:85
 msgid "Go to page..."
 msgstr ""
@@ -309,16 +352,16 @@
 msgid "Loading..."
 msgstr ""
 
-#: ../src/app/qml/ubuntu-docviewer-app.qml:202
+#: ../src/app/qml/ubuntu-docviewer-app.qml:240
 msgid "Document successfully imported!"
 msgid_plural "Documents successfully imported!"
 msgstr[0] ""
 msgstr[1] ""
 
-#: ../src/app/qml/ubuntu-docviewer-app.qml:205
+#: ../src/app/qml/ubuntu-docviewer-app.qml:243
 msgid "Open"
 msgstr ""
 
-#: /home/stefano/tmp/build-sdcard-read-support-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:2
+#: /home/stefano/Progetti/docviewer/build-document-page-filters-UbuntuSDK_for_armhf_GCC_ubuntu_sdk_14_10_utopic-Default/po/com.ubuntu.docviewer.desktop.in.in.h:2
 msgid "documents;viewer;pdf;reader;"
 msgstr ""

=== added file 'src/app/graphics/settings_alt.svg'
--- src/app/graphics/settings_alt.svg	1970-01-01 00:00:00 +0000
+++ src/app/graphics/settings_alt.svg	2015-06-12 14:48:32 +0000
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="90"
+   height="90"
+   id="svg3133"
+   version="1.1"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="settings@xxxxxx">
+  <defs
+     id="defs3135" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="6.3664628"
+     inkscape:cx="93.340685"
+     inkscape:cy="27.377839"
+     inkscape:document-units="px"
+     inkscape:current-layer="g4674"
+     showgrid="true"
+     inkscape:window-width="1920"
+     inkscape:window-height="1029"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     showguides="true"
+     inkscape:guide-bbox="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2992"
+       empspacing="6"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="4.2039363e-07px"
+       originy="0px" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="45,11"
+       id="guide3763" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="48,45"
+       id="guide3765" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata3138">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(4.2039363e-7,-962.3622)">
+    <g
+       id="g4978"
+       transform="matrix(0.99934414,0,0,1,-106.92982,549.00002)">
+      <g
+         id="g4674"
+         transform="matrix(1.0006563,0,0,1,-155.17195,-2.6171874e-6)">
+        <rect
+           y="431.36218"
+           x="262"
+           height="72"
+           width="72"
+           id="rect4869"
+           style="opacity:0.01000001;color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+        <path
+           style="color:#000000;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+           d="m 320.5,419.36218 c 6.5,0 7.49965,0 7.49979,7 l 2.1e-4,10 c 1.5e-4,7 -1,7 -7.5,7 -6.5,0 -7.50015,0 -7.5,-7 l 2.1e-4,-9.99997 c 1.4e-4,-7.00003 0.99979,-7.00003 7.49979,-7.00003 z"
+           id="rect4871"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="zsszssz" />
+        <path
+           style="color:#000000;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+           d="m 262,428.36218 0,6 45,0 0,-6 z m 72,0 0,6 18,0 0,-6 z"
+           id="rect4882"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccccccccc" />
+        <path
+           id="path4887"
+           d="m 262,455.36218 0,6 18,0 0,-6 z m 45,0 0,6 45,0 0,-6 z"
+           style="color:#000000;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="cccccccccc" />
+        <path
+           sodipodi:nodetypes="cccccccccc"
+           inkscape:connector-curvature="0"
+           style="color:#000000;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+           d="m 262,482.36218 0,6 45,0 0,-6 z m 72,0 0,6 18,0 0,-6 z"
+           id="path4889" />
+        <rect
+           y="413.36218"
+           x="262"
+           height="90"
+           width="90"
+           id="rect2993"
+           style="color:#000000;fill:none;stroke:none;stroke-width:11.80000019;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+        <path
+           sodipodi:nodetypes="zsszssz"
+           inkscape:connector-curvature="0"
+           id="path3775"
+           d="m 293.5,446.36218 c 6.5,0 7.49965,0 7.49979,7 l 2.1e-4,10 c 1.5e-4,7 -1,7 -7.5,7 -6.5,0 -7.50015,0 -7.5,-7 l 2.1e-4,-9.99997 c 1.4e-4,-7.00003 0.99979,-7.00003 7.49979,-7.00003 z"
+           style="color:#000000;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+        <path
+           style="color:#000000;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+           d="m 320.5,473.36218 c 6.5,0 7.49965,0 7.49979,7 l 2.1e-4,10 c 1.5e-4,7 -1,7 -7.5,7 -6.5,0 -7.50015,0 -7.5,-7 l 2.1e-4,-9.99997 c 1.4e-4,-7.00003 0.99979,-7.00003 7.49979,-7.00003 z"
+           id="path3777"
+           inkscape:connector-curvature="0"
+           sodipodi:nodetypes="zsszssz" />
+      </g>
+    </g>
+  </g>
+</svg>

=== modified file 'src/app/qml/documentPage/DocumentListView.qml'
--- src/app/qml/documentPage/DocumentListView.qml	2015-04-29 15:58:13 +0000
+++ src/app/qml/documentPage/DocumentListView.qml	2015-06-12 14:48:32 +0000
@@ -129,22 +129,46 @@
 
     listModel: folderModel
 
-    section.property: "dateDiff"
+    section.property: {
+        switch (sortSettings.sortMode) {
+        case 0:     // sort by date
+            return "dateDiff"
+        case 1:     // sort by name
+            return "name"
+        default:    // sort by size -> do not show section header
+            return ""
+        }
+    }
+
+    section.criteria: {
+        if (sortSettings.sortMode === 1)    // sort by name
+            return ViewSection.FirstCharacter
+
+        return ViewSection.FullString
+    }
+
     section.delegate: ListItem.Header {
         text: {
-            if (section == DocumentsModel.Today)
-                return i18n.tr("Today")
-
-            if (section == DocumentsModel.Yesterday)
-                return i18n.tr("Yesterday")
-
-            if (section == DocumentsModel.LastWeek)
-                return i18n.tr("Earlier this week")
-
-            if (section == DocumentsModel.LastMonth)
-                return i18n.tr("Earlier this month")
-
-            return i18n.tr("Even earlier...")
+            if (sortSettings.sortMode === 1)    // sort by name
+                return section
+
+            if (sortSettings.sortMode === 0) {    // sort by date
+                if (section == DocumentsModel.Today)
+                    return i18n.tr("Today")
+
+                if (section == DocumentsModel.Yesterday)
+                    return i18n.tr("Yesterday")
+
+                if (section == DocumentsModel.LastWeek)
+                    return i18n.tr("Earlier this week")
+
+                if (section == DocumentsModel.LastMonth)
+                    return i18n.tr("Earlier this month")
+
+                return i18n.tr("Even earlier...")
+            }
+
+            return ""
         }
     }
 

=== modified file 'src/app/qml/documentPage/DocumentPage.qml'
--- src/app/qml/documentPage/DocumentPage.qml	2015-05-13 14:22:36 +0000
+++ src/app/qml/documentPage/DocumentPage.qml	2015-06-12 14:48:32 +0000
@@ -16,7 +16,6 @@
 
 import QtQuick 2.0
 import Ubuntu.Components 1.1
-import Ubuntu.Components.Popups 1.0
 import Qt.labs.settings 1.0
 
 Page {
@@ -26,6 +25,7 @@
     flickable: null
 
     property bool useGridView: false
+    property bool searchMode: false
     property alias view: viewLoader
 
     onActiveChanged: {
@@ -43,9 +43,10 @@
         id: viewLoader
         anchors.fill: parent
 
-        source: (folderModel.count === 0) ? Qt.resolvedUrl("./DocumentEmptyState.qml")
-                                     : useGridView ? Qt.resolvedUrl("./DocumentGridView.qml")
-                                                   : Qt.resolvedUrl("./DocumentListView.qml")
+        source: (folderModel.count === 0) ? documentPage.state == "search" ? Qt.resolvedUrl("./SearchEmptyState.qml")
+                                                                           : Qt.resolvedUrl("./DocumentEmptyState.qml")
+                                          : useGridView ? Qt.resolvedUrl("./DocumentGridView.qml")
+                                                        : Qt.resolvedUrl("./DocumentListView.qml")
     }
 
     // *** HEADER ***
@@ -53,7 +54,7 @@
         DocumentPageDefaultHeader {
             name: "default"
             targetPage: documentPage
-            when: !mainView.pickMode && !viewLoader.item.isInSelectionMode
+            when: !mainView.pickMode && !viewLoader.item.isInSelectionMode && !documentPage.searchMode
         },
 
         DocumentPagePickModeHeader {
@@ -66,6 +67,12 @@
             name: "selection"
             targetPage: documentPage
             when: !mainView.pickMode && viewLoader.item.isInSelectionMode
+        },
+
+        DocumentPageSearchHeader {
+            name: "search"
+            targetPage: documentPage
+            when: !mainView.pickMode && !viewLoader.item.isInSelectionMode && documentPage.searchMode
         }
     ]
 
@@ -78,6 +85,10 @@
             } else {
                 viewLoader.item.cancelSelection()
             }
+
+            // Reset any previous search
+            documentPage.searchMode = false
+            folderModel.search("")  // Empty search, reset filter.
         }
     }
 }

=== modified file 'src/app/qml/documentPage/DocumentPageDefaultHeader.qml'
--- src/app/qml/documentPage/DocumentPageDefaultHeader.qml	2015-03-03 15:41:11 +0000
+++ src/app/qml/documentPage/DocumentPageDefaultHeader.qml	2015-06-12 14:48:32 +0000
@@ -16,6 +16,7 @@
 
 import QtQuick 2.3
 import Ubuntu.Components 1.1
+import Ubuntu.Components.Popups 1.0
 
 PageHeadState {
     id: rootItem
@@ -23,12 +24,30 @@
     property Page targetPage
     head: targetPage.head
 
-    actions:  Action {
-        id: switchView
-        text: targetPage.useGridView ? i18n.tr("Switch to single column list") : i18n.tr("Switch to grid")
-        iconName: targetPage.useGridView ? "view-list-symbolic" : "view-grid-symbolic"
-        onTriggered: targetPage.useGridView = !targetPage.useGridView
-
-        visible: folderModel.count !== 0
-    }
+    actions: [
+        Action {
+            text: i18n.tr("Search...")
+            iconName: "search"
+            onTriggered: targetPage.searchMode = true
+
+            visible: folderModel.count !== 0
+        },
+
+        Action {
+            text: i18n.tr("Sorting settings...")
+            iconSource: Qt.resolvedUrl("../../graphics/settings_alt.svg")
+            onTriggered: PopupUtils.open(Qt.resolvedUrl("SortSettingsDialog.qml"))
+
+            visible: folderModel.count !== 0
+        },
+
+        Action {
+            id: switchView
+            text: targetPage.useGridView ? i18n.tr("Switch to single column list") : i18n.tr("Switch to grid")
+            iconName: targetPage.useGridView ? "view-list-symbolic" : "view-grid-symbolic"
+            onTriggered: targetPage.useGridView = !targetPage.useGridView
+
+            visible: folderModel.count !== 0
+        }
+    ]
 }

=== added file 'src/app/qml/documentPage/DocumentPageSearchHeader.qml'
--- src/app/qml/documentPage/DocumentPageSearchHeader.qml	1970-01-01 00:00:00 +0000
+++ src/app/qml/documentPage/DocumentPageSearchHeader.qml	2015-06-12 14:48:32 +0000
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014-2015 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.3
+import Ubuntu.Components 1.1
+
+PageHeadState {
+    id: rootItem
+
+    property Page targetPage
+    head: targetPage.head
+
+    backAction: Action {
+        text: i18n.tr("Back")
+        iconName: "back"
+
+        onTriggered: {
+            // Clear the search
+            searchField.text = ""
+            targetPage.searchMode = false
+        }
+    }
+
+    contents: TextField {
+        id: searchField
+        width: parent.width - units.gu(4)
+
+        primaryItem: Icon {
+            height: parent.height - units.gu(2)
+            width: height
+            name: "search"
+        }
+
+        placeholderText: i18n.tr("search in documents...")
+        onTextChanged: folderModel.search(text)
+
+        // Disable predictive text
+        inputMethodHints: Qt.ImhNoPredictiveText
+
+        // Force active focus when this becomes the current PageHead state and
+        // show OSK if appropriate.
+        onVisibleChanged: forceActiveFocus()
+    }
+}

=== added file 'src/app/qml/documentPage/SearchEmptyState.qml'
--- src/app/qml/documentPage/SearchEmptyState.qml	1970-01-01 00:00:00 +0000
+++ src/app/qml/documentPage/SearchEmptyState.qml	2015-06-12 14:48:32 +0000
@@ -0,0 +1,32 @@
+/*
+  Copyright (C) 2015 Stefano Verzegnassi
+
+    This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License 3 as published by
+  the Free Software Foundation.
+
+    This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+  along with this program. If not, see http://www.gnu.org/licenses/.
+*/
+
+import QtQuick 2.0
+import "../upstreamComponents"
+
+Item {
+    anchors.fill: parent
+
+    EmptyState {
+        title: i18n.tr("No matching document found")
+
+        subTitle: i18n.tr("Please ensure that your query is not misspelled and/or try a different query.")
+        iconName: "search"
+
+        anchors.centerIn: parent
+        width: parent.width
+    }
+}

=== added file 'src/app/qml/documentPage/SortSettingsDialog.qml'
--- src/app/qml/documentPage/SortSettingsDialog.qml	1970-01-01 00:00:00 +0000
+++ src/app/qml/documentPage/SortSettingsDialog.qml	2015-06-12 14:48:32 +0000
@@ -0,0 +1,57 @@
+/*
+  Copyright (C) 2013-2015 Stefano Verzegnassi
+
+    This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License 3 as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+  along with this program. If not, see http://www.gnu.org/licenses/.
+*/
+
+import QtQuick 2.0
+import Ubuntu.Components 1.1
+import Ubuntu.Components.Popups 1.0
+import QtQuick.Layouts 1.0
+
+Dialog {
+    id: sortSettingsDialog
+
+    title: i18n.tr("Sorting settings")
+
+    OptionSelector {
+        expanded: true
+        model: [
+            i18n.tr("Sort by date (Latest first)"),
+            i18n.tr("Sort by name (A-Z)"),
+            i18n.tr("Sort by size (Smaller first)")
+        ]
+
+        Component.onCompleted: selectedIndex = sortSettings.sortMode
+        onSelectedIndexChanged: sortSettings.sortMode = selectedIndex
+    }
+
+    RowLayout {
+        CheckBox {
+            Component.onCompleted: checked = sortSettings.reverseOrder
+            onCheckedChanged: sortSettings.reverseOrder = checked
+        }
+
+        Label {
+            text: i18n.tr("Reverse order")
+            Layout.fillWidth: true
+        }
+    }
+
+    Button {
+        text: i18n.tr("Close")
+        onClicked: PopupUtils.close(sortSettingsDialog)
+    }
+}
+

=== modified file 'src/app/qml/ubuntu-docviewer-app.qml'
--- src/app/qml/ubuntu-docviewer-app.qml	2015-04-29 16:06:32 +0000
+++ src/app/qml/ubuntu-docviewer-app.qml	2015-06-12 14:48:32 +0000
@@ -19,6 +19,7 @@
 import Ubuntu.Components.Popups 1.0
 import DocumentViewer 1.0
 import QtQuick.Window 2.0
+import Qt.labs.settings 1.0
 
 import "common"
 import "common/loadComponent.js" as LoadComponent
@@ -131,6 +132,12 @@
 
     SortFilterModel {
         id: folderModel
+
+        function search(pattern) {
+            // Search the given pattern, case insensitive
+            filter.pattern = new RegExp(pattern, 'i')
+        }
+
         model: DocumentsModel {
             id: docModel
 
@@ -138,13 +145,44 @@
             customDir: DOC_VIEWER.documentsDir
         }
 
-        sort.property: "date"
-        sort.order: Qt.DescendingOrder
+        sort.property: {
+            switch (sortSettings.sortMode) {
+            case 0:
+                return "date"
+            case 1:
+                return "name"
+            case 2:
+                return "size"
+            default:
+                return "date"
+            }
+        }
+        sort.order: {
+            switch (sortSettings.sortMode) {
+            case 0:     // sort by date
+                return sortSettings.reverseOrder ? Qt.AscendingOrder : Qt.DescendingOrder
+            case 1:     // sort by name
+                return sortSettings.reverseOrder ? Qt.DescendingOrder : Qt.AscendingOrder
+            case 2:     // sort by size
+                return sortSettings.reverseOrder ? Qt.DescendingOrder : Qt.AscendingOrder
+            default:
+                return sortSettings.reverseOrder ? Qt.AscendingOrder : Qt.DescendingOrder
+            }
+        }
         sortCaseSensitivity: Qt.CaseSensitive
+
+        filter.property: "name"
     }
 
     PageStack { id: pageStack }
 
+    Settings {
+        id: sortSettings
+
+        property int sortMode: 0    // 0 = by date, 1 = by name, 2 = by size
+        property bool reverseOrder: false
+    }
+
     Connections {
         target: UriHandler
         onOpened: {


Follow ups