Merge lp:~artmello/ubuntu-calendar-app/ubuntu-calendar-app-fix_1563316 into lp:ubuntu-calendar-app

Proposed by Arthur Mello
Status: Merged
Approved by: Renato Araujo Oliveira Filho
Approved revision: 814
Merged at revision: 811
Proposed branch: lp:~artmello/ubuntu-calendar-app/ubuntu-calendar-app-fix_1563316
Merge into: lp:ubuntu-calendar-app
Diff against target: 397 lines (+256/-21)
4 files modified
EventBubble.qml (+42/-15)
TimeLineBaseComponent.qml (+1/-1)
tests/unittests/tst_calendar_canvas.qml (+5/-5)
tests/unittests/tst_event_bubble.qml (+208/-0)
To merge this branch: bzr merge lp:~artmello/ubuntu-calendar-app/ubuntu-calendar-app-fix_1563316
Reviewer Review Type Date Requested Status
Renato Araujo Oliveira Filho (community) Approve
Jenkins Bot continuous-integration Approve
Review via email: mp+290317@code.launchpad.net

Commit message

Change Event Bubble style depending if user is attending the event following design spec

Description of the change

Change Event Bubble style depending if user is attending the event following design spec

Testing
=======
Import from google account events with different attendee status (Yes/Maybe/No) both for future and past end times. Make sure that the event bubble is updated as expected

To post a comment you must log in.
Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
810. By Arthur Mello

Fix when requesting owner status for local events

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
811. By Arthur Mello

Fix calendar canvas unittest

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
812. By Arthur Mello

Merge with trunk

813. By Arthur Mello

Add unit test

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
814. By Arthur Mello

Add border with same color as collection for unaswered events

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

