← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

[Merge] lp:~dpniel/ubuntu-calendar-app/ScrollView2 into lp:ubuntu-calendar-app

 

Dan Chapman  has proposed merging lp:~dpniel/ubuntu-calendar-app/ScrollView2 into lp:ubuntu-calendar-app.

Commit message:
Adds ScrollView component to view Flickables
  
It's not possible to add the ScrollView to the PathView where used for
horizontal traversing, like in year view as Path doesn't inherit
Flickable. So another solution will Probably be needed for those areas.

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

For more details, see:
https://code.launchpad.net/~dpniel/ubuntu-calendar-app/ScrollView2/+merge/285027

Adds ScrollView component to view Flickables
  
It's not possible to add the ScrollView to the PathView where used for
horizontal traversing, like in year view as Path doesn't inherit
Flickable. So another solution will Probably be needed for those areas.
-- 
Your team Ubuntu Calendar Developers is requested to review the proposed merge of lp:~dpniel/ubuntu-calendar-app/ScrollView2 into lp:ubuntu-calendar-app.
=== modified file 'NewEvent.qml'
--- NewEvent.qml	2016-02-02 22:54:03 +0000
+++ NewEvent.qml	2016-02-04 09:42:02 +0000
@@ -344,321 +344,325 @@
         id:eventUtils
     }
 
