Merge lp:~majster-pl/ubuntu-calendar-app/new-event-page2 into lp:ubuntu-calendar-app

Proposed by Szymon Waliczek on 2016-04-11
Status: Superseded
Proposed branch: lp:~majster-pl/ubuntu-calendar-app/new-event-page2
Merge into: lp:ubuntu-calendar-app
Diff against target: 1600 lines (+766/-533)
5 files modified
ContactChoicePopup.qml (+268/-125)
KeyboardRectangle.qml (+12/-10)
NewEvent.qml (+329/-283)
NewEventTimePicker.qml (+100/-59)
po/com.ubuntu.calendar.pot (+57/-56)
To merge this branch: bzr merge lp:~majster-pl/ubuntu-calendar-app/new-event-page2
Reviewer Review Type Date Requested Status
Renato Araujo Oliveira Filho (community) 2016-04-11 Needs Fixing on 2016-04-14
Review via email: mp+291516@code.launchpad.net

This proposal has been superseded by a proposal from 2016-05-12.

Description of the change

this is very first proposal for new Event Page, adding new guest is currently to be work on... but first implementation is done.

To post a comment you must log in.

Good work. Some small inline comments.

review: Needs Fixing

Thanks for the work. I will create a new branch based on this one to fix some small problems.

Unmerged revisions

821. By Szymon Waliczek on 2016-04-11