great job.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'EventBubble.qml'
2--- EventBubble.qml 2016-03-28 18:14:09 +0000
3+++ EventBubble.qml 2016-03-31 19:20:26 +0000
4@@ -38,7 +38,14 @@
5 property Flickable flickable;
6 property bool isEventBubble: true
7 property real minimumHeight: units.gu(4)
8+
9+ // Event bubble style
10+ property alias titleText: eventTitle.text
11+ property alias titleColor: eventTitle.color
12 property alias strikeoutTitle: eventTitle.font.strikeout
13+ property alias backgroundColor: bg.color
14+ property alias backgroundOpacity: bg.opacity
15+ property color borderColor: "white"
16
17 readonly property bool isSingleLine: (infoBubble.height < (minimumHeight * 2))
18 readonly property real startTimeInMinutes: event ? CanlendarCanvas.minutesSince(infoBubble.anchorDate, event.startDateTime) : 0.0
19@@ -52,10 +59,10 @@
20 Connections {
21 target: model
22 ignoreUnknownSignals: true
23- onCollectionsChanged: assignBgColor()
24+ onCollectionsChanged: updateEventBubbleStyle()
25 }
26
27- function assignBgColor() {
28+ function updateEventBubbleStyle() {
29 if (model && event ) {
30 var collection = model.collection( event.collectionId );
31 var now = new Date();
32@@ -64,15 +71,35 @@
33 endDateTime = event.startDateTime;
34 }
35
36+ updateTitle()
37+
38+ //Accepted events: Solid collection color with white text.
39+ infoBubble.backgroundColor = collection.color
40+ infoBubble.backgroundOpacity = 1
41+ infoBubble.titleColor = "white";
42+ infoBubble.strikeoutTitle = false;
43+ infoBubble.borderColor = "white";
44+
45 if( endDateTime >= now) {
46- bg.color = collection.color
47-
48- if( getOwnersStatus(collection) === EventAttendee.StatusDeclined ) {
49+ var ownersStatus = getOwnersStatus(collection);
50+ if (ownersStatus === EventAttendee.StatusDeclined) {
51+ // Declined events: As per accepted events with strike-through text.
52 infoBubble.strikeoutTitle = true;
53+
54+ } else if (ownersStatus === EventAttendee.StatusTentative) {
55+ //Maybe events: As per accepted events with ‘(?)’ placed before Event Title.
56+ infoBubble.titleText = "(?) " + infoBubble.titleText
57+
58+ } else if (ownersStatus !== EventAttendee.StatusAccepted) {
59+ //Unresponded events: Accepted event colours inverted (i.e. collection color text/ outline on white background).
60+ infoBubble.backgroundColor = "white"
61+ infoBubble.titleColor = collection.color;
62+ infoBubble.borderColor = collection.color;
63+
64 }
65 } else {
66- //if event is on past then add some white color to original color
67- bg.color = Qt.tint( collection.color, "#aaffffff" );
68+ // Past events: As per accepted events, but at 75% transparency.
69+ infoBubble.backgroundOpacity = 0.25
70 }
71 }
72 }
73@@ -89,6 +116,8 @@
74 }
75 }
76 }
77+
78+ return EventAttendee.StatusAccepted;
79 }
80
81 function updateTitle() {
82@@ -106,12 +135,12 @@
83
84 //there is space for two lines
85 if (infoBubble.isSingleLine) {
86- eventTitle.text = ("%1 %2").arg(timeString).arg(event.displayLabel);
87+ infoBubble.titleText = ("%1 %2").arg(timeString).arg(event.displayLabel);
88 } else {
89- eventTitle.text = ("%1\n%2").arg(timeString).arg(event.displayLabel);
90+ infoBubble.titleText = ("%1\n%2").arg(timeString).arg(event.displayLabel);
91 }
92 } else {
93- eventTitle.text = event.displayLabel
94+ infoBubble.titleText = event.displayLabel
95 }
96 }
97
98@@ -124,10 +153,9 @@
99 height = Math.max(minimumHeight, durationInMinutes * parent.minuteHeight)
100 }
101
102- onIsSingleLineChanged: updateTitle()
103+ onIsSingleLineChanged: updateEventBubbleStyle()
104 onEventChanged: {
105- assignBgColor()
106- updateTitle()
107+ updateEventBubbleStyle()
108 resize()
109 }
110
111@@ -146,7 +174,7 @@
112 Rectangle{
113 id: bg
114 anchors.fill: parent
115- border.color: isLiveEditing ? "red" : "white"
116+ border.color: isLiveEditing ? "red" : infoBubble.borderColor
117 }
118
119 Label {
120@@ -158,7 +186,6 @@
121 }
122 clip: true
123 fontSize: "small"
124- color: "White"
125 font.bold: true
126 }
127
128
129=== modified file 'TimeLineBaseComponent.qml'
130--- TimeLineBaseComponent.qml 2016-03-22 13:52:25 +0000
131+++ TimeLineBaseComponent.qml 2016-03-31 19:20:26 +0000
132@@ -347,7 +347,7 @@
133 onPositionChanged: {
134 dropArea.modifyEventForDrag(drag)
135 var eventBubble = drag.source;
136- eventBubble.assignBgColor();
137+ eventBubble.updateEventBubbleStyle();
138
139 if( eventBubble.y + eventBubble.height + units.gu(8) > timeLineView.contentY + timeLineView.height ) {
140 var diff = Math.abs((eventBubble.y + eventBubble.height + units.gu(8)) -
141
142=== modified file 'tests/unittests/tst_calendar_canvas.qml'
143--- tests/unittests/tst_calendar_canvas.qml 2016-03-02 00:24:42 +0000
144+++ tests/unittests/tst_calendar_canvas.qml 2016-03-31 19:20:26 +0000
145@@ -639,34 +639,34 @@
146 compare(eventsA.event.displayLabel, "Event at 14:15 until 15:15")
147 compare(eventsA.y, 0)
148 compare(eventsA.intersectionCount, 5)
149- fuzzyCompare(eventsA.width, 0.2, 0.1)
150+ fuzzyCompare(eventsA.width, 0.3, 0.1)
151
152 //"Event at 14:30 until 15:00"
153 var eventsB = eventMap[1]
154 compare(eventsB.event.displayLabel, "Event at 14:30 until 15:00")
155 compare(eventsB.y, 1)
156 compare(eventsB.intersectionCount, 5)
157- fuzzyCompare(eventsB.width, 0.2, 0.1)
158+ fuzzyCompare(eventsB.width, 0.3, 0.1)
159
160 //"Event at 14:45 until 15:45"
161 var eventsC = eventMap[2]
162 compare(eventsC.event.displayLabel, "Event at 14:45 until 15:45")
163 compare(eventsC.y, 2)
164 compare(eventsC.intersectionCount, 5)
165- fuzzyCompare(eventsC.width, 0.2, 0.1)
166+ fuzzyCompare(eventsC.width, 0.3, 0.1)
167
168 //"Event at 15:30 until 16:30"
169 var eventsD = eventMap[3]
170 compare(eventsD.event.displayLabel, "Event at 15:30 until 16:30")
171 compare(eventsD.y, 0)
172 compare(eventsD.intersectionCount, 5)
173- fuzzyCompare(eventsD.width, 0.2, 0.1)
174+ fuzzyCompare(eventsD.width, 0.3, 0.1)
175
176 //"Event at 15:30 until 16:30 (1)"
177 var eventsE = eventMap[4]
178 compare(eventsE.event.displayLabel, "Event at 15:30 until 16:30 (1)")
179 compare(eventsE.y, 1)
180 compare(eventsE.intersectionCount, 5)
181- fuzzyCompare(eventsE.width, 0.2, 0.1)
182+ fuzzyCompare(eventsE.width, 0.3, 0.1)
183 }
184 }
185
186=== added file 'tests/unittests/tst_event_bubble.qml'
187--- tests/unittests/tst_event_bubble.qml 1970-01-01 00:00:00 +0000
188+++ tests/unittests/tst_event_bubble.qml 2016-03-31 19:20:26 +0000
189@@ -0,0 +1,208 @@
190+import QtQuick 2.0
191+import QtTest 1.0
192+import QtOrganizer 5.0
193+
194+TestCase{
195+ id: root
196+ name: "Event Bubble tests"
197+
198+ property OrganizerModel model: null
199+ property Collection collection: null
200+ property Event event: null
201+ property var eventBubble: null
202+
203+ Component {
204+ id: modelComp
205+
206+ OrganizerModel {}
207+ }
208+
209+ Component {
210+ id: collectionComp
211+
212+ Collection {}
213+ }
214+
215+ Component {
216+ id: eventAttendeeComp
217+
218+ EventAttendee {}
219+ }
220+
221+ Component {
222+ id: eventComp
223+
224+ Event {}
225+ }
226+
227+ function create_model_from_data(data)
228+ {
229+ return modelComp.createObject(root,
230+ {"manager": data.manager,
231+ "startPeriod": data.startPeriod,
232+ "endPeriod": data.endPeriod,
233+ "autoUpdate": data.autoUpdate})
234+ }
235+
236+ function create_collection_from_data(data)
237+ {
238+ return collectionComp.createObject(root,
239+ {"name": data.name,
240+ "color": data.color})
241+ }
242+
243+ function create_event_attendee_from_data(data)
244+ {
245+ return eventAttendeeComp.createObject(root,
246+ {"emailAddress": data.emailAddress,
247+ "participationStatus": data.participationStatus})
248+ }
249+
250+ function create_event_from_data(data)
251+ {
252+ return eventComp.createObject(root,
253+ {"collectionId": data.collectionId,
254+ "allDay": data.allDay,
255+ "displayLabel": data.label,
256+ "startDateTime": data.startDate,
257+ "endDateTime": data.endDate,
258+ "attendees": data.attendees})
259+ }
260+
261+ function create_event_bubble(event)
262+ {
263+ var component = Qt.createComponent(Qt.resolvedUrl("../../EventBubble.qml"))
264+ if (component.status === Component.Ready)
265+ return component.createObject(root, {"model": root.model, "event": event})
266+
267+ return null
268+ }
269+
270+ function get_collection_id_by_name(model, name)
271+ {
272+ for (var i = 0 ; i < model.collections.length ; ++i) {
273+ if (model.collections[i].name === name ) {
274+ return model.collections[i].collectionId
275+ }
276+ }
277+ return ""
278+ }
279+
280+ function initTestCase()
281+ {
282+ var startPeriod = new Date(2016, 1, 1, 0, 0, 0, 0)
283+ var endPeriod = new Date(2017, 1, 1, 0, 0, 0, 0)
284+ var modelData = {"manager": "memory",
285+ "startPeriod": startPeriod,
286+ "endPeriod": endPeriod,
287+ "autoUpdate": true}
288+ root.model = create_model_from_data(modelData)
289+
290+ var collectionData = {"name": "test@calendar.com",
291+ "color": "black" }
292+ root.collection = create_collection_from_data(collectionData)
293+ root.model.saveCollection(root.collection)
294+ }
295+
296+ function init()
297+ {
298+ var collectionId = get_collection_id_by_name(root.model, root.collection.name)
299+ var startDate = new Date(2016, 3, 28, 14, 0,0 )
300+ var endDate = new Date(2016, 3, 28, 15, 0,0 )
301+ var eventData = {"collectionId": collectionId,
302+ "label": "Sample Test Event",
303+ "allDay": false,
304+ "startDate": startDate,
305+ "endDate": endDate}
306+ root.event = create_event_from_data(eventData)
307+ }
308+
309+ function cleanup()
310+ {
311+ if (root.event) {
312+ root.event.destroy()
313+ root.event = null
314+ }
315+
316+ if (root.eventBubble) {
317+ root.eventBubble.destroy()
318+ root.eventBubble = null
319+ }
320+ }
321+
322+ function test_visual_style_future_accepted_event()
323+ {
324+ var eventAttendeeData = {"emailAddress": root.collection.name,
325+ "participationStatus": EventAttendee.StatusAccepted}
326+
327+ var eventAttendee = create_event_attendee_from_data(eventAttendeeData)
328+ root.event.setDetail(eventAttendee)
329+
330+ eventBubble = create_event_bubble(root.event)
331+ eventBubble.updateEventBubbleStyle()
332+
333+ compare(eventBubble.backgroundColor, root.collection.color)
334+ compare(eventBubble.borderColor, "#ffffff")
335+ compare(eventBubble.backgroundOpacity, 1.0)
336+ compare(eventBubble.titleText, "Sample Test Event")
337+ compare(eventBubble.titleColor, "#ffffff")
338+ verify(!eventBubble.strikeoutTitle)
339+ }
340+
341+ function test_visual_style_future_declined_event()
342+ {
343+ var eventAttendeeData = {"emailAddress": root.collection.name,
344+ "participationStatus": EventAttendee.StatusDeclined}
345+
346+ var eventAttendee = create_event_attendee_from_data(eventAttendeeData)
347+ root.event.setDetail(eventAttendee)
348+
349+ eventBubble = create_event_bubble(root.event)
350+ eventBubble.updateEventBubbleStyle()
351+
352+ compare(eventBubble.backgroundColor, root.collection.color)
353+ compare(eventBubble.borderColor, "#ffffff")
354+ compare(eventBubble.backgroundOpacity, 1.0)
355+ compare(eventBubble.titleText, "Sample Test Event")
356+ compare(eventBubble.titleColor, "#ffffff")
357+ verify(eventBubble.strikeoutTitle)
358+ }
359+
360+ function test_visual_style_future_maybe_event()
361+ {
362+ var eventAttendeeData = {"emailAddress": root.collection.name,
363+ "participationStatus": EventAttendee.StatusTentative}
364+
365+ var eventAttendee = create_event_attendee_from_data(eventAttendeeData)
366+ root.event.setDetail(eventAttendee)
367+
368+ eventBubble = create_event_bubble(root.event)
369+ eventBubble.updateEventBubbleStyle()
370+
371+ compare(eventBubble.backgroundColor, root.collection.color)
372+ compare(eventBubble.borderColor, "#ffffff")
373+ compare(eventBubble.backgroundOpacity, 1.0)
374+ compare(eventBubble.titleText, "(?) Sample Test Event")
375+ compare(eventBubble.titleColor, "#ffffff")
376+ verify(!eventBubble.strikeoutTitle)
377+ }
378+
379+ function test_visual_style_future_unknown_event()
380+ {
381+ var eventAttendeeData = {"emailAddress": root.collection.name,
382+ "participationStatus": EventAttendee.StatusUnknown}
383+
384+ var eventAttendee = create_event_attendee_from_data(eventAttendeeData)
385+ root.event.setDetail(eventAttendee)
386+
387+ eventBubble = create_event_bubble(root.event)
388+ eventBubble.updateEventBubbleStyle()
389+
390+ compare(eventBubble.backgroundColor, "#ffffff")
391+ compare(eventBubble.borderColor, root.collection.color)
392+ compare(eventBubble.backgroundOpacity, 1.0)
393+ compare(eventBubble.titleText, "Sample Test Event")
394+ compare(eventBubble.titleColor, root.collection.color)
395+ verify(!eventBubble.strikeoutTitle)
396+ }
397+}

Subscribers

People subscribed via source and target branches

to status/vote changes: