diff --git a/applets/digital-clock/package/contents/ui/CalendarView.qml b/applets/digital-clock/package/contents/ui/CalendarView.qml index e30eb8828..7ecc8ee34 100644 --- a/applets/digital-clock/package/contents/ui/CalendarView.qml +++ b/applets/digital-clock/package/contents/ui/CalendarView.qml @@ -1,377 +1,476 @@ /* * Copyright 2013 Sebastian Kügler * Copyright 2015 Martin Klapetek * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.4 import QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.calendar 2.0 as PlasmaCalendar import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.extras 2.0 as PlasmaExtras Item { id: calendar + // The "sensible" values + property int _minimumWidth: rootLayout.childrenRect.width + (rootLayout.anchors.margins * 2) + property int _minimumHeight: rootLayout.childrenRect.height + (rootLayout.anchors.margins * 2) + Layout.minimumWidth: _minimumWidth Layout.minimumHeight: _minimumHeight - - // The "sensible" values - property int _minimumWidth: (showAgenda ? agendaViewWidth : 0) + monthViewWidth - property int _minimumHeight: units.gridUnit * 14 Layout.preferredWidth: _minimumWidth - Layout.preferredHeight: _minimumHeight * 1.5 - Layout.maximumWidth: Layout.preferredWidth - Layout.maximumHeight: Layout.preferredHeight + Layout.preferredHeight: _minimumHeight + Layout.maximumWidth: _minimumWidth + Layout.maximumHeight: _minimumHeight readonly property bool showAgenda: PlasmaCalendar.EventPluginsManager.enabledPlugins.length > 0 + readonly property bool showClocks: plasmoid.configuration.selectedTimeZones.length > 1 - readonly property int agendaViewWidth: _minimumHeight * 1.5 - readonly property int monthViewWidth: monthView.showWeekNumbers ? Math.round(_minimumHeight * 1.75) : Math.round(_minimumHeight * 1.5) - - property int boxWidth: (agendaViewWidth + monthViewWidth - ((showAgenda ? 3 : 4) * spacing)) / 2 - - property int spacing: units.largeSpacing property alias borderWidth: monthView.borderWidth property alias monthView: monthView property bool debug: false property bool isExpanded: plasmoid.expanded onIsExpandedChanged: { // clear all the selections when the plasmoid is showing/hiding monthView.resetToToday(); } - Item { - id: agenda - visible: calendar.showAgenda + // Top-level layout containing: + // - Left column with current date header, calendar, and agenda view + // - Right column with world clocks + RowLayout { + id: rootLayout - width: boxWidth anchors { top: parent.top left: parent.left - bottom: parent.bottom - leftMargin: spacing - topMargin: spacing - bottomMargin: spacing + margins: units.largeSpacing } - function dateString(format) { - return Qt.formatDate(monthView.currentDate, format); - } + // Left column containing header, calendar, and event view + ColumnLayout { + id: leftColumnLayout - function formatDateWithoutYear(date) { - // Unfortunatelly Qt overrides ECMA's Date.toLocaleDateString(), - // which is able to return locale-specific date-and-month-only date - // formats, with its dumb version that only supports Qt::DateFormat - // enum subset. So to get a day-and-month-only date format string we - // must resort to this magic and hope there are no locales that use - // other separators... - var format = Qt.locale().dateFormat(Locale.ShortFormat).replace(/[./ ]*Y{2,4}[./ ]*/i, ''); - return Qt.formatDate(date, format); - } + Layout.minimumWidth: units.gridUnit * 18 - Connections { - target: monthView - - onCurrentDateChanged: { - // Apparently this is needed because this is a simple QList being - // returned and if the list for the current day has 1 event and the - // user clicks some other date which also has 1 event, QML sees the - // sizes match and does not update the labels with the content. - // Resetting the model to null first clears it and then correct data - // are displayed. - holidaysList.model = null; - holidaysList.model = monthView.daysModel.eventsForDate(monthView.currentDate); + function dateString(format) { + return Qt.formatDate(monthView.currentDate, format); } - } - Connections { - target: monthView.daysModel + // Header for the calendar: Current day, month, and year + RowLayout { + id: currentDateHeaderLayout + + PlasmaComponents.Label { + height: dayAndMonthLayout.height + width: paintedWidth + font.pixelSize: dayAndMonthLayout.height + font.weight: Font.Light + text: leftColumnLayout.dateString("dd") + opacity: 0.6 + } - onAgendaUpdated: { - // Checks if the dates are the same, comparing the date objects - // directly won't work and this does a simple integer subtracting - // so should be fastest. One of the JS weirdness. - if (updatedDate - monthView.currentDate === 0) { - holidaysList.model = null; - holidaysList.model = monthView.daysModel.eventsForDate(monthView.currentDate); + ColumnLayout { + id: dayAndMonthLayout + PlasmaExtras.Heading { + level: 1 + elide: Text.ElideRight + text: leftColumnLayout.dateString("dddd") + } + PlasmaComponents.Label { + elide: Text.ElideRight + text: Qt.locale().standaloneMonthName(monthView.currentDate.getMonth()) + + leftColumnLayout.dateString(" yyyy") + } } } - } - Connections { - target: plasmoid.configuration - onEnabledCalendarPluginsChanged: { - PlasmaCalendar.EventPluginsManager.enabledPlugins = plasmoid.configuration.enabledCalendarPlugins; + // Horizontal separator line + PlasmaCore.SvgItem { + Layout.fillWidth: true + Layout.preferredHeight: naturalSize.height + elementId: "horizontal-line" + svg: PlasmaCore.Svg { + imagePath: "widgets/line" + } } - } - Binding { - target: plasmoid - property: "hideOnWindowDeactivate" - value: !plasmoid.configuration.pin - } - - PlasmaComponents.Label { - id: dayLabel - anchors.left: parent.left - height: dayHeading.height + dateHeading.height - width: paintedWidth - font.pixelSize: height - font.weight: Font.Light - text: agenda.dateString("dd") - opacity: 0.6 - } - PlasmaExtras.Heading { - id: dayHeading - anchors { - top: parent.top - left: dayLabel.right - right: parent.right - leftMargin: spacing / 2 - } - level: 1 - elide: Text.ElideRight - text: agenda.dateString("dddd") - } - PlasmaComponents.Label { - id: dateHeading - anchors { - top: dayHeading.bottom - left: dayLabel.right - right: parent.right - leftMargin: spacing / 2 + // Calendar + // TODO KF6: remove the `Item` wrapper, which this is only needed since + // PlasmaCalendar.MonthView internally has `anchors.fill:parent` set on + // it, erroneously expecting to never be in a Layout + Item { + id: monthViewContainer + Layout.fillWidth: true + Layout.minimumHeight: units.gridUnit * 12 + + PlasmaCalendar.MonthView { + id: monthView + borderOpacity: 0.25 + today: root.tzDate + showWeekNumbers: plasmoid.configuration.showWeekNumbers + } } - elide: Text.ElideRight - text: Qt.locale().standaloneMonthName(monthView.currentDate.getMonth()) - + agenda.dateString(" yyyy") - } - TextMetrics { - id: dateLabelMetrics - // Date/time are arbitrary values with all parts being two-digit - readonly property string timeString: Qt.formatTime(new Date(2000, 12, 12, 12, 12, 12, 12)) - readonly property string dateString: agenda.formatDateWithoutYear(new Date(2000, 12, 12, 12, 12, 12)) + // Agenda view + Item { + id: agenda + visible: calendar.showAgenda - font: theme.defaultFont - text: timeString.length > dateString.length ? timeString : dateString - } + Layout.fillWidth: true + Layout.minimumHeight: units.gridUnit * 12 - PlasmaExtras.ScrollArea { - id: holidaysView - anchors { - top: dateHeading.bottom - left: parent.left - right: parent.right - bottom: parent.bottom - } - flickableItem.boundsBehavior: Flickable.StopAtBounds + function formatDateWithoutYear(date) { + // Unfortunatelly Qt overrides ECMA's Date.toLocaleDateString(), + // which is able to return locale-specific date-and-month-only date + // formats, with its dumb version that only supports Qt::DateFormat + // enum subset. So to get a day-and-month-only date format string we + // must resort to this magic and hope there are no locales that use + // other separators... + var format = Qt.locale().dateFormat(Locale.ShortFormat).replace(/[./ ]*Y{2,4}[./ ]*/i, ''); + return Qt.formatDate(date, format); + } - ListView { - id: holidaysList + Connections { + target: monthView + + onCurrentDateChanged: { + // Apparently this is needed because this is a simple QList being + // returned and if the list for the current day has 1 event and the + // user clicks some other date which also has 1 event, QML sees the + // sizes match and does not update the labels with the content. + // Resetting the model to null first clears it and then correct data + // are displayed. + holidaysList.model = null; + holidaysList.model = monthView.daysModel.eventsForDate(monthView.currentDate); + } + } - delegate: PlasmaComponents.ListItem { - id: eventItem - property bool hasTime: { - // Explicitly all-day event - if (modelData.isAllDay) { - return false; - } - // Multi-day event which does not start or end today (so - // is all-day from today's point of view) - if (modelData.startDateTime - monthView.currentDate < 0 && - modelData.endDateTime - monthView.currentDate > 86400000) { // 24hrs in ms - return false; + Connections { + target: monthView.daysModel + + onAgendaUpdated: { + // Checks if the dates are the same, comparing the date objects + // directly won't work and this does a simple integer subtracting + // so should be fastest. One of the JS weirdness. + if (updatedDate - monthView.currentDate === 0) { + holidaysList.model = null; + holidaysList.model = monthView.daysModel.eventsForDate(monthView.currentDate); } + } + } + + Connections { + target: plasmoid.configuration + + onEnabledCalendarPluginsChanged: { + PlasmaCalendar.EventPluginsManager.enabledPlugins = plasmoid.configuration.enabledCalendarPlugins; + } + } - // Non-explicit all-day event - var startIsMidnight = modelData.startDateTime.getHours() === 0 - && modelData.startDateTime.getMinutes() === 0; + Binding { + target: plasmoid + property: "hideOnWindowDeactivate" + value: !plasmoid.configuration.pin + } + + TextMetrics { + id: dateLabelMetrics - var endIsMidnight = modelData.endDateTime.getHours() === 0 - && modelData.endDateTime.getMinutes() === 0; + // Date/time are arbitrary values with all parts being two-digit + readonly property string timeString: Qt.formatTime(new Date(2000, 12, 12, 12, 12, 12, 12)) + readonly property string dateString: agenda.formatDateWithoutYear(new Date(2000, 12, 12, 12, 12, 12)) - var sameDay = modelData.startDateTime.getDate() === modelData.endDateTime.getDate() - && modelData.startDateTime.getDay() === modelData.endDateTime.getDay() + font: theme.defaultFont + text: timeString.length > dateString.length ? timeString : dateString + } + + PlasmaExtras.ScrollArea { + id: holidaysView + anchors.fill: parent + + ListView { + id: holidaysList + + delegate: PlasmaComponents.ListItem { + id: eventItem + property bool hasTime: { + // Explicitly all-day event + if (modelData.isAllDay) { + return false; + } + // Multi-day event which does not start or end today (so + // is all-day from today's point of view) + if (modelData.startDateTime - monthView.currentDate < 0 && + modelData.endDateTime - monthView.currentDate > 86400000) { // 24hrs in ms + return false; + } + + // Non-explicit all-day event + var startIsMidnight = modelData.startDateTime.getHours() === 0 + && modelData.startDateTime.getMinutes() === 0; + + var endIsMidnight = modelData.endDateTime.getHours() === 0 + && modelData.endDateTime.getMinutes() === 0; + + var sameDay = modelData.startDateTime.getDate() === modelData.endDateTime.getDate() + && modelData.startDateTime.getDay() === modelData.endDateTime.getDay() + + if (startIsMidnight && endIsMidnight && sameDay) { + return false + } + + return true; + } - if (startIsMidnight && endIsMidnight && sameDay) { - return false + PlasmaCore.ToolTipArea { + width: parent.width + height: eventGrid.height + active: eventTitle.truncated || eventDescription.truncated + mainText: active ? eventTitle.text : "" + subText: active ? eventDescription.text : "" + + GridLayout { + id: eventGrid + columns: 3 + rows: 2 + rowSpacing: 0 + columnSpacing: 2 * units.smallSpacing + + width: parent.width + + Rectangle { + id: eventColor + + Layout.row: 0 + Layout.column: 0 + Layout.rowSpan: 2 + Layout.fillHeight: true + + color: modelData.eventColor + width: 5 * units.devicePixelRatio + visible: modelData.eventColor !== "" + } + + PlasmaComponents.Label { + id: startTimeLabel + + readonly property bool startsToday: modelData.startDateTime - monthView.currentDate >= 0 + readonly property bool startedYesterdayLessThan12HoursAgo: modelData.startDateTime - monthView.currentDate >= -43200000 //12hrs in ms + + Layout.row: 0 + Layout.column: 1 + Layout.minimumWidth: dateLabelMetrics.width + + text: startsToday || startedYesterdayLessThan12HoursAgo + ? Qt.formatTime(modelData.startDateTime) + : agenda.formatDateWithoutYear(modelData.startDateTime) + horizontalAlignment: Qt.AlignRight + visible: eventItem.hasTime + } + + PlasmaComponents.Label { + id: endTimeLabel + + readonly property bool endsToday: modelData.endDateTime - monthView.currentDate <= 86400000 // 24hrs in ms + readonly property bool endsTomorrowInLessThan12Hours: modelData.endDateTime - monthView.currentDate <= 86400000 + 43200000 // 36hrs in ms + + Layout.row: 1 + Layout.column: 1 + Layout.minimumWidth: dateLabelMetrics.width + + text: endsToday || endsTomorrowInLessThan12Hours + ? Qt.formatTime(modelData.endDateTime) + : agenda.formatDateWithoutYear(modelData.endDateTime) + horizontalAlignment: Qt.AlignRight + enabled: false + + visible: eventItem.hasTime + } + + PlasmaComponents.Label { + id: eventTitle + + readonly property bool wrap: eventDescription.text === "" + + Layout.row: 0 + Layout.rowSpan: wrap ? 2 : 1 + Layout.column: 2 + Layout.fillWidth: true + + font.weight: Font.Bold + elide: Text.ElideRight + text: modelData.title + verticalAlignment: Text.AlignVCenter + maximumLineCount: 2 + wrapMode: wrap ? Text.Wrap : Text.NoWrap + } + + PlasmaComponents.Label { + id: eventDescription + + Layout.row: 1 + Layout.column: 2 + Layout.fillWidth: true + + elide: Text.ElideRight + text: modelData.description + verticalAlignment: Text.AlignVCenter + enabled: false + + visible: text !== "" + } + } + } } - return true; + section.property: "modelData.eventType" + section.delegate: PlasmaExtras.Heading { + level: 3 + elide: Text.ElideRight + text: section + } } + } - PlasmaCore.ToolTipArea { - width: parent.width - height: eventGrid.height - active: eventTitle.truncated || eventDescription.truncated - mainText: active ? eventTitle.text : "" - subText: active ? eventDescription.text : "" - - GridLayout { - id: eventGrid - columns: 3 - rows: 2 - rowSpacing: 0 - columnSpacing: 2 * units.smallSpacing - - width: parent.width - - Rectangle { - id: eventColor - - Layout.row: 0 - Layout.column: 0 - Layout.rowSpan: 2 - Layout.fillHeight: true - - color: modelData.eventColor - width: 5 * units.devicePixelRatio - visible: modelData.eventColor !== "" - } + PlasmaExtras.Heading { + anchors.fill: holidaysView + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.leftMargin: units.largeSpacing + anchors.rightMargin: units.largeSpacing + text: monthView.isToday(monthView.currentDate) ? i18n("No events for today") + : i18n("No events for this day"); + level: 3 + enabled: false + visible: holidaysList.count == 0 + } + } + } - PlasmaComponents.Label { - id: startTimeLabel - readonly property bool startsToday: modelData.startDateTime - monthView.currentDate >= 0 - readonly property bool startedYesterdayLessThan12HoursAgo: modelData.startDateTime - monthView.currentDate >= -43200000 //12hrs in ms + // Vertical separator line between columns + PlasmaCore.SvgItem { + visible: calendar.showClocks + Layout.preferredWidth: naturalSize.width + Layout.leftMargin: units.largeSpacing + Layout.rightMargin: units.largeSpacing + Layout.fillHeight: true + elementId: "vertical-line" + svg: PlasmaCore.Svg { + imagePath: "widgets/line" + } + } - Layout.row: 0 - Layout.column: 1 - Layout.minimumWidth: dateLabelMetrics.width - text: startsToday || startedYesterdayLessThan12HoursAgo - ? Qt.formatTime(modelData.startDateTime) - : agenda.formatDateWithoutYear(modelData.startDateTime) - horizontalAlignment: Qt.AlignRight - visible: eventItem.hasTime - } + // List of world clocks + ColumnLayout { + id: worldClocks - PlasmaComponents.Label { - id: endTimeLabel + visible: calendar.showClocks - readonly property bool endsToday: modelData.endDateTime - monthView.currentDate <= 86400000 // 24hrs in ms - readonly property bool endsTomorrowInLessThan12Hours: modelData.endDateTime - monthView.currentDate <= 86400000 + 43200000 // 36hrs in ms + Layout.minimumWidth: units.gridUnit * 12 + Layout.fillHeight: true - Layout.row: 1 - Layout.column: 1 - Layout.minimumWidth: dateLabelMetrics.width + // Header text + PlasmaExtras.Heading { + Layout.minimumHeight: currentDateHeaderLayout.height + verticalAlignment: Text.AlignBottom + text: i18n("Time Zones") + maximumLineCount: 1 + elide: Text.ElideRight + } - text: endsToday || endsTomorrowInLessThan12Hours - ? Qt.formatTime(modelData.endDateTime) - : agenda.formatDateWithoutYear(modelData.endDateTime) - horizontalAlignment: Qt.AlignRight - enabled: false + // Horizontal separator line + PlasmaCore.SvgItem { + Layout.fillWidth: true + Layout.preferredHeight: naturalSize.height + elementId: "horizontal-line" + svg: PlasmaCore.Svg { + imagePath: "widgets/line" + } + } - visible: eventItem.hasTime - } + // Clocks list + PlasmaExtras.ScrollArea { + Layout.fillWidth: true + Layout.fillHeight: true - PlasmaComponents.Label { - id: eventTitle + ListView { + id: clocksList - readonly property bool wrap: eventDescription.text === "" + model: { + var timezones = []; + for (var i = 0; i < plasmoid.configuration.selectedTimeZones.length; i++) { + timezones.push(plasmoid.configuration.selectedTimeZones[i]); + } - Layout.row: 0 - Layout.rowSpan: wrap ? 2 : 1 - Layout.column: 2 - Layout.fillWidth: true + return timezones; + } - font.weight: Font.Bold - elide: Text.ElideRight - text: modelData.title - verticalAlignment: Text.AlignVCenter - maximumLineCount: 2 - wrapMode: wrap ? Text.Wrap : Text.NoWrap - } + delegate: PlasmaComponents.ListItem { + id: listItem + readonly property bool isCurrentTimeZone: modelData === plasmoid.configuration.lastSelectedTimezone - PlasmaComponents.Label { - id: eventDescription + ColumnLayout { - Layout.row: 1 - Layout.column: 2 - Layout.fillWidth: true + width: clocksList.width + spacing: 0 + PlasmaExtras.Heading { + Layout.fillWidth: true + level: 3 + text: root.nameForZone(modelData) + font.weight: listItem.isCurrentTimeZone ? Font.Bold : Font.Normal + maximumLineCount: 1 elide: Text.ElideRight - text: modelData.description - verticalAlignment: Text.AlignVCenter - enabled: false + } - visible: text !== "" + PlasmaExtras.Heading { + Layout.fillWidth: true + level: 5 + text: root.timeForZone(modelData) + font.weight: listItem.isCurrentTimeZone ? Font.Bold : Font.Normal + maximumLineCount: 2 + elide: Text.ElideRight + opacity: 0.6 } } } } - - section.property: "modelData.eventType" - section.delegate: PlasmaExtras.Heading { - level: 3 - elide: Text.ElideRight - text: section - } } } - - PlasmaExtras.Heading { - anchors.fill: holidaysView - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - anchors.leftMargin: units.largeSpacing - anchors.rightMargin: units.largeSpacing - text: monthView.isToday(monthView.currentDate) ? i18n("No events for today") - : i18n("No events for this day"); - level: 3 - enabled: false - visible: holidaysList.count == 0 - } - } - Item { - id: cal - width: boxWidth - anchors { - top: parent.top - right: parent.right - bottom: parent.bottom - margins: spacing - } - - PlasmaCalendar.MonthView { - id: monthView - borderOpacity: 0.25 - today: root.tzDate - showWeekNumbers: plasmoid.configuration.showWeekNumbers - anchors.fill: parent - } - } // Allows the user to keep the calendar open for reference PlasmaComponents.ToolButton { anchors.right: parent.right width: Math.round(units.gridUnit * 1.25) height: width checkable: true iconSource: "window-pin" checked: plasmoid.configuration.pin onCheckedChanged: plasmoid.configuration.pin = checked tooltip: i18n("Keep Open") } } diff --git a/applets/digital-clock/package/contents/ui/Tooltip.qml b/applets/digital-clock/package/contents/ui/Tooltip.qml index e5492cb4d..9d033095e 100644 --- a/applets/digital-clock/package/contents/ui/Tooltip.qml +++ b/applets/digital-clock/package/contents/ui/Tooltip.qml @@ -1,147 +1,116 @@ /* * Copyright 2015 by Martin Klapetek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. */ import QtQuick 2.0 import QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.extras 2.0 as PlasmaExtras -import org.kde.plasma.private.digitalclock 1.0 Item { id: tooltipContentItem property int preferredTextWidth: units.gridUnit * 20 width: childrenRect.width + units.gridUnit height: childrenRect.height + units.gridUnit LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft LayoutMirroring.childrenInherit: true PlasmaCore.ColorScope.colorGroup: PlasmaCore.Theme.NormalColorGroup PlasmaCore.ColorScope.inherit: false - function timeForZone(zone) { - var compactRepresentationItem = plasmoid.compactRepresentationItem; - if (!compactRepresentationItem) { - return ""; - } - - // get the time for the given timezone from the dataengine - var now = dataSource.data[zone]["DateTime"]; - // get current UTC time - var msUTC = now.getTime() + (now.getTimezoneOffset() * 60000); - // add the dataengine TZ offset to it - var dateTime = new Date(msUTC + (dataSource.data[zone]["Offset"] * 1000)); - - var formattedTime = Qt.formatTime(dateTime, compactRepresentationItem.timeFormat); - - if (dateTime.getDay() !== dataSource.data["Local"]["DateTime"].getDay()) { - formattedTime += " (" + Qt.formatDate(dateTime, compactRepresentationItem.dateFormat) + ")"; - } - - return formattedTime; - } - - function nameForZone(zone) { - // add the timezone string to the clock - var timezoneString = plasmoid.configuration.displayTimezoneAsCode ? dataSource.data[zone]["Timezone Abbreviation"] - : TimezonesI18n.i18nCity(dataSource.data[zone]["Timezone City"]); - - return timezoneString; - } - RowLayout { anchors { left: parent.left top: parent.top margins: units.gridUnit / 2 } spacing: units.largeSpacing PlasmaCore.IconItem { id: tooltipIcon source: "preferences-system-time" Layout.alignment: Qt.AlignTop visible: true implicitWidth: units.iconSizes.medium Layout.preferredWidth: implicitWidth Layout.preferredHeight: implicitWidth } ColumnLayout { PlasmaExtras.Heading { id: tooltipMaintext level: 3 Layout.minimumWidth: Math.min(implicitWidth, preferredTextWidth) Layout.maximumWidth: preferredTextWidth elide: Text.ElideRight text: Qt.formatDate(tzDate,"dddd") } PlasmaComponents.Label { id: tooltipSubtext Layout.minimumWidth: Math.min(implicitWidth, preferredTextWidth) Layout.maximumWidth: preferredTextWidth text: Qt.formatDate(tzDate, dateFormatString) opacity: 0.6 } GridLayout { Layout.minimumWidth: Math.min(implicitWidth, preferredTextWidth) Layout.maximumWidth: preferredTextWidth Layout.maximumHeight: childrenRect.height columns: 2 visible: plasmoid.configuration.selectedTimeZones.length > 1 Repeater { model: { // The timezones need to be duplicated in the array // because we need their data twice - once for the name // and once for the time and the Repeater delegate cannot // be one Item with two Labels because that wouldn't work // in a grid then var timezones = []; for (var i = 0; i < plasmoid.configuration.selectedTimeZones.length; i++) { timezones.push(plasmoid.configuration.selectedTimeZones[i]); timezones.push(plasmoid.configuration.selectedTimeZones[i]); } return timezones; } PlasmaComponents.Label { id: timezone // Layout.fillWidth is buggy here Layout.alignment: index % 2 === 0 ? Qt.AlignRight : Qt.AlignLeft wrapMode: Text.NoWrap text: index % 2 == 0 ? nameForZone(modelData) : timeForZone(modelData) font.weight: modelData === plasmoid.configuration.lastSelectedTimezone ? Font.Bold : Font.Normal height: paintedHeight elide: Text.ElideNone opacity: 0.6 } } } } } } diff --git a/applets/digital-clock/package/contents/ui/main.qml b/applets/digital-clock/package/contents/ui/main.qml index d91cabe04..3f92a23fc 100644 --- a/applets/digital-clock/package/contents/ui/main.qml +++ b/applets/digital-clock/package/contents/ui/main.qml @@ -1,118 +1,148 @@ /* * Copyright 2013 Heena Mahour * Copyright 2013 Sebastian Kügler * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Layouts 1.1 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.kquickcontrolsaddons 2.0 import org.kde.plasma.private.digitalclock 1.0 import org.kde.kquickcontrolsaddons 2.0 import org.kde.plasma.calendar 2.0 as PlasmaCalendar Item { id: root width: units.gridUnit * 10 height: units.gridUnit * 4 property string dateFormatString: setDateFormatString() Plasmoid.backgroundHints: PlasmaCore.Types.ShadowBackground | PlasmaCore.Types.ConfigurableBackground property date tzDate: { // get the time for the given timezone from the dataengine var now = dataSource.data[plasmoid.configuration.lastSelectedTimezone]["DateTime"]; // get current UTC time var msUTC = now.getTime() + (now.getTimezoneOffset() * 60000); // add the dataengine TZ offset to it return new Date(msUTC + (dataSource.data[plasmoid.configuration.lastSelectedTimezone]["Offset"] * 1000)); } function initTimezones() { var tz = Array() if (plasmoid.configuration.selectedTimeZones.indexOf("Local") === -1) { tz.push("Local"); } root.allTimezones = tz.concat(plasmoid.configuration.selectedTimeZones); } + function timeForZone(zone) { + var compactRepresentationItem = plasmoid.compactRepresentationItem; + if (!compactRepresentationItem) { + return ""; + } + + // get the time for the given timezone from the dataengine + var now = dataSource.data[zone]["DateTime"]; + // get current UTC time + var msUTC = now.getTime() + (now.getTimezoneOffset() * 60000); + // add the dataengine TZ offset to it + var dateTime = new Date(msUTC + (dataSource.data[zone]["Offset"] * 1000)); + + var formattedTime = Qt.formatTime(dateTime, compactRepresentationItem.timeFormat); + + if (dateTime.getDay() !== dataSource.data["Local"]["DateTime"].getDay()) { + formattedTime += " (" + Qt.formatDate(dateTime, compactRepresentationItem.dateFormat) + ")"; + } + + return formattedTime; + } + + function nameForZone(zone) { + // add the timezone string to the clock + var timezoneString = plasmoid.configuration.displayTimezoneAsCode ? dataSource.data[zone]["Timezone Abbreviation"] + : TimezonesI18n.i18nCity(dataSource.data[zone]["Timezone City"]); + + return timezoneString; + } + Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation Plasmoid.compactRepresentation: DigitalClock { } Plasmoid.fullRepresentation: CalendarView { } Plasmoid.toolTipItem: Loader { id: tooltipLoader Layout.minimumWidth: item ? item.width : 0 Layout.maximumWidth: item ? item.width : 0 Layout.minimumHeight: item ? item.height : 0 Layout.maximumHeight: item ? item.height : 0 source: "Tooltip.qml" } //We need Local to be *always* present, even if not disaplayed as //it's used for formatting in ToolTip.dateTimeChanged() property var allTimezones Connections { target: plasmoid.configuration onSelectedTimeZonesChanged: root.initTimezones(); } PlasmaCore.DataSource { id: dataSource engine: "time" connectedSources: allTimezones interval: plasmoid.configuration.showSeconds ? 1000 : 60000 intervalAlignment: plasmoid.configuration.showSeconds ? PlasmaCore.Types.NoAlignment : PlasmaCore.Types.AlignToMinute } function setDateFormatString() { // remove "dddd" from the locale format string // /all/ locales in LongFormat have "dddd" either // at the beginning or at the end. so we just // remove it + the delimiter and space var format = Qt.locale().dateFormat(Locale.LongFormat); format = format.replace(/(^dddd.?\s)|(,?\sdddd$)/, ""); return format; } function action_clockkcm() { KCMShell.open("clock"); } function action_formatskcm() { KCMShell.open("formats"); } Component.onCompleted: { plasmoid.setAction("clipboard", i18n("Copy to Clipboard"), "edit-copy"); ClipboardMenu.setupMenu(plasmoid.action("clipboard")); root.initTimezones(); if (KCMShell.authorize("clock.desktop").length > 0) { plasmoid.setAction("clockkcm", i18n("Adjust Date and Time..."), "preferences-system-time"); } if (KCMShell.authorize("formats.desktop").length > 0) { plasmoid.setAction("formatskcm", i18n("Set Time Format...")); } // Set the list of enabled plugins from config // to the manager PlasmaCalendar.EventPluginsManager.enabledPlugins = plasmoid.configuration.enabledCalendarPlugins; } }