Merge lp:~mzanetti/reminders-app/listitemwithactions into lp:reminders-app
- listitemwithactions
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Riccardo Padovani | ||||
Approved revision: | 345 | ||||
Merged at revision: | 343 | ||||
Proposed branch: | lp:~mzanetti/reminders-app/listitemwithactions | ||||
Merge into: | lp:reminders-app | ||||
Diff against target: |
758 lines (+580/-45) 10 files modified
src/app/qml/components/ListItemWithActions.qml (+455/-0) src/app/qml/components/ListItemWithActionsCheckBox.qml (+25/-0) src/app/qml/components/NotesDelegate.qml (+39/-4) src/app/qml/components/RemindersDelegate.qml (+30/-37) src/app/qml/components/ubuntu_component_store.json (+6/-0) src/app/qml/reminders.qml (+3/-1) src/app/qml/ui/NotesPage.qml (+17/-1) src/app/qml/ui/RemindersPage.qml (+2/-1) src/libqtevernote/note.cpp (+1/-1) src/libqtevernote/resourceimageprovider.cpp (+2/-0) |
||||
To merge this branch: | bzr merge lp:~mzanetti/reminders-app/listitemwithactions | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Riccardo Padovani | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+249585@code.launchpad.net |
Commit message
use the awesome ListItemWithActions from the Ubuntu Component Store
Description of the change
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
- 340. By Michael Zanetti
-
also allow editing tags from the listitemmenu
- 341. By Michael Zanetti
-
also use the listitemwithactions for the reminders page
- 342. By Michael Zanetti
-
drop commented code
- 343. By Michael Zanetti
-
allow editing the reminder from the listitem actions
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:340
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:343
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 344. By Michael Zanetti
-
fix reminders delegate background color
- 345. By Michael Zanetti
-
fix a bug in ListItemWithActions
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:344
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:345
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Riccardo Padovani (rpadovani) wrote : | # |
Awesome, thanks!
Preview Diff
1 | === added file 'src/app/qml/components/ListItemWithActions.qml' | |||
2 | --- src/app/qml/components/ListItemWithActions.qml 1970-01-01 00:00:00 +0000 | |||
3 | +++ src/app/qml/components/ListItemWithActions.qml 2015-02-13 01:03:14 +0000 | |||
4 | @@ -0,0 +1,455 @@ | |||
5 | 1 | /* | ||
6 | 2 | * Copyright (C) 2012-2014 Canonical, Ltd. | ||
7 | 3 | * | ||
8 | 4 | * This program is free software; you can redistribute it and/or modify | ||
9 | 5 | * it under the terms of the GNU General Public License as published by | ||
10 | 6 | * the Free Software Foundation; version 3. | ||
11 | 7 | * | ||
12 | 8 | * This program is distributed in the hope that it will be useful, | ||
13 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | 11 | * GNU General Public License for more details. | ||
16 | 12 | * | ||
17 | 13 | * You should have received a copy of the GNU General Public License | ||
18 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | 15 | */ | ||
20 | 16 | |||
21 | 17 | import QtQuick 2.2 | ||
22 | 18 | import Ubuntu.Components 1.1 | ||
23 | 19 | |||
24 | 20 | Item { | ||
25 | 21 | id: root | ||
26 | 22 | |||
27 | 23 | property Action leftSideAction: null | ||
28 | 24 | property list<Action> rightSideActions | ||
29 | 25 | property double defaultHeight: units.gu(8) | ||
30 | 26 | property bool locked: false | ||
31 | 27 | property Action activeAction: null | ||
32 | 28 | property var activeItem: null | ||
33 | 29 | property bool triggerActionOnMouseRelease: false | ||
34 | 30 | property color color: Theme.palette.normal.background | ||
35 | 31 | property color selectedColor: "#E6E6E6" | ||
36 | 32 | property bool selected: false | ||
37 | 33 | property bool selectionMode: false | ||
38 | 34 | property alias internalAnchors: mainContents.anchors | ||
39 | 35 | default property alias contents: mainContents.children | ||
40 | 36 | |||
41 | 37 | readonly property double actionWidth: units.gu(4) | ||
42 | 38 | readonly property double leftActionWidth: units.gu(10) | ||
43 | 39 | readonly property double actionThreshold: actionWidth * 0.4 | ||
44 | 40 | readonly property double threshold: 0.4 | ||
45 | 41 | readonly property string swipeState: main.x == 0 ? "Normal" : main.x > 0 ? "LeftToRight" : "RightToLeft" | ||
46 | 42 | readonly property alias swipping: mainItemMoving.running | ||
47 | 43 | readonly property bool _showActions: mouseArea.pressed || swipeState != "Normal" || swipping | ||
48 | 44 | |||
49 | 45 | /* internal */ | ||
50 | 46 | property var _visibleRightSideActions: filterVisibleActions(rightSideActions) | ||
51 | 47 | |||
52 | 48 | signal itemClicked(var mouse) | ||
53 | 49 | signal itemPressAndHold(var mouse) | ||
54 | 50 | |||
55 | 51 | function returnToBoundsRTL(direction) | ||
56 | 52 | { | ||
57 | 53 | var actionFullWidth = actionWidth + units.gu(2) | ||
58 | 54 | |||
59 | 55 | // go back to normal state if swipping reverse | ||
60 | 56 | if (direction === "LTR") { | ||
61 | 57 | updatePosition(0) | ||
62 | 58 | return | ||
63 | 59 | } else if (!triggerActionOnMouseRelease) { | ||
64 | 60 | updatePosition(-rightActionsView.width + units.gu(2)) | ||
65 | 61 | return | ||
66 | 62 | } | ||
67 | 63 | |||
68 | 64 | var xOffset = Math.abs(main.x) | ||
69 | 65 | var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length) | ||
70 | 66 | var newX = 0 | ||
71 | 67 | if (index === _visibleRightSideActions.length) { | ||
72 | 68 | newX = -(rightActionsView.width - units.gu(2)) | ||
73 | 69 | } else if (index >= 1) { | ||
74 | 70 | newX = -(actionFullWidth * index) | ||
75 | 71 | } | ||
76 | 72 | updatePosition(newX) | ||
77 | 73 | } | ||
78 | 74 | |||
79 | 75 | function returnToBoundsLTR(direction) | ||
80 | 76 | { | ||
81 | 77 | var finalX = leftActionWidth | ||
82 | 78 | if ((direction === "RTL") || (main.x <= (finalX * root.threshold))) | ||
83 | 79 | finalX = 0 | ||
84 | 80 | updatePosition(finalX) | ||
85 | 81 | } | ||
86 | 82 | |||
87 | 83 | function returnToBounds(direction) | ||
88 | 84 | { | ||
89 | 85 | if (main.x < 0) { | ||
90 | 86 | returnToBoundsRTL(direction) | ||
91 | 87 | } else if (main.x > 0) { | ||
92 | 88 | returnToBoundsLTR(direction) | ||
93 | 89 | } else { | ||
94 | 90 | updatePosition(0) | ||
95 | 91 | } | ||
96 | 92 | } | ||
97 | 93 | |||
98 | 94 | function contains(item, point, marginX) | ||
99 | 95 | { | ||
100 | 96 | var itemStartX = item.x - marginX | ||
101 | 97 | var itemEndX = item.x + item.width + marginX | ||
102 | 98 | return (point.x >= itemStartX) && (point.x <= itemEndX) && | ||
103 | 99 | (point.y >= item.y) && (point.y <= (item.y + item.height)); | ||
104 | 100 | } | ||
105 | 101 | |||
106 | 102 | function getActionAt(point) | ||
107 | 103 | { | ||
108 | 104 | if (contains(leftActionView, point, 0)) { | ||
109 | 105 | return leftSideAction | ||
110 | 106 | } else if (contains(rightActionsView, point, 0)) { | ||
111 | 107 | var newPoint = root.mapToItem(rightActionsView, point.x, point.y) | ||
112 | 108 | for (var i = 0; i < rightActionsRepeater.count; i++) { | ||
113 | 109 | var child = rightActionsRepeater.itemAt(i) | ||
114 | 110 | if (contains(child, newPoint, units.gu(1))) { | ||
115 | 111 | return i | ||
116 | 112 | } | ||
117 | 113 | } | ||
118 | 114 | } | ||
119 | 115 | return -1 | ||
120 | 116 | } | ||
121 | 117 | |||
122 | 118 | function updateActiveAction() | ||
123 | 119 | { | ||
124 | 120 | if (triggerActionOnMouseRelease && | ||
125 | 121 | (main.x <= -(root.actionWidth + units.gu(2))) && | ||
126 | 122 | (main.x > -(rightActionsView.width - units.gu(2)))) { | ||
127 | 123 | var actionFullWidth = actionWidth + units.gu(2) | ||
128 | 124 | var xOffset = Math.abs(main.x) | ||
129 | 125 | var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length) | ||
130 | 126 | index = index - 1 | ||
131 | 127 | if (index > -1) { | ||
132 | 128 | root.activeItem = rightActionsRepeater.itemAt(index) | ||
133 | 129 | root.activeAction = root._visibleRightSideActions[index] | ||
134 | 130 | } | ||
135 | 131 | } else { | ||
136 | 132 | root.activeAction = null | ||
137 | 133 | } | ||
138 | 134 | } | ||
139 | 135 | |||
140 | 136 | function resetSwipe() | ||
141 | 137 | { | ||
142 | 138 | updatePosition(0) | ||
143 | 139 | } | ||
144 | 140 | |||
145 | 141 | function filterVisibleActions(actions) | ||
146 | 142 | { | ||
147 | 143 | var visibleActions = [] | ||
148 | 144 | for(var i = 0; i < actions.length; i++) { | ||
149 | 145 | var action = actions[i] | ||
150 | 146 | if (action.visible) { | ||
151 | 147 | visibleActions.push(action) | ||
152 | 148 | } | ||
153 | 149 | } | ||
154 | 150 | return visibleActions | ||
155 | 151 | } | ||
156 | 152 | |||
157 | 153 | function updatePosition(pos) | ||
158 | 154 | { | ||
159 | 155 | if (!root.triggerActionOnMouseRelease && (pos !== 0)) { | ||
160 | 156 | mouseArea.state = pos > 0 ? "RightToLeft" : "LeftToRight" | ||
161 | 157 | } else { | ||
162 | 158 | mouseArea.state = "" | ||
163 | 159 | } | ||
164 | 160 | main.x = pos | ||
165 | 161 | } | ||
166 | 162 | |||
167 | 163 | states: [ | ||
168 | 164 | State { | ||
169 | 165 | name: "select" | ||
170 | 166 | when: selectionMode || selected | ||
171 | 167 | PropertyChanges { | ||
172 | 168 | target: selectionIcon | ||
173 | 169 | source: Qt.resolvedUrl("ListItemWithActionsCheckBox.qml") | ||
174 | 170 | anchors.leftMargin: units.gu(2) | ||
175 | 171 | } | ||
176 | 172 | PropertyChanges { | ||
177 | 173 | target: root | ||
178 | 174 | locked: true | ||
179 | 175 | } | ||
180 | 176 | PropertyChanges { | ||
181 | 177 | target: main | ||
182 | 178 | x: 0 | ||
183 | 179 | } | ||
184 | 180 | } | ||
185 | 181 | ] | ||
186 | 182 | |||
187 | 183 | height: defaultHeight | ||
188 | 184 | clip: height !== defaultHeight | ||
189 | 185 | |||
190 | 186 | Rectangle { | ||
191 | 187 | id: leftActionView | ||
192 | 188 | |||
193 | 189 | anchors { | ||
194 | 190 | top: parent.top | ||
195 | 191 | bottom: parent.bottom | ||
196 | 192 | right: main.left | ||
197 | 193 | } | ||
198 | 194 | width: root.leftActionWidth + actionThreshold | ||
199 | 195 | visible: leftSideAction | ||
200 | 196 | color: UbuntuColors.red | ||
201 | 197 | |||
202 | 198 | Icon { | ||
203 | 199 | anchors { | ||
204 | 200 | centerIn: parent | ||
205 | 201 | horizontalCenterOffset: actionThreshold / 2 | ||
206 | 202 | } | ||
207 | 203 | name: leftSideAction && _showActions ? leftSideAction.iconName : "" | ||
208 | 204 | color: Theme.palette.selected.field | ||
209 | 205 | height: units.gu(3) | ||
210 | 206 | width: units.gu(3) | ||
211 | 207 | } | ||
212 | 208 | } | ||
213 | 209 | |||
214 | 210 | Rectangle { | ||
215 | 211 | id: rightActionsView | ||
216 | 212 | |||
217 | 213 | anchors { | ||
218 | 214 | top: main.top | ||
219 | 215 | left: main.right | ||
220 | 216 | bottom: main.bottom | ||
221 | 217 | } | ||
222 | 218 | visible: _visibleRightSideActions.length > 0 | ||
223 | 219 | width: rightActionsRepeater.count > 0 ? rightActionsRepeater.count * (root.actionWidth + units.gu(2)) + root.actionThreshold + units.gu(2) : 0 | ||
224 | 220 | color: "white" | ||
225 | 221 | Row { | ||
226 | 222 | anchors{ | ||
227 | 223 | top: parent.top | ||
228 | 224 | left: parent.left | ||
229 | 225 | leftMargin: units.gu(2) | ||
230 | 226 | right: parent.right | ||
231 | 227 | rightMargin: units.gu(2) | ||
232 | 228 | bottom: parent.bottom | ||
233 | 229 | } | ||
234 | 230 | spacing: units.gu(2) | ||
235 | 231 | Repeater { | ||
236 | 232 | id: rightActionsRepeater | ||
237 | 233 | |||
238 | 234 | model: _showActions ? _visibleRightSideActions : [] | ||
239 | 235 | Item { | ||
240 | 236 | property alias image: img | ||
241 | 237 | |||
242 | 238 | height: rightActionsView.height | ||
243 | 239 | width: root.actionWidth | ||
244 | 240 | |||
245 | 241 | Icon { | ||
246 | 242 | id: img | ||
247 | 243 | |||
248 | 244 | anchors.centerIn: parent | ||
249 | 245 | width: units.gu(3) | ||
250 | 246 | height: units.gu(3) | ||
251 | 247 | name: modelData.iconName | ||
252 | 248 | source: modelData.iconSource | ||
253 | 249 | color: root.activeAction === modelData ? UbuntuColors.lightAubergine : UbuntuColors.lightGrey | ||
254 | 250 | } | ||
255 | 251 | } | ||
256 | 252 | } | ||
257 | 253 | } | ||
258 | 254 | } | ||
259 | 255 | |||
260 | 256 | |||
261 | 257 | Rectangle { | ||
262 | 258 | id: main | ||
263 | 259 | objectName: "mainItem" | ||
264 | 260 | |||
265 | 261 | anchors { | ||
266 | 262 | top: parent.top | ||
267 | 263 | bottom: parent.bottom | ||
268 | 264 | } | ||
269 | 265 | |||
270 | 266 | width: parent.width | ||
271 | 267 | color: root.selected ? root.selectedColor : root.color | ||
272 | 268 | |||
273 | 269 | Loader { | ||
274 | 270 | id: selectionIcon | ||
275 | 271 | |||
276 | 272 | anchors { | ||
277 | 273 | left: main.left | ||
278 | 274 | verticalCenter: main.verticalCenter | ||
279 | 275 | } | ||
280 | 276 | width: (status === Loader.Ready) ? item.implicitWidth : 0 | ||
281 | 277 | visible: (status === Loader.Ready) && (item.width === item.implicitWidth) | ||
282 | 278 | Behavior on width { | ||
283 | 279 | NumberAnimation { | ||
284 | 280 | duration: UbuntuAnimation.SnapDuration | ||
285 | 281 | } | ||
286 | 282 | } | ||
287 | 283 | } | ||
288 | 284 | |||
289 | 285 | |||
290 | 286 | Item { | ||
291 | 287 | id: mainContents | ||
292 | 288 | |||
293 | 289 | anchors { | ||
294 | 290 | left: selectionIcon.right | ||
295 | 291 | // leftMargin: units.gu(2) | ||
296 | 292 | top: parent.top | ||
297 | 293 | // topMargin: units.gu(1) | ||
298 | 294 | right: parent.right | ||
299 | 295 | // rightMargin: units.gu(2) | ||
300 | 296 | bottom: parent.bottom | ||
301 | 297 | // bottomMargin: units.gu(1) | ||
302 | 298 | } | ||
303 | 299 | } | ||
304 | 300 | |||
305 | 301 | Behavior on x { | ||
306 | 302 | UbuntuNumberAnimation { | ||
307 | 303 | id: mainItemMoving | ||
308 | 304 | |||
309 | 305 | easing.type: Easing.OutElastic | ||
310 | 306 | duration: UbuntuAnimation.SlowDuration | ||
311 | 307 | } | ||
312 | 308 | } | ||
313 | 309 | Behavior on color { | ||
314 | 310 | ColorAnimation {} | ||
315 | 311 | } | ||
316 | 312 | } | ||
317 | 313 | |||
318 | 314 | SequentialAnimation { | ||
319 | 315 | id: triggerAction | ||
320 | 316 | |||
321 | 317 | property var currentItem: root.activeItem ? root.activeItem.image : null | ||
322 | 318 | |||
323 | 319 | running: false | ||
324 | 320 | ParallelAnimation { | ||
325 | 321 | UbuntuNumberAnimation { | ||
326 | 322 | target: triggerAction.currentItem | ||
327 | 323 | property: "opacity" | ||
328 | 324 | from: 1.0 | ||
329 | 325 | to: 0.0 | ||
330 | 326 | duration: UbuntuAnimation.SlowDuration | ||
331 | 327 | easing {type: Easing.InOutBack; } | ||
332 | 328 | } | ||
333 | 329 | UbuntuNumberAnimation { | ||
334 | 330 | target: triggerAction.currentItem | ||
335 | 331 | properties: "width, height" | ||
336 | 332 | from: units.gu(3) | ||
337 | 333 | to: root.actionWidth | ||
338 | 334 | duration: UbuntuAnimation.SlowDuration | ||
339 | 335 | easing {type: Easing.InOutBack; } | ||
340 | 336 | } | ||
341 | 337 | } | ||
342 | 338 | PropertyAction { | ||
343 | 339 | target: triggerAction.currentItem | ||
344 | 340 | properties: "width, height" | ||
345 | 341 | value: units.gu(3) | ||
346 | 342 | } | ||
347 | 343 | PropertyAction { | ||
348 | 344 | target: triggerAction.currentItem | ||
349 | 345 | properties: "opacity" | ||
350 | 346 | value: 1.0 | ||
351 | 347 | } | ||
352 | 348 | ScriptAction { | ||
353 | 349 | script: { | ||
354 | 350 | root.activeAction.triggered(root) | ||
355 | 351 | root.activeAction = null; | ||
356 | 352 | mouseArea.state = "" | ||
357 | 353 | } | ||
358 | 354 | } | ||
359 | 355 | PauseAnimation { | ||
360 | 356 | duration: 500 | ||
361 | 357 | } | ||
362 | 358 | UbuntuNumberAnimation { | ||
363 | 359 | target: main | ||
364 | 360 | property: "x" | ||
365 | 361 | to: 0 | ||
366 | 362 | } | ||
367 | 363 | } | ||
368 | 364 | |||
369 | 365 | MouseArea { | ||
370 | 366 | id: mouseArea | ||
371 | 367 | |||
372 | 368 | property bool locked: root.locked || ((root.leftSideAction === null) && (root._visibleRightSideActions.count === 0)) | ||
373 | 369 | property bool manual: false | ||
374 | 370 | property string direction: "None" | ||
375 | 371 | property real lastX: -1 | ||
376 | 372 | |||
377 | 373 | anchors.fill: parent | ||
378 | 374 | drag { | ||
379 | 375 | target: locked ? null : main | ||
380 | 376 | axis: Drag.XAxis | ||
381 | 377 | minimumX: rightActionsView.visible ? -(rightActionsView.width) : 0 | ||
382 | 378 | maximumX: leftActionView.visible ? leftActionView.width : 0 | ||
383 | 379 | threshold: root.actionThreshold | ||
384 | 380 | } | ||
385 | 381 | |||
386 | 382 | states: [ | ||
387 | 383 | State { | ||
388 | 384 | name: "LeftToRight" | ||
389 | 385 | PropertyChanges { | ||
390 | 386 | target: mouseArea | ||
391 | 387 | drag.maximumX: 0 | ||
392 | 388 | } | ||
393 | 389 | }, | ||
394 | 390 | State { | ||
395 | 391 | name: "RightToLeft" | ||
396 | 392 | PropertyChanges { | ||
397 | 393 | target: mouseArea | ||
398 | 394 | drag.minimumX: 0 | ||
399 | 395 | } | ||
400 | 396 | } | ||
401 | 397 | ] | ||
402 | 398 | |||
403 | 399 | onMouseXChanged: { | ||
404 | 400 | var offset = (lastX - mouseX) | ||
405 | 401 | if (Math.abs(offset) <= root.actionThreshold) { | ||
406 | 402 | return | ||
407 | 403 | } | ||
408 | 404 | lastX = mouseX | ||
409 | 405 | direction = offset > 0 ? "RTL" : "LTR"; | ||
410 | 406 | } | ||
411 | 407 | |||
412 | 408 | onPressed: { | ||
413 | 409 | lastX = mouse.x | ||
414 | 410 | } | ||
415 | 411 | |||
416 | 412 | onReleased: { | ||
417 | 413 | if (root.triggerActionOnMouseRelease && root.activeAction) { | ||
418 | 414 | triggerAction.start() | ||
419 | 415 | } else { | ||
420 | 416 | root.returnToBounds(direction) | ||
421 | 417 | root.activeAction = null | ||
422 | 418 | } | ||
423 | 419 | lastX = -1 | ||
424 | 420 | direction = "None" | ||
425 | 421 | } | ||
426 | 422 | onClicked: { | ||
427 | 423 | if (main.x === 0) { | ||
428 | 424 | root.itemClicked(mouse) | ||
429 | 425 | } else if (main.x > 0) { | ||
430 | 426 | var action = getActionAt(Qt.point(mouse.x, mouse.y)) | ||
431 | 427 | if (action && action !== -1) { | ||
432 | 428 | action.triggered(root) | ||
433 | 429 | } | ||
434 | 430 | } else { | ||
435 | 431 | var actionIndex = getActionAt(Qt.point(mouse.x, mouse.y)) | ||
436 | 432 | if (actionIndex !== -1) { | ||
437 | 433 | root.activeItem = rightActionsRepeater.itemAt(actionIndex) | ||
438 | 434 | root.activeAction = root._visibleRightSideActions[actionIndex] | ||
439 | 435 | triggerAction.start() | ||
440 | 436 | return | ||
441 | 437 | } | ||
442 | 438 | } | ||
443 | 439 | root.resetSwipe() | ||
444 | 440 | } | ||
445 | 441 | |||
446 | 442 | onPositionChanged: { | ||
447 | 443 | if (mouseArea.pressed) { | ||
448 | 444 | updateActiveAction() | ||
449 | 445 | } | ||
450 | 446 | } | ||
451 | 447 | onPressAndHold: { | ||
452 | 448 | if (main.x === 0) { | ||
453 | 449 | root.itemPressAndHold(mouse) | ||
454 | 450 | } | ||
455 | 451 | } | ||
456 | 452 | z: -1 | ||
457 | 453 | } | ||
458 | 454 | } | ||
459 | 455 | |||
460 | 0 | 456 | ||
461 | === added file 'src/app/qml/components/ListItemWithActionsCheckBox.qml' | |||
462 | --- src/app/qml/components/ListItemWithActionsCheckBox.qml 1970-01-01 00:00:00 +0000 | |||
463 | +++ src/app/qml/components/ListItemWithActionsCheckBox.qml 2015-02-13 01:03:14 +0000 | |||
464 | @@ -0,0 +1,25 @@ | |||
465 | 1 | /* | ||
466 | 2 | * Copyright (C) 2012-2014 Canonical, Ltd. | ||
467 | 3 | * | ||
468 | 4 | * This program is free software; you can redistribute it and/or modify | ||
469 | 5 | * it under the terms of the GNU General Public License as published by | ||
470 | 6 | * the Free Software Foundation; version 3. | ||
471 | 7 | * | ||
472 | 8 | * This program is distributed in the hope that it will be useful, | ||
473 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
474 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
475 | 11 | * GNU General Public License for more details. | ||
476 | 12 | * | ||
477 | 13 | * You should have received a copy of the GNU General Public License | ||
478 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
479 | 15 | */ | ||
480 | 16 | |||
481 | 17 | import QtQuick 2.2 | ||
482 | 18 | import Ubuntu.Components 1.1 | ||
483 | 19 | |||
484 | 20 | CheckBox { | ||
485 | 21 | checked: root.selected | ||
486 | 22 | width: implicitWidth | ||
487 | 23 | // disable item mouse area to avoid conflicts with parent mouse area | ||
488 | 24 | __mouseArea.enabled: false | ||
489 | 25 | } | ||
490 | 0 | 26 | ||
491 | === modified file 'src/app/qml/components/NotesDelegate.qml' | |||
492 | --- src/app/qml/components/NotesDelegate.qml 2014-12-16 21:01:28 +0000 | |||
493 | +++ src/app/qml/components/NotesDelegate.qml 2015-02-13 01:03:14 +0000 | |||
494 | @@ -22,9 +22,10 @@ | |||
495 | 22 | import Ubuntu.Components.ListItems 1.0 | 22 | import Ubuntu.Components.ListItems 1.0 |
496 | 23 | import Evernote 0.1 | 23 | import Evernote 0.1 |
497 | 24 | 24 | ||
499 | 25 | Empty { | 25 | ListItemWithActions { |
500 | 26 | id: root | 26 | id: root |
501 | 27 | height: units.gu(12) | 27 | height: units.gu(12) |
502 | 28 | width: parent.width | ||
503 | 28 | 29 | ||
504 | 29 | property string title | 30 | property string title |
505 | 30 | property date creationDate | 31 | property date creationDate |
506 | @@ -39,10 +40,44 @@ | |||
507 | 39 | property bool conflicting | 40 | property bool conflicting |
508 | 40 | property string notebookColor | 41 | property string notebookColor |
509 | 41 | 42 | ||
512 | 42 | showDivider: false; | 43 | signal deleteNote() |
513 | 43 | 44 | signal editNote() | |
514 | 45 | signal editReminder() | ||
515 | 46 | signal editTags() | ||
516 | 47 | |||
517 | 48 | leftSideAction: Action { | ||
518 | 49 | iconName: "delete" | ||
519 | 50 | text: i18n.tr("Delete") | ||
520 | 51 | onTriggered: { | ||
521 | 52 | root.deleteNote() | ||
522 | 53 | } | ||
523 | 54 | } | ||
524 | 55 | |||
525 | 56 | rightSideActions: [ | ||
526 | 57 | Action { | ||
527 | 58 | iconName: "alarm-clock" | ||
528 | 59 | text: i18n.tr("Reminder") | ||
529 | 60 | onTriggered: { | ||
530 | 61 | root.editReminder(); | ||
531 | 62 | } | ||
532 | 63 | }, | ||
533 | 64 | Action { | ||
534 | 65 | iconSource: "../images/tags.svg" | ||
535 | 66 | text: i18n.tr("Tags") | ||
536 | 67 | onTriggered: { | ||
537 | 68 | root.editTags(); | ||
538 | 69 | } | ||
539 | 70 | }, | ||
540 | 71 | Action { | ||
541 | 72 | iconName: "edit" | ||
542 | 73 | text: i18n.tr("Edit") | ||
543 | 74 | onTriggered: { | ||
544 | 75 | root.editNote(); | ||
545 | 76 | } | ||
546 | 77 | } | ||
547 | 78 | ] | ||
548 | 44 | ColumnLayout { | 79 | ColumnLayout { |
550 | 45 | anchors { fill: parent; leftMargin: units.gu(1); rightMargin: units.gu(1) } | 80 | anchors { fill: parent } |
551 | 46 | spacing: 0 | 81 | spacing: 0 |
552 | 47 | 82 | ||
553 | 48 | Rectangle { | 83 | Rectangle { |
554 | 49 | 84 | ||
555 | === modified file 'src/app/qml/components/RemindersDelegate.qml' | |||
556 | --- src/app/qml/components/RemindersDelegate.qml 2014-12-14 21:28:11 +0000 | |||
557 | +++ src/app/qml/components/RemindersDelegate.qml 2015-02-13 01:03:14 +0000 | |||
558 | @@ -24,54 +24,47 @@ | |||
559 | 24 | import Ubuntu.Components.Pickers 1.0 | 24 | import Ubuntu.Components.Pickers 1.0 |
560 | 25 | import Evernote 0.1 | 25 | import Evernote 0.1 |
561 | 26 | 26 | ||
563 | 27 | Base { | 27 | ListItemWithActions { |
564 | 28 | id: root | 28 | id: root |
565 | 29 | height: units.gu(10) | 29 | height: units.gu(10) |
566 | 30 | clip: true | 30 | clip: true |
588 | 31 | removable: true | 31 | color: "transparent" |
568 | 32 | |||
569 | 33 | backgroundIndicator: Row { | ||
570 | 34 | x: root.__contents.x > 0 ? root.__contents.x - width : 0 | ||
571 | 35 | width: childrenRect.width | ||
572 | 36 | anchors.verticalCenter: parent.verticalCenter | ||
573 | 37 | spacing: units.gu(1) | ||
574 | 38 | |||
575 | 39 | Icon { | ||
576 | 40 | height: units.gu(3) | ||
577 | 41 | width: height | ||
578 | 42 | anchors.verticalCenter: parent.verticalCenter | ||
579 | 43 | name: root.note.reminderDone ? "clear" : "select" | ||
580 | 44 | } | ||
581 | 45 | |||
582 | 46 | Label { | ||
583 | 47 | id: confirmRemovalDialog | ||
584 | 48 | anchors.verticalCenter: parent.verticalCenter | ||
585 | 49 | text: root.note.reminderDone ? i18n.tr("Clear reminder") : i18n.tr("Mark as done") | ||
586 | 50 | } | ||
587 | 51 | } | ||
589 | 52 | 32 | ||
590 | 53 | property var note | 33 | property var note |
591 | 54 | 34 | ||
592 | 35 | leftSideAction: Action { | ||
593 | 36 | text: i18n.tr("Clear reminder") | ||
594 | 37 | iconName: "clear" | ||
595 | 38 | onTriggered: { | ||
596 | 39 | note.reminder = false; | ||
597 | 40 | NotesStore.saveNote(note.guid) | ||
598 | 41 | } | ||
599 | 42 | } | ||
600 | 43 | |||
601 | 44 | rightSideActions: [ | ||
602 | 45 | Action { | ||
603 | 46 | iconSource: root.note.reminderDone ? "image://theme/select" : "../images/unchecked.svg" | ||
604 | 47 | text: root.note.reminderDone ? i18n.tr("Mark as undone") : i18n.tr("Mark as done") | ||
605 | 48 | onTriggered: { | ||
606 | 49 | note.reminderDone = !root.note.reminderDone; | ||
607 | 50 | NotesStore.saveNote(note.guid) | ||
608 | 51 | } | ||
609 | 52 | }, | ||
610 | 53 | Action { | ||
611 | 54 | iconName: "alarm-clock" | ||
612 | 55 | text: i18n.tr("Edit reminder") | ||
613 | 56 | onTriggered: { | ||
614 | 57 | pageStack.push(Qt.resolvedUrl("../ui/SetReminderPage.qml"), { note: root.note }); | ||
615 | 58 | } | ||
616 | 59 | } | ||
617 | 60 | ] | ||
618 | 61 | |||
619 | 55 | Behavior on height { | 62 | Behavior on height { |
620 | 56 | UbuntuNumberAnimation {} | 63 | UbuntuNumberAnimation {} |
621 | 57 | } | 64 | } |
622 | 58 | 65 | ||
623 | 59 | onItemRemoved: { | ||
624 | 60 | // Revert "removal" | ||
625 | 61 | root.cancelItemRemoval(); | ||
626 | 62 | root.height = units.gu(10) | ||
627 | 63 | print("marking reminder as", !note.reminderDone, " done for note", note.title); | ||
628 | 64 | if (!note.reminderDone) { | ||
629 | 65 | note.reminderDone = true; | ||
630 | 66 | } else { | ||
631 | 67 | note.reminder = false; | ||
632 | 68 | } | ||
633 | 69 | |||
634 | 70 | NotesStore.saveNote(note.guid) | ||
635 | 71 | } | ||
636 | 72 | |||
637 | 73 | RowLayout { | 66 | RowLayout { |
639 | 74 | anchors { fill: parent; topMargin: units.gu(1); bottomMargin: units.gu(1) } | 67 | anchors { fill: parent; margins: units.gu(1) } |
640 | 75 | spacing: units.gu(1) | 68 | spacing: units.gu(1) |
641 | 76 | 69 | ||
642 | 77 | UbuntuShape { | 70 | UbuntuShape { |
643 | 78 | 71 | ||
644 | === added file 'src/app/qml/components/ubuntu_component_store.json' | |||
645 | --- src/app/qml/components/ubuntu_component_store.json 1970-01-01 00:00:00 +0000 | |||
646 | +++ src/app/qml/components/ubuntu_component_store.json 2015-02-13 01:03:14 +0000 | |||
647 | @@ -0,0 +1,6 @@ | |||
648 | 1 | { | ||
649 | 2 | "name": "ListItemWithActions", | ||
650 | 3 | "description": "This widget provides an updated listitem which is what the core apps currently use.", | ||
651 | 4 | "version": "1.0", | ||
652 | 5 | "documentation_url": "http://ubuntu-component-store.readthedocs.org/en/latest/_components/listitemwithactions.html" | ||
653 | 6 | } | ||
654 | 0 | 7 | ||
655 | === modified file 'src/app/qml/reminders.qml' | |||
656 | --- src/app/qml/reminders.qml 2015-02-12 14:02:35 +0000 | |||
657 | +++ src/app/qml/reminders.qml 2015-02-13 01:03:14 +0000 | |||
658 | @@ -128,7 +128,9 @@ | |||
659 | 128 | 128 | ||
660 | 129 | function switchToEditMode(note) { | 129 | function switchToEditMode(note) { |
661 | 130 | if (root.narrowMode) { | 130 | if (root.narrowMode) { |
663 | 131 | pagestack.pop(); | 131 | if (pagestack.depth > 1) { |
664 | 132 | pagestack.pop(); | ||
665 | 133 | } | ||
666 | 132 | var component = Qt.createComponent(Qt.resolvedUrl("ui/EditNotePage.qml")); | 134 | var component = Qt.createComponent(Qt.resolvedUrl("ui/EditNotePage.qml")); |
667 | 133 | var page = component.createObject(); | 135 | var page = component.createObject(); |
668 | 134 | page.exitEditMode.connect(function() {Qt.inputMethod.hide(); pagestack.pop()}); | 136 | page.exitEditMode.connect(function() {Qt.inputMethod.hide(); pagestack.pop()}); |
669 | 135 | 137 | ||
670 | === modified file 'src/app/qml/ui/NotesPage.qml' | |||
671 | --- src/app/qml/ui/NotesPage.qml 2014-12-16 21:01:28 +0000 | |||
672 | +++ src/app/qml/ui/NotesPage.qml 2015-02-13 01:03:14 +0000 | |||
673 | @@ -20,6 +20,7 @@ | |||
674 | 20 | import QtQuick.Layouts 1.0 | 20 | import QtQuick.Layouts 1.0 |
675 | 21 | import Ubuntu.Components 1.1 | 21 | import Ubuntu.Components 1.1 |
676 | 22 | import Ubuntu.Components.ListItems 1.0 | 22 | import Ubuntu.Components.ListItems 1.0 |
677 | 23 | import Ubuntu.Components.Popups 1.0 | ||
678 | 23 | import Evernote 0.1 | 24 | import Evernote 0.1 |
679 | 24 | import "../components" | 25 | import "../components" |
680 | 25 | 26 | ||
681 | @@ -148,6 +149,7 @@ | |||
682 | 148 | creationDate: model.created | 149 | creationDate: model.created |
683 | 149 | changedDate: model.updated | 150 | changedDate: model.updated |
684 | 150 | content: model.tagline | 151 | content: model.tagline |
685 | 152 | triggerActionOnMouseRelease: true | ||
686 | 151 | tags: { | 153 | tags: { |
687 | 152 | var tags = new Array(); | 154 | var tags = new Array(); |
688 | 153 | for (var i = 0; i < model.tagGuids.length; i++) { | 155 | for (var i = 0; i < model.tagGuids.length; i++) { |
689 | @@ -163,11 +165,25 @@ | |||
690 | 163 | syncError: model.syncError | 165 | syncError: model.syncError |
691 | 164 | conflicting: model.conflicting | 166 | conflicting: model.conflicting |
692 | 165 | 167 | ||
694 | 166 | onClicked: { | 168 | onItemClicked: { |
695 | 167 | if (!model.conflicting) { | 169 | if (!model.conflicting) { |
696 | 168 | root.selectedNote = NotesStore.note(guid); | 170 | root.selectedNote = NotesStore.note(guid); |
697 | 169 | } | 171 | } |
698 | 170 | } | 172 | } |
699 | 173 | |||
700 | 174 | onDeleteNote: { | ||
701 | 175 | NotesStore.deleteNote(model.guid) | ||
702 | 176 | } | ||
703 | 177 | onEditNote: { | ||
704 | 178 | root.editNote(NotesStore.note(model.guid)); | ||
705 | 179 | } | ||
706 | 180 | onEditReminder: { | ||
707 | 181 | pageStack.push(Qt.resolvedUrl("SetReminderPage.qml"), { note: NotesStore.note(model.guid) }); | ||
708 | 182 | } | ||
709 | 183 | onEditTags: { | ||
710 | 184 | PopupUtils.open(Qt.resolvedUrl("../components/EditTagsDialog.qml"), root, | ||
711 | 185 | { note: NotesStore.note(model.guid), pageHeight: root.height }); | ||
712 | 186 | } | ||
713 | 171 | } | 187 | } |
714 | 172 | 188 | ||
715 | 173 | section.criteria: ViewSection.FullString | 189 | section.criteria: ViewSection.FullString |
716 | 174 | 190 | ||
717 | === modified file 'src/app/qml/ui/RemindersPage.qml' | |||
718 | --- src/app/qml/ui/RemindersPage.qml 2014-12-14 22:31:00 +0000 | |||
719 | +++ src/app/qml/ui/RemindersPage.qml 2015-02-13 01:03:14 +0000 | |||
720 | @@ -68,8 +68,9 @@ | |||
721 | 68 | delegate: RemindersDelegate { | 68 | delegate: RemindersDelegate { |
722 | 69 | width: remindersListView.width | 69 | width: remindersListView.width |
723 | 70 | note: notes.note(guid) | 70 | note: notes.note(guid) |
724 | 71 | triggerActionOnMouseRelease: true | ||
725 | 71 | 72 | ||
727 | 72 | onClicked: { | 73 | onItemClicked: { |
728 | 73 | root.selectedNote = NotesStore.note(guid); | 74 | root.selectedNote = NotesStore.note(guid); |
729 | 74 | } | 75 | } |
730 | 75 | } | 76 | } |
731 | 76 | 77 | ||
732 | === modified file 'src/libqtevernote/note.cpp' | |||
733 | --- src/libqtevernote/note.cpp 2014-12-16 21:01:28 +0000 | |||
734 | +++ src/libqtevernote/note.cpp 2015-02-13 01:03:14 +0000 | |||
735 | @@ -35,8 +35,8 @@ | |||
736 | 35 | Note::Note(const QString &guid, quint32 updateSequenceNumber, QObject *parent) : | 35 | Note::Note(const QString &guid, quint32 updateSequenceNumber, QObject *parent) : |
737 | 36 | QObject(parent), | 36 | QObject(parent), |
738 | 37 | m_isSearchResult(false), | 37 | m_isSearchResult(false), |
739 | 38 | m_deleted(false), | ||
740 | 38 | m_updateSequenceNumber(updateSequenceNumber), | 39 | m_updateSequenceNumber(updateSequenceNumber), |
741 | 39 | m_deleted(false), | ||
742 | 40 | m_loading(false), | 40 | m_loading(false), |
743 | 41 | m_loaded(false), | 41 | m_loaded(false), |
744 | 42 | m_syncError(false), | 42 | m_syncError(false), |
745 | 43 | 43 | ||
746 | === modified file 'src/libqtevernote/resourceimageprovider.cpp' | |||
747 | --- src/libqtevernote/resourceimageprovider.cpp 2014-10-23 21:27:46 +0000 | |||
748 | +++ src/libqtevernote/resourceimageprovider.cpp 2015-02-13 01:03:14 +0000 | |||
749 | @@ -26,7 +26,9 @@ | |||
750 | 26 | 26 | ||
751 | 27 | QImage image; | 27 | QImage image; |
752 | 28 | if (mediaType.startsWith("image")) { | 28 | if (mediaType.startsWith("image")) { |
753 | 29 | qDebug() << "image requested" << NotesStore::instance()->note(noteGuid)->resource(resourceHash); | ||
754 | 29 | image = QImage::fromData(NotesStore::instance()->note(noteGuid)->resource(resourceHash)->imageData(requestedSize)); | 30 | image = QImage::fromData(NotesStore::instance()->note(noteGuid)->resource(resourceHash)->imageData(requestedSize)); |
755 | 31 | qDebug() << "done..."; | ||
756 | 30 | } else if (mediaType.startsWith("audio")) { | 32 | } else if (mediaType.startsWith("audio")) { |
757 | 31 | image.load("/usr/share/icons/ubuntu-mobile/actions/scalable/media-playback-start.svg"); | 33 | image.load("/usr/share/icons/ubuntu-mobile/actions/scalable/media-playback-start.svg"); |
758 | 32 | } else { | 34 | } else { |
PASSED: Continuous integration, rev:339 91.189. 93.70:8080/ job/reminders- app-ci/ 646/ 91.189. 93.70:8080/ job/generic- mediumtests- vivid/1059 91.189. 93.70:8080/ job/generic- mediumtests- vivid/1059/ artifact/ work/output/ *zip*/output. zip 91.189. 93.70:8080/ job/reminders- app-vivid- amd64-ci/ 67
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/reminders- app-ci/ 646/rebuild
http://