Merge lp:~cellsoftware/telegram-app/1450227-NEW into lp:telegram-app
- 1450227-NEW
- Merge into telegram
Proposed by
Paz Chauhan
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Jin | ||||
Approved revision: | 195 | ||||
Merged at revision: | 195 | ||||
Proposed branch: | lp:~cellsoftware/telegram-app/1450227-NEW | ||||
Merge into: | lp:telegram-app | ||||
Diff against target: |
433 lines (+341/-19) 6 files modified
telegram/app/asemantools/asemancountriesmodel.cpp (+18/-0) telegram/app/asemantools/asemancountriesmodel.h (+1/-1) telegram/app/qml/AuthCountriesPage.qml (+157/-18) telegram/app/qml/components/SearchHeadState.qml (+92/-0) telegram/app/qml/components/SearchableHeadState.qml (+71/-0) telegram/app/telegram.qrc (+2/-0) |
||||
To merge this branch: | bzr merge lp:~cellsoftware/telegram-app/1450227-NEW | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jin (community) | Approve | ||
Review via email: mp+295083@code.launchpad.net |
Commit message
Description of the change
Country list search feature added during startup
To post a comment you must log in.
- 194. By Paz Chauhan
-
Double spacing removed for get() in .cpp file
- 195. By Paz Chauhan
-
.po and .pot files reverted
Revision history for this message
Paz Chauhan (paz-chauhan) wrote : | # |
@jin, double spacing removed
> @Paz,
> Other files looks good to me,
> but for asemancountries
> could you help us to patch that with a synced coding style?
> (which mean for the double spaces fuction get())
Revision history for this message
Jin (jindallo) wrote : | # |
Code looks good to me,
verified pass on my local,
I approve.
Revision history for this message
Jin (jindallo) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'telegram/app/asemantools/asemancountriesmodel.cpp' |
2 | --- telegram/app/asemantools/asemancountriesmodel.cpp 2015-09-22 09:57:07 +0000 |
3 | +++ telegram/app/asemantools/asemancountriesmodel.cpp 2016-05-20 10:00:48 +0000 |
4 | @@ -140,6 +140,24 @@ |
5 | return res; |
6 | } |
7 | |
8 | + |
9 | +QVariantMap AsemanCountriesModel::get( int rowNumber ) const |
10 | +{ |
11 | + // Create a map to hold all the role information about the data item in question |
12 | + // Use the role names as the keys for the map so that the same referances can be |
13 | + // used in the QML to get the data (i.e. role_display, role_value). |
14 | + |
15 | + QVariantMap map; |
16 | + QHash<int,QByteArray> roleName = roleNames(); |
17 | + |
18 | + foreach (int i, roleName.keys()) |
19 | + { |
20 | + map[roleName.value(i)] = data( index( rowNumber,0 ), i ); |
21 | + } |
22 | + return map; |
23 | +} |
24 | + |
25 | + |
26 | QHash<qint32, QByteArray> AsemanCountriesModel::roleNames() const |
27 | { |
28 | static QHash<qint32, QByteArray> *res = 0; |
29 | |
30 | === modified file 'telegram/app/asemantools/asemancountriesmodel.h' |
31 | --- telegram/app/asemantools/asemancountriesmodel.h 2015-09-22 09:57:07 +0000 |
32 | +++ telegram/app/asemantools/asemancountriesmodel.h 2016-05-20 10:00:48 +0000 |
33 | @@ -60,7 +60,7 @@ |
34 | |
35 | int rowCount(const QModelIndex & parent = QModelIndex()) const; |
36 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; |
37 | - |
38 | + Q_INVOKABLE QVariantMap get( int rowNumber ) const; |
39 | QHash<qint32,QByteArray> roleNames() const; |
40 | int count() const; |
41 | |
42 | |
43 | === modified file 'telegram/app/qml/AuthCountriesPage.qml' |
44 | --- telegram/app/qml/AuthCountriesPage.qml 2016-05-03 05:17:47 +0000 |
45 | +++ telegram/app/qml/AuthCountriesPage.qml 2016-05-20 10:00:48 +0000 |
46 | @@ -2,6 +2,8 @@ |
47 | import Ubuntu.Components 1.3 |
48 | import Ubuntu.Components.ListItems 1.3 as ListItem |
49 | import AsemanTools 1.0 |
50 | +import QtQml.Models 2.1 |
51 | + |
52 | |
53 | Page { |
54 | id: page |
55 | @@ -13,7 +15,57 @@ |
56 | |
57 | focus: true |
58 | flickable: null |
59 | - title: i18n.tr("Country Code") |
60 | + title: i18n.tr("Choose a country") |
61 | + |
62 | + // Page states |
63 | + state: "default" |
64 | + states: [ |
65 | + PageHeadState { |
66 | + name: "default" |
67 | + head: page.head |
68 | + actions: [ |
69 | + Action { |
70 | + iconName: "search"; |
71 | + text: i18n.tr("Search"); |
72 | + onTriggered:{ |
73 | + page.state = "search"; |
74 | + search_text_field.forceActiveFocus(); |
75 | + } |
76 | + } |
77 | + ] |
78 | + }, |
79 | + PageHeadState { |
80 | + name: "search" |
81 | + head: page.head |
82 | + actions: [] |
83 | + backAction: Action { |
84 | + // TRANSLATORS: As in, back out of contacts page. |
85 | + text: i18n.tr("Back") |
86 | + iconName: "back" |
87 | + onTriggered: { |
88 | + search_text_field.text = ""; |
89 | + page.state = "default"; |
90 | + } |
91 | + } |
92 | + contents: TextField { |
93 | + id: search_text_field |
94 | + anchors { |
95 | + right: parent ? parent.right : undefined |
96 | + rightMargin: units.gu(2) |
97 | + } |
98 | + focus: true |
99 | + inputMethodHints: Qt.ImhNoPredictiveText |
100 | + onTextChanged: country_list_delegateModel.searchChanged(text) |
101 | + // TRANSLATORS: Placeholder for contacts search field. |
102 | + placeholderText: i18n.tr("Search countries...") |
103 | + |
104 | + onTriggered: { |
105 | + // TODO No worky. |
106 | + page.state = "default"; |
107 | + } |
108 | + } |
109 | + } |
110 | + ] |
111 | |
112 | onCodeChanged: { |
113 | if (code.length > 0) { |
114 | @@ -21,6 +73,72 @@ |
115 | } |
116 | } |
117 | |
118 | + // Delegate for country_list ListView |
119 | + Component { |
120 | + id: filterDelegate |
121 | + ListItem.SingleValue { |
122 | + objectName: getObjectName() |
123 | + text: name |
124 | + value: nativeName |
125 | + onClicked: { |
126 | + country_list.currentIndex = index; |
127 | + |
128 | + // Force change in case same number picked again. |
129 | + page.code = ""; |
130 | + page.code = callingCode; |
131 | + } |
132 | + |
133 | + function getObjectName() { |
134 | + return name.toLowerCase().split(' ').join('_') |
135 | + } |
136 | + } |
137 | + } |
138 | + |
139 | + // In conjunction with DelegateModelGroup this will allow us to |
140 | + // filter the country list based on user input in the search field |
141 | + DelegateModel { |
142 | + |
143 | + signal searchChanged(string text) |
144 | + |
145 | + id: country_list_delegateModel |
146 | + model: CountriesModel {} |
147 | + delegate: filterDelegate |
148 | + |
149 | + groups: [ |
150 | + DelegateModelGroup { |
151 | + id: searchResults |
152 | + includeByDefault: true |
153 | + name: "displaySearchResults" |
154 | + } |
155 | + ] |
156 | + filterOnGroup: "displaySearchResults" |
157 | + |
158 | + onSearchChanged: { |
159 | + console.log("Searching for " + text); |
160 | + country_list_delegateModel.processSearchFilter(text); |
161 | + } |
162 | + |
163 | + function processSearchFilter(searchTerm) { |
164 | + |
165 | + var allRowsCount = model.count; |
166 | + var filteredRowsCount = searchResults.count; |
167 | + |
168 | + searchResults.remove(0,filteredRowsCount); |
169 | + |
170 | + for(var i = 0 ; i < allRowsCount ; i++) { |
171 | + var entry = model.get(i); |
172 | + |
173 | + // Perform case insensitive search for the user input within the name of each country |
174 | + if(entry.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1 || (searchTerm === "")) { |
175 | +// console.log("Adding " + entry.name); |
176 | + searchResults.insert(entry, searchResults.name); |
177 | + } |
178 | + } |
179 | +// console.log("Filter group contains " + searchResults.count + " items"); |
180 | + } |
181 | + } |
182 | + |
183 | + |
184 | ListView { |
185 | id: country_list |
186 | objectName: "countriesList" |
187 | @@ -32,23 +150,44 @@ |
188 | flickDeceleration: 2000 |
189 | maximumFlickVelocity: 5000 |
190 | |
191 | - model: CountriesModel {} |
192 | - delegate: ListItem.SingleValue { |
193 | - objectName: getObjectName() |
194 | - text: name |
195 | - value: nativeName |
196 | - onClicked: { |
197 | - country_list.currentIndex = index; |
198 | - |
199 | - // Force change in case same number picked again. |
200 | - page.code = ""; |
201 | - page.code = callingCode; |
202 | - } |
203 | - |
204 | - function getObjectName() { |
205 | - return name.toLowerCase().split(' ').join('_') |
206 | - } |
207 | - } |
208 | + model: country_list_delegateModel |
209 | +//======= |
210 | +// model: CountriesModel {} |
211 | +// delegate: ListItem.SingleValue { |
212 | +// objectName: getObjectName() |
213 | +// text: name |
214 | +// value: nativeName |
215 | +// onClicked: { |
216 | +// country_list.currentIndex = index; |
217 | + |
218 | +// // Force change in case same number picked again. |
219 | +// page.code = ""; |
220 | +// page.code = callingCode; |
221 | +// } |
222 | + |
223 | +// function getObjectName() { |
224 | +// return name.toLowerCase().split(' ').join('_') |
225 | +// } |
226 | +// } |
227 | + |
228 | + |
229 | +// model: CountriesModel {} |
230 | +// delegate: ListItem.SingleValue { |
231 | +// objectName: getObjectName() |
232 | +// text: name |
233 | +// value: nativeName |
234 | +// onClicked: { |
235 | +// country_list.currentIndex = index; |
236 | + |
237 | +// // Force change in case same number picked again. |
238 | +// page.code = ""; |
239 | +// page.code = callingCode; |
240 | +// } |
241 | + |
242 | +// function getObjectName() { |
243 | +// return name.toLowerCase().split(' ').join('_') |
244 | +// } |
245 | +// } |
246 | |
247 | Component.onCompleted: { |
248 | // FIXME: workaround for qtubuntu not returning values depending on the grid unit definition |
249 | |
250 | === added file 'telegram/app/qml/components/SearchHeadState.qml' |
251 | --- telegram/app/qml/components/SearchHeadState.qml 1970-01-01 00:00:00 +0000 |
252 | +++ telegram/app/qml/components/SearchHeadState.qml 2016-05-20 10:00:48 +0000 |
253 | @@ -0,0 +1,92 @@ |
254 | +/* |
255 | + * Copyright (C) 2015 |
256 | + * Andrew Hayzen <ahayzen@gmail.com> |
257 | + * Victor Thompson <victor.thompson@gmail.com> |
258 | + * |
259 | + * This program is free software; you can redistribute it and/or modify |
260 | + * it under the terms of the GNU General Public License as published by |
261 | + * the Free Software Foundation; version 3. |
262 | + * |
263 | + * This program is distributed in the hope that it will be useful, |
264 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
265 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
266 | + * GNU General Public License for more details. |
267 | + * |
268 | + * You should have received a copy of the GNU General Public License |
269 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
270 | + */ |
271 | + |
272 | +import QtQuick 2.4 |
273 | +import Ubuntu.Components 1.3 |
274 | + |
275 | +State { |
276 | + name: "search" |
277 | + |
278 | + property PageHeader thisHeader: PageHeader { |
279 | + id: headerState |
280 | + contents: TextField { |
281 | + id: searchField |
282 | + anchors { |
283 | + left: parent ? parent.left : undefined |
284 | + right: parent ? parent.right : undefined |
285 | + verticalCenter: parent ? parent.verticalCenter : undefined |
286 | + } |
287 | + color: UbuntuColors.ash |
288 | + focus: true |
289 | + hasClearButton: true |
290 | + inputMethodHints: Qt.ImhNoPredictiveText |
291 | + placeholderText: i18n.tr("Search music") |
292 | + |
293 | + // Use the page onVisible as the text field goes visible=false when switching states |
294 | + // This is used when popping from the pageStack and returning back to a page with search |
295 | + Connections { |
296 | + target: thisPage |
297 | + |
298 | + onStateChanged: { // ensure the search is reset (eg pressing Esc) |
299 | + if (state === "default") { |
300 | + searchField.text = "" |
301 | + } |
302 | + } |
303 | + |
304 | + onVisibleChanged: { |
305 | + // clear when the page becomes visible not invisible |
306 | + // if invisible is used the delegates can be destroyed which |
307 | + // have created the pushed component |
308 | + if (visible) { |
309 | + thisPage.state = "default" |
310 | + } |
311 | + } |
312 | + } |
313 | + } |
314 | + flickable: thisPage.flickable |
315 | + leadingActionBar { |
316 | + actions: [ |
317 | + Action { |
318 | + id: leaveSearchAction |
319 | + text: "back" |
320 | + iconName: "back" |
321 | + onTriggered: thisPage.state = "default" |
322 | + } |
323 | + ] |
324 | + } |
325 | + visible: thisPage.state === "search" |
326 | + |
327 | + onVisibleChanged: { |
328 | + if (visible) { |
329 | + searchField.forceActiveFocus() |
330 | + } |
331 | + } |
332 | + |
333 | + StyleHints { |
334 | + backgroundColor: mainView.headerColor |
335 | + dividerColor: Qt.darker(mainView.headerColor, 1.1) |
336 | + } |
337 | + } |
338 | + property Item thisPage |
339 | + property alias query: searchField.text |
340 | + |
341 | + PropertyChanges { |
342 | + target: thisPage |
343 | + header: thisHeader |
344 | + } |
345 | +} |
346 | |
347 | === added file 'telegram/app/qml/components/SearchableHeadState.qml' |
348 | --- telegram/app/qml/components/SearchableHeadState.qml 1970-01-01 00:00:00 +0000 |
349 | +++ telegram/app/qml/components/SearchableHeadState.qml 2016-05-20 10:00:48 +0000 |
350 | @@ -0,0 +1,71 @@ |
351 | +/* |
352 | + * Copyright (C) 2015 |
353 | + * Andrew Hayzen <ahayzen@gmail.com> |
354 | + * Victor Thompson <victor.thompson@gmail.com> |
355 | + * |
356 | + * This program is free software; you can redistribute it and/or modify |
357 | + * it under the terms of the GNU General Public License as published by |
358 | + * the Free Software Foundation; version 3. |
359 | + * |
360 | + * This program is distributed in the hope that it will be useful, |
361 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
362 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
363 | + * GNU General Public License for more details. |
364 | + * |
365 | + * You should have received a copy of the GNU General Public License |
366 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
367 | + */ |
368 | + |
369 | +import QtQuick 2.4 |
370 | +import Ubuntu.Components 1.3 |
371 | + |
372 | + |
373 | +State { |
374 | + name: "default" |
375 | + |
376 | + property alias searchEnabled: searchAction.enabled |
377 | + property PageHeader thisHeader: PageHeader { |
378 | + id: headerState |
379 | + flickable: thisPage.flickable |
380 | + leadingActionBar { |
381 | + actions: { |
382 | + if (mainPageStack.currentPage === tabs) { |
383 | + tabs.tabActions |
384 | + } else if (mainPageStack.depth > 1) { |
385 | + backActionComponent |
386 | + } |
387 | + } |
388 | + } |
389 | + title: thisPage.title |
390 | + trailingActionBar { |
391 | + actions: [ |
392 | + Action { |
393 | + id: searchAction |
394 | + iconName: "search" |
395 | + onTriggered: { |
396 | + thisPage.state = "search"; |
397 | + thisPage.header.contents.forceActiveFocus(); |
398 | + } |
399 | + } |
400 | + ] |
401 | + } |
402 | + visible: thisPage.state === "default" |
403 | + |
404 | + Action { |
405 | + id: backActionComponent |
406 | + iconName: "back" |
407 | + onTriggered: mainPageStack.pop() |
408 | + } |
409 | + |
410 | + StyleHints { |
411 | + backgroundColor: mainView.headerColor |
412 | + dividerColor: Qt.darker(mainView.headerColor, 1.1) |
413 | + } |
414 | + } |
415 | + property Item thisPage |
416 | + |
417 | + PropertyChanges { |
418 | + target: thisPage |
419 | + header: thisHeader |
420 | + } |
421 | +} |
422 | |
423 | === modified file 'telegram/app/telegram.qrc' |
424 | --- telegram/app/telegram.qrc 2016-02-29 22:46:12 +0000 |
425 | +++ telegram/app/telegram.qrc 2016-05-20 10:00:48 +0000 |
426 | @@ -147,5 +147,7 @@ |
427 | <file>qml/files/emoticons-telegram.png</file> |
428 | <file>qml/files/emojis.svg</file> |
429 | <file>qml/InstallStickerDialog.qml</file> |
430 | + <file>qml/components/SearchableHeadState.qml</file> |
431 | + <file>qml/components/SearchHeadState.qml</file> |
432 | </qresource> |
433 | </RCC> |
@Paz, model.cpp one,
Other files looks good to me,
but for asemancountries
could you help us to patch that with a synced coding style?
(which mean for the double spaces fuction get())