First implementation of new designs for New Event page.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ContactChoicePopup.qml'
--- ContactChoicePopup.qml 2016-02-04 13:37:00 +0000
+++ ContactChoicePopup.qml 2016-04-11 14:35:38 +0000
@@ -1,154 +1,297 @@
1/*1///*
2 * Copyright (C) 2013-2014 Canonical Ltd2// * Copyright (C) 2013-2014 Canonical Ltd
3 *3// *
4 * This file is part of Ubuntu Calendar App4// * This file is part of Ubuntu Calendar App
5 *5// *
6 * Ubuntu Calendar App is free software: you can redistribute it and/or modify6// * Ubuntu Calendar App is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 3 as7// * it under the terms of the GNU General Public License version 3 as
8 * published by the Free Software Foundation.8// * published by the Free Software Foundation.
9 *9// *
10 * Ubuntu Calendar App is distributed in the hope that it will be useful,10// * Ubuntu Calendar App is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of11// * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.13// * GNU General Public License for more details.
14 *14// *
15 * You should have received a copy of the GNU General Public License15// * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.16// * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */17// */
18import QtQuick 2.418import QtQuick 2.4
19import Ubuntu.Components 1.319import Ubuntu.Components 1.3
20import Ubuntu.Components.Popups 1.3
21import Ubuntu.Components.ListItems 1.0
22import Ubuntu.Components.Themes.Ambiance 1.0
23import QtOrganizer 5.0
24import QtContacts 5.020import QtContacts 5.0
2521
26import "Defines.js" as Defines22Item {
27
28Popover {
29 id: root23 id: root
30 objectName: "contactPopover"24
25 width: parent.width
26 height: mainColumn.height
27
28 property bool contactOpen: false
29 property var openContanctObject
3130
32 signal contactSelected(var contact, string emailAddress);31 signal contactSelected(var contact, string emailAddress);
3332
34 Label {33 onContactOpenChanged: {
35 id: noContact34 positionDelay.start()
36 anchors.centerIn: parent35 }
37 text: i18n.tr("No contact")36
38 visible: contactModel.contacts.length === 037 Timer {
39 }38 id: positionDelay
4039 interval: 300
41 UnionFilter {40 onTriggered: suggestionsFlickable.contentY = openContanctObject.y
42 id: filter41 }
4342
44 property string searchString: ""43 states: [
4544 State {
46 filters: [45 name: "open"
47 DetailFilter{46 PropertyChanges { target: contactsSuggestionItem; height: units.gu(10)}
48 detail: ContactDetail.Name47 },
49 field: Name.FirstName48 State {
50 matchFlags: Filter.MatchContains49 name: "close"
51 value: filter.searchString50 PropertyChanges { target: contactsSuggestionItem; height: 0}
52 },51 }
53 DetailFilter{52
54 detail: ContactDetail.Name53 ]
55 field: Name.LastName54
56 matchFlags: Filter.MatchContains55 Behavior on height {
57 value: filter.searchString56 UbuntuNumberAnimation {}
58 },57 }
59 DetailFilter{58
60 detail: ContactDetail.DisplayLabel
61 field: DisplayLabel.Label
62 matchFlags: Filter.MatchContains
63 value: filter.searchString
64 }
65 ]
66 }
6759
68 ContactModel {60 ContactModel {
69 id: contactModel61 id: contactModel
70 manager: "galera"62 manager: "galera"
71 filter: filter
72 autoUpdate: true63 autoUpdate: true
73 }64 }
7465
75 Timer {
76 id: idleSearch
7766
78 interval: 500
79 repeat: false
80 onTriggered: {
81 filter.searchString = searchBox.text
82 }
83 }
8467
85 Column {68 Column {
86 anchors.top: parent.top69 id: mainColumn
87 anchors.left: parent.left70 width: parent.width
88 anchors.right: parent.right71 spacing: units.gu(1)
89 anchors.margins: units.gu(1)72
73 Item {
74 id: guestsAdded
75 width: parent.width
76
77 }
9078
91 TextField {79 TextField {
92 id: searchBox80 id: addGuestTestField
93 objectName: "contactPopoverInput"81 objectName: "addGuestTestField"
94 focus: true82
95 width: parent.width83 width: parent.width
96 placeholderText: i18n.tr("Search contact")
97 inputMethodHints: Qt.ImhNoPredictiveText84 inputMethodHints: Qt.ImhNoPredictiveText
98 primaryItem: Icon {85 placeholderText: i18n.tr("Guests")
99 height: parent.height*0.586
100 width: parent.height*0.587 onActiveFocusChanged: {
101 anchors.verticalCenter: parent.verticalCenter88 if(addGuestTestField.activeFocus) {
102 name:"find"89 lol2.state = "open"
103 }90 flickable.makeMeVisible(addGuestListItem);
104 onTextChanged: {91 } else {
105 idleSearch.restart()92 lol2.state = "close"
106 }93 }
94 }
95
107 }96 }
10897
109 ListView {98 Component {
110 id: contactList99 id: suggestionsDelegate
111 objectName: "contactPopoverList"100 Item {
112 width: parent.width101 id: rootSug
113 model: contactModel102
114 height: units.gu(15)103 clip: true
115 clip: true104 width: String(contact.displayLabel.label).toLowerCase().search(addGuestTestField.text.toLowerCase()) == - 1 ? 0 : mainGrid.width
116 focus: false105 height: mainGrid.height
117 delegate: Column {106
118 width: contactList.width107 ListModel {
119 Repeater {108 id: addressesModel
120 anchors {109 }
121 left: parent.left110
122 right: parent.right111
123 }112 function getEmails() {
124 height: childrenRect.height113 for(var i=0; contact.emails.length > i; i++) {
125114 addressesModel.append({"email": contact.emails[i].emailAddress})
126 model: Math.max(1, contact.emails.length)115 }
127 delegate: ListItem {116 }
128 property string emailAddress: contact.emails.length > index ? contact.emails[index].emailAddress : ""117
129118
119 Behavior on width {
120 UbuntuNumberAnimation {}
121 }
122
123 Connections {
124 target: root
125 onContactOpenChanged: {
126 if(!contactOpen) {
127 emailAddressesColumn.state = "default"
128 }
129 }
130 }
131
132
133
134 Row {
135 id: mainGrid
136
137 AbstractButton {
138 id: contactNameAbstractButton
139
140 width: contactNameLabel.width + units.gu(1)
141 height: contactNameLabel.height + units.gu(1)
130 activeFocusOnPress: false142 activeFocusOnPress: false
131 opacity: emailAddress.length > 0 ? 1.0 : 0.3143 enabled: contact.emails.length > 0
132 width: contactList.width144
133 objectName: "contactPopoverList%1".arg(index)145 Rectangle {
134 ListItemLayout {
135 title.text: contact.displayLabel.label
136 subtitle.text: emailAddress
137 }
138 MouseArea {
139 anchors.fill: parent146 anchors.fill: parent
140 onClicked: {147 color: (parent.pressed || (emailAddressesColumn.state === "open")) ? UbuntuColors.lightGrey : "transparent"
141 if (emailAddress.length > 0) {148 }
142 root.contactSelected(contact, emailAddress);149
143 PopupUtils.close(root)150 Label {
144 }151 id: contactNameLabel
145 }152 text: emailAddressesColumn.state === "open" ? contact.displayLabel.label+":" : contact.displayLabel.label
146 }153 anchors.centerIn: parent
147 }154 color: contact.emails.length > 0 ? "black" : UbuntuColors.lightGrey
148 }155 font.italic: contact.emails.length > 0 ? false : true
149 }156 fontSize: "medium"
150 }157 }
158 onClicked: {
159 if(contact.emails.length > 1) {
160// emailAddressesColumn.openClose()
161 if(contactOpen) {
162 contactOpen = false
163 } else {
164 emailAddressesColumn.openClose()
165 openContanctObject = rootSug
166 }
167
168 } else {
169 root.contactSelected(contact, contact.email.emailAddress);
170 }
171 }
172 }
173 Column {
174 id: emailAddressesColumn
175
176 clip: true
177 state: "default"
178
179 function openClose() {
180 if(emailAddressesColumn.state === "open") {
181 emailAddressesColumn.state = "default"
182 } else {
183 emailAddressesColumn.state = "open"
184 }
185 }
186
187 states: [
188 State {
189 name: "default"
190 PropertyChanges { target: emailAddressesColumn; width: 0 }
191 },
192 State {
193 name: "open"
194 PropertyChanges { target: emailAddressesColumn; width: mainColumn.width - contactNameAbstractButton.width }
195 }
196
197 ]
198
199 onStateChanged: {
200 if(state === "open") {
201 rootSug.getEmails()
202// suggestionsFlickable.contentY = rootSug.y
203 contactOpen = true
204 } else {
205 addressesModel.clear()
206 }
207 }
208
209 Repeater {
210 model: addressesModel
211 delegate: AbstractButton {
212 width: contactEmailLabel.width + units.gu(2)
213 height: contactEmailLabel.height + units.gu(1)
214 activeFocusOnPress: false
215
216 Rectangle {
217 anchors.fill: parent
218 color: parent.pressed ? UbuntuColors.lightGrey : "transparent"
219 }
220
221 Label {
222 id: contactEmailLabel
223 anchors.verticalCenter: parent.verticalCenter
224 anchors.left: parent.left
225 anchors.leftMargin: units.gu(1)
226 text: email
227 color: contact.emails.length > 0 ? "black" : UbuntuColors.lightGrey
228 font.italic: contact.emails.length > 0 ? false : true
229 fontSize: "medium"
230 elide: Text.ElideRight
231 }
232
233 onClicked: {
234 root.contactSelected(contact, email);
235 emailAddressesColumn.state = "default"
236 }
237 }
238
239 }
240
241 }
242 }
243
244
245 }
246
247 }
248
249 Item {
250 id: contactsSuggestionItem
251 width: parent.width
252 clip: true
253
254 Flickable {
255 id: suggestionsFlickable
256 width: parent.width - units.gu(0)
257 height: parent.height - units.gu(1)
258 anchors.top: parent.top
259 anchors.topMargin: units.gu(1)
260// anchors.horizontalCenter: parent.horizontalCenter
261 contentHeight: suggestionsListView.height + units.gu(1)
262
263 // animation on flickable contentY change
264 Behavior on contentY {
265 UbuntuNumberAnimation {}
266 }
267
268 onFlickStarted: contactOpen = false
269// contentY: contactOpen && !flicking ? openContanctObject.y : NaN
270
271
272 Flow {
273 id: suggestionsListView
274 width: parent.width
275 spacing: units.gu(1.5)
276
277 Repeater {
278 model: contactModel
279 delegate: suggestionsDelegate
280 }
281
282 }
283 }
284
285 Scrollbar {
286 flickableItem: suggestionsFlickable
287 align: Qt.AlignTrailing
288 }
289 }
290
151 }291 }
152292
153 Component.onCompleted: searchBox.forceActiveFocus()293
294
295
154}296}
297
155298
=== modified file 'KeyboardRectangle.qml'
--- KeyboardRectangle.qml 2016-02-03 19:53:46 +0000
+++ KeyboardRectangle.qml 2016-04-11 14:35:38 +0000
@@ -26,16 +26,18 @@
26 anchors.bottom: parent.bottom26 anchors.bottom: parent.bottom
27 height: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 027 height: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
2828
29 states: [29 property bool isVisible: Qt.inputMethod.visible
30 State {30
31 name: "hidden"31// states: [
32 when: keyboardRect.height == 032// State {
33 },33// name: "hidden"
34 State {34// when: keyboardRect.height == 0
35 name: "shown"35// },
36 when: keyboardRect.height == Qt.inputMethod.keyboardRectangle.height36// State {
37 }37// name: "shown"
38 ]38// when: keyboardRect.height == Qt.inputMethod.keyboardRectangle.height
39// }
40// ]
3941
40 function recursiveFindFocusedItem(parent) {42 function recursiveFindFocusedItem(parent) {
41 if (parent.activeFocus) {43 if (parent.activeFocus) {
4244
=== modified file 'NewEvent.qml'
--- NewEvent.qml 2016-04-06 18:46:29 +0000
+++ NewEvent.qml 2016-04-11 14:35:38 +0000
@@ -319,46 +319,69 @@
319 }319 }
320320
321 Keys.onEscapePressed: root.cancel()321 Keys.onEscapePressed: root.cancel()
322
322 header: PageHeader {323 header: PageHeader {
323 id: pageHeader324 id: pageHeader
324325
325 flickable: null326 flickable: null
326 title: isEdit ? i18n.tr("Edit Event"):i18n.tr("New Event")327 property Component delegate: Component {
327 leadingActionBar.actions: Action {328 AbstractButton {
328 id: backAction329 id: button
329330 action: modelData
330 name: "cancel"331 width: label.width + units.gu(4)
331 text: i18n.tr("Cancel")332 height: parent.height
332 iconName: isEdit ? "back" : "down"333 Rectangle {
333 onTriggered: root.cancel()334 color: parent.pressed ? UbuntuColors.coolGrey : UbuntuColors.slate
334 }335 opacity: 0.1
335336 anchors.fill: parent
336 trailingActionBar.actions: [337 visible: button.pressed
337 Action {338 }
338 text: i18n.tr("Delete");339 Label {
339 objectName: "delete"340 anchors.centerIn: parent
340 iconName: "delete"341 id: label
341 visible : isEdit342 text: action.text
342 onTriggered: {343 color: text === i18n.tr("Delete") ? UbuntuColors.red : Theme.palette.selected.fieldText
343 var dialog = PopupUtils.open(Qt.resolvedUrl("DeleteConfirmationDialog.qml"),root,{"event": event});344 font.weight: text === i18n.tr("Save") ? Font.Normal : Font.Light
344 dialog.deleteEvent.connect( function(eventId){345 }
345 model.removeItem(eventId);346 }
346 if (pageStack)347 }
347 pageStack.pop();348 leadingActionBar {
348 root.eventDeleted(eventId);349 anchors.leftMargin: 0
349 });350 actions: Action {
350 }351 text: i18n.tr("Cancel")
351 },352 iconName: "close"
352 Action {353 onTriggered: root.cancel()
353 iconName: "ok"354 }
354 objectName: "save"355 delegate: pageHeader.delegate
355 text: i18n.tr("Save")356 }
356 enabled: !!titleEdit.text.trim()357 trailingActionBar {
357 onTriggered: saveToQtPim();358 anchors.rightMargin: 0
358 }359 actions: [
359 ]360 Action {
361 text: i18n.tr("Save")
362 iconName: "tick"
363 onTriggered: saveToQtPim();
364 },
365 Action {
366 text: i18n.tr("Delete")
367 iconName: "delete"
368 visible : isEdit
369 onTriggered: {
370 var dialog = PopupUtils.open(Qt.resolvedUrl("DeleteConfirmationDialog.qml"),root,{"event": event});
371 dialog.deleteEvent.connect( function(eventId){
372 model.removeItem(eventId);
373 if (pageStack)
374 pageStack.pop();
375 root.eventDeleted(eventId);
376 });
377 }
378 }
379 ]
380 delegate: pageHeader.delegate
381 }
360 }382 }
361383
384
362 Component{385 Component{
363 id: errorDlgComponent386 id: errorDlgComponent
364 Dialog {387 Dialog {
@@ -399,7 +422,7 @@
399 // if it is not, try to scroll and make it visible422 // if it is not, try to scroll and make it visible
400 var targetY = position.y + item.height - flickable.height423 var targetY = position.y + item.height - flickable.height
401 if (targetY >= 0 && position.y) {424 if (targetY >= 0 && position.y) {
402 flickable.contentY = targetY;425 flickable.contentY = targetY + units.gu(1);
403 } else if (position.y < flickable.contentY) {426 } else if (position.y < flickable.contentY) {
404 // if it is hidden at the top, also show it427 // if it is hidden at the top, also show it
405 flickable.contentY = position.y;428 flickable.contentY = position.y;
@@ -407,6 +430,11 @@
407 flickable.returnToBounds()430 flickable.returnToBounds()
408 }431 }
409432
433 // animation on flickable contentY change
434 Behavior on contentY {
435 UbuntuNumberAnimation {}
436 }
437
410 flickableDirection: Flickable.VerticalFlick438 flickableDirection: Flickable.VerticalFlick
411 anchors{439 anchors{
412 left: parent.left440 left: parent.left
@@ -425,9 +453,8 @@
425453
426 NewEventTimePicker{454 NewEventTimePicker{
427 id: startDateTimeInput455 id: startDateTimeInput
428 objectName: "startDateTimeInput"456 //TRANSLATORS: this referes to date. eg: To: Wendsday, 9 March 2016
429457 headerText: i18n.tr("From")
430 header: i18n.tr("From")
431 showTimePicker: !allDayEventCheckbox.checked458 showTimePicker: !allDayEventCheckbox.checked
432 anchors {459 anchors {
433 left: parent.left460 left: parent.left
@@ -435,257 +462,277 @@
435 }462 }
436 onDateTimeChanged: {463 onDateTimeChanged: {
437 startDate = dateTime;464 startDate = dateTime;
438 endDateTimeInput.dateTime = new Date(startDate.getTime() + root.eventSize)
439 }465 }
440 }466 }
441467
442 NewEventTimePicker{468 NewEventTimePicker{
443 id: endDateTimeInput469 id: endDateTimeInput
444 objectName: "endDateTimeInput"470 //TRANSLATORS: this referes to date. eg: From: Wendsday, 9 March 2016
445471 headerText: i18n.tr("To")
446 header: i18n.tr("To")
447 showTimePicker: !allDayEventCheckbox.checked472 showTimePicker: !allDayEventCheckbox.checked
448 anchors {473 anchors {
449 left: parent.left474 left: parent.left
450 right: parent.right475 right: parent.right
451 }476 }
452 onDateTimeChanged: {477 onDateTimeChanged: {
453 if (dateTime.getTime() < startDate.getTime()) {
454 root.eventSize = root.allDay ? 0 : root.millisecsInAnHour
455 dateTime = new Date(startDate.getTime() + root.eventSize)
456 return
457 }
458
459 endDate = dateTime;478 endDate = dateTime;
460 if (allDay)479 }
461 root.eventSize = endDate.midnight().getTime() - startDate.midnight().getTime()480 }
462 else481
463 root.eventSize = endDate.getTime() - startDate.getTime()482 // All day event ListItem with Switch
464 }483 ListItem {
465 }484 width: parent.width
466485
467 ListItems.Standard {486 ListItemLayout {
468 anchors {487 title.text: i18n.tr("All day event")
469 left: parent.left488 Switch {
470 right: parent.right489 id: allDayEventCheckbox
471 }490 checked: false
472491 SlotsLayout.position: SlotsLayout.Trailing;
473 text: i18n.tr("All day event")492 }
474 __foregroundColor: Theme.palette.normal.baseText493 }
475 showDivider: false494 onClicked: {
476 control: CheckBox {495// Haptics.play()
477 objectName: "allDayEventCheckbox"496 allDayEventCheckbox.checked = !allDayEventCheckbox.checked
478 id: allDayEventCheckbox497 }
479 checked: false498
480 onCheckedChanged: {499 }
481 if (checked)500
482 root.eventSize = Math.max(endDate.midnight().getTime() - startDate.midnight().getTime(), 0)501 // ListItem which holds "Event details" label + TextField + TextArea + TextField
483 else502 ListItem {
484 root.eventSize = Math.max(endDate.getTime() - startDate.getTime(), root.millisecsInAnHour)503 height: eventDetailsColumn.height + (eventDetailsColumn.anchors.margins*2)
485 }504
486 }505 Column {
487 }506 id: eventDetailsColumn
488507 spacing: units.gu(2)
489 ListItems.ThinDivider {}508 anchors {
490509 left: parent.left
491 Column {510 right: parent.right
492 width: parent.width511 top: parent.top
493 spacing: units.gu(1)512 margins: units.gu(2)
494513 }
495 ListItems.Header{514
496 text: i18n.tr("Event Details")515 Label {
497 __foregroundColor: Theme.palette.normal.baseText516 width: parent.width
498 }517 text: i18n.tr("Event details")
499518 elide: Text.ElideRight
500 TextField {519 }
501 id: titleEdit520
502 objectName: "newEventName"521 TextField {
503522 id: titleEdit
504 anchors {523 objectName: "newEventName"
505 left: parent.left524
506 right: parent.right525 width: parent.width
507 margins: units.gu(2)526 inputMethodHints: Qt.ImhNoPredictiveText
508 }527 placeholderText: i18n.tr("Event Name")
509528
510 placeholderText: i18n.tr("Event Name")529 onActiveFocusChanged: {
511 onFocusChanged: {530 if(titleEdit.activeFocus) {
512 if(titleEdit.focus) {531 flickable.makeMeVisible(titleEdit);
513 flickable.makeMeVisible(titleEdit);532 }
514 }533 }
515 }534 }
516 }535
517536 TextArea{
518 TextArea{537 id: messageEdit
519 id: messageEdit538 objectName: "eventDescriptionInput"
520 objectName: "eventDescriptionInput"539
521540 width: parent.width
522 anchors {541 placeholderText: i18n.tr("Description")
523 left: parent.left542
524 right: parent.right543 onActiveFocusChanged: {
525 margins: units.gu(2)544 if(messageEdit.activeFocus) {
526 }545 flickable.makeMeVisible(messageEdit);
527546 }
528 placeholderText: i18n.tr("Description")547 }
529 onFocusChanged: {548 }
530 if(messageEdit.focus) {549
531 flickable.makeMeVisible(messageEdit);550 TextField {
532 }551 id: locationEdit
533 }552 objectName: "eventLocationInput"
534 }553
535554 width: parent.width
536 TextField {555 inputMethodHints: Qt.ImhNoPredictiveText
537 id: locationEdit556 placeholderText: i18n.tr("Location")
538 objectName: "eventLocationInput"557
539558 onActiveFocusChanged: {
540 anchors {559 if(locationEdit.activeFocus) {
541 left: parent.left560 flickable.makeMeVisible(locationEdit);
542 right: parent.right561 }
543 margins: units.gu(2)562 }
544 }563 }
545564 }
546 inputMethodHints: Qt.ImhNoPredictiveText565 }
547 placeholderText: i18n.tr("Location")566
548567 // ListItem to hold calendars selector
549 onFocusChanged: {568 ListItem {
550 if(locationEdit.focus) {569 height: chooseCalendarColumn.height + (eventDetailsColumn.anchors.topMargin*2)
551 flickable.makeMeVisible(locationEdit);570
552 }571 Column {
553 }572 id: chooseCalendarColumn
554 }573 spacing: units.gu(2)
555 }574 anchors {
556575 left: parent.left
557 Column {576 right: parent.right
558 width: parent.width577 top: parent.top
559 spacing: units.gu(1)578 topMargin: units.gu(2)
560579 }
561 ListItems.Header {580
562 text: i18n.tr("Calendar")581 Label {
563 __foregroundColor: Theme.palette.normal.baseText582 width: parent.width
564 }583 anchors {
565584 left: parent.left
566 OptionSelector{585 leftMargin: units.gu(2)
567 id: calendarsOption586 right: parent.right
568 objectName: "calendarsOption"587 rightMargin: units.gu(2)
569588 }
570 anchors {589 text: i18n.tr("Choose calendar")
571 left: parent.left590 elide: Text.ElideRight
572 right: parent.right591 }
573 margins: units.gu(2)592
574 }593 ListItems.ItemSelector {
575594 id: calendarsOption
576 containerHeight: itemHeight * 4595 model: root.model.getWritableCollections();
577 model: root.model ? root.model.getWritableAndSelectedCollections() : []596 delegate: OptionSelectorDelegate { text: modelData.name }
578597 }
579 delegate: OptionSelectorDelegate{598
580 text: modelData.name599 }
581600 }
582 UbuntuShape{601
583 id: calColor602
584 width: height603 // add guest field
585 height: parent.height - units.gu(2)604 ListItem {
586 color: modelData.color605 id: addGuestListItem
587 anchors {606 height: addGusestColumn.height + (addGusestColumn.anchors.margins*2)
588 right: parent.right607
589 rightMargin: units.gu(4)608 Column {
590 verticalCenter: parent.verticalCenter609 id: addGusestColumn
591 }610// spacing: units.gu(2)
592 }611 anchors {
593 }612 left: parent.left
594 onExpandedChanged: Qt.inputMethod.hide();613 right: parent.right
595 }614 top: parent.top
596 }615 margins: units.gu(2)
597616 }
598 Column {617
599 width: parent.width618 Behavior on height {
600 spacing: units.gu(1)619 UbuntuNumberAnimation {}
601620 }
602 ListItems.Header {621
603 text: i18n.tr("Guests")622 Label {
604 __foregroundColor: Theme.palette.normal.baseText623 width: parent.width
605 }624 text: i18n.tr("Event details")
606625 elide: Text.ElideRight
607 Button{626 }
608 id: addGuestButton627
609 objectName: "addGuestButton"628 Item {
610629 width: parent.width
611 property var contactsPopup: null630 height: units.gu(1)
612631 }
613 text: i18n.tr("Add Guest")632
614 anchors {633 ListModel{
615 left: parent.left634 id: contactModel
616 right: parent.right635 }
617 margins: units.gu(2)636
618 }637 Component {
619638 id: addedGusestDelegate
620 onClicked: {639 Item {
621 if (contactsPopup)640 width: delegateRow.width + units.gu(1)
622 return641 height: units.gu(3)
623642
624 flickable.makeMeVisible(addGuestButton)643 Rectangle {
625 contactsPopup = PopupUtils.open(Qt.resolvedUrl("ContactChoicePopup.qml"), addGuestButton);644 anchors.fill: parent
626 contactsPopup.contactSelected.connect( function(contact, emailAddress) {645 color: delegateMouseArea.pressed ? UbuntuColors.lightGrey : "transparent"
627 if(!internal.isContactAlreadyAdded(contact, emailAddress) ) {646 }
628 var t = internal.contactToAttendee(contact, emailAddress);647
629 contactModel.append({"contact": t});648 Row {
630 }649 id: delegateRow
631650 height: parent.height
632 });651// width: rec.width + lab.width + units.gu(1)
633 contactsPopup.Component.onDestruction.connect( function() {652 spacing: units.gu(0.5)
634 addGuestButton.contactsPopup = null653 anchors.horizontalCenter: parent.horizontalCenter
635 })654
636 }655 UbuntuShape {
637 }656 id: rec
638657 height: parent.height - units.gu(0.5)
639 UbuntuShape {658 anchors.verticalCenter: parent.verticalCenter
640 anchors {659 width: height
641 left: parent.left660 color: "green"
642 right: parent.right661 Text {
643 margins: units.gu(2)662 anchors.centerIn: parent
644 }663 text: contact.name.charAt(0).toUpperCase()
645664 font.bold: true
646 height: contactList.height665 color: "white"
647
648 Column{
649 id: contactList
650 objectName: "guestList"
651
652 spacing: units.gu(1)
653 width: parent.width
654 clip: true
655
656 ListModel{
657 id: contactModel
658 }
659
660 Repeater{
661 model: contactModel
662 delegate: ListItem {
663 objectName: "eventGuest%1".arg(index)
664
665 ListItemLayout {
666 title.text: contact.name
667 subtitle.text: contact.emailAddress
668 }
669
670 leadingActions: ListItemActions {
671 actions: Action {
672 iconName: "delete"
673 onTriggered: {
674 contactModel.remove(index)
675 }
676 }666 }
677 }667 }
678 }668 Label {
679 }669 id: lab
680 }670// id: delagateLabel
681 }671 anchors.verticalCenter: parent.verticalCenter
682672 text: contact.name
683 ListItems.ThinDivider {673 }
684 visible: (event != undefined) && (event.itemType === Type.Event)674 }
685 }675
686676 MouseArea {
677 id: delegateMouseArea
678 anchors.fill: parent
679 onClicked: contactModel.remove(index)
680
681 }
682
683 }
684 }
685
686 // Add guest section (this is now in development)
687 Item {
688 width: parent.width
689// height: contactModel.count > 0 ? units.gu(5) : 0
690 height: suggestionsListView.height + units.gu(0.5)
691 Behavior on height {
692 UbuntuNumberAnimation {}
693 }
694
695 Flow {
696 id: suggestionsListView
697 width: parent.width
698 spacing: units.gu(1.5)
699 move: Transition {
700 NumberAnimation {
701 properties: "x,y"
702 }
703 }
704 add: Transition {
705 NumberAnimation {
706 properties: "x,y"
707 }
708 }
709
710 Repeater {
711 model: contactModel
712 delegate: addedGusestDelegate
713 }
714
715 }
716
717 }
718
719 ContactChoicePopup {
720 id: lol2
721 width: parent.width
722
723 onContactSelected: {
724 if(!internal.isContactAlreadyAdded(contact, emailAddress) ) {
725 var t = internal.contactToAttendee(contact, emailAddress);
726 contactModel.append({"contact": t});
727 }
728
729 }
730 }
731
732 }
687 }733 }
688734
735
689 ListItem {736 ListItem {
690 id:thisHappens737 id:thisHappens
691 objectName :"thisHappens"738 objectName :"thisHappens"
@@ -768,6 +815,12 @@
768 }815 }
769 }816 }
770817
818 // Scrollbar
819 Scrollbar{
820 flickableItem: flickable
821 align: Qt.AlignTrailing
822 }
823
771 // used to keep the field visible when the keyboard appear or dismiss824 // used to keep the field visible when the keyboard appear or dismiss
772 KeyboardRectangle {825 KeyboardRectangle {
773 id: keyboardRectangle826 id: keyboardRectangle
@@ -783,14 +836,8 @@
783 PauseAnimation { duration: 200 }836 PauseAnimation { duration: 200 }
784 ScriptAction {837 ScriptAction {
785 script: {838 script: {
786 if (addGuestButton.contactsPopup) {839 flickable.makeMeVisible(flickable.activeItem)
787 // WORKAROUND: causes the popover to follow the buttom position when keyboard appears840
788 flickable.makeMeVisible(addGuestButton)
789 addGuestButton.contactsPopup.caller = null
790 addGuestButton.contactsPopup.caller = addGuestButton
791 } else {
792 flickable.makeMeVisible(flickable.activeItem)
793 }
794 }841 }
795 }842 }
796 }843 }
@@ -827,8 +874,7 @@
827 return false;874 return false;
828 }875 }
829876
830 function attendeeFromData(id, name, emailAddress)877 function attendeeFromData(id, name, emailAddress) {
831 {
832 var attendee = Qt.createQmlObject("import QtOrganizer 5.0; EventAttendee{}", internal, "NewEvent.qml");878 var attendee = Qt.createQmlObject("import QtOrganizer 5.0; EventAttendee{}", internal, "NewEvent.qml");
833 attendee.name = name879 attendee.name = name
834 attendee.emailAddress = emailAddress880 attendee.emailAddress = emailAddress
835881
=== modified file 'NewEventTimePicker.qml'
--- NewEventTimePicker.qml 2016-03-22 20:09:08 +0000
+++ NewEventTimePicker.qml 2016-04-11 14:35:38 +0000
@@ -1,76 +1,117 @@
1import QtQuick 2.41import QtQuick 2.4
2import Ubuntu.Components.ListItems 1.0 as ListItem2import Ubuntu.Components 1.3
3import Ubuntu.Components.Themes.Ambiance 1.03import Ubuntu.Components.Themes.Ambiance 1.0
4import Ubuntu.Components.Pickers 1.04import Ubuntu.Components.Pickers 1.3
5//import QtQuick.Layouts 1.1
56
6Column {7ListItem {
7 id: dateTimeInput8 id: dateTimeInput
8 property alias header: listHeader.text9
910 property string headerText //header label ("From" or "To")
10 property date dateTime;11 property date dateTime //keep date from DatePicker
11 property bool showTimePicker;12 property bool showTimePicker //if true then user is able to set time on event
13
14 // when new date set in DatePicker then this will be run.
15 onDateTimeChanged: {
16 layout.summary.text = dateTime.toLocaleDateString() // set date
17 secondLabel.text = Qt.formatTime(dateTime, "hh:mm AP").replace(/\./g, "") // set time
18 }
1219
13 function clearFocus() {20 function clearFocus() {
14 dateInput.focus = false;21 dateBG.focus = false;
15 timeInput.focus = false;22 timeBG.focus = false;
16 }23 }
1724
25 // function to open date/time picker
18 function openDatePicker (element, caller, callerProperty, mode) {26 function openDatePicker (element, caller, callerProperty, mode) {
19 element.highlighted = true;27 element.highlighted = true;
20 var picker = PickerPanel.openDatePicker(caller, callerProperty, mode);28 var picker = PickerPanel.openDatePicker(caller, callerProperty, mode);
21 if (!picker) return;29 if (!picker) return;
22 picker.closed.connect(function () {30 picker.closed.connect(function () { element.highlighted = false; });
23 element.highlighted = false;31 }
24 });32
25 }33 height: layout.height + divider.height
2634
27 onDateTimeChanged: {35 // backgroud color of full date fabel, to be shown when user click on date and DatePicker is visable
28 dateInput.text = dateTime.toLocaleDateString();36 Rectangle {
29 timeInput.text = Qt.formatTime(dateTime);37 id: dateBG
30 }38
3139 property bool highlighted: false
32 ListItem.Header {40
33 id: listHeader41 height: layout.summary.height + units.gu(3.5)
34 __foregroundColor: Theme.palette.normal.baseText42 width: showTimePicker ? layout.title.width + units.gu(3) : layout.width
35 }43 anchors.bottom: parent.bottom
3644 color: highlighted || abstractButtonDate.pressed ? UbuntuColors.lightGrey : "transparent"
37 Item {45
38 anchors {46// Behavior on color { ColorAnimation {} }
39 left: parent.left47 }
40 right: parent.right48
41 margins: units.gu(2)49 // backgroud color of time label, to be shown when user click on date and DatePicker is visable
42 }50 Rectangle {
4351 id: timeBG
44 height: dateInput.height52
4553 property bool highlighted: false
46 NewEventEntryField{54
47 id: dateInput55 height: dateBG.height
48 objectName: "dateInput"56 width: slot.width + units.gu(4)
4957 anchors.bottom: parent.bottom
50 text: ""58 anchors.right: parent.right
51 anchors.left: parent.left59 color: (highlighted || abstractButtonTime.pressed) ? UbuntuColors.lightGrey : "transparent"
52 width: !showTimePicker ? parent.width : 4 * parent.width / 560
5361// Behavior on color { ColorAnimation {} }
54 MouseArea{62 }
55 anchors.fill: parent63
56 onClicked: openDatePicker(dateInput, dateTimeInput, "dateTime", "Years|Months|Days")64 // ListItemLayout to keep full date label and time label
57 }65 ListItemLayout {
58 }66 id: layout
5967
60 NewEventEntryField{68 title.text: headerText
61 id: timeInput69 title.color: Theme.palette.selected.overlayText
62 objectName: "timeInput"70 title.font.pixelSize: FontUtils.sizeToPixels("small")
6371 subtitle.text: " "
64 text: ""72 summary.color: dateBG.highlighted ? "white" : Theme.palette.selected.fieldText
65 anchors.right: parent.right73 summary.font.pixelSize: FontUtils.sizeToPixels("medium")
66 width: parent.width / 574
75// Behavior on summary.color { ColorAnimation {} }
76
77 // Item to hold Trailing tile label item
78 Item {
79 id: slot
80
81 width: secondLabel.width
82 height: parent.height
67 visible: showTimePicker83 visible: showTimePicker
68 horizontalAlignment: Text.AlignRight84 SlotsLayout.overrideVerticalPositioning: true
6985
70 MouseArea{86 // label to keep time [ 10:20 AM ]
71 anchors.fill: parent87 Label {
72 onClicked: openDatePicker(timeInput, dateTimeInput, "dateTime", "Hours|Minutes")88 id: secondLabel
89
90 fontSize: "medium"
91 color: timeBG.highlighted ? "white" : Theme.palette.selected.fieldText
92 y: layout.mainSlot.y + layout.summary.y + layout.summary.baselineOffset - baselineOffset
93// Behavior on color { ColorAnimation {} }
94// Behavior on color { ColorAnimation {duration: 700} }
95
73 }96 }
74 }97 }
75 }98 }
99
100 // AbstractButton to be triggered when user click on full date
101 AbstractButton {
102 id: abstractButtonDate
103
104 anchors.fill: dateBG
105 onClicked: { openDatePicker(dateBG, dateTimeInput, "dateTime", "Years|Months|Days")}
106 }
107
108 // AbstractButton to be triggered when user click on time
109 AbstractButton {
110 id: abstractButtonTime
111
112 anchors.fill: timeBG
113 visible: showTimePicker
114 onClicked: { openDatePicker(timeBG, dateTimeInput, "dateTime", "Hours|Minutes")}
115 }
116
76}117}
77118
=== modified file 'po/com.ubuntu.calendar.pot'
--- po/com.ubuntu.calendar.pot 2016-03-23 03:59:15 +0000
+++ po/com.ubuntu.calendar.pot 2016-04-11 14:35:38 +0000
@@ -1,6 +1,6 @@
1# SOME DESCRIPTIVE TITLE.1# SOME DESCRIPTIVE TITLE.
2# Copyright (C) YEAR Canonical Ltd.2# Copyright (C) YEAR Canonical Ltd.
3# This file is distributed under the same license as the PACKAGE package.3# This file is distributed under the same license as the package.
4# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.4# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5#5#
6#, fuzzy6#, fuzzy
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: \n"9"Project-Id-Version: \n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2016-03-23 00:58-0300\n"11"POT-Creation-Date: 2016-04-11 15:19+0100\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,7 +18,7 @@
18"Content-Transfer-Encoding: 8bit\n"18"Content-Transfer-Encoding: 8bit\n"
19"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"19"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
2020
21#: ../AgendaView.qml:50 ../calendar.qml:344 ../calendar.qml:57621#: ../AgendaView.qml:50 ../calendar.qml:348 ../calendar.qml:580
22msgid "Agenda"22msgid "Agenda"
23msgstr ""23msgstr ""
2424
@@ -104,16 +104,12 @@
104msgstr ""104msgstr ""
105105
106#: ../ColorPickerDialog.qml:55 ../DeleteConfirmationDialog.qml:60106#: ../ColorPickerDialog.qml:55 ../DeleteConfirmationDialog.qml:60
107#: ../EditEventConfirmationDialog.qml:53 ../NewEvent.qml:341107#: ../EditEventConfirmationDialog.qml:53 ../NewEvent.qml:351
108msgid "Cancel"108msgid "Cancel"
109msgstr ""109msgstr ""
110110
111#: ../ContactChoicePopup.qml:37111#: ../ContactChoicePopup.qml:85
112msgid "No contact"112msgid "Guests"
113msgstr ""
114
115#: ../ContactChoicePopup.qml:96
116msgid "Search contact"
117msgstr ""113msgstr ""
118114
119#: ../DayView.qml:72 ../MonthView.qml:50 ../WeekView.qml:55 ../YearView.qml:57115#: ../DayView.qml:72 ../MonthView.qml:50 ../WeekView.qml:55 ../YearView.qml:57
@@ -154,11 +150,11 @@
154msgid "Delete this"150msgid "Delete this"
155msgstr ""151msgstr ""
156152
157#: ../DeleteConfirmationDialog.qml:51 ../NewEvent.qml:348153#: ../DeleteConfirmationDialog.qml:51 ../NewEvent.qml:343 ../NewEvent.qml:366
158msgid "Delete"154msgid "Delete"
159msgstr ""155msgstr ""
160156
161#: ../EditEventConfirmationDialog.qml:29 ../NewEvent.qml:336157#: ../EditEventConfirmationDialog.qml:29
162msgid "Edit Event"158msgid "Edit Event"
163msgstr ""159msgstr ""
164160
@@ -182,12 +178,12 @@
182178
183#. TRANSLATORS: the first argument (%1) refers to a start time for an event,179#. TRANSLATORS: the first argument (%1) refers to a start time for an event,
184#. while the second one (%2) refers to the end time180#. while the second one (%2) refers to the end time
185#: ../EventBubble.qml:100181#: ../EventBubble.qml:136
186#, qt-format182#, qt-format
187msgid "%1 - %2"183msgid "%1 - %2"
188msgstr ""184msgstr ""
189185
190#: ../EventDetails.qml:37 ../NewEvent.qml:484186#: ../EventDetails.qml:37
191msgid "Event Details"187msgid "Event Details"
192msgstr ""188msgstr ""
193189
@@ -195,32 +191,35 @@
195msgid "Edit"191msgid "Edit"
196msgstr ""192msgstr ""
197193
198#: ../EventDetails.qml:164 ../TimeLineHeader.qml:66194#: ../EventDetails.qml:117
195msgid "Attending"
196msgstr ""
197
198#: ../EventDetails.qml:120
199msgid "Not Attending"
200msgstr ""
201
202#: ../EventDetails.qml:123
203msgid "Maybe"
204msgstr ""
205
206#: ../EventDetails.qml:126
207msgid "No Reply"
208msgstr ""
209
210#: ../EventDetails.qml:162 ../TimeLineHeader.qml:66
199msgid "All Day"211msgid "All Day"
200msgstr ""212msgstr ""
201213
202#: ../EventDetails.qml:336 ../NewEvent.qml:549214#: ../EventDetails.qml:334 com.ubuntu.calendar_calendar.desktop.in.in.h:1
203#: com.ubuntu.calendar_calendar.desktop.in.in.h:1
204msgid "Calendar"215msgid "Calendar"
205msgstr ""216msgstr ""
206217
207#: ../EventDetails.qml:369218#: ../EventDetails.qml:391 ../NewEvent.qml:541
208msgid "Not Attending"
209msgstr ""
210
211#: ../EventDetails.qml:373
212msgid "Attending"
213msgstr ""
214
215#: ../EventDetails.qml:377
216msgid "No Reply"
217msgstr ""
218
219#: ../EventDetails.qml:400 ../NewEvent.qml:515
220msgid "Description"219msgid "Description"
221msgstr ""220msgstr ""
222221
223#: ../EventDetails.qml:418 ../EventReminder.qml:36 ../NewEvent.qml:711222#: ../EventDetails.qml:409 ../NewEvent.qml:768 ../NewEvent.qml:807
224msgid "Reminder"223msgid "Reminder"
225msgstr ""224msgstr ""
226225
@@ -228,7 +227,7 @@
228#. and it is shown as the header of the page to choose repetition227#. and it is shown as the header of the page to choose repetition
229#. and as the header of the list item that shows the repetition228#. and as the header of the list item that shows the repetition
230#. summary in the page that displays the event details229#. summary in the page that displays the event details
231#: ../EventRepetition.qml:40 ../EventRepetition.qml:153230#: ../EventRepetition.qml:40 ../EventRepetition.qml:152
232msgid "Repeat"231msgid "Repeat"
233msgstr ""232msgstr ""
234233
@@ -236,18 +235,18 @@
236msgid "Repeats On:"235msgid "Repeats On:"
237msgstr ""236msgstr ""
238237
239#: ../EventRepetition.qml:217238#: ../EventRepetition.qml:218
240msgid "Recurring event ends"239msgid "Recurring event ends"
241msgstr ""240msgstr ""
242241
243#. TRANSLATORS: this refers to how often a recurrent event repeats242#. TRANSLATORS: this refers to how often a recurrent event repeats
244#. and it is shown as the header of the option selector to choose243#. and it is shown as the header of the option selector to choose
245#. its repetition244#. its repetition
246#: ../EventRepetition.qml:240 ../NewEvent.qml:685245#: ../EventRepetition.qml:242 ../NewEvent.qml:744
247msgid "Repeats"246msgid "Repeats"
248msgstr ""247msgstr ""
249248
250#: ../EventRepetition.qml:265249#: ../EventRepetition.qml:268
251msgid "Date"250msgid "Date"
252msgstr ""251msgstr ""
253252
@@ -288,7 +287,7 @@
288287
289#. TRANSLATORS: This is shown in the month view as "Wk" as a title288#. TRANSLATORS: This is shown in the month view as "Wk" as a title
290#. to indicate the week numbers. It should be a max of up to 3 characters.289#. to indicate the week numbers. It should be a max of up to 3 characters.
291#: ../MonthComponent.qml:317290#: ../MonthComponent.qml:316
292msgid "Wk"291msgid "Wk"
293msgstr ""292msgstr ""
294293
@@ -297,52 +296,54 @@
297msgid "%1 %2"296msgid "%1 %2"
298msgstr ""297msgstr ""
299298
300#: ../NewEvent.qml:179299#: ../NewEvent.qml:185
301msgid "End time can't be before start time"300msgid "End time can't be before start time"
302msgstr ""301msgstr ""
303302
304#: ../NewEvent.qml:336 ../NewEventBottomEdge.qml:53303#: ../NewEvent.qml:344 ../NewEvent.qml:361
305msgid "New Event"
306msgstr ""
307
308#: ../NewEvent.qml:365
309msgid "Save"304msgid "Save"
310msgstr ""305msgstr ""
311306
312#: ../NewEvent.qml:376307#: ../NewEvent.qml:389
313msgid "Error"308msgid "Error"
314msgstr ""309msgstr ""
315310
316#: ../NewEvent.qml:378311#: ../NewEvent.qml:391
317msgid "OK"312msgid "OK"
318msgstr ""313msgstr ""
319314
320#: ../NewEvent.qml:438315#. TRANSLATORS: this referes to date. eg: To: Wendsday, 9 March 2016
316#: ../NewEvent.qml:457
321msgid "From"317msgid "From"
322msgstr ""318msgstr ""
323319
324#: ../NewEvent.qml:451320#. TRANSLATORS: this referes to date. eg: From: Wendsday, 9 March 2016
321#: ../NewEvent.qml:471
325msgid "To"322msgid "To"
326msgstr ""323msgstr ""
327324
328#: ../NewEvent.qml:468325#: ../NewEvent.qml:487
329msgid "All day event"326msgid "All day event"
330msgstr ""327msgstr ""
331328
332#: ../NewEvent.qml:497329#: ../NewEvent.qml:517 ../NewEvent.qml:624
330msgid "Event details"
331msgstr ""
332
333#: ../NewEvent.qml:527
333msgid "Event Name"334msgid "Event Name"
334msgstr ""335msgstr ""
335336
336#: ../NewEvent.qml:534337#: ../NewEvent.qml:556
337msgid "Location"338msgid "Location"
338msgstr ""339msgstr ""
339340
340#: ../NewEvent.qml:589341#: ../NewEvent.qml:589
341msgid "Guests"342msgid "Choose calendar"
342msgstr ""343msgstr ""
343344
344#: ../NewEvent.qml:598345#: ../NewEventBottomEdge.qml:53
345msgid "Add Guest"346msgid "New Event"
346msgstr ""347msgstr ""
347348
348#: ../RecurrenceLabelDefines.qml:23349#: ../RecurrenceLabelDefines.qml:23
@@ -466,19 +467,19 @@
466"about them"467"about them"
467msgstr ""468msgstr ""
468469
469#: ../calendar.qml:312 ../calendar.qml:492470#: ../calendar.qml:316 ../calendar.qml:496
470msgid "Year"471msgid "Year"
471msgstr ""472msgstr ""
472473
473#: ../calendar.qml:320 ../calendar.qml:513474#: ../calendar.qml:324 ../calendar.qml:517
474msgid "Month"475msgid "Month"
475msgstr ""476msgstr ""
476477
477#: ../calendar.qml:328 ../calendar.qml:534478#: ../calendar.qml:332 ../calendar.qml:538
478msgid "Week"479msgid "Week"
479msgstr ""480msgstr ""
480481
481#: ../calendar.qml:336 ../calendar.qml:555482#: ../calendar.qml:340 ../calendar.qml:559
482msgid "Day"483msgid "Day"
483msgstr ""484msgstr ""
484485

Subscribers

People subscribed via source and target branches

to status/vote changes: