Changeset View
Changeset View
Standalone View
Standalone View
applets/digital-clock/package/contents/ui/CalendarView.qml
Show All 19 Lines | |||||
20 | import org.kde.plasma.core 2.0 as PlasmaCore | 20 | import org.kde.plasma.core 2.0 as PlasmaCore | ||
21 | import org.kde.plasma.calendar 2.0 as PlasmaCalendar | 21 | import org.kde.plasma.calendar 2.0 as PlasmaCalendar | ||
22 | import org.kde.plasma.components 2.0 as PlasmaComponents | 22 | import org.kde.plasma.components 2.0 as PlasmaComponents | ||
23 | import org.kde.plasma.extras 2.0 as PlasmaExtras | 23 | import org.kde.plasma.extras 2.0 as PlasmaExtras | ||
24 | 24 | | |||
25 | Item { | 25 | Item { | ||
26 | id: calendar | 26 | id: calendar | ||
27 | 27 | | |||
28 | // The "sensible" values | ||||
29 | property int _minimumWidth: rootLayout.childrenRect.width + (rootLayout.anchors.margins * 2) | ||||
30 | property int _minimumHeight: rootLayout.childrenRect.height + (rootLayout.anchors.margins * 2) | ||||
31 | | ||||
28 | Layout.minimumWidth: _minimumWidth | 32 | Layout.minimumWidth: _minimumWidth | ||
29 | Layout.minimumHeight: _minimumHeight | 33 | Layout.minimumHeight: _minimumHeight | ||
30 | | ||||
31 | // The "sensible" values | | |||
32 | property int _minimumWidth: (showAgenda ? agendaViewWidth : 0) + monthViewWidth | | |||
33 | property int _minimumHeight: units.gridUnit * 14 | | |||
34 | Layout.preferredWidth: _minimumWidth | 34 | Layout.preferredWidth: _minimumWidth | ||
35 | Layout.preferredHeight: _minimumHeight * 1.5 | 35 | Layout.preferredHeight: _minimumHeight | ||
36 | Layout.maximumWidth: Layout.preferredWidth | 36 | Layout.maximumWidth: _minimumWidth | ||
37 | Layout.maximumHeight: Layout.preferredHeight | 37 | Layout.maximumHeight: _minimumHeight | ||
38 | 38 | | |||
39 | readonly property bool showAgenda: PlasmaCalendar.EventPluginsManager.enabledPlugins.length > 0 | 39 | readonly property bool showAgenda: PlasmaCalendar.EventPluginsManager.enabledPlugins.length > 0 | ||
40 | readonly property bool showClocks: plasmoid.configuration.selectedTimeZones.length > 1 | ||||
40 | 41 | | |||
41 | readonly property int agendaViewWidth: _minimumHeight * 1.5 | | |||
42 | readonly property int monthViewWidth: monthView.showWeekNumbers ? Math.round(_minimumHeight * 1.75) : Math.round(_minimumHeight * 1.5) | | |||
43 | | ||||
44 | property int boxWidth: (agendaViewWidth + monthViewWidth - ((showAgenda ? 3 : 4) * spacing)) / 2 | | |||
45 | | ||||
46 | property int spacing: units.largeSpacing | | |||
47 | property alias borderWidth: monthView.borderWidth | 42 | property alias borderWidth: monthView.borderWidth | ||
48 | property alias monthView: monthView | 43 | property alias monthView: monthView | ||
49 | 44 | | |||
50 | property bool debug: false | 45 | property bool debug: false | ||
51 | 46 | | |||
52 | property bool isExpanded: plasmoid.expanded | 47 | property bool isExpanded: plasmoid.expanded | ||
53 | 48 | | |||
54 | onIsExpandedChanged: { | 49 | onIsExpandedChanged: { | ||
55 | // clear all the selections when the plasmoid is showing/hiding | 50 | // clear all the selections when the plasmoid is showing/hiding | ||
56 | monthView.resetToToday(); | 51 | monthView.resetToToday(); | ||
57 | } | 52 | } | ||
58 | 53 | | |||
59 | Item { | 54 | // Top-level layout containing: | ||
60 | id: agenda | 55 | // - Left column with current date header, calendar, and agenda view | ||
61 | visible: calendar.showAgenda | 56 | // - Right column with world clocks | ||
57 | RowLayout { | ||||
58 | id: rootLayout | ||||
62 | 59 | | |||
63 | width: boxWidth | | |||
64 | anchors { | 60 | anchors { | ||
65 | top: parent.top | 61 | top: parent.top | ||
66 | left: parent.left | 62 | left: parent.left | ||
67 | bottom: parent.bottom | 63 | margins: units.largeSpacing | ||
68 | leftMargin: spacing | | |||
69 | topMargin: spacing | | |||
70 | bottomMargin: spacing | | |||
71 | } | 64 | } | ||
72 | 65 | | |||
66 | // Left column containing header, calendar, and event view | ||||
67 | ColumnLayout { | ||||
68 | id: leftColumnLayout | ||||
69 | | ||||
70 | Layout.minimumWidth: units.gridUnit * 18 | ||||
71 | | ||||
73 | function dateString(format) { | 72 | function dateString(format) { | ||
74 | return Qt.formatDate(monthView.currentDate, format); | 73 | return Qt.formatDate(monthView.currentDate, format); | ||
75 | } | 74 | } | ||
76 | 75 | | |||
76 | // Header for the calendar: Current day, month, and year | ||||
77 | RowLayout { | ||||
78 | id: currentDateHeaderLayout | ||||
79 | | ||||
80 | PlasmaComponents.Label { | ||||
81 | height: dayAndMonthLayout.height | ||||
82 | width: paintedWidth | ||||
83 | font.pixelSize: dayAndMonthLayout.height | ||||
84 | font.weight: Font.Light | ||||
85 | text: leftColumnLayout.dateString("dd") | ||||
86 | opacity: 0.6 | ||||
87 | } | ||||
88 | | ||||
89 | ColumnLayout { | ||||
90 | id: dayAndMonthLayout | ||||
91 | PlasmaExtras.Heading { | ||||
92 | level: 1 | ||||
93 | elide: Text.ElideRight | ||||
94 | text: leftColumnLayout.dateString("dddd") | ||||
95 | } | ||||
96 | PlasmaComponents.Label { | ||||
97 | elide: Text.ElideRight | ||||
98 | text: Qt.locale().standaloneMonthName(monthView.currentDate.getMonth()) | ||||
99 | + leftColumnLayout.dateString(" yyyy") | ||||
100 | } | ||||
101 | } | ||||
102 | } | ||||
103 | | ||||
104 | | ||||
105 | // Horizontal separator line | ||||
106 | PlasmaCore.SvgItem { | ||||
107 | Layout.fillWidth: true | ||||
108 | Layout.preferredHeight: naturalSize.height | ||||
109 | elementId: "horizontal-line" | ||||
110 | svg: PlasmaCore.Svg { | ||||
111 | imagePath: "widgets/line" | ||||
112 | } | ||||
113 | } | ||||
114 | | ||||
115 | | ||||
116 | // Calendar | ||||
117 | // TODO KF6: remove the `Item` wrapper, which this is only needed since | ||||
118 | // PlasmaCalendar.MonthView internally has `anchors.fill:parent` set on | ||||
119 | // it, erroneously expecting to never be in a Layout | ||||
120 | Item { | ||||
121 | id: monthViewContainer | ||||
122 | Layout.fillWidth: true | ||||
123 | Layout.minimumHeight: units.gridUnit * 12 | ||||
124 | | ||||
125 | PlasmaCalendar.MonthView { | ||||
126 | id: monthView | ||||
127 | borderOpacity: 0.25 | ||||
128 | today: root.tzDate | ||||
129 | showWeekNumbers: plasmoid.configuration.showWeekNumbers | ||||
130 | } | ||||
131 | } | ||||
132 | | ||||
133 | | ||||
134 | // Agenda view | ||||
135 | Item { | ||||
136 | id: agenda | ||||
137 | visible: calendar.showAgenda | ||||
138 | | ||||
139 | Layout.fillWidth: true | ||||
140 | Layout.minimumHeight: units.gridUnit * 12 | ||||
141 | | ||||
77 | function formatDateWithoutYear(date) { | 142 | function formatDateWithoutYear(date) { | ||
78 | // Unfortunatelly Qt overrides ECMA's Date.toLocaleDateString(), | 143 | // Unfortunatelly Qt overrides ECMA's Date.toLocaleDateString(), | ||
79 | // which is able to return locale-specific date-and-month-only date | 144 | // which is able to return locale-specific date-and-month-only date | ||
80 | // formats, with its dumb version that only supports Qt::DateFormat | 145 | // formats, with its dumb version that only supports Qt::DateFormat | ||
81 | // enum subset. So to get a day-and-month-only date format string we | 146 | // enum subset. So to get a day-and-month-only date format string we | ||
82 | // must resort to this magic and hope there are no locales that use | 147 | // must resort to this magic and hope there are no locales that use | ||
83 | // other separators... | 148 | // other separators... | ||
84 | var format = Qt.locale().dateFormat(Locale.ShortFormat).replace(/[./ ]*Y{2,4}[./ ]*/i, ''); | 149 | var format = Qt.locale().dateFormat(Locale.ShortFormat).replace(/[./ ]*Y{2,4}[./ ]*/i, ''); | ||
Show All 38 Lines | |||||
123 | } | 188 | } | ||
124 | 189 | | |||
125 | Binding { | 190 | Binding { | ||
126 | target: plasmoid | 191 | target: plasmoid | ||
127 | property: "hideOnWindowDeactivate" | 192 | property: "hideOnWindowDeactivate" | ||
128 | value: !plasmoid.configuration.pin | 193 | value: !plasmoid.configuration.pin | ||
129 | } | 194 | } | ||
130 | 195 | | |||
131 | PlasmaComponents.Label { | | |||
132 | id: dayLabel | | |||
133 | anchors.left: parent.left | | |||
134 | height: dayHeading.height + dateHeading.height | | |||
135 | width: paintedWidth | | |||
136 | font.pixelSize: height | | |||
137 | font.weight: Font.Light | | |||
138 | text: agenda.dateString("dd") | | |||
139 | opacity: 0.6 | | |||
140 | } | | |||
141 | | ||||
142 | PlasmaExtras.Heading { | | |||
143 | id: dayHeading | | |||
144 | anchors { | | |||
145 | top: parent.top | | |||
146 | left: dayLabel.right | | |||
147 | right: parent.right | | |||
148 | leftMargin: spacing / 2 | | |||
149 | } | | |||
150 | level: 1 | | |||
151 | elide: Text.ElideRight | | |||
152 | text: agenda.dateString("dddd") | | |||
153 | } | | |||
154 | PlasmaComponents.Label { | | |||
155 | id: dateHeading | | |||
156 | anchors { | | |||
157 | top: dayHeading.bottom | | |||
158 | left: dayLabel.right | | |||
159 | right: parent.right | | |||
160 | leftMargin: spacing / 2 | | |||
161 | } | | |||
162 | elide: Text.ElideRight | | |||
163 | text: Qt.locale().standaloneMonthName(monthView.currentDate.getMonth()) | | |||
164 | + agenda.dateString(" yyyy") | | |||
165 | } | | |||
166 | | ||||
167 | TextMetrics { | 196 | TextMetrics { | ||
168 | id: dateLabelMetrics | 197 | id: dateLabelMetrics | ||
169 | 198 | | |||
170 | // Date/time are arbitrary values with all parts being two-digit | 199 | // Date/time are arbitrary values with all parts being two-digit | ||
171 | readonly property string timeString: Qt.formatTime(new Date(2000, 12, 12, 12, 12, 12, 12)) | 200 | readonly property string timeString: Qt.formatTime(new Date(2000, 12, 12, 12, 12, 12, 12)) | ||
172 | readonly property string dateString: agenda.formatDateWithoutYear(new Date(2000, 12, 12, 12, 12, 12)) | 201 | readonly property string dateString: agenda.formatDateWithoutYear(new Date(2000, 12, 12, 12, 12, 12)) | ||
173 | 202 | | |||
174 | font: theme.defaultFont | 203 | font: theme.defaultFont | ||
175 | text: timeString.length > dateString.length ? timeString : dateString | 204 | text: timeString.length > dateString.length ? timeString : dateString | ||
176 | } | 205 | } | ||
177 | 206 | | |||
178 | PlasmaExtras.ScrollArea { | 207 | PlasmaExtras.ScrollArea { | ||
179 | id: holidaysView | 208 | id: holidaysView | ||
180 | anchors { | 209 | anchors.fill: parent | ||
181 | top: dateHeading.bottom | | |||
182 | left: parent.left | | |||
183 | right: parent.right | | |||
184 | bottom: parent.bottom | | |||
185 | } | | |||
186 | flickableItem.boundsBehavior: Flickable.StopAtBounds | | |||
187 | 210 | | |||
188 | ListView { | 211 | ListView { | ||
189 | id: holidaysList | 212 | id: holidaysList | ||
190 | 213 | | |||
191 | delegate: PlasmaComponents.ListItem { | 214 | delegate: PlasmaComponents.ListItem { | ||
192 | id: eventItem | 215 | id: eventItem | ||
193 | property bool hasTime: { | 216 | property bool hasTime: { | ||
194 | // Explicitly all-day event | 217 | // Explicitly all-day event | ||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Line(s) | 355 | PlasmaExtras.Heading { | |||
336 | anchors.leftMargin: units.largeSpacing | 359 | anchors.leftMargin: units.largeSpacing | ||
337 | anchors.rightMargin: units.largeSpacing | 360 | anchors.rightMargin: units.largeSpacing | ||
338 | text: monthView.isToday(monthView.currentDate) ? i18n("No events for today") | 361 | text: monthView.isToday(monthView.currentDate) ? i18n("No events for today") | ||
339 | : i18n("No events for this day"); | 362 | : i18n("No events for this day"); | ||
340 | level: 3 | 363 | level: 3 | ||
341 | enabled: false | 364 | enabled: false | ||
342 | visible: holidaysList.count == 0 | 365 | visible: holidaysList.count == 0 | ||
343 | } | 366 | } | ||
367 | } | ||||
368 | } | ||||
369 | | ||||
344 | 370 | | |||
371 | // Vertical separator line between columns | ||||
372 | PlasmaCore.SvgItem { | ||||
373 | visible: calendar.showClocks | ||||
374 | Layout.preferredWidth: naturalSize.width | ||||
375 | Layout.leftMargin: units.largeSpacing | ||||
376 | Layout.rightMargin: units.largeSpacing | ||||
377 | Layout.fillHeight: true | ||||
378 | elementId: "vertical-line" | ||||
379 | svg: PlasmaCore.Svg { | ||||
380 | imagePath: "widgets/line" | ||||
345 | } | 381 | } | ||
346 | Item { | | |||
347 | id: cal | | |||
348 | width: boxWidth | | |||
349 | anchors { | | |||
350 | top: parent.top | | |||
351 | right: parent.right | | |||
352 | bottom: parent.bottom | | |||
353 | margins: spacing | | |||
354 | } | 382 | } | ||
355 | 383 | | |||
356 | PlasmaCalendar.MonthView { | 384 | | ||
357 | id: monthView | 385 | // List of world clocks | ||
358 | borderOpacity: 0.25 | 386 | ColumnLayout { | ||
359 | today: root.tzDate | 387 | id: worldClocks | ||
360 | showWeekNumbers: plasmoid.configuration.showWeekNumbers | 388 | | ||
361 | anchors.fill: parent | 389 | visible: calendar.showClocks | ||
390 | | ||||
391 | Layout.minimumWidth: units.gridUnit * 12 | ||||
392 | Layout.fillHeight: true | ||||
393 | | ||||
394 | // Header text | ||||
395 | PlasmaExtras.Heading { | ||||
396 | Layout.minimumHeight: currentDateHeaderLayout.height | ||||
397 | verticalAlignment: Text.AlignBottom | ||||
398 | text: i18n("Time Zones") | ||||
399 | maximumLineCount: 1 | ||||
400 | elide: Text.ElideRight | ||||
401 | } | ||||
402 | | ||||
403 | // Horizontal separator line | ||||
404 | PlasmaCore.SvgItem { | ||||
405 | Layout.fillWidth: true | ||||
406 | Layout.preferredHeight: naturalSize.height | ||||
407 | elementId: "horizontal-line" | ||||
408 | svg: PlasmaCore.Svg { | ||||
409 | imagePath: "widgets/line" | ||||
410 | } | ||||
411 | } | ||||
412 | | ||||
413 | // Clocks list | ||||
414 | PlasmaExtras.ScrollArea { | ||||
415 | Layout.fillWidth: true | ||||
416 | Layout.fillHeight: true | ||||
417 | | ||||
418 | ListView { | ||||
419 | id: clocksList | ||||
420 | | ||||
421 | model: { | ||||
422 | var timezones = []; | ||||
423 | for (var i = 0; i < plasmoid.configuration.selectedTimeZones.length; i++) { | ||||
424 | timezones.push(plasmoid.configuration.selectedTimeZones[i]); | ||||
362 | } | 425 | } | ||
363 | 426 | | |||
427 | return timezones; | ||||
364 | } | 428 | } | ||
365 | 429 | | |||
430 | delegate: PlasmaComponents.ListItem { | ||||
431 | id: listItem | ||||
432 | readonly property bool isCurrentTimeZone: modelData === plasmoid.configuration.lastSelectedTimezone | ||||
cblack: This property's name doesn't imply it's a boolean | |||||
433 | | ||||
434 | ColumnLayout { | ||||
435 | | ||||
436 | width: clocksList.width | ||||
437 | spacing: 0 | ||||
438 | | ||||
439 | PlasmaExtras.Heading { | ||||
440 | Layout.fillWidth: true | ||||
441 | level: 3 | ||||
442 | text: root.nameForZone(modelData) | ||||
443 | font.weight: listItem.isCurrentTimeZone ? Font.Bold : Font.Normal | ||||
444 | maximumLineCount: 1 | ||||
445 | elide: Text.ElideRight | ||||
446 | } | ||||
447 | | ||||
448 | PlasmaExtras.Heading { | ||||
449 | Layout.fillWidth: true | ||||
450 | level: 5 | ||||
451 | text: root.timeForZone(modelData) | ||||
452 | font.weight: listItem.isCurrentTimeZone ? Font.Bold : Font.Normal | ||||
453 | maximumLineCount: 2 | ||||
454 | elide: Text.ElideRight | ||||
455 | opacity: 0.6 | ||||
456 | } | ||||
457 | } | ||||
458 | } | ||||
459 | } | ||||
460 | } | ||||
461 | } | ||||
462 | } | ||||
463 | | ||||
464 | | ||||
366 | // Allows the user to keep the calendar open for reference | 465 | // Allows the user to keep the calendar open for reference | ||
367 | PlasmaComponents.ToolButton { | 466 | PlasmaComponents.ToolButton { | ||
368 | anchors.right: parent.right | 467 | anchors.right: parent.right | ||
369 | width: Math.round(units.gridUnit * 1.25) | 468 | width: Math.round(units.gridUnit * 1.25) | ||
370 | height: width | 469 | height: width | ||
371 | checkable: true | 470 | checkable: true | ||
372 | iconSource: "window-pin" | 471 | iconSource: "window-pin" | ||
373 | checked: plasmoid.configuration.pin | 472 | checked: plasmoid.configuration.pin | ||
374 | onCheckedChanged: plasmoid.configuration.pin = checked | 473 | onCheckedChanged: plasmoid.configuration.pin = checked | ||
375 | tooltip: i18n("Keep Open") | 474 | tooltip: i18n("Keep Open") | ||
376 | } | 475 | } | ||
377 | } | 476 | } |
This property's name doesn't imply it's a boolean