initial commit
This commit is contained in:
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright 2013 Sebastian Kügler <sebas@kde.org>
|
||||
* Copyright 2015 Martin Klapetek <mklapetek@kde.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
readonly property bool showAgenda: PlasmaCalendar.EventPluginsManager.enabledPlugins.length > 0
|
||||
|
||||
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
|
||||
|
||||
width: boxWidth
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
leftMargin: spacing
|
||||
topMargin: spacing
|
||||
bottomMargin: spacing
|
||||
}
|
||||
|
||||
function dateString(format) {
|
||||
return Qt.formatDate(monthView.currentDate, format);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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))
|
||||
|
||||
font: theme.defaultFont
|
||||
text: timeString.length > dateString.length ? timeString : dateString
|
||||
}
|
||||
|
||||
PlasmaExtras.ScrollArea {
|
||||
id: holidaysView
|
||||
anchors {
|
||||
top: dateHeading.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
flickableItem.boundsBehavior: Flickable.StopAtBounds
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 !== ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.property: "modelData.eventType"
|
||||
section.delegate: PlasmaExtras.Heading {
|
||||
level: 3
|
||||
elide: Text.ElideRight
|
||||
text: section
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaExtras.Heading {
|
||||
anchors.fill: holidaysView
|
||||
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
|
||||
opacity: 0.4
|
||||
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: plasmoid.configuration.showBorders ? 0.25 : 0
|
||||
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")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright 2013 Heena Mahour <heena393@gmail.com>
|
||||
* Copyright 2013 Sebastian Kügler <sebas@kde.org>
|
||||
* Copyright 2013 Martin Klapetek <mklapetek@kde.org>
|
||||
* Copyright 2014 David Edmundson <davidedmundson@kde.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.1
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 2.0 as Components
|
||||
import org.kde.plasma.private.digitalclock 1.0
|
||||
|
||||
Item {
|
||||
id: main
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: false
|
||||
Layout.minimumWidth: paintArea.width
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
|
||||
property string timeFormat
|
||||
property date currentTime
|
||||
property bool showSeconds: plasmoid.configuration.showSeconds
|
||||
property bool showLocalTimezone: plasmoid.configuration.showLocalTimezone
|
||||
property bool showDate: plasmoid.configuration.showDate
|
||||
property bool showSeparator: plasmoid.configuration.showSeparator
|
||||
property bool fixedFont: plasmoid.configuration.fixedFont
|
||||
property var dateFormat: {
|
||||
if (plasmoid.configuration.dateFormat === "customDate") {
|
||||
return plasmoid.configuration.customDateFormat;
|
||||
} else if (plasmoid.configuration.dateFormat === "longDate") {
|
||||
return Qt.SystemLocaleLongDate;
|
||||
} else if (plasmoid.configuration.dateFormat === "isoDate") {
|
||||
return Qt.ISODate;
|
||||
} else if (plasmoid.configuration.dateFormat === "qtDate") {
|
||||
return Qt.TextDate;
|
||||
} else if (plasmoid.configuration.dateFormat === "rfcDate") {
|
||||
return Qt.RFC2822Date;
|
||||
} else {
|
||||
return Qt.SystemLocaleShortDate; }}
|
||||
|
||||
property string lastSelectedTimezone: plasmoid.configuration.lastSelectedTimezone
|
||||
property bool displayTimezoneAsCode: plasmoid.configuration.displayTimezoneAsCode
|
||||
property int use24hFormat: plasmoid.configuration.use24hFormat
|
||||
property int fontSize: plasmoid.configuration.fontSize
|
||||
property string lastDate: ""
|
||||
property int tzOffset
|
||||
property int tzIndex: 0
|
||||
readonly property bool oneLineMode: plasmoid.formFactor == PlasmaCore.Types.Horizontal &&
|
||||
main.height <= 2 * theme.smallestFont.pixelSize &&
|
||||
(main.showDate || timezoneLabel.visible)
|
||||
|
||||
onDateFormatChanged: { setupLabels(); }
|
||||
onDisplayTimezoneAsCodeChanged: { setupLabels(); }
|
||||
|
||||
onLastSelectedTimezoneChanged: { timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat)) }
|
||||
onShowSecondsChanged: { timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat)) }
|
||||
onShowLocalTimezoneChanged: { timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat)) }
|
||||
onShowDateChanged: { timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat)) }
|
||||
onUse24hFormatChanged: { timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat)) }
|
||||
|
||||
Connections {
|
||||
target: plasmoid
|
||||
onContextualActionsAboutToShow: {
|
||||
ClipboardMenu.secondsIncluded = main.showSeconds;
|
||||
ClipboardMenu.currentDate = main.currentTime; }}
|
||||
|
||||
Connections {
|
||||
target: plasmoid.configuration
|
||||
onSelectedTimeZonesChanged: {
|
||||
var lastSelectedTimezone = plasmoid.configuration.lastSelectedTimezone;
|
||||
if (plasmoid.configuration.selectedTimeZones.indexOf(lastSelectedTimezone) == -1) {
|
||||
plasmoid.configuration.lastSelectedTimezone = plasmoid.configuration.selectedTimeZones[0]; }
|
||||
setupLabels();
|
||||
setTimezoneIndex(); }}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
property int wheelDelta: 0
|
||||
anchors.fill: parent
|
||||
onClicked: plasmoid.expanded = !plasmoid.expanded
|
||||
onWheel: {
|
||||
if (!plasmoid.configuration.wheelChangesTimezone) {
|
||||
return; }
|
||||
var delta = wheel.angleDelta.y || wheel.angleDelta.x
|
||||
var newIndex = main.tzIndex;
|
||||
wheelDelta += delta;
|
||||
while (wheelDelta >= 120) {
|
||||
wheelDelta -= 120;
|
||||
newIndex--; }
|
||||
while (wheelDelta <= -120) {
|
||||
wheelDelta += 120;
|
||||
newIndex++; }
|
||||
if (newIndex >= plasmoid.configuration.selectedTimeZones.length) {
|
||||
newIndex = 0; } else if (newIndex < 0) {
|
||||
newIndex = plasmoid.configuration.selectedTimeZones.length - 1; }
|
||||
if (newIndex !== main.tzIndex) {
|
||||
plasmoid.configuration.lastSelectedTimezone = plasmoid.configuration.selectedTimeZones[newIndex];
|
||||
main.tzIndex = newIndex;
|
||||
dataSource.dataChanged();
|
||||
setupLabels(); }}}
|
||||
|
||||
property font font: Qt.font({
|
||||
family: plasmoid.configuration.fontFamily || theme.defaultFont.family,
|
||||
weight: plasmoid.configuration.boldText ? Font.Bold : theme.defaultFont.weight,
|
||||
italic: plasmoid.configuration.italicText,
|
||||
pixelSize: fixedFont ? fontSize : 1024 })
|
||||
|
||||
// -------------
|
||||
// BEGIN VISIBLE
|
||||
Row {
|
||||
id: paintArea
|
||||
|
||||
spacing: plasmoid.configuration.customSpacing * 2
|
||||
leftPadding: spacing
|
||||
rightPadding: spacing
|
||||
|
||||
anchors {
|
||||
centerIn: parent
|
||||
horizontalCenterOffset: plasmoid.configuration.customOffsetX - 50
|
||||
verticalCenterOffset: -plasmoid.configuration.customOffsetY
|
||||
}
|
||||
|
||||
Components.Label {
|
||||
id: dateLabel
|
||||
|
||||
height: timeLabel.height
|
||||
width: dateLabel.paintedWidth
|
||||
font: main.font
|
||||
fontSizeMode: fixedFont ? Text.FixedSize : Text.VerticalFit
|
||||
minimumPixelSize: 1
|
||||
visible: main.showDate
|
||||
}
|
||||
|
||||
Components.Label {
|
||||
id: separator
|
||||
|
||||
height: timeLabel.height
|
||||
width: separator.paintedWidth
|
||||
font: main.font
|
||||
fontSizeMode: fixedFont ? Text.FixedSize : Text.VerticalFit
|
||||
minimumPixelSize: 1
|
||||
transform: Translate { y: separator.paintedHeight / -15 }
|
||||
visible: dateLabel.visible && plasmoid.configuration.showSeparator
|
||||
text: "|"
|
||||
}
|
||||
|
||||
Components.Label {
|
||||
id: timeLabel
|
||||
|
||||
height: sizehelper.height
|
||||
width: timeLabel.paintedWidth
|
||||
font: main.font
|
||||
fontSizeMode: fixedFont ? Text.FixedSize : Text.VerticalFit
|
||||
minimumPixelSize: 1
|
||||
text: {
|
||||
var now = dataSource.data[plasmoid.configuration.lastSelectedTimezone]["DateTime"];
|
||||
var msUTC = now.getTime() + (now.getTimezoneOffset() * 60000);
|
||||
var currentTime = new Date(msUTC + (dataSource.data[plasmoid.configuration.lastSelectedTimezone]["Offset"] * 1000));
|
||||
main.currentTime = currentTime;
|
||||
return Qt.formatTime(currentTime, main.timeFormat); }
|
||||
}
|
||||
|
||||
Components.Label {
|
||||
id: timezoneLabel
|
||||
|
||||
height: timeLabel.height
|
||||
width: timezoneLabel.paintedWidth
|
||||
font: main.font
|
||||
fontSizeMode: fixedFont ? Text.FixedSize : Text.VerticalFit
|
||||
minimumPixelSize: 1
|
||||
visible: text.length > 0
|
||||
}
|
||||
}
|
||||
// ENDOF VISIBLE
|
||||
|
||||
Components.Label {
|
||||
id: sizehelper
|
||||
height: Math.min(main.height, 2.5 * theme.defaultFont.pixelSize)
|
||||
font.family: timeLabel.font.family
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
font.pixelSize: fixedFont ? fontSize : 2.5 * theme.defaultFont.pixelSize
|
||||
fontSizeMode: fixedFont ? Text.FixedSize : Text.VerticalFit
|
||||
minimumPixelSize: 1
|
||||
visible: false }
|
||||
|
||||
FontMetrics {
|
||||
id: timeMetrics
|
||||
font.family: timeLabel.font.family
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic }
|
||||
|
||||
|
||||
function timeFormatCorrection(timeFormatString) {
|
||||
var regexp = /(hh*)(.+)(mm)/i
|
||||
var match = regexp.exec(timeFormatString);
|
||||
var hours = match[1];
|
||||
var delimiter = match[2];
|
||||
var minutes = match[3]
|
||||
var seconds = "ss";
|
||||
var amPm = "AP";
|
||||
var uses24hFormatByDefault = timeFormatString.toLowerCase().indexOf("ap") === -1;
|
||||
var result = hours.toLowerCase() + delimiter + minutes;
|
||||
if (main.showSeconds) {
|
||||
result += delimiter + seconds; }
|
||||
if ((main.use24hFormat == Qt.PartiallyChecked && !uses24hFormatByDefault) || main.use24hFormat == Qt.Unchecked) {
|
||||
result += " " + amPm; }
|
||||
main.timeFormat = result;
|
||||
setupLabels(); }
|
||||
|
||||
function setupLabels() {
|
||||
var showTimezone = main.showLocalTimezone || (plasmoid.configuration.lastSelectedTimezone !== "Local" && dataSource.data["Local"]["Timezone City"] !== dataSource.data[plasmoid.configuration.lastSelectedTimezone]["Timezone City"]);
|
||||
var timezoneString = "";
|
||||
if (showTimezone) {
|
||||
timezoneString = plasmoid.configuration.displayTimezoneAsCode ? dataSource.data[plasmoid.configuration.lastSelectedTimezone]["Timezone Abbreviation"] : TimezonesI18n.i18nCity(dataSource.data[plasmoid.configuration.lastSelectedTimezone]["Timezone City"]);
|
||||
timezoneLabel.text = "(" + timezoneString + ")";
|
||||
} else { timezoneLabel.text = timezoneString; }
|
||||
if (main.showDate) { dateLabel.text = Qt.formatDate(main.currentTime, main.dateFormat);
|
||||
} else { dateLabel.text = ""; }
|
||||
var maximumWidthNumber = 0;
|
||||
var maximumAdvanceWidth = 0;
|
||||
for (var i = 0; i <= 9; i++) {
|
||||
var advanceWidth = timeMetrics.advanceWidth(i);
|
||||
if (advanceWidth > maximumAdvanceWidth) {
|
||||
maximumAdvanceWidth = advanceWidth;
|
||||
maximumWidthNumber = i; }}
|
||||
var format = main.timeFormat.replace(/(h+|m+|s+)/g, "" + maximumWidthNumber + maximumWidthNumber); // make sure maximumWidthNumber is formatted as string
|
||||
var date = new Date(2000, 0, 1, 1, 0, 0);
|
||||
var timeAm = Qt.formatTime(date, format);
|
||||
var advanceWidthAm = timeMetrics.advanceWidth(timeAm);
|
||||
date.setHours(13);
|
||||
var timePm = Qt.formatTime(date, format);
|
||||
var advanceWidthPm = timeMetrics.advanceWidth(timePm);
|
||||
if (advanceWidthAm > advanceWidthPm) { sizehelper.text = timeAm;
|
||||
} else { sizehelper.text = timePm; }}
|
||||
|
||||
function dateTimeChanged() {
|
||||
var doCorrections = false;
|
||||
if (main.showDate) {
|
||||
var currentDate = Qt.formatDateTime(dataSource.data["Local"]["DateTime"], "yyyy-mm-dd");
|
||||
if (main.lastDate !== currentDate) {
|
||||
doCorrections = true;
|
||||
main.lastDate = currentDate }}
|
||||
var currentTZOffset = dataSource.data["Local"]["Offset"] / 60;
|
||||
if (currentTZOffset !== tzOffset) {
|
||||
doCorrections = true;
|
||||
tzOffset = currentTZOffset;
|
||||
Date.timeZoneUpdated(); }
|
||||
if (doCorrections) {
|
||||
timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat)); }}
|
||||
|
||||
function setTimezoneIndex() {
|
||||
for (var i = 0; i < plasmoid.configuration.selectedTimeZones.length; i++) {
|
||||
if (plasmoid.configuration.selectedTimeZones[i] === plasmoid.configuration.lastSelectedTimezone) {
|
||||
main.tzIndex = i;
|
||||
break; }}}
|
||||
|
||||
Component.onCompleted: {
|
||||
var sortArray = plasmoid.configuration.selectedTimeZones;
|
||||
sortArray.sort(function(a, b) { return dataSource.data[a]["Offset"] - dataSource.data[b]["Offset"]; });
|
||||
plasmoid.configuration.selectedTimeZones = sortArray;
|
||||
setTimezoneIndex();
|
||||
tzOffset = -(new Date().getTimezoneOffset());
|
||||
dateTimeChanged();
|
||||
timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat));
|
||||
dataSource.onDataChanged.connect(dateTimeChanged); }
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013 Sebastian Kügler <sebas@kde.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick 2.0
|
||||
import org.kde.plasma.calendar 2.0 as PlasmaCalendar
|
||||
|
||||
PlasmaCalendar.MonthMenu { }
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2015 by Martin Klapetek <mklapetek@kde.org>
|
||||
*
|
||||
* 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
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright 2013 Bhushan Shah <bhush94@gmail.com>
|
||||
* Copyright 2013 Sebastian Kügler <sebas@kde.org>
|
||||
* Copyright 2015 Kai Uwe Broulik <kde@privat.broulik.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.3 as QtControls
|
||||
import QtQuick.Layouts 1.0 as QtLayouts
|
||||
import org.kde.plasma.calendar 2.0 as PlasmaCalendar
|
||||
import org.kde.kirigami 2.5 as Kirigami
|
||||
|
||||
QtLayouts.ColumnLayout {
|
||||
id: appearancePage
|
||||
|
||||
signal configurationChanged
|
||||
|
||||
property string cfg_fontFamily
|
||||
property string cfg_timeFormat: ""
|
||||
property string cfg_dateFormat: "shortDate"
|
||||
property alias cfg_boldText: boldCheckBox.checked
|
||||
property alias cfg_italicText: italicCheckBox.checked
|
||||
property alias cfg_showLocalTimezone: showLocalTimezone.checked
|
||||
property alias cfg_displayTimezoneAsCode: timezoneCodeRadio.checked
|
||||
property alias cfg_showSeconds: showSeconds.checked
|
||||
property alias cfg_showDate: showDate.checked
|
||||
property alias cfg_showSeparator: showSeparator.checked
|
||||
property alias cfg_customDateFormat: customDateFormat.text
|
||||
property alias cfg_use24hFormat: use24hFormat.checkState
|
||||
property alias cfg_customSpacing: customSpacing.value
|
||||
property alias cfg_fixedFont: fixedFont.checked
|
||||
property alias cfg_fontSize: fontSize.value
|
||||
property alias cfg_customOffsetY: customOffsetY.value
|
||||
property alias cfg_customOffsetX: customOffsetX.value
|
||||
|
||||
onCfg_fontFamilyChanged: {
|
||||
// HACK by the time we populate our model and/or the ComboBox is finished the value is still undefined
|
||||
if (cfg_fontFamily) {
|
||||
for (var i = 0, j = fontsModel.count; i < j; ++i) {
|
||||
if (fontsModel.get(i).value == cfg_fontFamily) {
|
||||
fontFamilyComboBox.currentIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: fontsModel
|
||||
Component.onCompleted: {
|
||||
var arr = [] // use temp array to avoid constant binding stuff
|
||||
arr.push({text: i18nc("Use default font", "Default"), value: ""})
|
||||
|
||||
var fonts = Qt.fontFamilies()
|
||||
var foundIndex = 0
|
||||
for (var i = 0, j = fonts.length; i < j; ++i) {
|
||||
arr.push({text: fonts[i], value: fonts[i]})
|
||||
}
|
||||
append(arr)
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: showDate
|
||||
Kirigami.FormData.label: i18n("Information:")
|
||||
text: i18n("Show date")
|
||||
}
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: showSeparator
|
||||
enabled: cfg_showDate
|
||||
text: i18n("Show Separator")
|
||||
}
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: showSeconds
|
||||
text: i18n("Show seconds")
|
||||
}
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: use24hFormat
|
||||
text: i18nc("Checkbox label; means 24h clock format, without am/pm", "Use 24-hour Clock")
|
||||
tristate: true
|
||||
}
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: showLocalTimezone
|
||||
text: i18n("Show local time zone")
|
||||
}
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: fixedFont
|
||||
text: i18n("Use fixed font size")
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
Kirigami.FormData.label: i18n("Font Size:")
|
||||
Kirigami.FormData.buddyFor: fontSize
|
||||
|
||||
QtControls.SpinBox {
|
||||
id: fontSize
|
||||
enabled: cfg_fixedFont
|
||||
from: 1
|
||||
to: 60
|
||||
editable: true
|
||||
validator: IntValidator {
|
||||
locale: control.locale.name
|
||||
bottom: Math.min(control.from, control.to)
|
||||
top: Math.max(control.from, control.to)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
QtLayouts.ColumnLayout {
|
||||
Kirigami.FormData.label: i18n("Display time zone as:")
|
||||
Kirigami.FormData.buddyFor: timezoneCityRadio
|
||||
|
||||
QtControls.RadioButton {
|
||||
id: timezoneCityRadio
|
||||
text: i18n("Time zone city")
|
||||
}
|
||||
|
||||
QtControls.RadioButton {
|
||||
id: timezoneCodeRadio
|
||||
text: i18n("Time zone code")
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
QtControls.ComboBox {
|
||||
id: dateFormat
|
||||
Kirigami.FormData.label: i18n("Date format:")
|
||||
enabled: showDate.checked
|
||||
// QtLayouts.Layout.fillWidth: cfg_dateFormat == "customDate" ? true : false
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
textRole: "label"
|
||||
model: [
|
||||
{
|
||||
'label': i18n("Long Date"),
|
||||
'name': "longDate"
|
||||
},
|
||||
{
|
||||
'label': i18n("Short Date"),
|
||||
'name': "shortDate"
|
||||
},
|
||||
{
|
||||
'label': i18n("ISO Date"),
|
||||
'name': "isoDate"
|
||||
},
|
||||
{
|
||||
'label': i18n("Qt Date"),
|
||||
'name': "qtDate"
|
||||
},
|
||||
{
|
||||
'label': i18n("RFC Date"),
|
||||
'name': "rfcDate"
|
||||
},
|
||||
{
|
||||
'label': i18nc("custom date format", "Custom Date"),
|
||||
'name': "customDate"
|
||||
}
|
||||
]
|
||||
onCurrentIndexChanged: cfg_dateFormat = model[currentIndex]["name"]
|
||||
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < model.length; i++) {
|
||||
if (model[i]["name"] == plasmoid.configuration.dateFormat) {
|
||||
dateFormat.currentIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtControls.TextField {
|
||||
id: customDateFormat
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
visible: cfg_dateFormat == "customDate"
|
||||
}
|
||||
|
||||
QtControls.Label {
|
||||
text: i18n("<a href=\"http://doc.qt.io/qt-5/qml-qtqml-qt.html#formatDateTime-method\">Time Format Documentation</a>")
|
||||
visible: cfg_dateFormat == "customDate"
|
||||
wrapMode: Text.Wrap
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton // We don't want to eat clicks on the Label
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
Kirigami.FormData.label: i18n("Font style:")
|
||||
|
||||
QtControls.ComboBox {
|
||||
id: fontFamilyComboBox
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
currentIndex: 0
|
||||
// ComboBox's sizing is just utterly broken
|
||||
QtLayouts.Layout.minimumWidth: units.gridUnit * 10
|
||||
model: fontsModel
|
||||
// doesn't autodeduce from model because we manually populate it
|
||||
textRole: "text"
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
var current = model.get(currentIndex)
|
||||
if (current) {
|
||||
cfg_fontFamily = current.value
|
||||
appearancePage.configurationChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtControls.Button {
|
||||
id: boldCheckBox
|
||||
QtControls.ToolTip {
|
||||
text: i18n("Bold text")
|
||||
}
|
||||
icon.name: "format-text-bold"
|
||||
checkable: true
|
||||
Accessible.name: tooltip
|
||||
}
|
||||
|
||||
QtControls.Button {
|
||||
id: italicCheckBox
|
||||
QtControls.ToolTip {
|
||||
text: i18n("Italic text")
|
||||
}
|
||||
icon.name: "format-text-italic"
|
||||
checkable: true
|
||||
Accessible.name: tooltip
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
Kirigami.FormData.label: i18n("Spacing:")
|
||||
Kirigami.FormData.buddyFor: customSpacing
|
||||
|
||||
QtControls.Slider {
|
||||
id: customSpacing
|
||||
from: 0
|
||||
to: 10
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
}
|
||||
|
||||
QtControls.Button {
|
||||
id: resetCustomSpacing
|
||||
text: i18n("Reset")
|
||||
onClicked: customSpacing.value = 1
|
||||
}
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
Kirigami.FormData.label: i18n("Vertical Offset:")
|
||||
Kirigami.FormData.buddyFor: customOffsetY
|
||||
|
||||
QtControls.SpinBox {
|
||||
id: customOffsetY
|
||||
from: -10
|
||||
to: 10
|
||||
editable: true
|
||||
validator: IntValidator {
|
||||
locale: customOffsetY.locale.name
|
||||
bottom: Math.min(customOffsetY.from, customOffsetY.to)
|
||||
top: Math.max(customOffsetY.from, customOffsetY.to)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
Kirigami.FormData.label: i18n("Horizontal Offset:")
|
||||
Kirigami.FormData.buddyFor: customOffsetX
|
||||
|
||||
QtControls.Slider {
|
||||
id: customOffsetX
|
||||
from: 0
|
||||
to: 100
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
}
|
||||
|
||||
QtControls.Button {
|
||||
id: resetOffsetX
|
||||
text: i18n("Reset")
|
||||
onClicked: customOffsetX.value = 50
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Item {
|
||||
QtLayouts.Layout.fillHeight: true
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (plasmoid.configuration.displayTimezoneAsCode) {
|
||||
timezoneCodeRadio.checked = true;
|
||||
} else {
|
||||
timezoneCityRadio.checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2015 Martin Klapetek <mklapetek@kde.org>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.4 as QtControls
|
||||
import QtQuick.Layouts 1.0 as QtLayouts
|
||||
import org.kde.plasma.calendar 2.0 as PlasmaCalendar
|
||||
import org.kde.kirigami 2.5 as Kirigami
|
||||
|
||||
Item {
|
||||
id: calendarPage
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
|
||||
signal configurationChanged
|
||||
|
||||
property alias cfg_showWeekNumbers: showWeekNumbers.checked
|
||||
|
||||
function saveConfig()
|
||||
{
|
||||
plasmoid.configuration.enabledCalendarPlugins = PlasmaCalendar.EventPluginsManager.enabledPlugins;
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: showWeekNumbers
|
||||
Kirigami.FormData.label: i18n("General:")
|
||||
text: i18n("Show week numbers")
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: showBorders
|
||||
Kirigami.FormData.label: i18n("Visuals:")
|
||||
text: i18n("Show borders")
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: true
|
||||
}
|
||||
|
||||
QtLayouts.ColumnLayout {
|
||||
Kirigami.FormData.label: i18n("Available Plugins:")
|
||||
Kirigami.FormData.buddyFor: children[1] // 0 is the Repeater
|
||||
|
||||
Repeater {
|
||||
id: calendarPluginsRepeater
|
||||
model: PlasmaCalendar.EventPluginsManager.model
|
||||
delegate: QtLayouts.RowLayout {
|
||||
QtControls.CheckBox {
|
||||
text: model.display
|
||||
checked: model.checked
|
||||
onClicked: {
|
||||
//needed for model's setData to be called
|
||||
model.checked = checked;
|
||||
calendarPage.configurationChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
PlasmaCalendar.EventPluginsManager.populateEnabledPluginsList(plasmoid.configuration.enabledCalendarPlugins);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.2 as QtControls
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
import org.kde.plasma.private.digitalclock 1.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
|
||||
Item {
|
||||
id: timeZonesPage
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
property alias cfg_selectedTimeZones: timeZones.selectedTimeZones
|
||||
property alias cfg_wheelChangesTimezone: enableWheelCheckBox.checked
|
||||
|
||||
TimeZoneModel {
|
||||
id: timeZones
|
||||
|
||||
onSelectedTimeZonesChanged: {
|
||||
if (selectedTimeZones.length == 0) {
|
||||
messageWidget.visible = true;
|
||||
|
||||
timeZones.selectLocalTimeZone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is just for getting the column width
|
||||
QtControls.CheckBox {
|
||||
id: checkbox
|
||||
visible: false
|
||||
}
|
||||
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
id: messageWidget
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 1
|
||||
}
|
||||
|
||||
height: 0
|
||||
|
||||
//TODO: This is the actual color KMessageWidget uses as its base color but here it gives
|
||||
// a different color, figure out why
|
||||
//property color gradBaseColor: Qt.rgba(0.69, 0.5, 0, 1)
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: "#FFD86D" } //Qt.lighter(messageWidget.gradBaseColor, 1.1)
|
||||
GradientStop { position: 0.1; color: "#EAC360" } // messageWidget.gradBaseColor
|
||||
GradientStop { position: 1.0; color: "#CAB064" } //Qt.darker(messageWidget.gradBaseColor, 1.1)
|
||||
}
|
||||
|
||||
radius: 5
|
||||
border.width: 1
|
||||
border.color: "#79735B"
|
||||
|
||||
visible: false
|
||||
|
||||
Behavior on visible {
|
||||
ParallelAnimation {
|
||||
PropertyAnimation {
|
||||
target: messageWidget
|
||||
property: "opacity"
|
||||
to: messageWidget.visible ? 0 : 1.0
|
||||
easing.type: Easing.Linear
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: messageWidget
|
||||
property: "Layout.minimumHeight"
|
||||
to: messageWidget.visible ? 0 : messageWidgetLabel.height + (2 *units.largeSpacing)
|
||||
easing.type: Easing.Linear
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: units.largeSpacing
|
||||
anchors.leftMargin: units.smallSpacing
|
||||
anchors.rightMargin: units.smallSpacing
|
||||
spacing: units.smallSpacing
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: units.iconSizes.smallMedium
|
||||
width: height
|
||||
source: "dialog-warning"
|
||||
}
|
||||
|
||||
QtControls.Label {
|
||||
id: messageWidgetLabel
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.fillWidth: true
|
||||
text: i18n("At least one time zone needs to be enabled. 'Local' was enabled automatically.")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
iconName: "dialog-close"
|
||||
flat: true
|
||||
|
||||
onClicked: {
|
||||
messageWidget.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtControls.TextField {
|
||||
id: filter
|
||||
Layout.fillWidth: true
|
||||
placeholderText: i18n("Search Time Zones")
|
||||
}
|
||||
|
||||
QtControls.TableView {
|
||||
id: timeZoneView
|
||||
|
||||
signal toggleCurrent
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Keys.onSpacePressed: toggleCurrent()
|
||||
|
||||
model: TimeZoneFilterProxy {
|
||||
sourceModel: timeZones
|
||||
filterString: filter.text
|
||||
}
|
||||
|
||||
QtControls.TableViewColumn {
|
||||
role: "checked"
|
||||
width: checkbox.width
|
||||
delegate:
|
||||
QtControls.CheckBox {
|
||||
id: checkBox
|
||||
anchors.centerIn: parent
|
||||
checked: styleData.value
|
||||
activeFocusOnTab: false // only let the TableView as a whole get focus
|
||||
onClicked: {
|
||||
//needed for model's setData to be called
|
||||
model.checked = checked;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: timeZoneView
|
||||
onToggleCurrent: {
|
||||
if (styleData.row === timeZoneView.currentRow) {
|
||||
model.checked = !checkBox.checked
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resizable: false
|
||||
movable: false
|
||||
}
|
||||
QtControls.TableViewColumn {
|
||||
role: "city"
|
||||
title: i18n("City")
|
||||
}
|
||||
QtControls.TableViewColumn {
|
||||
role: "region"
|
||||
title: i18n("Region")
|
||||
}
|
||||
QtControls.TableViewColumn {
|
||||
role: "comment"
|
||||
title: i18n("Comment")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
QtControls.CheckBox {
|
||||
id: enableWheelCheckBox
|
||||
text: i18n("Switch time zone with mouse wheel")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2013 Heena Mahour <heena393@gmail.com>
|
||||
* Copyright 2013 Sebastian Kügler <sebas@kde.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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()
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user