Linked key and ca file configuration to vpn execution. Added option to
[openvpnui.git] / qml / filebrowse / pages / SearchPage.qml
1 import QtQuick 2.0
2 import Sailfish.Silica 1.0
3 import harbour.file.browser.SearchEngine 1.0
4 import "functions.js" as Functions
5 import "../components"
6
7 Page {
8     id: page
9     //allowedOrientations: Orientation.All
10     showNavigationIndicator: false // hide back indicator because it would be on top of search field
11     property string dir: "/"
12     property string currentDirectory: ""
13
14     onStatusChanged: {
15         if (status === PageStatus.Active) {
16             listModel.update("." + engine.extensionFilter);
17             //foundText.visible = true;
18         }
19     }
20
21     // this and its bg worker thread will be destroyed when page in popped from stack
22     SearchEngine {
23         id: searchEngine
24         dir: page.dir
25
26         onProgressChanged: page.currentDirectory = directory
27         onMatchFound: listModel.append({ fullname: fullname, filename: filename,
28                                            absoluteDir: absoluteDir,
29                                            fileIcon: fileIcon, fileKind: fileKind });
30         onWorkerDone: { /* Nothing to do */ }
31         onWorkerErrorOccurred: { notificationPanel.showText(message, filename); }
32     }
33
34     SilicaListView {
35         id: fileList
36         anchors.fill: parent
37
38         // prevent newly added list delegates from stealing focus away from the search field
39         currentIndex: -1
40
41         model: ListModel {
42             id: listModel
43
44             function update(txt) {
45                 if (txt === "")
46                     searchEngine.cancel();
47
48                 clear();
49                 if (txt !== "") {
50                     searchEngine.search(txt);
51                 }
52             }
53
54             Component.onCompleted: update("")
55         }
56
57         VerticalScrollDecorator { flickable: fileList }
58
59 //        PullDownMenu {
60 //            MenuItem {
61 //                text: qsTr("Settings")
62 //                onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
63 //            }
64 //        }
65
66         header: Item {
67             width: parent.width
68             height: 110
69
70             SearchField {
71                 id: searchField
72                 anchors.left: parent.left
73                 anchors.right: cancelSearchButton.left
74                 placeholderText: qsTr("Search %1").arg(Functions.formatPathForSearch(page.dir))
75                 inputMethodHints: Qt.ImhNoAutoUppercase
76
77                 // get focus when page is shown for the first time
78                 Component.onCompleted: forceActiveFocus()
79
80                 // return key on virtual keyboard starts or restarts search
81                 EnterKey.enabled: true
82                 EnterKey.onClicked: {
83                     notificationPanel.hide();
84                     listModel.update(searchField.text);
85                     foundText.visible = true;
86                     searchField.focus = false;
87                 }
88             }
89             // our own "IconButton" to make the mouse area large and easier to tap
90             Rectangle {
91                 id: cancelSearchButton
92                 anchors.right: parent.right
93                 anchors.top: searchField.top
94                 width: Theme.iconSizeMedium+Theme.paddingLarge
95                 height: searchField.height
96                 color: cancelSearchMouseArea.pressed ? Theme.secondaryHighlightColor : "transparent"
97                 MouseArea {
98                     id: cancelSearchMouseArea
99                     anchors.fill: parent
100                     onClicked: {
101                         if (!searchEngine.running) {
102                             listModel.update(searchField.text);
103                             foundText.visible = true;
104                         } else {
105                             searchEngine.cancel()
106                         }
107                     }
108                     enabled: true
109                     Image {
110                         id: cancelSearchButtonImage
111                         anchors.verticalCenter: parent.verticalCenter
112                         anchors.right: parent.right
113                         anchors.rightMargin: Theme.paddingLarge
114                         source: searchEngine.running ? "image://theme/icon-m-clear" :
115                                                        "image://theme/icon-m-right"
116                     }
117                     BusyIndicator {
118                         id: searchBusy
119                         anchors.centerIn: cancelSearchButtonImage
120                         running: searchEngine.running
121                         size: BusyIndicatorSize.Small
122                     }
123                 }
124             }
125             Label {
126                 id: foundText
127                 visible: true
128                 anchors.left: parent.left
129                 anchors.leftMargin: searchField.textLeftMargin
130                 anchors.top: searchField.bottom
131                 anchors.topMargin: -26
132                 text: qsTr("%1 hits").arg(listModel.count)
133                 font.pixelSize: Theme.fontSizeTiny
134                 color: Theme.secondaryColor
135             }
136             Label {
137                 anchors.left: parent.left
138                 anchors.leftMargin: 240
139                 anchors.right: parent.right
140                 anchors.rightMargin: Theme.paddingLarge
141                 anchors.top: searchField.bottom
142                 anchors.topMargin: -26
143                 text: page.currentDirectory
144                 font.pixelSize: Theme.fontSizeTiny
145                 color: Theme.secondaryColor
146                 elide: Text.ElideRight
147             }
148         }
149
150         delegate: ListItem {
151             id: fileItem
152             menu: contextMenu
153             width: ListView.view.width
154             contentHeight: listLabel.height+listAbsoluteDir.height + 13
155
156             Image {
157                 id: listIcon
158                 anchors.left: parent.left
159                 anchors.leftMargin: Theme.paddingLarge
160                 anchors.top: parent.top
161                 anchors.topMargin: 11
162                 source: "../images/small-"+fileIcon+".png"
163             }
164             Label {
165                 id: listLabel
166                 anchors.left: listIcon.right
167                 anchors.leftMargin: 10
168                 anchors.right: parent.right
169                 anchors.rightMargin: Theme.paddingLarge
170                 anchors.top: parent.top
171                 anchors.topMargin: 5
172                 text: filename
173                 elide: Text.ElideRight
174             }
175             Label {
176                 id: listAbsoluteDir
177                 anchors.left: listIcon.right
178                 anchors.leftMargin: 10
179                 anchors.right: parent.right
180                 anchors.rightMargin: Theme.paddingLarge
181                 anchors.top: listLabel.bottom
182                 text: absoluteDir
183                 color: Theme.secondaryColor
184                 font.pixelSize: Theme.fontSizeExtraSmall
185                 elide: Text.ElideLeft
186             }
187
188             onClicked: {
189                 if (model.fileKind === "d")
190                     pageStack.push(Qt.resolvedUrl("DirectoryPage.qml"),
191                                    { dir: model.fullname });
192                 else
193                     Functions.fileSelect(model.fullname)
194 //                    pageStack.push(Qt.resolvedUrl("FilePage.qml"),
195 //                                   { file: model.fullname });
196             }
197
198             // delete file after remorse time
199             ListView.onRemove: animateRemoval(fileItem)
200             function deleteFile(deleteFilename) {
201                 remorseAction(qsTr("Deleting"), function() {
202                     progressPanel.showText(qsTr("Deleting"));
203                     engine.deleteFiles([ deleteFilename ]);
204                 }, 5000)
205             }
206
207             // context menu is activated with long press, visible if search is not running
208             Component {
209                  id: contextMenu
210                  ContextMenu {
211                      MenuItem {
212                          text: qsTr("Go to containing folder")
213                          onClicked: Functions.goToFolder(model.absoluteDir)
214                      }
215                      MenuItem {
216                          text: qsTr("Properties")
217                          onClicked: {
218                             pageStack.push(Qt.resolvedUrl("FilePage.qml"), { file: model.fullname });
219                          }
220                      }
221 //                     MenuItem {
222 //                         text: qsTr("Cut")
223 //                         onClicked: engine.cutFiles([ model.fullname ]);
224 //                     }
225 //                     MenuItem {
226 //                         text: qsTr("Copy")
227 //                         onClicked: engine.copyFiles([ model.fullname ]);
228 //                     }
229 //                     MenuItem {
230 //                         text: qsTr("Delete")
231 //                         onClicked: deleteFile(model.fullname);
232 //                     }
233                  }
234              }
235         }
236
237     }
238
239     // connect signals from engine to panels
240     Connections {
241         target: engine
242         onProgressChanged: progressPanel.text = engine.progressFilename
243         onWorkerDone: progressPanel.hide()
244         onWorkerErrorOccurred: {
245             // the error signal goes to all pages in pagestack, show it only in the active one
246             if (progressPanel.open) {
247                 progressPanel.hide();
248                 notificationPanel.showText(message, filename);
249             }
250         }
251
252         // item got deleted by worker, so remove it from list
253         onFileDeleted: {
254             for (var i = 0; i < listModel.count; ++i) {
255                 var item = listModel.get(i);
256                 if (item.fullname === fullname) {
257                     listModel.remove(i)
258                     return;
259                 }
260             }
261         }
262     }
263
264     NotificationPanel {
265         id: notificationPanel
266         page: page
267     }
268
269     ProgressPanel {
270         id: progressPanel
271         page: page
272         onCancelled: engine.cancel()
273     }
274 }
275
276