-    Flickable{
-        id: flickable
-        clip: true
-
-        property var activeItem: null
-
-        function makeMeVisible(item) {
-            if (!item) {
-                return
-            }
-
-            activeItem = item
-            var position = flickable.contentItem.mapFromItem(item, 0, 0);
-
-            // check if the item is already visible
-            var bottomY = flickable.contentY + flickable.height
-            var itemBottom = position.y + item.height
-            if (position.y >= flickable.contentY && itemBottom <= bottomY) {
-                return;
-            }
-
-            // if it is not, try to scroll and make it visible
-            var targetY = position.y + item.height - flickable.height
-            if (targetY >= 0 && position.y) {
-                flickable.contentY = targetY;
-            } else if (position.y < flickable.contentY) {
-                // if it is hidden at the top, also show it
-                flickable.contentY = position.y;
-            }
-            flickable.returnToBounds()
-        }
-
+    ScrollView {
         anchors.fill: parent
-        contentWidth: width
-        contentHeight: column.height + units.gu(10)
-
-        Column {
-            id: column
-
-            width: parent.width
-
-            NewEventTimePicker{
-                id: startDateTimeInput
-                header: i18n.tr("From")
-                showTimePicker: !allDayEventCheckbox.checked
-                anchors {
-                    left: parent.left
-                    right: parent.right
-                }
-                onDateTimeChanged: {
-                    startDate = dateTime;
-                }
-            }
-
-            NewEventTimePicker{
-                id: endDateTimeInput
-                header: i18n.tr("To")
-                showTimePicker: !allDayEventCheckbox.checked
-                anchors {
-                    left: parent.left
-                    right: parent.right
-                }
-                onDateTimeChanged: {
-                    endDate = dateTime;
-                }
-            }
-
-            ListItem.Standard {
-                anchors {
-                    left: parent.left
-                    right: parent.right
-                }
-
-                text: i18n.tr("All day event")
-                showDivider: false
-                control: CheckBox {
-                    objectName: "allDayEventCheckbox"
-                    id: allDayEventCheckbox
-                    checked: false
-                }
-            }
-
-            ListItem.ThinDivider {}
-
-            Column {
-                width: parent.width
-                spacing: units.gu(1)
-
-                ListItem.Header{
-                    text: i18n.tr("Event Details")
-                }
-
-                TextField {
-                    id: titleEdit
-                    objectName: "newEventName"
-
-                    anchors {
-                        left: parent.left
-                        right: parent.right
-                        margins: units.gu(2)
-                    }
-
-                    placeholderText: i18n.tr("Event Name")
-                    onFocusChanged: {
-                        if(titleEdit.focus) {
-                            flickable.makeMeVisible(titleEdit);
-                        }
-                    }
-                }
-
-                TextArea{
-                    id: messageEdit
-                    objectName: "eventDescriptionInput"
-
-                    anchors {
-                        left: parent.left
-                        right: parent.right
-                        margins: units.gu(2)
-                    }
-
-                    placeholderText: i18n.tr("Description")
-                    onFocusChanged: {
-                        if(messageEdit.focus) {
-                            flickable.makeMeVisible(messageEdit);
-                        }
-                    }
-                }
-
-                TextField {
-                    id: locationEdit
-                    objectName: "eventLocationInput"
-
-                    anchors {
-                        left: parent.left
-                        right: parent.right
-                        margins: units.gu(2)
-                    }
-
-                    placeholderText: i18n.tr("Location")
-
-                    onFocusChanged: {
-                        if(locationEdit.focus) {
-                            flickable.makeMeVisible(locationEdit);
-                        }
-                    }
-                }
-            }
-
-            Column {
-                width: parent.width
-                spacing: units.gu(1)
-
-                ListItem.Header {
-                    text: i18n.tr("Calendar")
-                }
-
-                OptionSelector{
-                    id: calendarsOption
-                    objectName: "calendarsOption"
-
-                    anchors {
-                        left: parent.left
-                        right: parent.right
-                        margins: units.gu(2)
-                    }
-
-                    containerHeight: itemHeight * 4
-                    model: root.model.getWritableCollections();
-
-                    delegate: OptionSelectorDelegate{
-                        text: modelData.name
-
-                        UbuntuShape{
-                            id: calColor
-                            width: height
-                            height: parent.height - units.gu(2)
-                            color: modelData.color
-                            anchors.right: parent.right
-                            anchors.rightMargin: units.gu(2)
-                            anchors.verticalCenter: parent.verticalCenter
-                        }
-                    }
-                    onExpandedChanged: Qt.inputMethod.hide();
-                }
-            }
-
-            Column {
-                width: parent.width
-                spacing: units.gu(1)
-
-                ListItem.Header {
-                    text: i18n.tr("Guests")
-                }
-
-                Button{
-                    text: i18n.tr("Add Guest")
-                    objectName: "addGuestButton"
-
-                    anchors {
-                        left: parent.left
-                        right: parent.right
-                        margins: units.gu(2)
-                    }
-
-                    onClicked: {
-                        var popup = PopupUtils.open(Qt.resolvedUrl("ContactChoicePopup.qml"), contactList);
-                        popup.contactSelected.connect( function(contact) {
-                            var t = internal.contactToAttendee(contact);
-                            if( !internal.isContactAlreadyAdded(contact) ) {
-                                contactModel.append(t);
-                                contactList.array.push(t);
-                            }
-                        });
-                    }
-                }
-
-                UbuntuShape {
-                    anchors {
-                        left: parent.left
-                        right: parent.right
-                        margins: units.gu(2)
-                    }
-
-                    height: contactList.height
-
-                    Column{
-                        id: contactList
-                        objectName: "guestList"
-
-                        spacing: units.gu(1)
-                        width: parent.width
-                        clip: true
-
-                        property var array: []
-
-                        ListModel{
-                            id: contactModel
-                        }
-
-                        Repeater{
-                            model: contactModel
-                            delegate: ListItem.Standard {
-                                objectName: "eventGuest%1".arg(index)
-                                height: units.gu(4)
-                                text: name
-                                removable: true
-                                onItemRemoved: {
-                                    contactList.array.splice(index, 1)
-                                    contactModel.remove(index)
-                                }
-                            }
-                        }
-                    }
+
+        Flickable{
+            id: flickable
+            clip: true
+
+            property var activeItem: null
+
+            function makeMeVisible(item) {
+                if (!item) {
+                    return
+                }
+
+                activeItem = item
+                var position = flickable.contentItem.mapFromItem(item, 0, 0);
+
+                // check if the item is already visible
+                var bottomY = flickable.contentY + flickable.height
+                var itemBottom = position.y + item.height
+                if (position.y >= flickable.contentY && itemBottom <= bottomY) {
+                    return;
+                }
+
+                // if it is not, try to scroll and make it visible
+                var targetY = position.y + item.height - flickable.height
+                if (targetY >= 0 && position.y) {
+                    flickable.contentY = targetY;
+                } else if (position.y < flickable.contentY) {
+                    // if it is hidden at the top, also show it
+                    flickable.contentY = position.y;
+                }
+                flickable.returnToBounds()
+            }
+
+            anchors.fill: parent
+            contentWidth: width
+            contentHeight: column.height + units.gu(10)
+
+            Column {
+                id: column
+
+                width: parent.width
+
+                NewEventTimePicker{
+                    id: startDateTimeInput
+                    header: i18n.tr("From")
+                    showTimePicker: !allDayEventCheckbox.checked
+                    anchors {
+                        left: parent.left
+                        right: parent.right
+                    }
+                    onDateTimeChanged: {
+                        startDate = dateTime;
+                    }
+                }
+
+                NewEventTimePicker{
+                    id: endDateTimeInput
+                    header: i18n.tr("To")
+                    showTimePicker: !allDayEventCheckbox.checked
+                    anchors {
+                        left: parent.left
+                        right: parent.right
+                    }
+                    onDateTimeChanged: {
+                        endDate = dateTime;
+                    }
+                }
+
+                ListItem.Standard {
+                    anchors {
+                        left: parent.left
+                        right: parent.right
+                    }
+
+                    text: i18n.tr("All day event")
+                    showDivider: false
+                    control: CheckBox {
+                        objectName: "allDayEventCheckbox"
+                        id: allDayEventCheckbox
+                        checked: false
+                    }
+                }
+
+                ListItem.ThinDivider {}
+
+                Column {
+                    width: parent.width
+                    spacing: units.gu(1)
+
+                    ListItem.Header{
+                        text: i18n.tr("Event Details")
+                    }
+
+                    TextField {
+                        id: titleEdit
+                        objectName: "newEventName"
+
+                        anchors {
+                            left: parent.left
+                            right: parent.right
+                            margins: units.gu(2)
+                        }
+
+                        placeholderText: i18n.tr("Event Name")
+                        onFocusChanged: {
+                            if(titleEdit.focus) {
+                                flickable.makeMeVisible(titleEdit);
+                            }
+                        }
+                    }
+
+                    TextArea{
+                        id: messageEdit
+                        objectName: "eventDescriptionInput"
+
+                        anchors {
+                            left: parent.left
+                            right: parent.right
+                            margins: units.gu(2)
+                        }
+
+                        placeholderText: i18n.tr("Description")
+                        onFocusChanged: {
+                            if(messageEdit.focus) {
+                                flickable.makeMeVisible(messageEdit);
+                            }
+                        }
+                    }
+
+                    TextField {
+                        id: locationEdit
+                        objectName: "eventLocationInput"
+
+                        anchors {
+                            left: parent.left
+                            right: parent.right
+                            margins: units.gu(2)
+                        }
+
+                        placeholderText: i18n.tr("Location")
+
+                        onFocusChanged: {
+                            if(locationEdit.focus) {
+                                flickable.makeMeVisible(locationEdit);
+                            }
+                        }
+                    }
+                }
+
+                Column {
+                    width: parent.width
+                    spacing: units.gu(1)
+
+                    ListItem.Header {
+                        text: i18n.tr("Calendar")
+                    }
+
+                    OptionSelector{
+                        id: calendarsOption
+                        objectName: "calendarsOption"
+
+                        anchors {
+                            left: parent.left
+                            right: parent.right
+                            margins: units.gu(2)
+                        }
+
+                        containerHeight: itemHeight * 4
+                        model: root.model.getWritableCollections();
+
+                        delegate: OptionSelectorDelegate{
+                            text: modelData.name
+
+                            UbuntuShape{
+                                id: calColor
+                                width: height
+                                height: parent.height - units.gu(2)
+                                color: modelData.color
+                                anchors.right: parent.right
+                                anchors.rightMargin: units.gu(2)
+                                anchors.verticalCenter: parent.verticalCenter
+                            }
+                        }
+                        onExpandedChanged: Qt.inputMethod.hide();
+                    }
+                }
+
+                Column {
+                    width: parent.width
+                    spacing: units.gu(1)
+
+                    ListItem.Header {
+                        text: i18n.tr("Guests")
+                    }
+
+                    Button{
+                        text: i18n.tr("Add Guest")
+                        objectName: "addGuestButton"
+
+                        anchors {
+                            left: parent.left
+                            right: parent.right
+                            margins: units.gu(2)
+                        }
+
+                        onClicked: {
+                            var popup = PopupUtils.open(Qt.resolvedUrl("ContactChoicePopup.qml"), contactList);
+                            popup.contactSelected.connect( function(contact) {
+                                var t = internal.contactToAttendee(contact);
+                                if( !internal.isContactAlreadyAdded(contact) ) {
+                                    contactModel.append(t);
+                                    contactList.array.push(t);
+                                }
+                            });
+                        }
+                    }
+
+                    UbuntuShape {
+                        anchors {
+                            left: parent.left
+                            right: parent.right
+                            margins: units.gu(2)
+                        }
+
+                        height: contactList.height
+
+                        Column{
+                            id: contactList
+                            objectName: "guestList"
+
+                            spacing: units.gu(1)
+                            width: parent.width
+                            clip: true
+
+                            property var array: []
+
+                            ListModel{
+                                id: contactModel
+                            }
+
+                            Repeater{
+                                model: contactModel
+                                delegate: ListItem.Standard {
+                                    objectName: "eventGuest%1".arg(index)
+                                    height: units.gu(4)
+                                    text: name
+                                    removable: true
+                                    onItemRemoved: {
+                                        contactList.array.splice(index, 1)
+                                        contactModel.remove(index)
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    ListItem.ThinDivider {
+                        visible: event.itemType === Type.Event
+                    }
+
+                }
+
+                ListItem.Subtitled{
+                    id:thisHappens
+                    objectName :"thisHappens"
+
+                    anchors {
+                        left: parent.left
+                    }
+
+                    showDivider: false
+                    progression: true
+                    visible: event.itemType === Type.Event
+                    text: i18n.tr("Repeats")
+                    subText: event.itemType === Type.Event ? rule === null ? Defines.recurrenceLabel[0] : eventUtils.getRecurrenceString(rule) : ""
+                    onClicked: pageStack.push(Qt.resolvedUrl("EventRepetition.qml"),{"eventRoot": root,"isEdit":isEdit});
                 }
 
                 ListItem.ThinDivider {
                     visible: event.itemType === Type.Event
                 }
 
-            }
-
-            ListItem.Subtitled{
-                id:thisHappens
-                objectName :"thisHappens"
-
-                anchors {
-                    left: parent.left
-                }
-
-                showDivider: false
-                progression: true
-                visible: event.itemType === Type.Event
-                text: i18n.tr("Repeats")
-                subText: event.itemType === Type.Event ? rule === null ? Defines.recurrenceLabel[0] : eventUtils.getRecurrenceString(rule) : ""
-                onClicked: pageStack.push(Qt.resolvedUrl("EventRepetition.qml"),{"eventRoot": root,"isEdit":isEdit});
-            }
-
-            ListItem.ThinDivider {
-                visible: event.itemType === Type.Event
-            }
-
-            ListItem.Subtitled{
-                id:eventReminder
-                objectName  : "eventReminder"
-
-                anchors.left:parent.left
-                showDivider: false
-                progression: true
-                text: i18n.tr("Reminder")
-
-                RemindersModel {
-                    id: reminderModel
-                }
-
-                subText:{
-                    if(visualReminder.secondsBeforeStart !== -1) {
-                        for( var i=0; i<reminderModel.count; i++ ) {
-                            if(visualReminder.secondsBeforeStart === reminderModel.get(i).value) {
-                                return reminderModel.get(i).label
+                ListItem.Subtitled{
+                    id:eventReminder
+                    objectName  : "eventReminder"
+
+                    anchors.left:parent.left
+                    showDivider: false
+                    progression: true
+                    text: i18n.tr("Reminder")
+
+                    RemindersModel {
+                        id: reminderModel
+                    }
+
+                    subText:{
+                        if(visualReminder.secondsBeforeStart !== -1) {
+                            for( var i=0; i<reminderModel.count; i++ ) {
+                                if(visualReminder.secondsBeforeStart === reminderModel.get(i).value) {
+                                    return reminderModel.get(i).label
+                                }
                             }
+                        } else {
+                            return reminderModel.get(0).label
                         }
-                    } else {
-                        return reminderModel.get(0).label
+
                     }
 
+                    onClicked: pageStack.push(Qt.resolvedUrl("EventReminder.qml"),
+                                              {"visualReminder": visualReminder,
+                                                  "audibleReminder": audibleReminder,
+                                                  "reminderModel": reminderModel,
+                                                  "eventTitle": titleEdit.text})
                 }
 
-                onClicked: pageStack.push(Qt.resolvedUrl("EventReminder.qml"),
-                                          {"visualReminder": visualReminder,
-                                              "audibleReminder": audibleReminder,
-                                              "reminderModel": reminderModel,
-                                              "eventTitle": titleEdit.text})
+                ListItem.ThinDivider {}
             }
-
-            ListItem.ThinDivider {}
         }
     }
     // used to keep the field visible when the keyboard appear or dismiss

=== modified file 'TimeLineBaseComponent.qml'
--- TimeLineBaseComponent.qml	2016-01-29 14:35:14 +0000
+++ TimeLineBaseComponent.qml	2016-02-04 09:42:02 +0000
@@ -111,11 +111,11 @@
     }
 
     Timer{
-       interval: 200; running: true; repeat: false
-       onTriggered: {
-           mainModel = modelComponent.createObject();
-           activityLoader.running = Qt.binding( function (){ return mainModel.isLoading;});
-       }
+        interval: 200; running: true; repeat: false
+        onTriggered: {
+            mainModel = modelComponent.createObject();
+            activityLoader.running = Qt.binding( function (){ return mainModel.isLoading;});
+        }
     }
 
     Component {
@@ -171,139 +171,140 @@
                 width: units.gu(0.1)
                 height: parent.height
             }
-
-            Flickable {
-                id: timeLineView
-                objectName: "timelineview"
-
+            ScrollView {
                 height: parent.height
                 width: parent.width - units.gu(6)
 
-                boundsBehavior: Flickable.StopAtBounds
-
-                property int delegateWidth: {
-                    if( type == ViewType.ViewTypeWeek ) {
-                        width/3 - units.gu(1) /*partial visible area*/
-                    } else {
-                        width
-                    }
-                }
-
-                contentHeight: units.gu(8) * 24
-                contentWidth: {
-                    if( type == ViewType.ViewTypeWeek ) {
-                        delegateWidth*7
-                    } else {
-                        width
-                    }
-                }
-
-                onContentWidthChanged: {
-                    scrollToCurrentTime();
-                    scrollTocurrentDate();
-                }
-
-                clip: true
-
-                TimeLineBackground{}
-
-                Row {
-                    id: week
+                Flickable {
+                    id: timeLineView
+                    objectName: "timelineview"
                     anchors.fill: parent
-                    Repeater {
-                        model: type == ViewType.ViewTypeWeek ? 7 : 1
-
-                        delegate: TimeLineBase {
-                            property int idx: index
-                            anchors.top: parent.top
-                            width: {
-                                if( type == ViewType.ViewTypeWeek ) {
-                                    parent.width / 7
-                                } else {
-                                    (parent.width)
-                                }
-                            }
-                            height: parent.height
-                            delegate: comp
-                            day: startDay.addDays(index)
-                            model: mainModel
-
-                            Connections{
-                                target: mainModel
-
-                                onModelChanged: {
-                                    createEvents();
-                                }
-                            }
-
-                            DropArea {
-                                id: dropArea
-                                objectName: "mouseArea"
-                                anchors.fill: parent
-
-                                 function modifyEventForDrag(drag) {
-                                    var event = drag.source.event;
-                                    var diff = event.endDateTime.getTime() - event.startDateTime.getTime();
-
-                                    var startDate = getTimeFromYPos(drag.y, day);
-                                    var endDate = new Date( startDate.getTime() + diff );
-
-                                    event.startDateTime = startDate;
-                                    event.endDateTime = endDate;
-
-                                     return event;
-                                }
-
-                                onDropped: {
-                                    var event = dropArea.modifyEventForDrag(drop);
-                                    model.saveItem(event);
-                                }
-
-                                onPositionChanged: {
-                                    dropArea.modifyEventForDrag(drag)
-                                    var eventBubble = drag.source;
-                                    eventBubble.assingnBgColor();
-                                    eventBubble.setDetails();
-
-                                    if( eventBubble.y + eventBubble.height + units.gu(8) > timeLineView.contentY + timeLineView.height ) {
-                                        var diff = Math.abs((eventBubble.y + eventBubble.height + units.gu(8))  -
-                                                            (timeLineView.height + timeLineView.contentY));
-                                        timeLineView.contentY += diff
-
-                                        if(timeLineView.contentY >= timeLineView.contentHeight - timeLineView.height) {
-                                            timeLineView.contentY = timeLineView.contentHeight - timeLineView.height
-                                        }
-                                    }
-
-                                    if(eventBubble.y - units.gu(8) < timeLineView.contentY ) {
-                                        var diff = Math.abs((eventBubble.y - units.gu(8))  - timeLineView.contentY);
-                                        timeLineView.contentY -= diff
-
-                                        if(timeLineView.contentY <= 0) {
-                                            timeLineView.contentY = 0;
-                                        }
-                                    }
-                                }
-                            }
-
-                            Loader{
-                                objectName: "weekdevider"
+                    boundsBehavior: Flickable.StopAtBounds
+
+                    property int delegateWidth: {
+                        if( type == ViewType.ViewTypeWeek ) {
+                            width/3 - units.gu(1) /*partial visible area*/
+                        } else {
+                            width
+                        }
+                    }
+
+                    contentHeight: units.gu(8) * 24
+                    contentWidth: {
+                        if( type == ViewType.ViewTypeWeek ) {
+                            delegateWidth*7
+                        } else {
+                            width
+                        }
+                    }
+
+                    onContentWidthChanged: {
+                        scrollToCurrentTime();
+                        scrollTocurrentDate();
+                    }
+
+                    clip: true
+
+                    TimeLineBackground{}
+
+                    Row {
+                        id: week
+                        anchors.fill: parent
+                        Repeater {
+                            model: type == ViewType.ViewTypeWeek ? 7 : 1
+
+                            delegate: TimeLineBase {
+                                property int idx: index
+                                anchors.top: parent.top
+                                width: {
+                                    if( type == ViewType.ViewTypeWeek ) {
+                                        parent.width / 7
+                                    } else {
+                                        (parent.width)
+                                    }
+                                }
                                 height: parent.height
-                                width: units.gu(0.15)
-                                sourceComponent: type == ViewType.ViewTypeWeek ? weekDividerComponent : undefined
-                            }
-
-                            Component {
-                                id: weekDividerComponent
-                                SimpleDivider{
+                                delegate: comp
+                                day: startDay.addDays(index)
+                                model: mainModel
+
+                                Connections{
+                                    target: mainModel
+
+                                    onModelChanged: {
+                                        createEvents();
+                                    }
+                                }
+
+                                DropArea {
+                                    id: dropArea
+                                    objectName: "mouseArea"
                                     anchors.fill: parent
-                                }
-                            }
-
-                            Connections{
-                                target: mainModel
-                                onStartPeriodChanged:{
-                                    destroyAllChildren();
+
+                                    function modifyEventForDrag(drag) {
+                                        var event = drag.source.event;
+                                        var diff = event.endDateTime.getTime() - event.startDateTime.getTime();
+
+                                        var startDate = getTimeFromYPos(drag.y, day);
+                                        var endDate = new Date( startDate.getTime() + diff );
+
+                                        event.startDateTime = startDate;
+                                        event.endDateTime = endDate;
+
+                                        return event;
+                                    }
+
+                                    onDropped: {
+                                        var event = dropArea.modifyEventForDrag(drop);
+                                        model.saveItem(event);
+                                    }
+
+                                    onPositionChanged: {
+                                        dropArea.modifyEventForDrag(drag)
+                                        var eventBubble = drag.source;
+                                        eventBubble.assingnBgColor();
+                                        eventBubble.setDetails();
+
+                                        if( eventBubble.y + eventBubble.height + units.gu(8) > timeLineView.contentY + timeLineView.height ) {
+                                            var diff = Math.abs((eventBubble.y + eventBubble.height + units.gu(8))  -
+                                                                (timeLineView.height + timeLineView.contentY));
+                                            timeLineView.contentY += diff
+
+                                            if(timeLineView.contentY >= timeLineView.contentHeight - timeLineView.height) {
+                                                timeLineView.contentY = timeLineView.contentHeight - timeLineView.height
+                                            }
+                                        }
+
+                                        if(eventBubble.y - units.gu(8) < timeLineView.contentY ) {
+                                            var diff = Math.abs((eventBubble.y - units.gu(8))  - timeLineView.contentY);
+                                            timeLineView.contentY -= diff
+
+                                            if(timeLineView.contentY <= 0) {
+                                                timeLineView.contentY = 0;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                Loader{
+                                    objectName: "weekdevider"
+                                    height: parent.height
+                                    width: units.gu(0.15)
+                                    sourceComponent: type == ViewType.ViewTypeWeek ? weekDividerComponent : undefined
+                                }
+
+                                Component {
+                                    id: weekDividerComponent
+                                    SimpleDivider{
+                                        anchors.fill: parent
+                                    }
+                                }
+
+                                Connections{
+                                    target: mainModel
+                                    onStartPeriodChanged:{
+                                        destroyAllChildren();
+                                    }
                                 }
                             }
                         }

=== modified file 'YearView.qml'
--- YearView.qml	2016-02-03 08:06:25 +0000
+++ YearView.qml	2016-02-04 09:42:02 +0000
@@ -89,15 +89,17 @@
 
             Component{
                 id: delegateComponent
-
-                YearViewDelegate{
-                    focus: index == yearPathView.currentIndex
-
-                    scrollMonth: 0;
-                    isCurrentItem: index == yearPathView.currentIndex
-                    year: (currentYear + yearPathView.indexType(index))
-
+                ScrollView {
                     anchors.fill: parent
+                    YearViewDelegate{
+                        focus: index == yearPathView.currentIndex
+
+                        scrollMonth: 0;
+                        isCurrentItem: index == yearPathView.currentIndex
+                        year: (currentYear + yearPathView.indexType(index))
+
+                        anchors.fill: parent
+                    }
                 }
             }
         }

=== modified file 'po/com.ubuntu.calendar.pot'
--- po/com.ubuntu.calendar.pot	2016-02-03 14:55:42 +0000
+++ po/com.ubuntu.calendar.pot	2016-02-04 09:42:02 +0000
@@ -1,6 +1,6 @@
 # SOME DESCRIPTIVE TITLE.
 # Copyright (C) YEAR Canonical Ltd.
-# This file is distributed under the same license as the PACKAGE package.
+# This file is distributed under the same license as the  package.
 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
 #
 #, fuzzy
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-11 21:36+0800\n"
+"POT-Creation-Date: 2016-02-04 09:32+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -18,30 +18,39 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
-#: ../AgendaView.qml:51 ../DayView.qml:40 ../MonthView.qml:39
-#: ../WeekView.qml:44 ../YearView.qml:36
+#: ../AgendaView.qml:52 ../DayView.qml:41 ../MonthView.qml:40
+#: ../WeekView.qml:45 ../YearView.qml:43
 msgid "Today"
 msgstr ""
 
-#: ../AgendaView.qml:92
+#: ../AgendaView.qml:62 ../calendar.qml:291 ../calendar.qml:512
+msgid "Agenda"
+msgstr ""
+
+#: ../AgendaView.qml:101
 msgid "No upcoming events"
 msgstr ""
 
-#: ../AgendaView.qml:95
+#: ../AgendaView.qml:104
 msgid "You have no calendars enabled"
 msgstr ""
 
-#: ../AgendaView.qml:105
+#: ../AgendaView.qml:114
 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:177 ../EventBubble.qml:133
 #, qt-format
 msgid "%1 - %2"
 msgstr ""
 
+#: ../AgendaView.qml:183
+#, qt-format
+msgid "%1 %2 %3 %4 %5"
+msgstr ""
+
 #. TRANSLATORS: the first parameter refers to the number of all-day events
 #. on a given day. "Ev." is short form for "Events".
 #. Please keep the translation of "Ev." to 3 characters only, as the week view
@@ -59,21 +68,21 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: ../CalendarChoicePopup.qml:33 ../EventActions.qml:60
+#: ../CalendarChoicePopup.qml:33 ../EventActions.qml:63
 msgid "Calendars"
 msgstr ""
 
-#: ../CalendarChoicePopup.qml:37
+#: ../CalendarChoicePopup.qml:37 ../Settings.qml:32
 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,10 +110,16 @@
 #. 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:60 ../WeekView.qml:63
+#: ../DayView.qml:64 ../DayView.qml:157 ../MonthView.qml:62
+#: ../MonthView.qml:149 ../WeekView.qml:68 ../WeekView.qml:180
 msgid "MMMM yyyy"
 msgstr ""
 
+#: ../DayView.qml:155 ../MonthView.qml:144 ../WeekView.qml:178
+#, qt-format
+msgid "%1 %2"
+msgstr ""
+
 #: ../DeleteConfirmationDialog.qml:31
 msgid "Delete Recurring Event"
 msgstr ""
@@ -136,7 +151,7 @@
 msgid "Delete"
 msgstr ""
 
-#: ../EditEventConfirmationDialog.qml:29 ../NewEvent.qml:324
+#: ../EditEventConfirmationDialog.qml:29 ../NewEvent.qml:325
 msgid "Edit Event"
 msgstr ""
 
@@ -154,10 +169,14 @@
 msgid "Edit this"
 msgstr ""
 
-#: ../EventActions.qml:50 ../NewEvent.qml:324
+#: ../EventActions.qml:52 ../NewEvent.qml:325
 msgid "New Event"
 msgstr ""
 
+#: ../EventActions.qml:75 ../Settings.qml:30
+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,35 +184,55 @@
 msgid "%1 <b>%2</b>"
 msgstr ""
 
-#: ../EventDetails.qml:43 ../NewEvent.qml:435
+#: ../EventDetails.qml:44 ../NewEvent.qml:439
 msgid "Event Details"
 msgstr ""
 
 #. TRANSLATORS: the first parameter refers to the name of event calendar.
-#: ../EventDetails.qml:68
+#: ../EventDetails.qml:69
 #, qt-format
 msgid "%1 Calendar"
 msgstr ""
 
-#: ../EventDetails.qml:129
+#: ../EventDetails.qml:143
+#, qt-format
+msgid "%1 %2 %3 - %4 %5 %6 (All Day)"
+msgstr ""
+
+#: ../EventDetails.qml:147
 #, qt-format
 msgid "%1 - %2 (All Day)"
 msgstr ""
 
-#: ../EventDetails.qml:133
+#: ../EventDetails.qml:153
+#, qt-format
+msgid "%1 %2 %3 (All Day)"
+msgstr ""
+
+#: ../EventDetails.qml:156
 #, qt-format
 msgid "%1 (All Day)"
 msgstr ""
 
-#: ../EventDetails.qml:203
+#: ../EventDetails.qml:162
+#, qt-format
+msgid "%1 %2 %3, %4 - %5 %6 %7, %8"
+msgstr ""
+
+#: ../EventDetails.qml:171
+#, qt-format
+msgid "%1 %2 %3, %4 - %5"
+msgstr ""
+
+#: ../EventDetails.qml:238
 msgid "Edit"
 msgstr ""
 
-#: ../EventDetails.qml:354 ../NewEvent.qml:537
+#: ../EventDetails.qml:389 ../NewEvent.qml:541
 msgid "Guests"
 msgstr ""
 
-#: ../EventDetails.qml:397 ../EventReminder.qml:35 ../NewEvent.qml:634
+#: ../EventDetails.qml:432 ../EventReminder.qml:35 ../NewEvent.qml:638
 msgid "Reminder"
 msgstr ""
 
@@ -216,7 +255,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:622
 msgid "Repeats"
 msgstr ""
 
@@ -247,6 +286,11 @@
 msgid "Weekly on %1"
 msgstr ""
 
+#: ../HeaderDateComponent.qml:90
+#, qt-format
+msgid "%1 %2 %3"
+msgstr ""
+
 #: ../LimitLabelModel.qml:25
 msgid "Never"
 msgstr ""
@@ -259,6 +303,10 @@
 msgid "After Date"
 msgstr ""
 
+#: ../MonthComponent.qml:262
+msgid "Wk"
+msgstr ""
+
 #: ../NewEvent.qml:84
 msgid "Save"
 msgstr ""
@@ -267,43 +315,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:393
 msgid "From"
 msgstr ""
 
-#: ../NewEvent.qml:402
+#: ../NewEvent.qml:406
 msgid "To"
 msgstr ""
 
-#: ../NewEvent.qml:419
+#: ../NewEvent.qml:423
 msgid "All day event"
 msgstr ""
 
-#: ../NewEvent.qml:448
+#: ../NewEvent.qml:452
 msgid "Event Name"
 msgstr ""
 
-#: ../NewEvent.qml:466
+#: ../NewEvent.qml:470
 msgid "Description"
 msgstr ""
 
-#: ../NewEvent.qml:484
+#: ../NewEvent.qml:488
 msgid "Location"
 msgstr ""
 
-#: ../NewEvent.qml:499 com.ubuntu.calendar_calendar.desktop.in.in.h:1
+#: ../NewEvent.qml:503 com.ubuntu.calendar_calendar.desktop.in.in.h:1
 msgid "Calendar"
 msgstr ""
 
-#: ../NewEvent.qml:541
+#: ../NewEvent.qml:545
 msgid "Add Guest"
 msgstr ""
 
@@ -390,52 +438,56 @@
 msgid "2 weeks"
 msgstr ""
 
+#: ../Settings.qml:60
+msgid "Show week numbers"
+msgstr ""
+
+#: ../Settings.qml:91
+msgid "Show lunar calendar"
+msgstr ""
+
 #: ../TimeLineBase.qml:73
 msgid "Untitled"
 msgstr ""
 
 #. TRANSLATORS: W refers to Week, followed by the actual week number (%1)
-#: ../TimeLineHeader.qml:54
+#: ../TimeLineHeader.qml:53
 #, qt-format
 msgid "W%1"
 msgstr ""
 
-#: ../TimeLineHeader.qml:66
+#: ../TimeLineHeader.qml:65
 msgid "All Day"
 msgstr ""
 
-#: ../YearView.qml:54
+#: ../YearView.qml:61 ../YearView.qml:114
 #, qt-format
 msgid "Year %1"
 msgstr ""
 
-#: ../calendar.qml:45
+#: ../calendar.qml:46
 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:354
+#: ../calendar.qml:259 ../calendar.qml:428
 msgid "Year"
 msgstr ""
 
-#: ../calendar.qml:388
+#: ../calendar.qml:267 ../calendar.qml:449
 msgid "Month"
 msgstr ""
 
-#: ../calendar.qml:421
+#: ../calendar.qml:275 ../calendar.qml:470
 msgid "Week"
 msgstr ""
 
-#: ../calendar.qml:459
+#: ../calendar.qml:283 ../calendar.qml:491
 msgid "Day"
 msgstr ""
 
-#: ../calendar.qml:491
-msgid "Agenda"
-msgstr ""
-
 #: com.ubuntu.calendar_calendar.desktop.in.in.h:2
 msgid "A calendar for Ubuntu which syncs with online accounts."
 msgstr ""


Follow ups