Merge lp:~gary-wzl77/ubuntu-calendar-app/dynamic_creation_perf_tunning into lp:ubuntu-calendar-app

Proposed by Gary.Wang
Status: Merged
Merge reported by: Gary.Wang
Merged at revision: not available
Proposed branch: lp:~gary-wzl77/ubuntu-calendar-app/dynamic_creation_perf_tunning
Merge into: lp:ubuntu-calendar-app
Diff against target: 658 lines (+172/-175)
8 files modified
ContactChoicePopup.qml (+1/-1)
EventBubble.qml (+2/-2)
EventListModel.qml (+1/-2)
NewEvent.qml (+1/-0)
YearView.qml (+7/-1)
YearViewDelegate.qml (+13/-9)
calendar.qml (+106/-123)
po/com.ubuntu.calendar.pot (+41/-37)
To merge this branch: bzr merge lp:~gary-wzl77/ubuntu-calendar-app/dynamic_creation_perf_tunning
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Needs Fixing
Kunal Parmar Approve
Review via email: mp+258449@code.launchpad.net

Commit message

performance tuning

Description of the change

Performance tunning for page transition.
Page Transition between different views will cause dynamic creation(Qt.ResolvedUrl)
for qml object back and forth.Using Qt.CreateComponent for dynamic creation for 1st
time and reuse exsiting obj without re-creating.

related bugs:#1423185,#1309263

To post a comment you must log in.
Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

Originally we were destroying Pages to conserve memory, but it that's not issue anymore. Then this MR looks good to me.

I will test some more and approve it.

Thanks for MR and taking your time to improve calendar

Revision history for this message
Gary.Wang (gary-wzl77) wrote :

Kunal, have u fun with this MR. Still two clear UI bugs has been fixed.
Pls approve.

BTW: Have u check this one on ur devices? it's marked as FIX COMMITTED.
     https://bugs.launchpad.net/ubuntu-calendar-app/+bug/1438910
     I can see it's still exciting with latest repo on 15.04(r211)

Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

sorry forgot about this MR, I will test this today night before calendar meeting and approve.

Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

looks good to me, thanks for MR

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :

FAILED: Autolanding.
No commit message was specified in the merge proposal. Hit 'Add commit message' on the merge proposal web page or follow the link below. You can approve the merge proposal yourself to rerun.
https://code.launchpad.net/~gary-wzl77/ubuntu-calendar-app/dynamic_creation_perf_tunning/+merge/258449/+edit-commit-message

