Merge lp:~qqworini/ubuntu-rssreader-app/optimization-0 into lp:~ubuntu-shorts-dev/ubuntu-rssreader-app/trunk
- optimization-0
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Nicholas Skaggs |
Approved revision: | 81 |
Merged at revision: | 83 |
Proposed branch: | lp:~qqworini/ubuntu-rssreader-app/optimization-0 |
Merge into: | lp:~ubuntu-shorts-dev/ubuntu-rssreader-app/trunk |
Diff against target: |
740 lines (+316/-134) 9 files modified
OrganicGrid.qml (+142/-18) article_items/ArticleFullImg.qml (+4/-0) article_items/ArticleOneImgA.qml (+25/-14) databasemodule_v2.js (+2/-2) feeds/AppendFeedPage.qml (+1/-0) feeds/ChooseTopicPage.qml (+1/-0) feeds/EditFeed.qml (+9/-10) feeds/TopicComponent.qml (+109/-90) feeds/TopicManagement.qml (+23/-0) |
To merge this branch: | bzr merge lp:~qqworini/ubuntu-rssreader-app/optimization-0 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Nicholas Skaggs (community) | Needs Fixing | ||
Roman Shchekin | Approve | ||
Review via email: mp+188259@code.launchpad.net |
Commit message
optimization for gridview, articles, input method, edit-topic
optimization:
1. dynamic loads in gridview
2. now all articles' images has max height
3. database, table article add column "media_group"
4. optimize edit-topic, now click other topics will also cancel editing
5. virtual keybroad now will hide itself automatically
6. edit-feed page, feed name and feed url are read-only now
Description of the change
optimization for gridview, articles, input method, edit-topic
optimization:
1. dynamic loads in gridview
2. now all articles' images has max height
3. database, table article add column "media_group"
4. optimize edit-topic, now click other topics will also cancel editing
5. virtual keybroad now will hide itself automatically
6. edit-feed page, feed name and feed url are read-only now
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Roman Shchekin (mrqtros) wrote : | # |
Wow, Joey, works pretty fine, and consumes only ~60 mb of memory in start (empty app ~40).
Roman Shchekin (mrqtros) wrote : | # |
I want to use "top approve" of course, but someone from Canonical may want take a look too :)
Roman Shchekin (mrqtros) wrote : | # |
This merge fixes slow image loading too (because if all components are created simultaneously they are simultaneously too trying too download their image, even components in background. And user must w8)
Joey Chan (qqworini) wrote : | # |
I added a simple algorithm, lets the gridview only loads 10 articles at the beginning, then loads more when it detect about to reach the edge.
> This merge fixes slow image loading too (because if all components are created
> simultaneously they are simultaneously too trying too download their image,
> even components in background. And user must w8)
Roman Shchekin (mrqtros) wrote : | # |
Yes, programming must be simple to reach prefect results ;)
App now starts much faster and uses less memory =)
30.09.13 10:44 Joey Chan написал(а):
I added a simple algorithm, lets the gridview only loads 10 articles at the beginning, then loads more when it detect about to reach the edge.
> This merge fixes slow image loading too (because if all components are created
> simultaneously they are simultaneously too trying too download their image,
> even components in background. And user must w8)
--
https:/
You are reviewing the proposed merge of lp:~qqworini/ubuntu-rssreader-app/optimization-0 into lp:ubuntu-rssreader-app.
David Planella (dpm) wrote : | # |
On Mon, Sep 30, 2013 at 7:47 AM, Roman Shchekin <email address hidden> wrote:
> Review: Approve
>
> I want to use "top approve" of course, but someone from Canonical may want
> take a look too :)
>
>
Feel free to top-approve if you think the changes make sense and there is
nothing to fix, no need to block on approval from Canonical folks (unless
you explicitly want someone to review it). These apps are all
community-driven and meritocracy-driven, so you should think of Canonical
employees as reviewers with the same status as you guys, we're all Ubuntu
community members :)
Cheers,
David.
Roman Shchekin (mrqtros) wrote : | # |
Thanks, David, I can do it in evening only, can you please approve? =)
Btw, I've got device today =)
30.09.13 13:30 David Planella написал(а):
On Mon, Sep 30, 2013 at 7:47 AM, Roman Shchekin <email address hidden> wrote:
> Review: Approve
>
> I want to use "top approve" of course, but someone from Canonical may want
> take a look too :)
>
>
Feel free to top-approve if you think the changes make sense and there is
nothing to fix, no need to block on approval from Canonical folks (unless
you explicitly want someone to review it). These apps are all
community-driven and meritocracy-driven, so you should think of Canonical
employees as reviewers with the same status as you guys, we're all Ubuntu
community members :)
Cheers,
David.
--
https:/
You are reviewing the proposed merge of lp:~qqworini/ubuntu-rssreader-app/optimization-0 into lp:ubuntu-rssreader-app.
David Planella (dpm) wrote : | # |
Sure, proxy-approving :)
David Planella (dpm) wrote : | # |
Ah, sorry, I hadn't realized: tests are failing, so I can't top-approve. Joey: could you have a look at the tests that are failing and get in touch with fginther or balloons on IRC if you need help? Thanks!
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:81
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Joey Chan (qqworini) wrote : | # |
I asked balloons, he said that is the same problem (add feed toolbar missing) happened, but I can't reproduce it ...
Nicholas Skaggs (nskaggs) wrote : | # |
Let me update my device quickly and run again. The tests pass on the desktop, but fail to open the toolbar on the device.
Nicholas Skaggs (nskaggs) wrote : | # |
On the latests phone build, the tests still fail to open the toolbar. The current tests don't have this issue, so this is definitely a regression that needs fixed before merging this.
(The current trunk tests suffer from the missing 'next' button on the 'add feeds' screen)
Joey Chan (qqworini) wrote : | # |
Could somebody help try this branch, I still can't reproduce the "miss-toolbar-bug", thanks
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) : | # |
Nicholas Skaggs (nskaggs) wrote : | # |
As there are pending sdk issues with the application, and this merge fixes one of those issues, I approved despite the failing tests. This brings us closer to the tests completely working (because the app is working properly with these changes)
Preview Diff
1 | === modified file 'OrganicGrid.qml' |
2 | --- OrganicGrid.qml 2013-09-22 15:38:03 +0000 |
3 | +++ OrganicGrid.qml 2013-09-30 04:16:05 +0000 |
4 | @@ -14,6 +14,14 @@ |
5 | property bool isAll: false |
6 | property var feedArray: [] |
7 | |
8 | + // Initial values for the starting column of items |
9 | + property int xEdge : 0 |
10 | + property int lastColumnX : 0 |
11 | + property int itemY : randomMargin() |
12 | + property var sequence : [0,1,0,1,2,1,0,0,2,1,0,1,0,0] |
13 | + |
14 | + property int currentLoadedIndex: 0 |
15 | + |
16 | Component.onCompleted: { |
17 | prepareComponents() |
18 | } |
19 | @@ -77,6 +85,7 @@ |
20 | */ |
21 | function reload() { |
22 | console.time("reload_grid") |
23 | +// connFlickable.target = null |
24 | clear() |
25 | // Decide if we should load all articles in our database or a subset. |
26 | if (!isAll) |
27 | @@ -105,16 +114,18 @@ |
28 | } |
29 | |
30 | // Initial values for the starting column of items |
31 | - var xEdge = 0; |
32 | - var lastColumnX = 0; |
33 | - var y = randomMargin(); |
34 | + xEdge = 0; |
35 | + lastColumnX = 0; |
36 | + itemY = randomMargin(); |
37 | |
38 | // A hard-coded sequence that gives an organic look, but is not |
39 | // completely random |
40 | - var sequence = [0,1,0,1,2,1,0,0,2,1,0,1,0,0]; |
41 | +// var sequence = [0,1,0,1,2,1,0,0,2,1,0,1,0,0]; |
42 | // var componentsPath = "article_items/" + "Article" |
43 | |
44 | - for(var i = 0; i < articleModel.count; i++) { |
45 | + currentLoadedIndex = 0 |
46 | + var numAdd = articleModel.count > 10 ? 10 : articleModel.count |
47 | + for(var i = 0; i < numAdd /*articleModel.count*/; i++) { |
48 | var article = articleModel.get(i); |
49 | // var imageArray = ImageSeparator.separate(article.content) |
50 | var imageArray = [article.image] |
51 | @@ -172,8 +183,8 @@ |
52 | // This is the actual item that will be on display |
53 | var articleItem = component.createObject(itemContainer /*organicFlickable.contentItem*/, properties); |
54 | |
55 | - if(y + articleItem.height > organicGridRoot.height) { |
56 | - y = randomMargin(); |
57 | + if(itemY + articleItem.height > organicGridRoot.height) { |
58 | + itemY = randomMargin(); |
59 | xEdge = lastColumnX; |
60 | } |
61 | |
62 | @@ -185,9 +196,9 @@ |
63 | x += randomMargin(); |
64 | |
65 | articleItem.x = x |
66 | - articleItem.y = y |
67 | + articleItem.y = itemY |
68 | |
69 | - // Check for collisions with all other items |
70 | + // Check for collisions with all other itemsy |
71 | // mrqtros: Now we are look only at 0xA last items. |
72 | //for(var j = 0; j < rectangleList.length; j++) { // mrqtros |
73 | for(var j = Math.max(0, rectangleList.length - 0xA); j < rectangleList.length; j++) { |
74 | @@ -202,15 +213,124 @@ |
75 | |
76 | rectangleList.push(articleItem) |
77 | |
78 | - // Increment y for the next item |
79 | - y += articleItem.height + randomMargin(); |
80 | + // Increment itemY for the next item |
81 | + itemY += articleItem.height + randomMargin(); |
82 | } |
83 | |
84 | organicFlickable.scrollToStart() |
85 | + currentLoadedIndex += numAdd |
86 | +// connFlickable.target = organicFlickable |
87 | console.timeEnd("reload_grid") |
88 | } |
89 | |
90 | /*! |
91 | + * dynamic loads others articles in organic view. |
92 | + */ |
93 | + function loadMore () { |
94 | + console.time("loadmore") |
95 | + var numAdd |
96 | + var tempAdd = articleModel.count - currentLoadedIndex |
97 | + if (tempAdd > 20) { |
98 | + numAdd = 20 |
99 | + } |
100 | + else if (tempAdd > 0) { |
101 | + numAdd = tempAdd |
102 | + } |
103 | + else |
104 | + return |
105 | + |
106 | + for(var i = currentLoadedIndex; i < currentLoadedIndex + numAdd /*articleModel.count*/; i++) { |
107 | + var article = articleModel.get(i); |
108 | +// var imageArray = ImageSeparator.separate(article.content) |
109 | + var imageArray = [article.image] |
110 | +// console.log("imageArray: ", imageArray) |
111 | + var hasImage = (article.image !== ""); |
112 | + |
113 | + // Pick the type of size we will use for this item from the sequence |
114 | + var sizeType = sequence[i % sequence.length]; |
115 | + var alignType = Math.round(Math.random()) |
116 | + |
117 | + //var alignName |
118 | + var alignIndex |
119 | + |
120 | + if(!hasImage) { |
121 | + switch(alignType) { |
122 | + case 0: |
123 | + //alignName = "TextA" |
124 | + alignIndex = 0 |
125 | + break; |
126 | + case 1: |
127 | + //alignName = "TextB" |
128 | + alignIndex = 1 |
129 | + break; |
130 | + } |
131 | + //noImageName += "NoImage"; |
132 | + sizeType = 0; |
133 | + } |
134 | + else { |
135 | + switch(alignType) { |
136 | + case 0: |
137 | + //alignName = "OneImgA" |
138 | + alignIndex = 2 |
139 | + break; |
140 | + case 1: |
141 | + //alignName = "FullImg" |
142 | + alignIndex = 3 |
143 | + break; |
144 | + } |
145 | + } |
146 | + |
147 | + var component = delegateComponents[alignIndex] //Qt.createComponent(componentName); |
148 | + |
149 | + var properties = { |
150 | + "modelItem": article, |
151 | + "imageArray": imageArray, |
152 | + "rssModel": articleModel, |
153 | + "modelIndex": article.modelIndex |
154 | + } |
155 | + |
156 | + // This is the actual item that will be on display |
157 | + var articleItem = component.createObject(itemContainer /*organicFlickable.contentItem*/, properties); |
158 | + |
159 | + if(itemY + articleItem.height > organicGridRoot.height) { |
160 | + itemY = randomMargin(); |
161 | + xEdge = lastColumnX; |
162 | + } |
163 | + |
164 | + // The xEdge is where the last "column" of items were placed last |
165 | + // This keeps us moving forward in x-direction |
166 | + var x = xEdge + randomMargin(); |
167 | + |
168 | + // We add some extra random margin to make it look a bit more organic |
169 | + x += randomMargin(); |
170 | + |
171 | + articleItem.x = x |
172 | + articleItem.y = itemY |
173 | + |
174 | + // Check for collisions with all other itemsy |
175 | + // mrqtros: Now we are look only at 0xA last items. |
176 | + //for(var j = 0; j < rectangleList.length; j++) { // mrqtros |
177 | + for(var j = Math.max(0, rectangleList.length - 0xA); j < rectangleList.length; j++) { |
178 | + var rect2 = rectangleList[j] |
179 | + if(checkCollision(articleItem, rect2)) { |
180 | + articleItem.x = rect2.x + rect2.width + randomMargin(); |
181 | + } |
182 | + } |
183 | + |
184 | + // Did we move the x-edge value further to the right than before? |
185 | + lastColumnX = Math.max(articleItem.x, lastColumnX); |
186 | + |
187 | + rectangleList.push(articleItem) |
188 | + |
189 | + // Increment itemY for the next item |
190 | + itemY += articleItem.height + randomMargin(); |
191 | + } |
192 | + currentLoadedIndex += numAdd |
193 | + organicFlickable.canAdd = true |
194 | + console.timeEnd("loadmore") |
195 | + } |
196 | + |
197 | + /*! |
198 | * use Flickable as articles container |
199 | */ |
200 | Flickable { |
201 | @@ -221,7 +341,6 @@ |
202 | |
203 | Item { |
204 | id: itemContainer |
205 | - // color: "white" |
206 | anchors { |
207 | left: parent.left |
208 | top: parent.top |
209 | @@ -231,12 +350,17 @@ |
210 | height: parent.height |
211 | } |
212 | |
213 | -// Behavior on contentX { |
214 | -// NumberAnimation { |
215 | -// duration: 600 |
216 | -// easing.type: Easing.InOutQuart |
217 | -// } |
218 | -// } |
219 | + /*! |
220 | + * use onContentXChanged signal to detect if user is about to flick to edge |
221 | + * then load more articles |
222 | + */ |
223 | + property bool canAdd: true |
224 | + onContentXChanged: { |
225 | + if ((visibleArea.xPosition > (1 - visibleArea.widthRatio * 1.5)) && canAdd ) { |
226 | + canAdd = false |
227 | + loadMore() |
228 | + } |
229 | + } |
230 | |
231 | function scrollToStart() { |
232 | contentX = 0 |
233 | |
234 | === modified file 'article_items/ArticleFullImg.qml' |
235 | --- article_items/ArticleFullImg.qml 2013-09-22 15:05:33 +0000 |
236 | +++ article_items/ArticleFullImg.qml 2013-09-30 04:16:05 +0000 |
237 | @@ -38,6 +38,7 @@ |
238 | width: parent.width |
239 | height: pic.height > (articleFullImg.height - units.gu(1.5)) ? (articleFullImg.height - units.gu(1.5)) : pic.height |
240 | radius: "medium" |
241 | + opacity: height |
242 | image: Image { |
243 | id: pic |
244 | width: { |
245 | @@ -48,6 +49,9 @@ |
246 | source: imageArray[0] |
247 | sourceSize.width: uPic.width |
248 | } |
249 | + |
250 | + Behavior on height { UbuntuNumberAnimation{} } |
251 | + Behavior on opacity { NumberAnimation{} } |
252 | } |
253 | } |
254 | |
255 | |
256 | === modified file 'article_items/ArticleOneImgA.qml' |
257 | --- article_items/ArticleOneImgA.qml 2013-09-22 15:05:33 +0000 |
258 | +++ article_items/ArticleOneImgA.qml 2013-09-30 04:16:05 +0000 |
259 | @@ -26,28 +26,39 @@ |
260 | } |
261 | } |
262 | |
263 | - UbuntuShape { |
264 | - id: uPic |
265 | - |
266 | + Item { |
267 | + id: shapeClipper |
268 | width: parent.width |
269 | - height: pic.height /*> units.gu(12) ? pic.height : units.gu(12)*/ |
270 | - radius: "medium" |
271 | - image: Image { |
272 | - id: pic |
273 | - width: { |
274 | - if (implicitHeight < 50 || implicitWidth < 50) return 0 |
275 | - else return uPic.width |
276 | + height: uPic.height > (articleOneImgA.height * 0.75) ? (articleOneImgA.height * 0.75) : uPic.height |
277 | + clip: true |
278 | + |
279 | + UbuntuShape { |
280 | + id: uPic |
281 | + |
282 | + width: parent.width |
283 | + height: pic.height /*> units.gu(12) ? pic.height : units.gu(12)*/ |
284 | + radius: "medium" |
285 | + opacity: height |
286 | + image: Image { |
287 | + id: pic |
288 | + width: { |
289 | + if (implicitHeight < 50 || implicitWidth < 50) return 0 |
290 | + else return uPic.width |
291 | + } |
292 | + height: width * implicitHeight / implicitWidth |
293 | + source: imageArray[0] |
294 | + sourceSize.width: uPic.width |
295 | } |
296 | - height: width * implicitHeight / implicitWidth |
297 | - source: imageArray[0] |
298 | - sourceSize.width: uPic.width |
299 | + |
300 | + Behavior on height { UbuntuNumberAnimation{} } |
301 | + Behavior on opacity { NumberAnimation{} } |
302 | } |
303 | } |
304 | |
305 | Column { |
306 | anchors { |
307 | left: parent.left; right: parent.right; |
308 | - top: uPic.bottom; bottom: parent.bottom |
309 | + top: shapeClipper.bottom; bottom: parent.bottom |
310 | topMargin: units.gu(2); bottomMargin: units.gu(1.5); |
311 | leftMargin: units.gu(1); rightMargin: units.gu(1.5) |
312 | } |
313 | |
314 | === modified file 'databasemodule_v2.js' |
315 | --- databasemodule_v2.js 2013-09-28 14:30:29 +0000 |
316 | +++ databasemodule_v2.js 2013-09-30 04:16:05 +0000 |
317 | @@ -23,10 +23,10 @@ |
318 | // I am currently working with 190 symbols length strings, all is ok :) |
319 | function checkTableExists(transaction /* and additional string keys */) { |
320 | transaction.executeSql('PRAGMA foreign_keys = ON;') // enable foreign key support |
321 | - transaction.executeSql("CREATE TABLE IF NOT EXISTS feed (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,source TEXT NULL,title TEXT NULL,link TEXT NULL, description TEXT NULL, status char(1) NULL DEFAULT '0', pubdate INTEGER NULL,image TEXT NULL, count INTEGER NULL DEFAULT 0);") // add "count", count user click |
322 | + transaction.executeSql("CREATE TABLE IF NOT EXISTS feed (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,source TEXT NULL,title TEXT NULL,link TEXT NULL, description TEXT NULL, status char(1) NULL DEFAULT '0', pubdate INTEGER NULL,image TEXT NULL, count INTEGER NULL DEFAULT 0);") |
323 | transaction.executeSql("CREATE TABLE IF NOT EXISTS tag (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL UNIQUE );") |
324 | transaction.executeSql("CREATE TABLE IF NOT EXISTS feed_tag (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,feed_id INTEGER NULL,tag_id INTEGER NULL,FOREIGN KEY(feed_id) REFERENCES feed(id) on delete cascade);") |
325 | - transaction.executeSql("CREATE TABLE IF NOT EXISTS article ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title TEXT NULL, content TEXT NULL, link TEXT NULL, description TEXT NULL, pubdate INTEGER NULL, status char(1) NULL DEFAULT '0', favourite char(1) NULL DEFAULT '0', image TEXT NULL, guid TEXT NULL, feed_id INTEGER NULL,count INTEGER NULL DEFAULT 0);") |
326 | + transaction.executeSql("CREATE TABLE IF NOT EXISTS article ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title TEXT NULL, content TEXT NULL, link TEXT NULL, description TEXT NULL, pubdate INTEGER NULL, status char(1) NULL DEFAULT '0', favourite char(1) NULL DEFAULT '0', image TEXT NULL, guid TEXT NULL, feed_id INTEGER NULL,count INTEGER NULL DEFAULT 0, media_groups TEXT NULL);") |
327 | transaction.executeSql("CREATE TABLE IF NOT EXISTS settings ( id INTEGER, current_database_version TEXT NULL, database_last_updated TEXT NULL, view_mode char(1) NULL DEFAULT '0', update_interval INTEGER NULL DEFAULT 0, network_mode char(1) NULL DEFAULT '0');") |
328 | var rs = transaction.executeSql("select * from settings") |
329 | if (rs.rows.length == 0) |
330 | |
331 | === modified file 'feeds/AppendFeedPage.qml' |
332 | --- feeds/AppendFeedPage.qml 2013-09-27 09:49:16 +0000 |
333 | +++ feeds/AppendFeedPage.qml 2013-09-30 04:16:05 +0000 |
334 | @@ -184,6 +184,7 @@ |
335 | } |
336 | |
337 | onAccepted: { |
338 | + Qt.inputMethod.hide() |
339 | var userInput = text |
340 | |
341 | if (userInput == "") |
342 | |
343 | === modified file 'feeds/ChooseTopicPage.qml' |
344 | --- feeds/ChooseTopicPage.qml 2013-09-27 09:49:16 +0000 |
345 | +++ feeds/ChooseTopicPage.qml 2013-09-30 04:16:05 +0000 |
346 | @@ -119,6 +119,7 @@ |
347 | } |
348 | |
349 | onAccepted: { |
350 | + Qt.inputMethod.hide() |
351 | if (text.replace(/^\s+|\s+$/g, '') != "") { // Check that text contains only spaces. |
352 | var tagName = text |
353 | |
354 | |
355 | === modified file 'feeds/EditFeed.qml' |
356 | --- feeds/EditFeed.qml 2013-09-21 09:27:59 +0000 |
357 | +++ feeds/EditFeed.qml 2013-09-30 04:16:05 +0000 |
358 | @@ -11,19 +11,14 @@ |
359 | objectName: "editfeedpage" |
360 | title: i18n.tr("Edit Feed") |
361 | flickable: null/*content*/ |
362 | - tools: ToolbarItems { |
363 | + tools: null |
364 | + |
365 | + ToolbarItems { |
366 | id: toolbar |
367 | |
368 | opened: true |
369 | locked: true |
370 | |
371 | -// ToolbarButton { |
372 | -// id: actionsButton |
373 | -// text: i18n.tr("Reads") |
374 | -// iconSource: Qt.resolvedUrl("avatar.png") |
375 | -// onTriggered: ; |
376 | -// visible: true |
377 | -// } |
378 | Button |
379 | { |
380 | id: btnDelete |
381 | @@ -49,7 +44,7 @@ |
382 | |
383 | onClicked: |
384 | { |
385 | - DB.updateFeedByUser(feedId, feedTitle, feedURL) ; |
386 | +// DB.updateFeedByUser(feedId, feedTitle, feedURL) ; |
387 | DB.deleteFeedTag(feedId, previousTopicId) ; |
388 | DB.addFeedTag(feedId, newTopicId) ; |
389 | apply(feedId, newTopicId, previousTopicId) ; |
390 | @@ -95,7 +90,7 @@ |
391 | } |
392 | |
393 | function reloadPageContent() { |
394 | - |
395 | + editPage.tools = toolbar |
396 | } |
397 | |
398 | Flickable { |
399 | @@ -127,6 +122,8 @@ |
400 | text: feedTitle |
401 | width: parent.width - labelTitle.width - parent.spacing |
402 | anchors.verticalCenter: parent.verticalCenter |
403 | + readOnly: true |
404 | + hasClearButton: false |
405 | } |
406 | } |
407 | |
408 | @@ -148,6 +145,8 @@ |
409 | text: feedURL |
410 | width: parent.width - labelURL.width - parent.spacing |
411 | anchors.verticalCenter: parent.verticalCenter |
412 | + readOnly: true |
413 | + hasClearButton: false |
414 | } |
415 | } |
416 | |
417 | |
418 | === modified file 'feeds/TopicComponent.qml' |
419 | --- feeds/TopicComponent.qml 2013-09-18 12:03:36 +0000 |
420 | +++ feeds/TopicComponent.qml 2013-09-30 04:16:05 +0000 |
421 | @@ -19,6 +19,7 @@ |
422 | property int modelIndex |
423 | |
424 | signal edit() |
425 | + signal editCanceled() |
426 | |
427 | // onClicked: isExpended = !isExpended ; |
428 | |
429 | @@ -64,28 +65,38 @@ |
430 | id: columnContent |
431 | anchors{ left: parent.left; right: parent.right } |
432 | |
433 | + /* |
434 | + topic item |
435 | + */ |
436 | Item |
437 | { |
438 | anchors{ left: parent.left; right: parent.right } |
439 | height: units.gu(5) |
440 | |
441 | + /* |
442 | + topic header for showing name and swipe remove |
443 | + */ |
444 | ListItem.Base{ |
445 | id: headerTopic |
446 | + enabled: !rowTopicContent.isEditing |
447 | removable: true |
448 | height: units.gu(5) |
449 | |
450 | - onClicked: isExpended = !isExpended |
451 | + onClicked: { |
452 | + isExpended = !isExpended |
453 | + editCanceled() |
454 | + } |
455 | |
456 | onItemRemoved:{ |
457 | console.log("item about to be removed: ", topicComponent.topicId) |
458 | -// itemCancelDelete.startCounting() |
459 | + // itemCancelDelete.startCounting() |
460 | var result = DB.deleteFeedByTagId(topicComponent.topicId) |
461 | if (result.rowsAffected == undefined) |
462 | { |
463 | topicManagement.reloadTopics() |
464 | } |
465 | result = DB.deleteTag(topicComponent.topicId) |
466 | -// topicManagement.reloadTopics() |
467 | + // topicManagement.reloadTopics() |
468 | if (result.rowsAffected == 1) |
469 | { |
470 | topicManagement.removeModelItem(topicComponent.modelIndex) |
471 | @@ -95,105 +106,113 @@ |
472 | topicManagement.reloadTopics() |
473 | } |
474 | } |
475 | - |
476 | - Row{ |
477 | - id: rowTopicContent |
478 | - anchors |
479 | - { |
480 | - top: parent.top; bottom: parent.bottom; left: parent.left; |
481 | - leftMargin: units.gu(0); topMargin: units.gu(1); bottomMargin: units.gu(1); |
482 | - } |
483 | - spacing: units.gu(2) |
484 | - |
485 | - property bool isEditing: false |
486 | - |
487 | - Image{ |
488 | - anchors |
489 | - { |
490 | - top: parent.top; bottom: parent.bottom; |
491 | - topMargin: units.gu(0.5); bottomMargin: units.gu(0.5); |
492 | - } |
493 | - fillMode: Image.PreserveAspectFit |
494 | - source: Qt.resolvedUrl("../icons_tmp/compose.svg") |
495 | - smooth: true |
496 | - |
497 | - MouseArea{ |
498 | - enabled: !rowTopicContent.isEditing |
499 | - anchors { fill: parent; margins: units.gu(-1) } |
500 | - onClicked: |
501 | - { |
502 | - rowTopicContent.isEditing = true |
503 | - topicComponent.edit() |
504 | - } |
505 | - } |
506 | - } |
507 | - |
508 | - Label{ |
509 | - id: labelTopicName |
510 | - anchors.verticalCenter: parent.verticalCenter |
511 | - text: topicName |
512 | - width: rowTopicContent.isEditing ? 0 : paintedWidth |
513 | - opacity: rowTopicContent.isEditing ? 0 : 1 |
514 | - |
515 | - // Behavior on width { UbuntuNumberAnimation{} } |
516 | - } |
517 | - |
518 | - TextField{ |
519 | - id: inputTopicName |
520 | - anchors.verticalCenter: parent.verticalCenter |
521 | - text: topicName |
522 | - width: rowTopicContent.isEditing ? headerTopic.width - units.gu(15) : 0 |
523 | - opacity: rowTopicContent.isEditing ? 1 : 0 |
524 | - hasClearButton: true |
525 | - activeFocusOnPress: true |
526 | - |
527 | - Behavior on width { UbuntuNumberAnimation{} } |
528 | - |
529 | - onAccepted: { |
530 | - Qt.inputMethod.hide() |
531 | - } |
532 | - |
533 | - Connections { |
534 | - target: Qt.inputMethod |
535 | - onVisibleChanged: { |
536 | - if (!Qt.inputMethod.visible) { |
537 | - topicComponent.focus = true |
538 | - } |
539 | - } |
540 | - } |
541 | - } |
542 | + } |
543 | + |
544 | + /* |
545 | + enable if edit mode active |
546 | + */ |
547 | + Row{ |
548 | + id: rowTopicContent |
549 | + anchors |
550 | + { |
551 | + top: parent.top; bottom: parent.bottom; left: parent.left; |
552 | + leftMargin: units.gu(1); topMargin: units.gu(0.7); bottomMargin: units.gu(1); |
553 | } |
554 | + spacing: units.gu(2) |
555 | + |
556 | + property bool isEditing: false |
557 | |
558 | Image{ |
559 | - id: imgArrow |
560 | anchors |
561 | { |
562 | - right: parent.right; top: parent.top; bottom: parent.bottom; |
563 | - topMargin: units.gu(1.5); bottomMargin: units.gu(1.5); rightMargin: units.gu(2) |
564 | + top: parent.top; bottom: parent.bottom; |
565 | + topMargin: units.gu(0.5); bottomMargin: units.gu(0.5); |
566 | } |
567 | fillMode: Image.PreserveAspectFit |
568 | - source: Qt.resolvedUrl("../icons_tmp/go-to.svg") |
569 | + source: Qt.resolvedUrl("../icons_tmp/compose.svg") |
570 | smooth: true |
571 | |
572 | - Behavior on rotation { UbuntuNumberAnimation{} } |
573 | - |
574 | - states: [ |
575 | - State { |
576 | - name: "expended" |
577 | - when: topicComponent.isExpended |
578 | - |
579 | - PropertyChanges |
580 | - { |
581 | - target: imgArrow |
582 | - rotation: 90 |
583 | - } |
584 | - } |
585 | - ] |
586 | - } |
587 | - } |
588 | + MouseArea{ |
589 | + enabled: !rowTopicContent.isEditing |
590 | + anchors { fill: parent; margins: units.gu(-1) } |
591 | + onClicked: |
592 | + { |
593 | + rowTopicContent.isEditing = true |
594 | + topicComponent.edit() |
595 | + inputTopicName.focus = true |
596 | + } |
597 | + } |
598 | + } |
599 | + |
600 | + Label{ |
601 | + id: labelTopicName |
602 | + anchors.verticalCenter: parent.verticalCenter |
603 | + text: topicName |
604 | + width: rowTopicContent.isEditing ? 0 : paintedWidth |
605 | + opacity: rowTopicContent.isEditing ? 0 : 1 |
606 | + |
607 | + // Behavior on width { UbuntuNumberAnimation{} } |
608 | + } |
609 | + |
610 | + TextField{ |
611 | + id: inputTopicName |
612 | + anchors.verticalCenter: parent.verticalCenter |
613 | + text: topicName |
614 | + width: rowTopicContent.isEditing ? headerTopic.width - units.gu(15) : 0 |
615 | + opacity: rowTopicContent.isEditing ? 1 : 0 |
616 | + hasClearButton: true |
617 | + activeFocusOnPress: true |
618 | + |
619 | + Behavior on width { UbuntuNumberAnimation{} } |
620 | + |
621 | + onAccepted: { |
622 | + console.log("accepted?") |
623 | + Qt.inputMethod.hide() |
624 | + } |
625 | + |
626 | + Keys.enabled: rowTopicContent.isEditing |
627 | + Keys.onPressed: { |
628 | + event.accepted = false |
629 | + if (event.key == Qt.Key_Return) { |
630 | + Qt.inputMethod.hide() |
631 | + } |
632 | + } |
633 | + } |
634 | + } |
635 | + |
636 | + Image{ |
637 | + id: imgArrow |
638 | + anchors |
639 | + { |
640 | + right: parent.right; top: parent.top; bottom: parent.bottom; |
641 | + topMargin: units.gu(1.5); bottomMargin: units.gu(1.5); rightMargin: units.gu(2) |
642 | + } |
643 | + fillMode: Image.PreserveAspectFit |
644 | + source: Qt.resolvedUrl("../icons_tmp/go-to.svg") |
645 | + smooth: true |
646 | + |
647 | + Behavior on rotation { UbuntuNumberAnimation{} } |
648 | + |
649 | + states: [ |
650 | + State { |
651 | + name: "expended" |
652 | + when: topicComponent.isExpended |
653 | + |
654 | + PropertyChanges |
655 | + { |
656 | + target: imgArrow |
657 | + rotation: 90 |
658 | + } |
659 | + } |
660 | + ] |
661 | + } |
662 | + |
663 | |
664 | } |
665 | |
666 | + /* |
667 | + feeds listview |
668 | + */ |
669 | ListView |
670 | { |
671 | id: feedList |
672 | |
673 | === modified file 'feeds/TopicManagement.qml' |
674 | --- feeds/TopicManagement.qml 2013-09-18 12:03:36 +0000 |
675 | +++ feeds/TopicManagement.qml 2013-09-30 04:16:05 +0000 |
676 | @@ -40,6 +40,9 @@ |
677 | |
678 | } |
679 | |
680 | + /* |
681 | + toolbar for normal state |
682 | + */ |
683 | ToolbarItems { |
684 | id: toolbar |
685 | |
686 | @@ -52,6 +55,9 @@ |
687 | } |
688 | } |
689 | |
690 | + /* |
691 | + toolbar for editing state |
692 | + */ |
693 | ToolbarItems { |
694 | id: editConfirm |
695 | opened: true |
696 | @@ -87,6 +93,9 @@ |
697 | } |
698 | } |
699 | |
700 | + /* |
701 | + main content |
702 | + */ |
703 | Flickable { |
704 | id: content |
705 | anchors.fill: parent |
706 | @@ -96,6 +105,9 @@ |
707 | Column{ |
708 | anchors{ left: parent.left; right: parent.right } |
709 | |
710 | + /* |
711 | + add topic button |
712 | + */ |
713 | Item { |
714 | id: itemAddTopic |
715 | objectName: "addTopic" |
716 | @@ -135,6 +147,9 @@ |
717 | } |
718 | } |
719 | |
720 | + /* |
721 | + topic listview |
722 | + */ |
723 | ListView { |
724 | id: topicList |
725 | anchors{ left: parent.left; right: parent.right } |
726 | @@ -190,6 +205,14 @@ |
727 | editConfirm.visible = true |
728 | topicList.currentIndex = index |
729 | } |
730 | + |
731 | + onEditCanceled: { |
732 | + if (topicList.currentItem) |
733 | + topicList.currentItem.cancelEdit() |
734 | + topicManagement.state = "" |
735 | + editConfirm.visible = false |
736 | + topicList.currentIndex = -1 |
737 | + } |
738 | } |
739 | |
740 | DropArea { |
FAILED: Continuous integration, rev:81 91.189. 93.70:8080/ job/ubuntu- rssreader- app-ci/ 61/ 91.189. 93.70:8080/ job/generic- mediumtests/ 563 91.189. 93.70:8080/ job/ubuntu- rssreader- app-precise- amd64-ci/ 61 91.189. 93.70:8080/ job/ubuntu- rssreader- app-quantal- amd64-ci/ 61 91.189. 93.70:8080/ job/ubuntu- rssreader- app-raring- amd64-ci/ 61 91.189. 93.70:8080/ job/ubuntu- rssreader- app-saucy- amd64-ci/ 61
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- rssreader- app-ci/ 61/rebuild
http://