Merge lp:~pkunal-parmar/ubuntu-calendar-app/LiveEventModification into lp:ubuntu-calendar-app
- LiveEventModification
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Alan Pope πΊπ§π± π¦ | ||||||||
Approved revision: | 580 | ||||||||
Merged at revision: | 600 | ||||||||
Proposed branch: | lp:~pkunal-parmar/ubuntu-calendar-app/LiveEventModification | ||||||||
Merge into: | lp:ubuntu-calendar-app | ||||||||
Diff against target: |
326 lines (+138/-36) 5 files modified
EventBubble.qml (+22/-2) NewEvent.qml (+2/-2) TimeLineBase.qml (+28/-10) TimeLineBaseComponent.qml (+74/-12) TimeLineHeader.qml (+12/-10) |
||||||||
To merge this branch: | bzr merge lp:~pkunal-parmar/ubuntu-calendar-app/LiveEventModification | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Alan Pope πΊπ§π± π¦ (community) | Approve | ||
Review via email: mp+247711@code.launchpad.net |
Commit message
User can create event by long press on TimeLine view,
Also event can be reschedules by darging it around.
Description of the change
As per new design[1] on page 4
User can create event by long press on TimeLine view,
Also event can be reschedules by darging it around.
Works like showen in below link,
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Mihir Soni (mihirsoni) wrote : | # |
Wow !!!
This is great !! code wise it looks good I'll do more testing.
Alan Pope πΊπ§π± π¦ (popey) wrote : | # |
Tested out on krillin and it works rather well.
The only issue I have is that it can be hard to get it to perfectly line up with hours. On a small screen it's easy to have meetings which look like they're lined up to an hour or half hour interval, but once you tap again on the meeting you find it's actually at 55, 05, 25 or 35 minutes past the hour. It's pretty easy to correct, so not a massive problem.
Kunal Parmar (pkunal-parmar) wrote : | # |
> Tested out on krillin and it works rather well.
>
> The only issue I have is that it can be hard to get it to perfectly line up
> with hours. On a small screen it's easy to have meetings which look like
> they're lined up to an hour or half hour interval, but once you tap again on
> the meeting you find it's actually at 55, 05, 25 or 35 minutes past the hour.
> It's pretty easy to correct, so not a massive problem.
Hi Alan, Thanks for testing it out,
I also thought the same, so as of when user create event by press and hold, event snaps to Hour.
But when use drag event to reschedule it, snap time interval is 5 minutes, I can easily make to 10 or 15 or whatever its good for user experience.
Thanks,
Alan Pope πΊπ§π± π¦ (popey) wrote : | # |
I think we should snap to 15.
Kunal Parmar (pkunal-parmar) wrote : | # |
> I think we should snap to 15.
Done. Changed snap to 15 min.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:579
http://
Executed test runs:
UNSTABLE: 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:579
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 : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
Kunal Parmar (pkunal-parmar) wrote : | # |
seems like some issue with jenkins, re-approving
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
Alan Pope πΊπ§π± π¦ (popey) wrote : | # |
I tried re-running and it failed again. Asking ci people for help.
Alan Pope πΊπ§π± π¦ (popey) wrote : | # |
13:28 < vila> ha, the failing test seems to be:
13:28 < vila> 12:16:42.866 INFO _logging:41 - Starting test
13:28 < vila> and it loops until 12:30:02.820 DEBUG _X11:309 - Releasing mouse button 1
Nicholas Skaggs (nskaggs) wrote : | # |
I've opened https:/
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:579
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nicholas Skaggs (nskaggs) wrote : | # |
Kunal, I have a working version in my branch; lp:~nskaggs/ubuntu-calendar-app/fix-infloop-ap
It needs flake8 fixes however.
Kunal Parmar (pkunal-parmar) wrote : | # |
> Kunal, I have a working version in my branch; lp:~nskaggs/ubuntu-calendar-app
> /fix-infloop-ap
>
>
> It needs flake8 fixes however.
ok, I will merge and see how it goes
Alan Pope πΊπ§π± π¦ (popey) wrote : | # |
Has any progress made on this? We really need this merge landing before we can update calendar in the store.
Nicholas Skaggs (nskaggs) wrote : | # |
I proposed my changes separately to trunk instead:
https:/
- 580. By Kunal Parmar
-
merge from trunk
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:580
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'EventBubble.qml' |
2 | --- EventBubble.qml 2014-12-18 14:27:22 +0000 |
3 | +++ EventBubble.qml 2015-03-05 12:28:58 +0000 |
4 | @@ -33,6 +33,8 @@ |
5 | property int depthInRow: 0; |
6 | property int sizeOfRow:0 |
7 | |
8 | + property bool isLiveEditing: false |
9 | + |
10 | property Flickable flickable; |
11 | |
12 | readonly property int minimumHeight: type == wideType |
13 | @@ -46,7 +48,7 @@ |
14 | Rectangle{ |
15 | id: bg |
16 | anchors.fill: parent |
17 | - border.color: "white" |
18 | + border.color: isLiveEditing ? "red" : "white" |
19 | } |
20 | |
21 | function resize() { |
22 | @@ -212,10 +214,28 @@ |
23 | } |
24 | } |
25 | |
26 | + Drag.active: dragArea.drag.active |
27 | + |
28 | MouseArea { |
29 | + id: dragArea |
30 | anchors.fill: parent |
31 | + drag.target: isLiveEditing ? infoBubble : null |
32 | + drag.axis: Drag.YAxis |
33 | + drag.minimumY: flickable.y |
34 | + drag.maximumY: flickable.contentHeight - infoBubble.height |
35 | + onReleased: parent.Drag.drop() |
36 | onClicked: { |
37 | - infoBubble.clicked(event); |
38 | + if( isLiveEditing ) { |
39 | + isLiveEditing = false; |
40 | + infoBubble.z -= 1; |
41 | + } else { |
42 | + infoBubble.clicked(event); |
43 | + } |
44 | + } |
45 | + |
46 | + onPressAndHold: { |
47 | + isLiveEditing = true; |
48 | + infoBubble.z += 1; |
49 | } |
50 | } |
51 | } |
52 | |
53 | === modified file 'NewEvent.qml' |
54 | --- NewEvent.qml 2014-11-27 17:46:47 +0000 |
55 | +++ NewEvent.qml 2015-03-05 12:28:58 +0000 |
56 | @@ -109,7 +109,7 @@ |
57 | event = Qt.createQmlObject("import QtOrganizer 5.0; Event { }", Qt.application,"NewEvent.qml"); |
58 | //Create fresh Recurrence Object. |
59 | rule = Qt.createQmlObject("import QtOrganizer 5.0; RecurrenceRule {}", event.recurrence,"EventRepetition.qml"); |
60 | - selectCalendar(model.defaultCollection().collectionId); |
61 | + selectCalendar(model.defaultCollection().collectionId); |
62 | } |
63 | |
64 | //Editing Event |
65 | @@ -212,7 +212,7 @@ |
66 | event.setDetail(audibleReminder); |
67 | } |
68 | event.collectionId = calendarsOption.model[calendarsOption.selectedIndex].collectionId; |
69 | - model.saveItem(event); |
70 | + model.saveItem(event); |
71 | pageStack.pop(); |
72 | root.eventAdded(event); |
73 | } |
74 | |
75 | === modified file 'TimeLineBase.qml' |
76 | --- TimeLineBase.qml 2014-11-04 17:30:15 +0000 |
77 | +++ TimeLineBase.qml 2015-03-05 12:28:58 +0000 |
78 | @@ -17,6 +17,8 @@ |
79 | */ |
80 | import QtQuick 2.3 |
81 | import Ubuntu.Components 1.1 |
82 | +import QtOrganizer 5.0 |
83 | + |
84 | import "dateExt.js" as DateExt |
85 | |
86 | Item { |
87 | @@ -29,13 +31,6 @@ |
88 | |
89 | Component.onCompleted: { |
90 | bubbleOverLay.createEvents(); |
91 | - model.addModelChangeListener(destroyAllChildren); |
92 | - model.addModelChangeListener(createEvents); |
93 | - } |
94 | - |
95 | - Component.onDestruction: { |
96 | - model.removeModelChangeListener(destroyAllChildren); |
97 | - model.removeModelChangeListener(createEvents); |
98 | } |
99 | |
100 | MouseArea { |
101 | @@ -45,7 +40,8 @@ |
102 | var selectedDate = new Date(day); |
103 | var hour = parseInt(mouseY / hourHeight); |
104 | selectedDate.setHours(hour) |
105 | - pageStack.push(Qt.resolvedUrl("NewEvent.qml"), {"date":selectedDate, "model":eventModel}); |
106 | + //pageStack.push(Qt.resolvedUrl("NewEvent.qml"), {"date":selectedDate, "model":eventModel}); |
107 | + createOrganizerEvent(selectedDate); |
108 | } |
109 | |
110 | onPressed: { |
111 | @@ -56,6 +52,28 @@ |
112 | } |
113 | } |
114 | |
115 | + function getTimeFromYPos(y, day) { |
116 | + var date = new Date(day); |
117 | + var time = y / hourHeight; |
118 | + var minutes = time % 1 ; |
119 | + var hour = time - minutes; |
120 | + minutes = parseInt(60 * minutes); |
121 | + minutes = Math.floor(minutes/15) * 15; |
122 | + date.setHours(hour); |
123 | + date.setMinutes(minutes); |
124 | + return date; |
125 | + } |
126 | + |
127 | + function createOrganizerEvent( startDate ) { |
128 | + var event = Qt.createQmlObject("import QtOrganizer 5.0; Event {}", Qt.application,"TimeLineBase.qml"); |
129 | + event.collectionId = (model.defaultCollection().collectionId); |
130 | + var endDate = new Date( startDate.getTime() + 3600000 ); |
131 | + event.startDateTime = startDate; |
132 | + event.endDateTime = endDate; |
133 | + event.displayLabel = i18n.tr("Untitled"); |
134 | + model.saveItem(event); |
135 | + } |
136 | + |
137 | TimeSeparator { |
138 | id: separator |
139 | objectName: "separator" |
140 | @@ -84,7 +102,7 @@ |
141 | } |
142 | } |
143 | |
144 | - function layoutEvents(array, depth) { |
145 | + function layoutEvents(array, depth) { |
146 | for(var i=0; i < array.length ; ++i) { |
147 | var schedule = array[i]; |
148 | var event = intern.eventMap[schedule.id]; |
149 | @@ -93,7 +111,7 @@ |
150 | } |
151 | |
152 | function createEvents() { |
153 | - if(!bubbleOverLay || bubbleOverLay == undefined || model === undefined) { |
154 | + if(!bubbleOverLay || bubbleOverLay == undefined || model === undefined || model === null) { |
155 | return; |
156 | } |
157 | |
158 | |
159 | === modified file 'TimeLineBaseComponent.qml' |
160 | --- TimeLineBaseComponent.qml 2015-02-26 16:44:43 +0000 |
161 | +++ TimeLineBaseComponent.qml 2015-03-05 12:28:58 +0000 |
162 | @@ -41,6 +41,8 @@ |
163 | //visible hour |
164 | property int scrollHour; |
165 | |
166 | + property EventListModel mainModel; |
167 | + |
168 | signal dateSelected(var date); |
169 | |
170 | function scrollToCurrentTime() { |
171 | @@ -98,17 +100,28 @@ |
172 | } |
173 | } |
174 | |
175 | - EventListModel { |
176 | - id: mainModel |
177 | - startPeriod: startDay.midnight(); |
178 | - endPeriod: type == ViewType.ViewTypeWeek ? startPeriod.addDays(7).endOfDay(): startPeriod.endOfDay() |
179 | - filter: eventModel.filter |
180 | + Timer{ |
181 | + interval: 200; running: true; repeat: false |
182 | + onTriggered: { |
183 | + mainModel = modelComponent.createObject(); |
184 | + activityLoader.running = Qt.binding( function (){ return mainModel.isLoading;}); |
185 | + } |
186 | + } |
187 | + |
188 | + Component { |
189 | + id: modelComponent |
190 | + EventListModel { |
191 | + id: mainModel |
192 | + startPeriod: startDay.midnight(); |
193 | + endPeriod: type == ViewType.ViewTypeWeek ? startPeriod.addDays(7).endOfDay(): startPeriod.endOfDay() |
194 | + filter: eventModel.filter |
195 | + } |
196 | } |
197 | |
198 | ActivityIndicator { |
199 | + id: activityLoader |
200 | visible: running |
201 | objectName : "activityIndicator" |
202 | - running: mainModel.isLoading |
203 | anchors.centerIn: parent |
204 | z:2 |
205 | } |
206 | @@ -194,13 +207,62 @@ |
207 | day: startDay.addDays(index) |
208 | model: mainModel |
209 | |
210 | - Component.onCompleted: { |
211 | - model.addModelChangeListener(destroyAllChildren); |
212 | - model.addModelChangeListener(createEvents); |
213 | + Connections{ |
214 | + target: mainModel |
215 | + |
216 | + onModelChanged: { |
217 | + createEvents(); |
218 | + } |
219 | } |
220 | - Component.onDestruction: { |
221 | - model.removeModelChangeListener(destroyAllChildren); |
222 | - model.removeModelChangeListener(createEvents); |
223 | + |
224 | + DropArea { |
225 | + id: dropArea |
226 | + objectName: "mouseArea" |
227 | + anchors.fill: parent |
228 | + |
229 | + function modifyEventForDrag(drag) { |
230 | + var event = drag.source.event; |
231 | + var diff = event.endDateTime.getTime() - event.startDateTime.getTime(); |
232 | + |
233 | + var startDate = getTimeFromYPos(drag.y, day); |
234 | + var endDate = new Date( startDate.getTime() + diff ); |
235 | + |
236 | + event.startDateTime = startDate; |
237 | + event.endDateTime = endDate; |
238 | + |
239 | + return event; |
240 | + } |
241 | + |
242 | + onDropped: { |
243 | + var event = dropArea.modifyEventForDrag(drop); |
244 | + model.saveItem(event); |
245 | + } |
246 | + |
247 | + onPositionChanged: { |
248 | + dropArea.modifyEventForDrag(drag) |
249 | + var eventBubble = drag.source; |
250 | + eventBubble.assingnBgColor(); |
251 | + eventBubble.setDetails(); |
252 | + |
253 | + if( eventBubble.y + eventBubble.height + units.gu(8) > timeLineView.contentY + timeLineView.height ) { |
254 | + var diff = Math.abs((eventBubble.y + eventBubble.height + units.gu(8)) - |
255 | + (timeLineView.height + timeLineView.contentY)); |
256 | + timeLineView.contentY += diff |
257 | + |
258 | + if(timeLineView.contentY >= timeLineView.contentHeight - timeLineView.height) { |
259 | + timeLineView.contentY = timeLineView.contentHeight - timeLineView.height |
260 | + } |
261 | + } |
262 | + |
263 | + if(eventBubble.y - units.gu(8) < timeLineView.contentY ) { |
264 | + var diff = Math.abs((eventBubble.y - units.gu(8)) - timeLineView.contentY); |
265 | + timeLineView.contentY -= diff |
266 | + |
267 | + if(timeLineView.contentY <= 0) { |
268 | + timeLineView.contentY = 0; |
269 | + } |
270 | + } |
271 | + } |
272 | } |
273 | |
274 | Loader{ |
275 | |
276 | === modified file 'TimeLineHeader.qml' |
277 | --- TimeLineHeader.qml 2015-02-26 16:44:43 +0000 |
278 | +++ TimeLineHeader.qml 2015-03-05 12:28:58 +0000 |
279 | @@ -106,17 +106,18 @@ |
280 | SimpleDivider{} |
281 | |
282 | AllDayEventComponent { |
283 | + id: dayAllDayComp |
284 | type: ViewType.ViewTypeDay |
285 | startDay: headerRoot.startDay |
286 | model: mainModel |
287 | width: parent.width |
288 | height: units.gu(5) |
289 | |
290 | - Component.onCompleted: { |
291 | - mainModel.addModelChangeListener(createAllDayEvents); |
292 | - } |
293 | - Component.onDestruction: { |
294 | - mainModel.removeModelChangeListener(createAllDayEvents); |
295 | + Connections{ |
296 | + target: mainModel |
297 | + onModelChanged : { |
298 | + dayAllDayComp.createAllDayEvents(); |
299 | + } |
300 | } |
301 | } |
302 | } |
303 | @@ -158,17 +159,18 @@ |
304 | SimpleDivider{} |
305 | |
306 | AllDayEventComponent { |
307 | + id: weekAllDayComp |
308 | type: ViewType.ViewTypeWeek |
309 | startDay: headerRoot.startDay |
310 | width: parent.width |
311 | height: units.gu(5) |
312 | model: mainModel |
313 | |
314 | - Component.onCompleted: { |
315 | - mainModel.addModelChangeListener(createAllDayEvents); |
316 | - } |
317 | - Component.onDestruction: { |
318 | - mainModel.removeModelChangeListener(createAllDayEvents); |
319 | + Connections{ |
320 | + target: mainModel |
321 | + onModelChanged : { |
322 | + weekAllDayComp.createAllDayEvents(); |
323 | + } |
324 | } |
325 | } |
326 | } |
PASSED: Continuous integration, rev:578 91.189. 93.70:8080/ job/ubuntu- calendar- app-ci/ 1065/ 91.189. 93.70:8080/ job/generic- mediumtests- vivid/836 91.189. 93.70:8080/ job/generic- mediumtests- vivid/836/ artifact/ work/output/ *zip*/output. zip 91.189. 93.70:8080/ job/ubuntu- calendar- app-vivid- amd64-ci/ 62
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- calendar- app-ci/ 1065/rebuild
http://