review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ContactChoicePopup.qml'
2--- ContactChoicePopup.qml 2014-09-20 10:45:35 +0000
3+++ ContactChoicePopup.qml 2015-05-14 03:37:54 +0000
4@@ -94,7 +94,7 @@
5 objectName: "contactPopoverList"
6 width: parent.width
7 model: contactModel
8- height: units.gu(30)
9+ height: units.gu(15)
10 clip: true
11 delegate: Standard{
12 objectName: "contactPopoverList%1".arg(index)
13
14=== modified file 'EventBubble.qml'
15--- EventBubble.qml 2015-01-22 19:34:59 +0000
16+++ EventBubble.qml 2015-05-14 03:37:54 +0000
17@@ -221,8 +221,8 @@
18 anchors.fill: parent
19 drag.target: isLiveEditing ? infoBubble : null
20 drag.axis: Drag.YAxis
21- drag.minimumY: flickable.y
22- drag.maximumY: flickable.contentHeight - infoBubble.height
23+ drag.minimumY: flickable === null? 0: flickable.y
24+ drag.maximumY: flickable === null? 0 :flickable.contentHeight - infoBubble.height
25 onReleased: parent.Drag.drop()
26 onClicked: {
27 if( isLiveEditing ) {
28
29=== modified file 'EventListModel.qml'
30--- EventListModel.qml 2014-09-28 05:25:31 +0000
31+++ EventListModel.qml 2015-05-14 03:37:54 +0000
32@@ -44,7 +44,7 @@
33 var newObject = Qt.createQmlObject("import QtQuick 2.3; Timer {interval: 1000; running: true; repeat: false;}",
34 eventModel, "EventListMode.qml");
35 newObject.onTriggered.connect( function(){
36- var items = getItems(eventModel.startPeriod, eventModel.endPeriod);
37+ var items = itemsByTimePeriod(eventModel.startPeriod, eventModel.endPeriod);
38 if( isLoading == true && items.length === 0) {
39 isLoading = false;
40 modelChanged();
41@@ -53,7 +53,6 @@
42 });
43 }
44
45-
46 onModelChanged: {
47 isLoading = false
48 if(listeners === undefined){
49
50=== modified file 'NewEvent.qml'
51--- NewEvent.qml 2015-04-05 04:54:54 +0000
52+++ NewEvent.qml 2015-05-14 03:37:54 +0000
53@@ -219,6 +219,7 @@
54 event.collectionId = calendarsOption.model[calendarsOption.selectedIndex].collectionId;
55 model.saveItem(event);
56 pageStack.pop();
57+
58 root.eventAdded(event);
59 }
60 }
61
62=== modified file 'YearView.qml'
63--- YearView.qml 2015-02-18 19:27:20 +0000
64+++ YearView.qml 2015-05-14 03:37:54 +0000
65@@ -29,6 +29,12 @@
66
67 Keys.forwardTo: [yearPathView]
68
69+ function refreshCurrentYear(year) {
70+ currentYear = year;
71+ var yearViewDelegate = yearPathView.currentItem.item;
72+ yearViewDelegate.refresh();
73+ }
74+
75 Action {
76 id: calendarTodayAction
77 objectName:"todaybutton"
78@@ -85,7 +91,7 @@
79
80 scrollMonth: 0;
81 isCurrentItem: index == yearPathView.currentIndex
82- year: (yearViewPage.currentYear + yearPathView.indexType(index))
83+ year: (currentYear + yearPathView.indexType(index))
84
85 anchors.fill: parent
86 }
87
88=== modified file 'YearViewDelegate.qml'
89--- YearViewDelegate.qml 2014-11-29 09:40:53 +0000
90+++ YearViewDelegate.qml 2015-05-14 03:37:54 +0000
91@@ -18,6 +18,19 @@
92 model: 12 /* months in a year */
93
94 onYearChanged: {
95+ refresh();
96+ }
97+
98+ //scroll in case content height changed
99+ onHeightChanged: {
100+ yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
101+ }
102+
103+ Component.onCompleted: {
104+ yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
105+ }
106+
107+ function refresh() {
108 scrollMonth = 0;
109 var today = new Date();
110 if(year == today.getFullYear()) {
111@@ -26,15 +39,6 @@
112 yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
113 }
114
115- //scroll in case content height changed
116- onHeightChanged: {
117- yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
118- }
119-
120- Component.onCompleted: {
121- yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
122- }
123-
124 Connections{
125 target: yearPathView
126 onScrollUp: {
127
128=== modified file 'calendar.qml'
129--- calendar.qml 2015-01-22 20:07:30 +0000
130+++ calendar.qml 2015-05-14 03:37:54 +0000
131@@ -186,7 +186,7 @@
132
133 Tabs{
134 id: tabs
135- Keys.forwardTo: [tabs.currentPage.item]
136+ Keys.forwardTo: [tabs.currentPage]
137
138 property var currentDay: DateExt.today();
139
140@@ -316,156 +316,139 @@
141 }
142 }
143
144+ onSelectedTabChanged: {
145+ switch (tabs.selectedTab) {
146+ case yearTab:{
147+ if (yearTab.page === null) {
148+ var yearViewCom = Qt.createComponent("YearView.qml");
149+ if (yearViewCom.status === Component.Ready) {
150+ var yearViewObj = yearViewCom.createObject(mainView);
151+
152+ yearViewObj.monthSelected.connect(function (date){
153+ var now = DateExt.today();
154+ if( date.getMonth() === now.getMonth()
155+ && date.getFullYear() === now.getFullYear()) {
156+ tabs.currentDay = now;
157+ } else {
158+ tabs.currentDay = date.midnight();
159+ }
160+ tabs.selectedTabIndex = monthTab.index;
161+ })
162+
163+ yearTab.page = yearViewObj;
164+ }
165+ } else {
166+ yearTab.page.refreshCurrentYear(DateExt.today().getFullYear());
167+ }
168+ } break;
169+ case monthTab: {
170+ if (monthTab.page === null) {
171+ var monthViewCom = Qt.createComponent("MonthView.qml");
172+ if (monthViewCom.status === Component.Ready) {
173+ var monthViewObj = monthViewCom.createObject(mainView);
174+
175+ monthViewObj.dateSelected.connect(function (date) {
176+ tabs.currentDay = date;
177+ tabs.selectedTabIndex = dayTab.index;
178+ })
179+
180+ monthTab.page = monthViewObj;
181+ }
182+ } else {
183+ monthTab.page.currentMonth = tabs.currentDay.midnight();
184+ }
185+ } break;
186+ case weekTab: {
187+ if (weekTab.page === null) {
188+ var weekViewCom = Qt.createComponent("WeekView.qml");
189+ if (weekViewCom.status === Component.Ready) {
190+ var weekViewObj = weekViewCom.createObject(mainView);
191+
192+ weekViewObj.isCurrentPage = Qt.binding(function() { return tabs.selectedTab == weekTab })
193+ weekViewObj.onDayStartChanged.connect(function (){
194+ tabs.currentDay = weekViewObj.dayStart;
195+ });
196+ weekViewObj.dateSelected.connect(function (date){
197+ tabs.currentDay = date;
198+ tabs.selectedTabIndex = dayTab.index;
199+ });
200+
201+ weekTab.page = weekViewObj;
202+ }
203+ } else {
204+ weekTab.page.dayStart = tabs.currentDay;
205+ }
206+ } break;
207+ case dayTab: {
208+ if (dayTab.page === null) {
209+ var dayViewCom = Qt.createComponent("DayView.qml");
210+ if (dayViewCom.status === Component.Ready) {
211+ var dayViewObj = dayViewCom.createObject(mainView);
212+
213+ dayViewObj.isCurrentPage= Qt.binding(function() { return tabs.selectedTab == dayTab })
214+ dayViewObj.onCurrentDayChanged.connect(function (){
215+ tabs.currentDay = dayViewObj.currentDay;
216+ });
217+ dayViewObj.dateSelected.connect(function (date) {
218+ tabs.currentDay = date;
219+ });
220+
221+ dayTab.page =dayViewObj;
222+ }
223+ } else {
224+ dayTab.page.currentDay = tabs.currentDay;
225+ }
226+ } break;
227+ case agendaTab: {
228+ var agendaViewCom = Qt.createComponent("AgendaView.qml");
229+ if (agendaViewCom.status === Component.Ready) {
230+ var agendaViewObj = agendaViewCom.createObject(mainView);
231+
232+ agendaViewObj.dateSelected.connect(function (date){
233+ tabs.currentDay = date;
234+ tabs.selectedTabIndex = dayTab.index;
235+ })
236+ agendaTab.page = agendaViewObj;
237+ }
238+ } break;
239+ default:
240+ break;
241+ }
242+ }
243+
244 Tab{
245 id: yearTab
246 objectName: "yearTab"
247 title: i18n.tr("Year")
248- page: Loader{
249- id: yearViewLoader
250- objectName: "yearViewLoader"
251- source: tabs.selectedTab == yearTab ? Qt.resolvedUrl("YearView.qml"):""
252- onLoaded: {
253- item.currentYear = tabs.currentDay.getFullYear();
254- }
255-
256- anchors{
257- left: parent.left
258- right: parent.right
259- bottom: parent.bottom
260- }
261-
262- Connections{
263- target: yearViewLoader.item
264- onMonthSelected: {
265- var now = DateExt.today();
266- if( date.getMonth() === now.getMonth()
267- && date.getFullYear() === now.getFullYear()) {
268- tabs.currentDay = now;
269- } else {
270- tabs.currentDay = date.midnight();
271- }
272- tabs.selectedTabIndex = monthTab.index;
273- }
274- }
275- }
276+ page: null
277 }
278
279 Tab{
280 id: monthTab
281 objectName: "monthTab"
282 title: i18n.tr("Month")
283- page: Loader{
284- id: monthViewLoader
285- objectName: "monthViewLoader"
286- source: tabs.selectedTab == monthTab ? Qt.resolvedUrl("MonthView.qml"):""
287- onLoaded: {
288- item.currentMonth = tabs.currentDay.midnight();
289- }
290-
291- anchors{
292- left: parent.left
293- right: parent.right
294- bottom: parent.bottom
295- }
296-
297- Connections{
298- target: monthViewLoader.item
299- onDateSelected: {
300- tabs.currentDay = date;
301- tabs.selectedTabIndex = dayTab.index;
302- }
303- }
304- }
305+ page: null
306 }
307
308 Tab{
309 id: weekTab
310 objectName: "weekTab"
311 title: i18n.tr("Week")
312- page: Loader{
313- id: weekViewLoader
314- objectName: "weekViewLoader"
315- source: tabs.selectedTab == weekTab ? Qt.resolvedUrl("WeekView.qml"):""
316- onLoaded: {
317- item.isCurrentPage= Qt.binding(function() { return tabs.selectedTab == weekTab })
318- item.dayStart = tabs.currentDay;
319- }
320-
321- anchors{
322- left: parent.left
323- right: parent.right
324- bottom: parent.bottom
325- }
326-
327- Connections{
328- target: weekViewLoader.item
329- onDayStartChanged: {
330- tabs.currentDay = weekViewLoader.item.dayStart;
331- }
332-
333- onDateSelected: {
334- tabs.currentDay = date;
335- tabs.selectedTabIndex = dayTab.index;
336- }
337- }
338- }
339+ page: null
340 }
341
342 Tab{
343 id: dayTab
344 objectName: "dayTab"
345 title: i18n.tr("Day")
346- page: Loader{
347- id: dayViewLoader
348- objectName: "dayViewLoader"
349- source: tabs.selectedTab == dayTab ? Qt.resolvedUrl("DayView.qml"):""
350- onLoaded: {
351- item.isCurrentPage= Qt.binding(function() { return tabs.selectedTab == dayTab })
352- item.currentDay = tabs.currentDay;
353- }
354-
355- anchors{
356- left: parent.left
357- right: parent.right
358- bottom: parent.bottom
359- }
360-
361- Connections{
362- target: dayViewLoader.item
363- onCurrentDayChanged: {
364- tabs.currentDay = dayViewLoader.item.currentDay;
365- }
366-
367- onDateSelected: {
368- tabs.currentDay = date;
369- }
370- }
371- }
372+ page: null
373 }
374
375 Tab {
376 id: agendaTab
377 objectName: "agendaTab"
378 title: i18n.tr("Agenda")
379- page: Loader {
380- id: agendaViewLoader
381- objectName: "agendaViewLoader"
382- source: tabs.selectedTab == agendaTab ? Qt.resolvedUrl("AgendaView.qml"):""
383-
384- anchors{
385- left: parent.left
386- right: parent.right
387- bottom: parent.bottom
388- }
389-
390- Connections{
391- target: agendaViewLoader.item
392- onDateSelected: {
393- tabs.currentDay = date;
394- tabs.selectedTabIndex = dayTab.index;
395- }
396- }
397- }
398+ page: null
399 }
400 }
401 }
402
403=== modified file 'po/com.ubuntu.calendar.pot'
404--- po/com.ubuntu.calendar.pot 2015-04-17 05:05:13 +0000
405+++ po/com.ubuntu.calendar.pot 2015-05-14 03:37:54 +0000
406@@ -8,7 +8,7 @@
407 msgstr ""
408 "Project-Id-Version: \n"
409 "Report-Msgid-Bugs-To: \n"
410-"POT-Creation-Date: 2015-04-17 07:04+0200\n"
411+"POT-Creation-Date: 2015-05-14 11:34+0800\n"
412 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
413 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
414 "Language-Team: LANGUAGE <LL@li.org>\n"
415@@ -19,7 +19,7 @@
416 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
417
418 #: ../AgendaView.qml:51 ../DayView.qml:40 ../MonthView.qml:37
419-#: ../WeekView.qml:42 ../YearView.qml:36
420+#: ../WeekView.qml:42 ../YearView.qml:42
421 msgid "Today"
422 msgstr ""
423
424@@ -37,7 +37,7 @@
425
426 #. TRANSLATORS: the first argument (%1) refers to a start time for an event,
427 #. while the second one (%2) refers to the end time
428-#: ../AgendaView.qml:168 ../EventBubble.qml:131
429+#: ../AgendaView.qml:168 ../EventBubble.qml:133
430 #, qt-format
431 msgid "%1 - %2"
432 msgstr ""
433@@ -59,7 +59,7 @@
434 msgstr[0] ""
435 msgstr[1] ""
436
437-#: ../CalendarChoicePopup.qml:33 ../EventActions.qml:59
438+#: ../CalendarChoicePopup.qml:33 ../EventActions.qml:60
439 msgid "Calendars"
440 msgstr ""
441
442@@ -77,15 +77,15 @@
443 msgid "Syncing"
444 msgstr ""
445
446-#: ../CalendarChoicePopup.qml:70
447+#: ../CalendarChoicePopup.qml:71
448 msgid "Add new Calendar"
449 msgstr ""
450
451-#: ../ColorPickerDialog.qml:24
452+#: ../ColorPickerDialog.qml:25
453 msgid "Select Color"
454 msgstr ""
455
456-#: ../ColorPickerDialog.qml:53 ../DeleteConfirmationDialog.qml:60
457+#: ../ColorPickerDialog.qml:55 ../DeleteConfirmationDialog.qml:60
458 #: ../EditEventConfirmationDialog.qml:53
459 msgid "Cancel"
460 msgstr ""
461@@ -101,7 +101,7 @@
462 #. TRANSLATORS: this is a time formatting string,
463 #. see http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for valid expressions.
464 #. It's used in the header of the month and week views
465-#: ../DayView.qml:59 ../MonthView.qml:57 ../WeekView.qml:61
466+#: ../DayView.qml:59 ../MonthView.qml:58 ../WeekView.qml:61
467 msgid "MMMM yyyy"
468 msgstr ""
469
470@@ -136,7 +136,7 @@
471 msgid "Delete"
472 msgstr ""
473
474-#: ../EditEventConfirmationDialog.qml:29 ../NewEvent.qml:283
475+#: ../EditEventConfirmationDialog.qml:29 ../NewEvent.qml:287
476 msgid "Edit Event"
477 msgstr ""
478
479@@ -154,18 +154,18 @@
480 msgid "Edit this"
481 msgstr ""
482
483-#: ../EventActions.qml:50 ../NewEvent.qml:283
484+#: ../EventActions.qml:50 ../NewEvent.qml:287
485 msgid "New Event"
486 msgstr ""
487
488 #. TRANSLATORS: the first argument (%1) refers to a time for an event,
489 #. while the second one (%2) refers to title of event
490-#: ../EventBubble.qml:142 ../EventBubble.qml:147
491+#: ../EventBubble.qml:144 ../EventBubble.qml:149
492 #, qt-format
493 msgid "%1 <b>%2</b>"
494 msgstr ""
495
496-#: ../EventDetails.qml:42 ../NewEvent.qml:393
497+#: ../EventDetails.qml:42 ../NewEvent.qml:398
498 msgid "Event Details"
499 msgstr ""
500
501@@ -189,11 +189,11 @@
502 msgid "Edit"
503 msgstr ""
504
505-#: ../EventDetails.qml:347 ../NewEvent.qml:479
506+#: ../EventDetails.qml:347 ../NewEvent.qml:500
507 msgid "Guests"
508 msgstr ""
509
510-#: ../EventDetails.qml:390 ../EventReminder.qml:35 ../NewEvent.qml:578
511+#: ../EventDetails.qml:390 ../EventReminder.qml:35 ../NewEvent.qml:599
512 msgid "Reminder"
513 msgstr ""
514
515@@ -201,26 +201,26 @@
516 #. and it is shown as the header of the page to choose repetition
517 #. and as the header of the list item that shows the repetition
518 #. summary in the page that displays the event details
519-#: ../EventRepetition.qml:41 ../EventRepetition.qml:132
520+#: ../EventRepetition.qml:41 ../EventRepetition.qml:150
521 msgid "Repeat"
522 msgstr ""
523
524-#: ../EventRepetition.qml:151
525+#: ../EventRepetition.qml:169
526 msgid "Repeats On:"
527 msgstr ""
528
529-#: ../EventRepetition.qml:196
530+#: ../EventRepetition.qml:214
531 msgid "Recurring event ends"
532 msgstr ""
533
534 #. TRANSLATORS: this refers to how often a recurrent event repeats
535 #. and it is shown as the header of the option selector to choose
536 #. its repetition
537-#: ../EventRepetition.qml:219 ../NewEvent.qml:560
538+#: ../EventRepetition.qml:237 ../NewEvent.qml:581
539 msgid "Repeats"
540 msgstr ""
541
542-#: ../EventRepetition.qml:244
543+#: ../EventRepetition.qml:262
544 msgid "Date"
545 msgstr ""
546
547@@ -259,51 +259,51 @@
548 msgid "After Date"
549 msgstr ""
550
551-#: ../NewEvent.qml:59
552+#: ../NewEvent.qml:61
553 msgid "Save"
554 msgstr ""
555
556-#: ../NewEvent.qml:165
557+#: ../NewEvent.qml:170
558 msgid "End time can't be before start time"
559 msgstr ""
560
561-#: ../NewEvent.qml:293
562+#: ../NewEvent.qml:297
563 msgid "Error"
564 msgstr ""
565
566-#: ../NewEvent.qml:295
567+#: ../NewEvent.qml:299
568 msgid "OK"
569 msgstr ""
570
571-#: ../NewEvent.qml:347
572+#: ../NewEvent.qml:352
573 msgid "From"
574 msgstr ""
575
576-#: ../NewEvent.qml:360
577+#: ../NewEvent.qml:365
578 msgid "To"
579 msgstr ""
580
581-#: ../NewEvent.qml:377
582+#: ../NewEvent.qml:382
583 msgid "All day event"
584 msgstr ""
585
586-#: ../NewEvent.qml:406
587+#: ../NewEvent.qml:411
588 msgid "Event Name"
589 msgstr ""
590
591-#: ../NewEvent.qml:419
592+#: ../NewEvent.qml:429
593 msgid "Description"
594 msgstr ""
595
596-#: ../NewEvent.qml:432
597+#: ../NewEvent.qml:447
598 msgid "Location"
599 msgstr ""
600
601-#: ../NewEvent.qml:441 com.ubuntu.calendar_calendar.desktop.in.in.h:1
602+#: ../NewEvent.qml:462 com.ubuntu.calendar_calendar.desktop.in.in.h:1
603 msgid "Calendar"
604 msgstr ""
605
606-#: ../NewEvent.qml:483
607+#: ../NewEvent.qml:504
608 msgid "Add Guest"
609 msgstr ""
610
611@@ -390,6 +390,10 @@
612 msgid "2 weeks"
613 msgstr ""
614
615+#: ../TimeLineBase.qml:73
616+msgid "Untitled"
617+msgstr ""
618+
619 #. TRANSLATORS: W refers to Week, followed by the actual week number (%1)
620 #: ../TimeLineHeader.qml:49
621 #, qt-format
622@@ -400,7 +404,7 @@
623 msgid "All Day"
624 msgstr ""
625
626-#: ../YearView.qml:54
627+#: ../YearView.qml:60
628 #, qt-format
629 msgid "Year %1"
630 msgstr ""
631@@ -412,23 +416,23 @@
632 "about them"
633 msgstr ""
634
635-#: ../calendar.qml:322
636+#: ../calendar.qml:422
637 msgid "Year"
638 msgstr ""
639
640-#: ../calendar.qml:356
641+#: ../calendar.qml:429
642 msgid "Month"
643 msgstr ""
644
645-#: ../calendar.qml:384
646+#: ../calendar.qml:436
647 msgid "Week"
648 msgstr ""
649
650-#: ../calendar.qml:417
651+#: ../calendar.qml:443
652 msgid "Day"
653 msgstr ""
654
655-#: ../calendar.qml:449
656+#: ../calendar.qml:450
657 msgid "Agenda"
658 msgstr ""
659

Subscribers

People subscribed via source and target branches

to status/vote changes: