← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

[Merge] lp:~gary-wzl77/ubuntu-calendar-app/opt_dynamic_creation into lp:ubuntu-calendar-app

 

Gary.Wang has proposed merging lp:~gary-wzl77/ubuntu-calendar-app/opt_dynamic_creation into lp:ubuntu-calendar-app.

Commit message:
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.

Requested reviews:
  Ubuntu Calendar Developers (ubuntu-calendar-dev)

For more details, see:
https://code.launchpad.net/~gary-wzl77/ubuntu-calendar-app/opt_dynamic_creation/+merge/268867

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.
-- 
Your team Ubuntu Calendar Developers is requested to review the proposed merge of lp:~gary-wzl77/ubuntu-calendar-app/opt_dynamic_creation into lp:ubuntu-calendar-app.
=== modified file 'AgendaView.qml'
--- AgendaView.qml	2015-02-22 10:18:16 +0000
+++ AgendaView.qml	2015-08-24 03:08:58 +0000
@@ -60,7 +60,8 @@
         commonHeaderActions.newEventAction,
         commonHeaderActions.showCalendarAction,
         commonHeaderActions.reloadAction,
-        commonHeaderActions.syncCalendarAction
+        commonHeaderActions.syncCalendarAction,
+        commonHeaderActions.settingsAction
     ]
 
     EventListModel {

=== modified file 'AllDayEventComponent.qml'
--- AllDayEventComponent.qml	2015-06-16 09:18:21 +0000
+++ AllDayEventComponent.qml	2015-08-24 03:08:58 +0000
@@ -40,6 +40,9 @@
         for(var i = 0 ; i < items.length ; ++i) {
             var event = items[(i)];
             if( event && event.allDay ) {
+
+                console.log("event.startDateTime", event.startDateTime,"    event.endDateTime",event.endDateTime);
+
                 for(var d = event.startDateTime; d < event.endDateTime; d = d.addDays(1)) {
                     var key = Qt.formatDateTime(d, "dd-MMM-yyyy");
                     if( !(key in map)) {

=== modified file 'ContactChoicePopup.qml'
--- ContactChoicePopup.qml	2014-09-20 10:45:35 +0000
+++ ContactChoicePopup.qml	2015-08-24 03:08:58 +0000
@@ -94,7 +94,7 @@
             objectName: "contactPopoverList"
             width: parent.width
             model: contactModel
-            height: units.gu(30)
+            height: units.gu(15)
             clip: true
             delegate: Standard{
                 objectName: "contactPopoverList%1".arg(index)

=== modified file 'DayView.qml'
--- DayView.qml	2015-02-18 19:27:20 +0000
+++ DayView.qml	2015-08-24 03:08:58 +0000
@@ -49,7 +49,8 @@
             commonHeaderActions.newEventAction,
             commonHeaderActions.showCalendarAction,
             commonHeaderActions.reloadAction,
-            commonHeaderActions.syncCalendarAction
+            commonHeaderActions.syncCalendarAction,
+            commonHeaderActions.settingsAction
         ]
 
         contents: Label {

=== modified file 'EventActions.qml'
--- EventActions.qml	2015-04-13 19:40:48 +0000
+++ EventActions.qml	2015-08-24 03:08:58 +0000
@@ -26,6 +26,7 @@
     property alias newEventAction: _newEventAction
     property alias showCalendarAction: _showCalendarAction
     property alias syncCalendarAction: _syncCalendarAction
+    property alias settingsAction: _settingsAction
 
     Action {
         id: _syncCalendarAction
@@ -63,4 +64,14 @@
             pageStack.currentPage.collectionUpdated.connect(eventModel.delayedApplyFilter);
         }
     }
+
+    Action{
+        id: _settingsAction
+        objectName: "settingsbutton"
+        iconName: "settings"
+        text: i18n.tr("Settings")
+        onTriggered: {
+            pageStack.push(Qt.resolvedUrl("Settings.qml"));
+        }
+    }
 }

=== modified file 'EventBubble.qml'
--- EventBubble.qml	2015-01-22 19:34:59 +0000
+++ EventBubble.qml	2015-08-24 03:08:58 +0000
@@ -221,8 +221,8 @@
         anchors.fill: parent
         drag.target: isLiveEditing ? infoBubble : null
         drag.axis: Drag.YAxis
-        drag.minimumY: flickable.y
-        drag.maximumY: flickable.contentHeight - infoBubble.height
+        drag.minimumY: flickable === null? 0: flickable.y
+        drag.maximumY: flickable === null? 0 :flickable.contentHeight - infoBubble.height
         onReleased: parent.Drag.drop()
         onClicked: {
             if( isLiveEditing ) {

=== modified file 'EventListModel.qml'
--- EventListModel.qml	2015-08-02 03:59:08 +0000
+++ EventListModel.qml	2015-08-24 03:08:58 +0000
@@ -44,7 +44,7 @@
         var newObject = Qt.createQmlObject("import QtQuick 2.3; Timer {interval: 1000; running: true; repeat: false;}",
             eventModel, "EventListMode.qml");
         newObject.onTriggered.connect( function(){
-            var items = getItems(eventModel.startPeriod, eventModel.endPeriod);
+            var items = itemsByTimePeriod(eventModel.startPeriod, eventModel.endPeriod);
             if( isLoading == true && items.length === 0) {
                 isLoading = false;
                 modelChanged();
@@ -53,7 +53,6 @@
         });
     }
 
-
     onModelChanged: {
         isLoading = false
         if(listeners === undefined){

=== modified file 'MonthComponent.qml'
--- MonthComponent.qml	2015-08-03 04:32:33 +0000
+++ MonthComponent.qml	2015-08-24 03:08:58 +0000
@@ -30,6 +30,7 @@
 
     property var currentMonth;
     property var isYearView;
+    property bool isWeekNumberShown:false;
 
     property string dayLabelFontSize: "medium"
     property string dateLabelFontSize: "large"
@@ -123,7 +124,10 @@
         id: column
 
         anchors {
-            fill: parent
+            left: weekNumLoader.right;
+            right: parent.right;
+            top: parent.top;
+            bottom: parent.bottom;
             topMargin: units.gu(1.5)
             bottomMargin: units.gu(1)
         }
@@ -191,6 +195,87 @@
         }
     }
 
+    Loader {
+        id: weekNumLoader;
+        anchors.left: parent.left;
+        width: isWeekNumberShown ? parent.width / 7:0;
+        height: parent.height;
+        visible: isWeekNumberShown;
+        sourceComponent: isWeekNumberShown ? weekNumComp : undefined;
+    }
+
+    Component {
+        id: weekNumComp
+
+        Column {
+            id: weekNumColumn;
+
+            anchors {
+                fill: parent
+                topMargin: units.gu(1.0)
+                bottomMargin: units.gu(1.25)
+            }
+
+            Item {
+                id: datePlaceHolder;
+                objectName:"datePlaceHolder"
+
+                width: parent.width;
+                height: isYearView ? units.gu(4.5): units.gu(1.25)
+            }
+
+            Item {
+                id: weekNumLabelItem;
+                objectName: "weekNumLabelItem"
+
+                width: parent.width;
+                height: weekNumLabel.height + units.gu(2.0)
+
+                Label{
+                    id: weekNumLabel;
+                    objectName: "weekNumLabel";
+                    width: parent.width;
+                    text: i18n.tr("Wk");
+                    horizontalAlignment: Text.AlignHCenter;
+                    verticalAlignment: Text.AlignVCenter;
+                    font.pixelSize: intern.dayFontSize;
+                    font.bold: true
+                    color: "black"
+                }
+            }
+
+            Repeater {
+                id: weekNumrepeater;
+                model: 6;
+
+                Label{
+                    id: weekNum
+                    objectName: "weekNum" + index
+                    width: parent.width;
+                    height: (weekNumColumn.height - weekNumLabelItem.height - datePlaceHolder.height) / 6;
+                    text: intern.monthStart.addDays(index * 7).weekNumber(Qt.locale().firstDayOfWeek)
+                    horizontalAlignment: Text.AlignHCenter;
+                    verticalAlignment: Text.AlignVCenter;
+                    font.pixelSize: intern.dayFontSize + 1;
+                    font.bold: true
+                    color: "black"
+
+                    MouseArea {
+                        anchors.fill: parent
+                        onClicked: {
+                            var selectedDate = new Date(intern.monthStart.addDays(index * 7))
+                            if( isYearView ) {
+                                root.monthSelected(selectedDate);
+                            } else {
+                                root.dateSelected(selectedDate);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     Component{
         id: defaultDateLabelComponent
         MonthComponentDateDelegate{

=== modified file 'MonthView.qml'
--- MonthView.qml	2015-03-01 14:01:35 +0000
+++ MonthView.qml	2015-08-24 03:08:58 +0000
@@ -46,7 +46,8 @@
             commonHeaderActions.newEventAction,
             commonHeaderActions.showCalendarAction,
             commonHeaderActions.reloadAction,
-            commonHeaderActions.syncCalendarAction
+            commonHeaderActions.syncCalendarAction,
+            commonHeaderActions.settingsAction
         ]
 
         contents: Label {
@@ -106,6 +107,8 @@
 
                     showEvents: true
 
+                    isWeekNumberShown: mainView.isWeekNumberShown;
+
                     anchors.fill: parent
 
                     currentMonth: monthViewPath.addMonth(monthViewPath.startMonth,

=== modified file 'NewEvent.qml'
--- NewEvent.qml	2015-08-04 02:18:52 +0000
+++ NewEvent.qml	2015-08-24 03:08:58 +0000
@@ -255,6 +255,7 @@
 
             model.saveItem(event);
             pageStack.pop();
+
             root.eventAdded(event);
         }
     }

=== added file 'OfflineStorage.js'
--- OfflineStorage.js	1970-01-01 00:00:00 +0000
+++ OfflineStorage.js	2015-08-24 03:08:58 +0000
@@ -0,0 +1,33 @@
+.pragma library
+.import QtQuick.LocalStorage 2.0 as Sql
+
+function getSettings(key, defaultValue) {
+    var db = Sql.LocalStorage.openDatabaseSync(
+                "com.ubuntu.calendar", "1.0", "Calendar offline storage", 50);
+
+    db.transaction (function (tx) {
+        tx.executeSql("CREATE TABLE IF NOT EXISTS settings (key TEXT UNIQUE, value BLOB)");
+        var rs = tx.executeSql("SELECT * FROM settings");
+
+        var item = {};
+        for (var i = 0; i < rs.rows.length; i++) {
+            if (key === rs.rows.item(i).key) {
+                defaultValue = rs.rows.item(i).value;
+                return;
+            }
+        }
+    })
+
+    return defaultValue;
+}
+
+function updateSettings(key, value) {
+    var db = Sql.LocalStorage.openDatabaseSync(
+                "com.ubuntu.calendar", "1.0", "Calendar offline storage", 50);
+
+    db.transaction (function (tx){
+        tx.executeSql("INSERT OR REPLACE INTO settings VALUES(?, ?)",
+                      [key, value]);
+    })
+}
+

=== added file 'Settings.qml'
--- Settings.qml	1970-01-01 00:00:00 +0000
+++ Settings.qml	2015-08-24 03:08:58 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013-2014 Canonical Ltd
+ *
+ * This file is part of Ubuntu Calendar App
+ *
+ * Ubuntu Calendar App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Calendar App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.3
+import Ubuntu.Components 1.1
+import Ubuntu.Components.Popups 1.0
+import Ubuntu.Components.ListItems 1.0 as ListItem
+import "OfflineStorage.js" as CalendarStorage
+
+Page {
+    id: root
+    objectName: "settings"
+
+    visible: false
+    title: i18n.tr("Settings")
+
+    head {
+        backAction: Action {
+            text: i18n.tr("Back")
+            iconName: "back"
+            onTriggered: {
+                pop();
+            }
+        }
+    }
+
+    ListModel{
+        id: model;
+    }
+
+    Column {
+        id: settingsColumn
+        objectName: "settingsColumn"
+        spacing: units.gu(0.5)
+        anchors {
+            margins: units.gu(2)
+            fill: parent
+        }
+
+        Item{
+            width: parent.width;
+            height: Math.max(weekNumber.height, weekCheckBox.height)
+
+            Label{
+                id: weekNumber;
+                objectName: "weekNumber"
+                text: i18n.tr("Show week numbers");
+                elide: Text.ElideRight
+                opacity: weekCheckBox.checked ? 1.0 : 0.8
+                color: UbuntuColors.midAubergine
+                anchors {
+                    left: parent.left
+                    right: weekCheckBox.left;
+                    margins: units.gu(2)
+                    verticalCenter: parent.verticalCenter
+                }
+            }
+
+            CheckBox {
+                id: weekCheckBox
+                objectName: "weekCheckBox"
+                anchors.right:parent.right;
+                onCheckedChanged: {
+                    mainView.isWeekNumberShown = weekCheckBox.checked;
+                    CalendarStorage.updateSettings("show_week_numbers",mainView.isWeekNumberShown);
+                }
+            }
+        }
+
+        ListItem.ThinDivider {}
+    }
+
+    Component.onCompleted: {
+        weekCheckBox.checked = mainView.isWeekNumberShown;
+    }
+}
+

=== modified file 'WeekView.qml'
--- WeekView.qml	2015-03-20 17:32:03 +0000
+++ WeekView.qml	2015-08-24 03:08:58 +0000
@@ -51,7 +51,8 @@
             commonHeaderActions.newEventAction,
             commonHeaderActions.showCalendarAction,
             commonHeaderActions.reloadAction,
-            commonHeaderActions.syncCalendarAction
+            commonHeaderActions.syncCalendarAction,
+            commonHeaderActions.settingsAction
         ]
 
         contents: Label {

=== modified file 'YearView.qml'
--- YearView.qml	2015-02-18 19:27:20 +0000
+++ YearView.qml	2015-08-24 03:08:58 +0000
@@ -29,6 +29,12 @@
 
     Keys.forwardTo: [yearPathView]
 
+    function refreshCurrentYear(year) {
+        currentYear = year;
+        var yearViewDelegate = yearPathView.currentItem.item;
+        yearViewDelegate.refresh();
+    }
+
     Action {
         id: calendarTodayAction
         objectName:"todaybutton"
@@ -45,7 +51,8 @@
             commonHeaderActions.newEventAction,
             commonHeaderActions.showCalendarAction,
             commonHeaderActions.reloadAction,
-            commonHeaderActions.syncCalendarAction
+            commonHeaderActions.syncCalendarAction,
+            commonHeaderActions.settingsAction
         ]
         contents: Label {
             id:year
@@ -85,7 +92,7 @@
 
                     scrollMonth: 0;
                     isCurrentItem: index == yearPathView.currentIndex
-                    year: (yearViewPage.currentYear + yearPathView.indexType(index))
+                    year: (currentYear + yearPathView.indexType(index))
 
                     anchors.fill: parent
                 }

=== modified file 'YearViewDelegate.qml'
--- YearViewDelegate.qml	2014-11-29 09:40:53 +0000
+++ YearViewDelegate.qml	2015-08-24 03:08:58 +0000
@@ -18,6 +18,19 @@
     model: 12 /* months in a year */
 
     onYearChanged: {
+        refresh();
+    }
+
+    //scroll in case content height changed
+    onHeightChanged: {
+        yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
+    }
+
+    Component.onCompleted: {
+        yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
+    }
+
+    function refresh() {
         scrollMonth = 0;
         var today = new Date();
         if(year == today.getFullYear()) {
@@ -26,15 +39,6 @@
         yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
     }
 
-    //scroll in case content height changed
-    onHeightChanged: {
-        yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
-    }
-
-    Component.onCompleted: {
-        yearView.positionViewAtIndex(scrollMonth, GridView.Beginning);
-    }
-
     Connections{
         target: yearPathView
         onScrollUp: {
@@ -74,7 +78,7 @@
                     objectName: "monthComponent" + index
                     showEvents: false
                     currentMonth: new Date(yearView.year, index, 1, 0, 0, 0, 0)
-
+                    isWeekNumberShown: mainView.isWeekNumberShown;
                     isCurrentItem: yearView.focus
 
                     isYearView: true

=== modified file 'calendar.qml'
--- calendar.qml	2015-06-11 12:29:28 +0000
+++ calendar.qml	2015-08-24 03:08:58 +0000
@@ -19,11 +19,15 @@
 import Ubuntu.Components 1.1
 import Ubuntu.Components.Popups 1.0
 import QtOrganizer 5.0
+import "OfflineStorage.js" as CalendarStorage
 
 import "dateExt.js" as DateExt
 
 MainView {
     id: mainView
+
+    property bool isWeekNumberShown: false;
+
     useDeprecatedToolbar: false
 
     // Work-around until this branch lands:
@@ -211,7 +215,7 @@
 
         Tabs{
             id: tabs
-            Keys.forwardTo: [tabs.currentPage.item]
+            Keys.forwardTo: [tabs.currentPage]
 
             property var currentDay: DateExt.today();
 
@@ -220,7 +224,11 @@
             property int starttime: -1;
             property int endtime: -1;
 
-            selectedTabIndex: weekTab.index
+            onSelectedTabIndexChanged: {
+                //Workaround: on u-touch, can't get respond from Component.onDestruction,
+                //which is a common way to record last session tab index
+                CalendarStorage.updateSettings("last_session_tabIndex",selectedTabIndex);
+            }
 
             function newEvent() {
                 var startDate = new Date();
@@ -282,6 +290,8 @@
             }
 
             Component.onCompleted: {
+                var lastSessionTabIndex = CalendarStorage.getSettings("last_session_tabIndex", weekTab.index);
+
                 // If an url has been set
                 if (args.defaultArgument.at(0)) {
                     parseArguments(args.defaultArgument.at(0))
@@ -307,11 +317,11 @@
                     else {
                         // Due to bug #1231558 {if (args.defaultArgument.at(0))} is always true
                         // After the fix we can delete this else
-                        tabs.selectedTabIndex = weekTab.index;
+                        tabs.selectedTabIndex = lastSessionTabIndex;
                     }
                 } // End of if about args.values
                 else {
-                    tabs.selectedTabIndex = weekTab.index;
+                     tabs.selectedTabIndex = lastSessionTabIndex;
                 }
             } // End of Component.onCompleted:
 
@@ -341,157 +351,144 @@
                 }
             }
 
+            onSelectedTabChanged: {
+                switch (tabs.selectedTab) {
+                case yearTab:{
+                    if (yearTab.page === null) {
+                        var yearViewCom = Qt.createComponent("YearView.qml");
+                        if (yearViewCom.status === Component.Ready) {
+                            var yearViewObj = yearViewCom.createObject(mainView);
+
+                            yearViewObj.monthSelected.connect(function (date){
+                                var now = DateExt.today();
+                                if( date.getMonth() === now.getMonth()
+                                        && date.getFullYear() === now.getFullYear()) {
+                                    tabs.currentDay = now;
+                                } else {
+                                    tabs.currentDay = date.midnight();
+                                }
+                                tabs.selectedTabIndex = monthTab.index;
+                            })
+
+                            yearTab.page = yearViewObj;
+                        }
+                    } else {
+                        yearTab.page.refreshCurrentYear(DateExt.today().getFullYear());
+                    }
+                } break;
+                case monthTab: {
+                    if (monthTab.page === null) {
+                        var monthViewCom = Qt.createComponent("MonthView.qml");
+                        if (monthViewCom.status === Component.Ready) {
+                            var monthViewObj = monthViewCom.createObject(mainView);
+
+                            monthViewObj.dateSelected.connect(function (date) {
+                                tabs.currentDay = date;
+                                tabs.selectedTabIndex = dayTab.index;
+                            })
+
+                            monthTab.page = monthViewObj;
+                        }
+                    } else {
+                        monthTab.page.currentMonth = tabs.currentDay.midnight();
+                    }
+                } break;
+                case weekTab: {
+                    if (weekTab.page === null) {
+                        var weekViewCom = Qt.createComponent("WeekView.qml");
+                        if (weekViewCom.status === Component.Ready) {
+                            var weekViewObj = weekViewCom.createObject(mainView);
+
+                            weekViewObj.isCurrentPage = Qt.binding(function() { return tabs.selectedTab == weekTab })
+                            weekViewObj.onDayStartChanged.connect(function (){
+                                tabs.currentDay = weekViewObj.dayStart;
+                            });
+                            weekViewObj.dateSelected.connect(function (date){
+                                tabs.currentDay = date;
+                                tabs.selectedTabIndex = dayTab.index;
+                            });
+
+                            weekTab.page = weekViewObj;
+                        }
+                    } else {
+                        weekTab.page.dayStart = tabs.currentDay;
+                    }
+                } break;
+                case dayTab: {
+                    if (dayTab.page === null) {
+                        var dayViewCom = Qt.createComponent("DayView.qml");
+                        if (dayViewCom.status === Component.Ready) {
+                            var dayViewObj = dayViewCom.createObject(mainView);
+
+                            dayViewObj.isCurrentPage= Qt.binding(function() { return tabs.selectedTab == dayTab })
+                            dayViewObj.onCurrentDayChanged.connect(function (){
+                                tabs.currentDay = dayViewObj.currentDay;
+                            });
+                            dayViewObj.dateSelected.connect(function (date) {
+                                tabs.currentDay = date;
+                            });
+
+                            dayTab.page  =dayViewObj;
+                        }
+                    } else {
+                        dayTab.page.currentDay = tabs.currentDay;
+                    }
+                } break;
+                case agendaTab: {
+                    var agendaViewCom = Qt.createComponent("AgendaView.qml");
+                    if (agendaViewCom.status === Component.Ready) {
+                        var agendaViewObj = agendaViewCom.createObject(mainView);
+
+                        agendaViewObj.dateSelected.connect(function (date){
+                            tabs.currentDay = date;
+                            tabs.selectedTabIndex = dayTab.index;
+                        })
+                        agendaTab.page = agendaViewObj;
+                    }
+                } break;
+                default:
+                    break;
+                }
+            }
+
             Tab{
                 id: yearTab
                 objectName: "yearTab"
                 title: i18n.tr("Year")
-                page: Loader{
-                    id: yearViewLoader
-                    objectName: "yearViewLoader"
-                    source: tabs.selectedTab == yearTab ? Qt.resolvedUrl("YearView.qml"):""
-                    onLoaded: {
-                        item.currentYear = tabs.currentDay.getFullYear();
-                    }
-
-                    anchors{
-                        left: parent.left
-                        right: parent.right
-                        bottom: parent.bottom
-                    }
-
-                    Connections{
-                        target: yearViewLoader.item
-                        onMonthSelected: {
-                            var now = DateExt.today();
-                            if( date.getMonth() === now.getMonth()
-                                    && date.getFullYear() === now.getFullYear()) {
-                                tabs.currentDay = now;
-                            } else {
-                                tabs.currentDay = date.midnight();
-                            }
-                            tabs.selectedTabIndex = monthTab.index;
-                        }
-                    }
-                }
+                page: null
             }
 
             Tab{
                 id: monthTab
                 objectName: "monthTab"
                 title: i18n.tr("Month")
-                page: Loader{
-                    id: monthViewLoader
-                    objectName: "monthViewLoader"
-                    source: tabs.selectedTab == monthTab ? Qt.resolvedUrl("MonthView.qml"):""
-                    onLoaded: {
-                        item.currentMonth = tabs.currentDay.midnight();
-                    }
-
-                    anchors{
-                        left: parent.left
-                        right: parent.right
-                        bottom: parent.bottom
-                    }
-
-                    Connections{
-                        target: monthViewLoader.item
-                        onDateSelected: {
-                            tabs.currentDay = date;
-                            tabs.selectedTabIndex = dayTab.index;
-                        }
-                    }
-                }
+                page: null
             }
 
             Tab{
                 id: weekTab
                 objectName: "weekTab"
                 title: i18n.tr("Week")
-                page: Loader{
-                    id: weekViewLoader
-                    objectName: "weekViewLoader"
-                    source: tabs.selectedTab == weekTab ? Qt.resolvedUrl("WeekView.qml"):""
-                    onLoaded: {
-                        item.isCurrentPage= Qt.binding(function() { return tabs.selectedTab == weekTab })
-                        item.dayStart = tabs.currentDay;
-                    }
-
-                    anchors{
-                        left: parent.left
-                        right: parent.right
-                        bottom: parent.bottom
-                    }
-
-                    Connections{
-                        target: weekViewLoader.item
-                        onDayStartChanged: {
-                            tabs.currentDay = weekViewLoader.item.dayStart;
-                        }
-
-                        onDateSelected: {
-                            tabs.currentDay = date;
-                            tabs.selectedTabIndex = dayTab.index;
-                        }
-                    }
-                }
+                page: null
             }
 
             Tab{
                 id: dayTab
                 objectName: "dayTab"
                 title: i18n.tr("Day")
-                page: Loader{
-                    id: dayViewLoader
-                    objectName: "dayViewLoader"
-                    source: tabs.selectedTab == dayTab ? Qt.resolvedUrl("DayView.qml"):""
-                    onLoaded: {
-                        item.isCurrentPage= Qt.binding(function() { return tabs.selectedTab == dayTab })
-                        item.currentDay = tabs.currentDay;
-                    }
-
-                    anchors{
-                        left: parent.left
-                        right: parent.right
-                        bottom: parent.bottom
-                    }
-
-                    Connections{
-                        target: dayViewLoader.item
-                        onCurrentDayChanged: {
-                            tabs.currentDay = dayViewLoader.item.currentDay;
-                        }
-
-                        onDateSelected: {
-                            tabs.currentDay = date;
-                        }
-                    }
-                }
+                page: null
             }
 
             Tab {
                 id: agendaTab
                 objectName: "agendaTab"
                 title: i18n.tr("Agenda")
-                page: Loader {
-                    id: agendaViewLoader
-                    objectName: "agendaViewLoader"
-                    source: tabs.selectedTab == agendaTab ? Qt.resolvedUrl("AgendaView.qml"):""
-
-                    anchors{
-                        left: parent.left
-                        right: parent.right
-                        bottom: parent.bottom
-                    }
-
-                    Connections{
-                        target: agendaViewLoader.item
-                        onDateSelected: {
-                            tabs.currentDay = date;
-                            tabs.selectedTabIndex = dayTab.index;
-                        }
-                    }
-                }
+                page: null
             }
         }
     }
+
+    Component.onCompleted: {
+        mainView.isWeekNumberShown = CalendarStorage.getSettings("show_week_numbers", false);
+    }
 }

=== modified file 'po/com.ubuntu.calendar.pot'
--- po/com.ubuntu.calendar.pot	2015-08-04 02:18:52 +0000
+++ po/com.ubuntu.calendar.pot	2015-08-24 03:08:58 +0000
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-08-04 10:18+0800\n"
+"POT-Creation-Date: 2015-08-24 10:31+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -19,25 +19,25 @@
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
 #: ../AgendaView.qml:51 ../DayView.qml:40 ../MonthView.qml:37
-#: ../WeekView.qml:42 ../YearView.qml:36
+#: ../WeekView.qml:42 ../YearView.qml:42
 msgid "Today"
 msgstr ""
 
-#: ../AgendaView.qml:92
+#: ../AgendaView.qml:93
 msgid "No upcoming events"
 msgstr ""
 
-#: ../AgendaView.qml:95
+#: ../AgendaView.qml:96
 msgid "You have no calendars enabled"
 msgstr ""
 
-#: ../AgendaView.qml:105
+#: ../AgendaView.qml:106
 msgid "Enable calendars"
 msgstr ""
 
 #. TRANSLATORS: the first argument (%1) refers to a start time for an event,
 #. while the second one (%2) refers to the end time
-#: ../AgendaView.qml:168 ../EventBubble.qml:133
+#: ../AgendaView.qml:169 ../EventBubble.qml:133
 #, qt-format
 msgid "%1 - %2"
 msgstr ""
@@ -46,34 +46,34 @@
 #. on a given day. "Ev." is short form for "Events".
 #. Please keep the translation of "Ev." to 3 characters only, as the week view
 #. where it's shown has limited space
-#: ../AllDayEventComponent.qml:123
+#: ../AllDayEventComponent.qml:126
 #, qt-format
 msgid "%1 ev."
 msgstr ""
 
 #. TRANSLATORS: the argument refers to the number of all day events
-#: ../AllDayEventComponent.qml:127
+#: ../AllDayEventComponent.qml:130
 #, qt-format
 msgid "%1 all day event"
 msgid_plural "%1 all day events"
 msgstr[0] ""
 msgstr[1] ""
 
-#: ../CalendarChoicePopup.qml:33 ../EventActions.qml:60
+#: ../CalendarChoicePopup.qml:33 ../EventActions.qml:61
 msgid "Calendars"
 msgstr ""
 
-#: ../CalendarChoicePopup.qml:37
+#: ../CalendarChoicePopup.qml:37 ../Settings.qml:33
 msgid "Back"
 msgstr ""
 
 #. TRANSLATORS: Please translate this string  to 15 characters only.
 #. Currently ,there is no way we can increase width of action menu currently.
-#: ../CalendarChoicePopup.qml:51 ../EventActions.qml:36
+#: ../CalendarChoicePopup.qml:51 ../EventActions.qml:37
 msgid "Sync"
 msgstr ""
 
-#: ../CalendarChoicePopup.qml:51 ../EventActions.qml:36
+#: ../CalendarChoicePopup.qml:51 ../EventActions.qml:37
 msgid "Syncing"
 msgstr ""
 
@@ -101,7 +101,7 @@
 #. TRANSLATORS: this is a time formatting string,
 #. see http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for valid expressions.
 #. It's used in the header of the month and week views
-#: ../DayView.qml:59 ../MonthView.qml:58 ../WeekView.qml:61
+#: ../DayView.qml:60 ../MonthView.qml:59 ../WeekView.qml:62
 msgid "MMMM yyyy"
 msgstr ""
 
@@ -136,7 +136,7 @@
 msgid "Delete"
 msgstr ""
 
-#: ../EditEventConfirmationDialog.qml:29 ../NewEvent.qml:324
+#: ../EditEventConfirmationDialog.qml:29 ../NewEvent.qml:325
 msgid "Edit Event"
 msgstr ""
 
@@ -154,10 +154,14 @@
 msgid "Edit this"
 msgstr ""
 
-#: ../EventActions.qml:50 ../NewEvent.qml:324
+#: ../EventActions.qml:51 ../NewEvent.qml:325
 msgid "New Event"
 msgstr ""
 
+#: ../EventActions.qml:72 ../Settings.qml:29
+msgid "Settings"
+msgstr ""
+
 #. TRANSLATORS: the first argument (%1) refers to a time for an event,
 #. while the second one (%2) refers to title of event
 #: ../EventBubble.qml:144 ../EventBubble.qml:149
@@ -165,7 +169,7 @@
 msgid "%1 <b>%2</b>"
 msgstr ""
 
-#: ../EventDetails.qml:43 ../NewEvent.qml:435
+#: ../EventDetails.qml:43 ../NewEvent.qml:436
 msgid "Event Details"
 msgstr ""
 
@@ -189,11 +193,11 @@
 msgid "Edit"
 msgstr ""
 
-#: ../EventDetails.qml:354 ../NewEvent.qml:537
+#: ../EventDetails.qml:354 ../NewEvent.qml:538
 msgid "Guests"
 msgstr ""
 
-#: ../EventDetails.qml:397 ../EventReminder.qml:35 ../NewEvent.qml:634
+#: ../EventDetails.qml:397 ../EventReminder.qml:35 ../NewEvent.qml:635
 msgid "Reminder"
 msgstr ""
 
@@ -216,7 +220,7 @@
 #. TRANSLATORS: this refers to how often a recurrent event repeats
 #. and it is shown as the header of the option selector to choose
 #. its repetition
-#: ../EventRepetition.qml:242 ../NewEvent.qml:618
+#: ../EventRepetition.qml:242 ../NewEvent.qml:619
 msgid "Repeats"
 msgstr ""
 
@@ -259,6 +263,10 @@
 msgid "After Date"
 msgstr ""
 
+#: ../MonthComponent.qml:238
+msgid "Wk"
+msgstr ""
+
 #: ../NewEvent.qml:84
 msgid "Save"
 msgstr ""
@@ -267,43 +275,43 @@
 msgid "End time can't be before start time"
 msgstr ""
 
-#: ../NewEvent.qml:334
+#: ../NewEvent.qml:335
 msgid "Error"
 msgstr ""
 
-#: ../NewEvent.qml:336
+#: ../NewEvent.qml:337
 msgid "OK"
 msgstr ""
 
-#: ../NewEvent.qml:389
+#: ../NewEvent.qml:390
 msgid "From"
 msgstr ""
 
-#: ../NewEvent.qml:402
+#: ../NewEvent.qml:403
 msgid "To"
 msgstr ""
 
-#: ../NewEvent.qml:419
+#: ../NewEvent.qml:420
 msgid "All day event"
 msgstr ""
 
-#: ../NewEvent.qml:448
+#: ../NewEvent.qml:449
 msgid "Event Name"
 msgstr ""
 
-#: ../NewEvent.qml:466
+#: ../NewEvent.qml:467
 msgid "Description"
 msgstr ""
 
-#: ../NewEvent.qml:484
+#: ../NewEvent.qml:485
 msgid "Location"
 msgstr ""
 
-#: ../NewEvent.qml:499 com.ubuntu.calendar_calendar.desktop.in.in.h:1
+#: ../NewEvent.qml:500 com.ubuntu.calendar_calendar.desktop.in.in.h:1
 msgid "Calendar"
 msgstr ""
 
-#: ../NewEvent.qml:541
+#: ../NewEvent.qml:542
 msgid "Add Guest"
 msgstr ""
 
@@ -390,6 +398,10 @@
 msgid "2 weeks"
 msgstr ""
 
+#: ../Settings.qml:61
+msgid "Show week numbers"
+msgstr ""
+
 #: ../TimeLineBase.qml:80
 msgid "Untitled"
 msgstr ""
@@ -404,35 +416,35 @@
 msgid "All Day"
 msgstr ""
 
-#: ../YearView.qml:54
+#: ../YearView.qml:61
 #, qt-format
 msgid "Year %1"
 msgstr ""
 
-#: ../calendar.qml:44
+#: ../calendar.qml:48
 msgid ""
 "Calendar app accept four arguments: --starttime, --endtime, --newevent and --"
 "eventid. They will be managed by system. See the source for a full comment "
 "about them"
 msgstr ""
 
-#: ../calendar.qml:347
+#: ../calendar.qml:457
 msgid "Year"
 msgstr ""
 
-#: ../calendar.qml:381
+#: ../calendar.qml:464
 msgid "Month"
 msgstr ""
 
-#: ../calendar.qml:409
+#: ../calendar.qml:471
 msgid "Week"
 msgstr ""
 
-#: ../calendar.qml:442
+#: ../calendar.qml:478
 msgid "Day"
 msgstr ""
 
-#: ../calendar.qml:474
+#: ../calendar.qml:485
 msgid "Agenda"
 msgstr ""
 


Follow ups