mirror of
https://gitgud.io/wackyideas/aerothemeplasma.git
synced 2024-08-15 00:43:43 +00:00
Very early KDE 6 release.
This commit is contained in:
parent
7cc4ccabbc
commit
686046d4f7
6272 changed files with 140920 additions and 529657 deletions
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2013 Bhushan Shah <bhush94@gmail.com>
|
||||
* 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 QtQml 2.2
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.configuration 2.0
|
||||
import org.kde.plasma.workspace.calendar 2.0 as PlasmaCalendar
|
||||
|
||||
ConfigModel {
|
||||
id: configModel
|
||||
|
||||
ConfigCategory {
|
||||
name: i18n("Appearance")
|
||||
icon: "preferences-desktop-color"
|
||||
source: "configAppearance.qml"
|
||||
}
|
||||
ConfigCategory {
|
||||
name: i18n("Calendar")
|
||||
icon: "preferences-system-time"
|
||||
source: "configCalendar.qml"
|
||||
}
|
||||
ConfigCategory {
|
||||
name: i18n("Time Zones")
|
||||
icon: "preferences-desktop-locale"
|
||||
source: "configTimeZones.qml"
|
||||
}
|
||||
|
||||
property QtObject eventPluginsManager: PlasmaCalendar.EventPluginsManager {
|
||||
Component.onCompleted: {
|
||||
populateEnabledPluginsList(Plasmoid.configuration.enabledCalendarPlugins);
|
||||
}
|
||||
}
|
||||
|
||||
property Instantiator __eventPlugins: Instantiator {
|
||||
model: eventPluginsManager.model
|
||||
delegate: ConfigCategory {
|
||||
name: model.display
|
||||
icon: { console.log(model.decoration); return model.decoration }
|
||||
source: model.configUi
|
||||
includeMargins: false
|
||||
visible: Plasmoid.configuration.enabledCalendarPlugins.indexOf(model.pluginId) > -1
|
||||
}
|
||||
|
||||
|
||||
onObjectAdded: (index, object) => configModel.appendCategory(object)
|
||||
onObjectRemoved: (index, object) => configModel.removeCategory(object)
|
||||
//onObjectAdded: configModel.appendCategory(object)
|
||||
//onObjectRemoved: configModel.removeCategory(object)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||
<kcfgfile name=""/>
|
||||
|
||||
<group name="Appearance">
|
||||
<entry name="showLocalTimezone" type="Bool">
|
||||
<label>Whether the timezone should be displayed when the clock is showing the local timezone.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="showSeconds" type="Bool">
|
||||
<label>Whether seconds should be shown in the clock.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="showDate" type="Bool">
|
||||
<label>Whether the date should be shown next to the clock.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="dateFormat" type="string">
|
||||
<label>The date format to display. Options are: shortDate, longDate or isoDate.</label>
|
||||
<default>shortDate</default>
|
||||
</entry>
|
||||
<entry name="fontFamily" type="string">
|
||||
<label>Font family. e.g "arial". The system font is used if this is not set.</label>
|
||||
<default></default>
|
||||
</entry>
|
||||
<entry name="fontSize" type="Int">
|
||||
<label>Font size described in pixels.</label>
|
||||
<default>9</default>
|
||||
</entry>
|
||||
<entry name="boldText" type="Bool">
|
||||
<label>Sets the font to bold.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="italicText" type="Bool">
|
||||
<label>Sets the font to italic.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="timeFormat" type="string">
|
||||
<default>default</default>
|
||||
</entry>
|
||||
<entry name="selectedTimeZones" type="StringList">
|
||||
<label>A list of the time zones available on mouse wheel. Requires wheelChangesTimezone to be true. Format is "Europe/London". Special entry "Local" indicates system time zone.</label>
|
||||
<default>Local</default>
|
||||
</entry>
|
||||
<entry name="lastSelectedTimezone" type="String">
|
||||
<label>When multiple time zones are configured, this is the one shown on widget restore.</label>
|
||||
<default>Local</default>
|
||||
</entry>
|
||||
<entry name="wheelChangesTimezone" type="Bool">
|
||||
<label>Whether the mouse wheel switches between the timezones configured in selectedTimeZones.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="displayTimezoneAsCode" type="Bool">
|
||||
<label>Whether the timezone is displayed as a code i.e. "GMT" or full text i.e. "London".</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="showWeekNumbers" type="Bool">
|
||||
<label>Whether the calendar should show week numbers.</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="firstDayOfWeek" type="Int">
|
||||
<label>Force the calendar to use a specific week day as first day of a week. -1 means follow user locale, 0 is Sunday, 1 is Monday, etc.</label>
|
||||
<default>-1</default>
|
||||
</entry>
|
||||
<entry name="use24hFormat" type="UInt">
|
||||
<label>Force the clock to use 12/24 hour time, instead of following the user locale.</label>
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="enabledCalendarPlugins" type="StringList">
|
||||
<label>A list of plugins where additional calendar event data can be sourced.</label>
|
||||
<default></default>
|
||||
</entry>
|
||||
<entry name="pin" type="Bool">
|
||||
<label>Whether the popup should remain open when another window is activated</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="checkUpdateStartup" type="Bool">
|
||||
<label>Notify for update on startup</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
|
@ -0,0 +1,586 @@
|
|||
/*
|
||||
* 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.15
|
||||
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.workspace.calendar 2.0 as PlasmaCalendar
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
PlasmaCore.Dialog {
|
||||
id: calendar
|
||||
objectName: "popupWindow"
|
||||
flags: Qt.WindowStaysOnTopHint
|
||||
location: PlasmaCore.Types.Floating //To make the dialog float in the corner of the screen
|
||||
hideOnWindowDeactivate: !plasmoid.configuration.pin
|
||||
|
||||
//Used for reading margin values
|
||||
KSvg.FrameSvgItem {
|
||||
id : panelSvg
|
||||
visible: false
|
||||
imagePath: "widgets/panel-background"
|
||||
}
|
||||
KSvg.FrameSvgItem {
|
||||
id : dialogSvg
|
||||
visible: false
|
||||
imagePath: "solid/dialogs/background"
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
popupPosition();
|
||||
monthView.resetToToday();
|
||||
holidaysList.model = null;
|
||||
holidaysList.model = monthView.daysModel.eventsForDate(monthView.currentDate);
|
||||
}
|
||||
onHeightChanged: {
|
||||
popupPosition();
|
||||
}
|
||||
property int flyoutMargin: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing/2
|
||||
|
||||
onWidthChanged: {
|
||||
popupPosition();
|
||||
}
|
||||
|
||||
function popupPosition() {
|
||||
var pos = root.mapToGlobal(root.x, root.y);
|
||||
var availScreen = Plasmoid.containment.availableScreenRect;
|
||||
|
||||
x = pos.x - calendar.width / 2 + root.width / 2
|
||||
y = pos.y - calendar.height;
|
||||
|
||||
if(x <= 0) x += flyoutMargin;
|
||||
if(x + calendar.width >= availScreen.width) {
|
||||
x = availScreen.width - calendar.width - flyoutMargin;
|
||||
|
||||
}
|
||||
if(y <= 0) y += flyoutMargin;
|
||||
if(y + calendar.height >= availScreen.height) {
|
||||
y = availScreen.height - calendar.height - flyoutMargin;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
readonly property bool showAgenda: Plasmoid.configuration.enabledCalendarPlugins.length > 0
|
||||
|
||||
property int _minimumWidth: 336//(showAgenda ? agendaViewWidth : Kirigami.Units.largeSpacing) + monthViewWidth
|
||||
property int _minimumHeight: 247
|
||||
|
||||
readonly property int agendaViewWidth: _minimumHeight
|
||||
readonly property int monthViewWidth: monthView.showWeekNumbers ? Math.round(_minimumHeight * 1.25) : Math.round(_minimumHeight * 1.125)
|
||||
|
||||
property int boxWidth: (agendaViewWidth + monthViewWidth - ((showAgenda ? 3 : 4) * spacing)) / 2
|
||||
|
||||
property int spacing: Kirigami.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();
|
||||
}
|
||||
|
||||
FocusScope {
|
||||
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
Kirigami.Theme.inherit: false
|
||||
Layout.minimumWidth: _minimumWidth
|
||||
Layout.minimumHeight: _minimumHeight
|
||||
Layout.maximumWidth: _minimumWidth
|
||||
Layout.maximumHeight: _minimumHeight
|
||||
Layout.preferredWidth: _minimumWidth
|
||||
Layout.preferredHeight: _minimumHeight
|
||||
|
||||
//colorGroup: PlasmaCore.Theme.ToolTipColorGroup
|
||||
anchors.fill: parent
|
||||
//This is the long date that appears on top of the dialog, pressing on it will set the calendar to the current day.
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: plasmoidFooter.top
|
||||
topMargin: dialogSvg.margins.top + Kirigami.Units.mediumSpacing*2
|
||||
leftMargin: dialogSvg.margins.left + Kirigami.Units.mediumSpacing*2
|
||||
bottomMargin: Kirigami.Units.mediumSpacing*2
|
||||
rightMargin: dialogSvg.margins.right + Kirigami.Units.mediumSpacing*2
|
||||
}
|
||||
PlasmaExtras.Heading {
|
||||
id: longDateLabel
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
/*anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
topMargin: Kirigami.Units.smallSpacing*2
|
||||
}*/
|
||||
width: paintedWidth
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
text: agenda.todayDateString("dddd") + ", " + Qt.locale().standaloneMonthName(monthView.today.getMonth()) + agenda.todayDateString(" dd") + ", " + agenda.todayDateString("yyyy")
|
||||
|
||||
color: "#0066cc" //heading_ma.containsPress ? "#90e7ff" : (heading_ma.containsMouse ? "#b6ffff" : Kirigami.Theme.textColor)
|
||||
font.underline: heading_ma.containsMouse
|
||||
level: 5
|
||||
MouseArea {
|
||||
id: heading_ma
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: monthView.resetToToday()
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
z: 5
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: 0
|
||||
//The calendar itself, on the left side of the dialog
|
||||
Item {
|
||||
id: cal
|
||||
Layout.preferredWidth: 168
|
||||
Layout.preferredHeight: 150
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
Layout.topMargin: Kirigami.Units.largeSpacing + Kirigami.Units.mediumSpacing
|
||||
|
||||
CustomMonthView {
|
||||
id: monthView
|
||||
today: root.tzDate
|
||||
showWeekNumbers: Plasmoid.configuration.showWeekNumbers
|
||||
firstDayOfWeek: Plasmoid.configuration.firstDayOfWeek
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id: testRect
|
||||
visible: !calendar.showAgenda
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.bottomMargin: Kirigami.Units.mediumSpacing
|
||||
Clock {
|
||||
id: clockWidget
|
||||
//anchors.fill: parent
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenterOffset: Kirigami.Units.largeSpacing
|
||||
anchors.verticalCenterOffset: -Kirigami.Units.largeSpacing
|
||||
width: 128
|
||||
height: 128
|
||||
|
||||
//Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
//Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: clockWidget
|
||||
horizontalOffset: 2
|
||||
verticalOffset: 2
|
||||
radius: 3.0
|
||||
color: "#10000000"
|
||||
source: clockWidget
|
||||
|
||||
}
|
||||
Text {
|
||||
id: clockTime
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing*2
|
||||
//anchors.bottomMargin: Kirigami.Units.mediumSpacing
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: Qt.formatTime(clockWidget.currentDate, main.use24hFormat ? "hh:mm:ss" : "h:mm:ss AP")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This is the side panel that appears on the right of the calendar view, showing holidays, events, reminders, etc. in a list.
|
||||
//Replaces the large graphical clock on the right on Windows 7's equivalent panel.
|
||||
Item {
|
||||
id: agenda
|
||||
visible: calendar.showAgenda
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||
|
||||
function todayDateString(format) {
|
||||
return Qt.formatDate(monthView.today, format);
|
||||
}
|
||||
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
|
||||
|
||||
function 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
|
||||
|
||||
function onAgendaUpdated(updatedDate) {
|
||||
// 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
|
||||
|
||||
function onEnabledCalendarPluginsChanged() {
|
||||
PlasmaCalendar.EventPluginsManager.enabledPlugins = Plasmoid.configuration.enabledCalendarPlugins;
|
||||
eventPluginsManager.enabledPlugins = Plasmoid.configuration.enabledCalendarPlugins;
|
||||
//console.log(PlasmaCalendar.EventPluginsManager.enabledPlugins);
|
||||
//console.log(eventPluginsManager.enabledPlugins);
|
||||
}
|
||||
}
|
||||
|
||||
/*Binding {
|
||||
target: Plasmoid
|
||||
property: "hideOnWindowDeactivate"
|
||||
value: !Plasmoid.configuration.pin
|
||||
}*/
|
||||
|
||||
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: Kirigami.Theme.defaultFont
|
||||
text: timeString.length > dateString.length ? timeString : dateString
|
||||
}
|
||||
|
||||
PlasmaComponents3.ScrollView {
|
||||
id: holidaysView
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: holidaysList
|
||||
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
highlightFollowsCurrentItem: false
|
||||
highlight: Item {
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
delegate: PlasmaComponents3.ItemDelegate {
|
||||
id: eventItem
|
||||
width: parent.width
|
||||
height: eventGrid.height
|
||||
|
||||
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 {
|
||||
|
||||
//anchors.fill: parent
|
||||
width: parent.width
|
||||
height: eventGrid.height
|
||||
active: eventTitle.truncated || eventDescription.truncated
|
||||
mainText: active ? eventTitle.text : ""
|
||||
subText: active ? eventDescription.text : ""
|
||||
textFormat: Text.RichText
|
||||
|
||||
GridLayout {
|
||||
id: eventGrid
|
||||
columns: 3
|
||||
rows: 2
|
||||
rowSpacing: 0
|
||||
columnSpacing: Kirigami.Units.smallSpacing
|
||||
|
||||
width: parent.width
|
||||
|
||||
Rectangle {
|
||||
id: eventColor
|
||||
|
||||
Layout.row: 0
|
||||
Layout.column: 0
|
||||
Layout.rowSpan: 2
|
||||
Layout.fillHeight: true
|
||||
|
||||
color: modelData.eventColor
|
||||
width: 3
|
||||
visible: modelData.eventColor !== ""
|
||||
}
|
||||
|
||||
PlasmaComponents3.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
|
||||
}
|
||||
|
||||
PlasmaComponents3.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
|
||||
}
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
id: eventTitle
|
||||
|
||||
readonly property bool wrap: eventDescription.text === ""
|
||||
|
||||
Layout.row: 0
|
||||
Layout.rowSpan: wrap ? 2 : 1
|
||||
Layout.column: 2
|
||||
Layout.fillWidth: true
|
||||
|
||||
|
||||
elide: Text.ElideRight
|
||||
text: modelData.title
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
maximumLineCount: 2
|
||||
wrapMode: wrap ? Text.Wrap : Text.NoWrap
|
||||
}
|
||||
TextEdit {
|
||||
id: descriptionHelper
|
||||
visible: false
|
||||
text: modelData.description
|
||||
textFormat: Text.RichText
|
||||
}
|
||||
PlasmaComponents3.Label {
|
||||
id: eventDescription
|
||||
|
||||
Layout.row: 1
|
||||
Layout.column: 2
|
||||
Layout.fillWidth: true
|
||||
|
||||
elide: Text.ElideRight
|
||||
text: descriptionHelper.getText(0, descriptionHelper.length)
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
enabled: false
|
||||
textFormat: Text.PlainText
|
||||
maximumLineCount: 1
|
||||
|
||||
visible: text !== ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section.property: "eventType"
|
||||
section.delegate:
|
||||
PlasmaExtras.Heading {
|
||||
width: holidaysList.width
|
||||
bottomPadding: Kirigami.Units.smallSpacing
|
||||
level: 5
|
||||
elide: Text.ElideRight
|
||||
text: section
|
||||
font.weight: Font.Bold
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaExtras.Heading {
|
||||
anchors.fill: holidaysView
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
//anchors.rightMargin: Kirigami.Units.largeSpacing
|
||||
text: monthView.isToday(monthView.currentDate) ? i18n("No events for today") + "\n"
|
||||
: i18n("No events for this day") + "\n";
|
||||
level: 5
|
||||
opacity: 0.8
|
||||
visible: holidaysList.count == 0
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: plasmoidFooter
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: dialogSvg.margins.left
|
||||
rightMargin: dialogSvg.margins.right
|
||||
bottomMargin: dialogSvg.margins.bottom
|
||||
|
||||
}
|
||||
//visible: container.appletHasFooter
|
||||
height: 40 + Kirigami.Units.smallSpacing / 2 //+ container.footerHeight + Kirigami.Units.smallSpacing
|
||||
//height: trayHeading.height + container.headingHeight + (container.headingHeight === 0 ? 0 : Kirigami.Units.smallSpacing/2)
|
||||
color: "#f1f5fb"
|
||||
Rectangle {
|
||||
id: plasmoidFooterBorder
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: "#ccd9ea" }
|
||||
GradientStop { position: 1.0; color: "#f1f5fb" }
|
||||
}
|
||||
height: Kirigami.Units.smallSpacing
|
||||
}
|
||||
|
||||
PlasmaExtras.Heading {
|
||||
id: settingsLink
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "Change date and time settings..."
|
||||
color: "#0066cc" //heading_ma.containsPress ? "#90e7ff" : (heading_ma.containsMouse ? "#b6ffff" : Kirigami.Theme.textColor)
|
||||
font.underline: link_ma.containsMouse
|
||||
level: 5
|
||||
MouseArea {
|
||||
id: link_ma
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: Plasmoid.internalAction("configure").trigger()
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
z: 5
|
||||
}
|
||||
}
|
||||
z: -9999
|
||||
}
|
||||
ToolButton {
|
||||
id: pinButton
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: dialogSvg.margins.right + Kirigami.Units.mediumSpacing + 2
|
||||
anchors.bottomMargin: dialogSvg.margins.bottom + Kirigami.Units.mediumSpacing + 2
|
||||
width: Kirigami.Units.iconSizes.small+1;
|
||||
height: Kirigami.Units.iconSizes.small;
|
||||
checkable: true
|
||||
checked: Plasmoid.configuration.pin
|
||||
|
||||
onClicked: (mouse) => {
|
||||
Plasmoid.configuration.pin = !Plasmoid.configuration.pin;
|
||||
}
|
||||
buttonIcon: "pin"
|
||||
|
||||
z: 9999
|
||||
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
calendar.backgroundHints = 2; //Sets the background type to 'Solid' in order to make use of the alternative dialog style.
|
||||
//The same is done to the system tray, giving the two plasmoids a consistent look and feel.
|
||||
popupPosition();
|
||||
//x = pos.x;
|
||||
//y = pos.y;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.15
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.kirigami 2.5 as Kirigami // For Settings.tabletMode
|
||||
|
||||
Item {
|
||||
id: clockItem
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
|
||||
property date currentDate: {
|
||||
// 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
|
||||
var currentTime = new Date(msUTC + (dataSource.data[Plasmoid.configuration.lastSelectedTimezone]["Offset"] * 1000));
|
||||
return currentTime
|
||||
}
|
||||
KSvg.SvgItem {
|
||||
id: clockface
|
||||
svg: clockSvg
|
||||
elementId: "clockface"
|
||||
anchors.fill: parent
|
||||
/*anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Rects
|
||||
Rectangle {
|
||||
id: secondHand
|
||||
color: "#bf546770"
|
||||
width: 1
|
||||
height: 65
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: 15
|
||||
anchors.horizontalCenterOffset: 1
|
||||
antialiasing: true
|
||||
transform: Rotation {
|
||||
origin.x: 0
|
||||
origin.y: 18
|
||||
angle: 360 * (currentDate.getSeconds() / 60) + 180
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: minuteHand
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0; color: "#df5c6c74" }
|
||||
GradientStop { position: 0.5; color: "#ef5c6c74" }
|
||||
GradientStop { position: 1; color: "#df5c6c74" }
|
||||
}
|
||||
radius: 1
|
||||
//color: "#bf546770"
|
||||
width: 2
|
||||
height: 47
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: minuteHand.height/2
|
||||
anchors.horizontalCenterOffset: currentDate.getMinutes() > 45 || currentDate.getMinutes() <= 15 ? 2 : 0
|
||||
antialiasing: true
|
||||
transform: Rotation {
|
||||
origin.x: 0
|
||||
origin.y: 0
|
||||
angle: 360 * (currentDate.getMinutes() / 60) + 180
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: hourHand
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0; color: "#df5c6c74" }
|
||||
GradientStop { position: 0.5; color: "#ef5c6c74" }
|
||||
GradientStop { position: 1; color: "#df5c6c74" }
|
||||
}
|
||||
radius: 1
|
||||
//color: "#bf546770"
|
||||
width: 2
|
||||
height: 36
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: hourHand.height/2
|
||||
anchors.horizontalCenterOffset: 1
|
||||
antialiasing: true
|
||||
transform: Rotation {
|
||||
origin.x: 0
|
||||
origin.y: 0
|
||||
angle: 360 * ((currentDate.getHours() % 12) / 12 + currentDate.getMinutes() / (12*60)) + 180
|
||||
}
|
||||
}
|
||||
KSvg.SvgItem {
|
||||
id: clockdot
|
||||
svg: clockSvg
|
||||
elementId: "clockdot"
|
||||
width: 5
|
||||
height: 5
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
KSvg.SvgItem {
|
||||
id: clockshine
|
||||
svg: clockSvg
|
||||
elementId: "clockshine"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Heena Mahour <heena393@gmail.com>
|
||||
SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
|
||||
SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de>
|
||||
SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import org.kde.plasma.workspace.calendar 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Item { // TODO KF6 switch to Item
|
||||
id: root
|
||||
|
||||
//anchors.fill: parent // TODO KF6 don't use anchors
|
||||
|
||||
//enabled: false
|
||||
|
||||
/**
|
||||
* Currently selected month name.
|
||||
* \property string MonthView::selectedMonth
|
||||
*/
|
||||
property alias selectedMonth: calendarBackend.monthName
|
||||
/**
|
||||
* Currently selected month year.
|
||||
* \property int MonthView::selectedYear
|
||||
*/
|
||||
property alias selectedYear: calendarBackend.year
|
||||
/**
|
||||
* The start day of a week.
|
||||
* \property int MonthView::firstDayOfWeek
|
||||
* \sa Calendar::firstDayOfWeek
|
||||
*/
|
||||
property alias firstDayOfWeek: calendarBackend.firstDayOfWeek
|
||||
|
||||
property QtObject date
|
||||
property date currentDate
|
||||
|
||||
property date showDate: new Date()
|
||||
|
||||
property int borderWidth: 1
|
||||
property real borderOpacity: 0.4
|
||||
|
||||
property int columns: calendarBackend.days
|
||||
property int rows: calendarBackend.weeks
|
||||
|
||||
property Item selectedItem
|
||||
property int week;
|
||||
property int firstDay: new Date(showDate.getFullYear(), showDate.getMonth(), 1).getDay()
|
||||
property alias today: calendarBackend.today
|
||||
property bool showWeekNumbers: false
|
||||
property bool showCustomHeader: false
|
||||
|
||||
/**
|
||||
* SwipeView currentIndex needed for binding a TabBar to the MonthView.
|
||||
*/
|
||||
property int currentIndex: swipeView.currentIndex
|
||||
|
||||
property alias cellHeight: mainDaysCalendar.cellHeight
|
||||
property QtObject daysModel: calendarBackend.daysModel
|
||||
|
||||
function isToday(date) {
|
||||
return date.toDateString() === new Date().toDateString();
|
||||
}
|
||||
|
||||
function eventDate(yearNumber,monthNumber,dayNumber) {
|
||||
const d = new Date(yearNumber, monthNumber-1, dayNumber);
|
||||
return Qt.formatDate(d, "dddd dd MMM yyyy");
|
||||
}
|
||||
|
||||
/**
|
||||
* Move calendar to month view showing today's date.
|
||||
*/
|
||||
function resetToToday() {
|
||||
calendarBackend.resetToToday();
|
||||
root.currentDate = root.today;
|
||||
swipeView.currentIndex = 0;
|
||||
}
|
||||
|
||||
function updateYearOverview() {
|
||||
const date = calendarBackend.displayedDate;
|
||||
const day = date.getDate();
|
||||
const year = date.getFullYear();
|
||||
|
||||
for (let i = 0, j = monthModel.count; i < j; ++i) {
|
||||
monthModel.setProperty(i, "yearNumber", year);
|
||||
}
|
||||
}
|
||||
|
||||
function updateDecadeOverview() {
|
||||
const date = calendarBackend.displayedDate;
|
||||
const day = date.getDate();
|
||||
const month = date.getMonth() + 1;
|
||||
const year = date.getFullYear();
|
||||
const decade = year - year % 10;
|
||||
|
||||
for (let i = 0, j = yearModel.count; i < j; ++i) {
|
||||
const label = decade - 1 + i;
|
||||
yearModel.setProperty(i, "yearNumber", label);
|
||||
yearModel.setProperty(i, "label", label);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible calendar views
|
||||
*/
|
||||
enum CalendarView {
|
||||
DayView,
|
||||
MonthView,
|
||||
YearView
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to the next month/year/decade depending on the current
|
||||
* calendar view displayed.
|
||||
*/
|
||||
function nextView() {
|
||||
if (swipeView.currentIndex === 0) {
|
||||
calendarBackend.nextMonth();
|
||||
} else if (swipeView.currentIndex === 1) {
|
||||
calendarBackend.nextYear();
|
||||
} else if (swipeView.currentIndex === 2) {
|
||||
calendarBackend.nextDecade();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to the previous month/year/decade depending on the current
|
||||
* calendar view displayed.
|
||||
*/
|
||||
function previousView() {
|
||||
if (swipeView.currentIndex === 0) {
|
||||
calendarBackend.previousMonth();
|
||||
} else if (swipeView.currentIndex === 1) {
|
||||
calendarBackend.previousYear();
|
||||
} else if (swipeView.currentIndex === 2) {
|
||||
calendarBackend.previousDecade();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \return CalendarView
|
||||
*/
|
||||
readonly property var calendarViewDisplayed: {
|
||||
if (swipeView.currentIndex === 0) {
|
||||
return MonthView.CalendarView.DayView;
|
||||
} else if (swipeView.currentIndex === 1) {
|
||||
return MonthView.CalendarView.MonthView;
|
||||
} else if (swipeView.currentIndex === 2) {
|
||||
return MonthView.CalendarView.YearView;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show month view.
|
||||
*/
|
||||
function showMonthView() {
|
||||
swipeView.currentIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show year view.
|
||||
*/
|
||||
function showYearView() {
|
||||
swipeView.currentIndex = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show month view.
|
||||
*/
|
||||
function showDecadeView() {
|
||||
swipeView.currentIndex = 2;
|
||||
}
|
||||
|
||||
//property QtObject eventPluginsManager: EventPluginsManager {}
|
||||
|
||||
Calendar {
|
||||
id: calendarBackend
|
||||
|
||||
days: 7
|
||||
weeks: 6
|
||||
firstDayOfWeek: Qt.locale().firstDayOfWeek
|
||||
today: root.today
|
||||
|
||||
Component.onCompleted: {
|
||||
daysModel.setPluginsManager(eventPluginsManager);
|
||||
}
|
||||
|
||||
onYearChanged: {
|
||||
updateYearOverview()
|
||||
updateDecadeOverview()
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: monthModel
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 12; ++i) {
|
||||
append({
|
||||
label: Qt.locale(Qt.locale().uiLanguages[0]).standaloneMonthName(i, Locale.LongFormat),
|
||||
monthNumber: i + 1,
|
||||
yearNumber: 2050,
|
||||
isCurrent: true
|
||||
})
|
||||
}
|
||||
updateYearOverview()
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: yearModel
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 12; ++i) {
|
||||
append({
|
||||
label: 2050, // this value will be overwritten, but it set the type of the property to int
|
||||
yearNumber: 2050,
|
||||
isCurrent: (i > 0 && i < 11) // first and last year are outside the decade
|
||||
})
|
||||
}
|
||||
updateDecadeOverview()
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: viewHeader
|
||||
visible: !showCustomHeader
|
||||
// Make sure the height of the invisible item is zero, otherwise anchoring to the item will
|
||||
// include the height even if it is invisible.
|
||||
height: !visible ? 0 : implicitHeight
|
||||
width: parent.width
|
||||
anchors {
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
|
||||
|
||||
ToolButton {
|
||||
id: previousButton
|
||||
flat: true
|
||||
buttonIcon: (previousButton.containsMouse && !previousButton.containsPress) ? "left-active" : "left"
|
||||
onClicked: root.previousView()
|
||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||
|
||||
}
|
||||
|
||||
PlasmaExtras.Heading {
|
||||
id: heading
|
||||
text: {
|
||||
if(swipeView.currentIndex == 0)
|
||||
return i18ndc("libplasma5", "Format: month year", "%1, %2", root.selectedMonth, root.selectedYear.toString());
|
||||
else if(swipeView.currentIndex == 1)
|
||||
return i18ndc("libplasma5", "Format: year", "%1", root.selectedYear.toString());
|
||||
else if(swipeView.currentIndex == 2) {
|
||||
var decade = root.selectedYear - root.selectedYear % 10;
|
||||
var nextDecade = decade+9;
|
||||
return i18ndc("libplasma5", "Format: year-year", "%1-%2", decade.toString(), nextDecade.toString());
|
||||
}
|
||||
|
||||
}
|
||||
level: 5
|
||||
font.capitalization: Font.Capitalize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
color: heading_ma.containsMouse && !heading_ma.containsPress ? "#0066cc" : Kirigami.Theme.textColor
|
||||
|
||||
MouseArea {
|
||||
id: heading_ma
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: if(swipeView.currentIndex != 2) swipeView.currentIndex++;
|
||||
//cursorShape: Qt.PointingHandCursor
|
||||
z: 5
|
||||
}
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
id: nextButton
|
||||
flat: true
|
||||
buttonIcon: (nextButton.containsMouse && !nextButton.containsPress) ? "right-active" : "right"
|
||||
onClicked: root.nextView()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PlasmaComponents3.SwipeView {
|
||||
id: swipeView
|
||||
anchors {
|
||||
top: viewHeader.bottom
|
||||
topMargin: Kirigami.Units.mediumSpacing
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
clip: true
|
||||
|
||||
onCurrentIndexChanged: if (currentIndex > 1) {
|
||||
updateDecadeOverview();
|
||||
}
|
||||
|
||||
// MonthView
|
||||
DaysCalendar {
|
||||
id: mainDaysCalendar
|
||||
|
||||
columns: calendarBackend.days
|
||||
rows: calendarBackend.weeks
|
||||
|
||||
showWeekNumbers: root.showWeekNumbers
|
||||
|
||||
headerModel: calendarBackend.days
|
||||
gridModel: calendarBackend.daysModel
|
||||
|
||||
dateMatchingPrecision: Calendar.MatchYearMonthAndDay
|
||||
|
||||
onActivated: (index, date) => {
|
||||
const rowNumber = Math.floor(index / columns);
|
||||
week = 1 + calendarBackend.weeksModel[rowNumber];
|
||||
root.currentDate = new Date(date.yearNumber, date.monthNumber - 1, date.dayNumber)
|
||||
}
|
||||
|
||||
onScrollUp: root.nextView()
|
||||
onScrollDown: root.previousView()
|
||||
}
|
||||
|
||||
// YearView
|
||||
DaysCalendar {
|
||||
columns: 4
|
||||
rows: 3
|
||||
|
||||
dateMatchingPrecision: Calendar.MatchYearAndMonth
|
||||
|
||||
gridModel: monthModel
|
||||
onActivated: (index, date, item) => {
|
||||
calendarBackend.goToMonth(date.monthNumber);
|
||||
swipeView.currentIndex = 0;
|
||||
}
|
||||
|
||||
onScrollUp: calendarBackend.nextYear()
|
||||
onScrollDown: calendarBackend.previousYear()
|
||||
}
|
||||
|
||||
// DecadeView
|
||||
DaysCalendar {
|
||||
readonly property int decade: {
|
||||
const year = calendarBackend.displayedDate.getFullYear()
|
||||
return year - year % 10
|
||||
}
|
||||
|
||||
columns: 4
|
||||
rows: 3
|
||||
|
||||
dateMatchingPrecision: Calendar.MatchYear
|
||||
|
||||
gridModel: yearModel
|
||||
onActivated: (index, date, item) => {
|
||||
calendarBackend.goToYear(date.yearNumber);
|
||||
swipeView.currentIndex = 1;
|
||||
}
|
||||
|
||||
onScrollUp: calendarBackend.nextDecade()
|
||||
onScrollDown: calendarBackend.previousDecade()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.currentDate = calendarBackend.today
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Heena Mahour <heena393@gmail.com>
|
||||
SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
|
||||
SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de>
|
||||
SPDX-FileCopyrightText: 2021 Jan Blackquill <uhhadd@gmail.com>
|
||||
SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
import QtQuick 2.2
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import QtQml.Models 2.15
|
||||
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.ksvg as KSvg
|
||||
import org.kde.plasma.workspace.calendar 2.0
|
||||
|
||||
PlasmaComponents3.AbstractButton {
|
||||
id: dayStyle
|
||||
|
||||
hoverEnabled: true
|
||||
property var dayModel: null
|
||||
|
||||
signal activated
|
||||
|
||||
|
||||
readonly property date thisDate: new Date(yearNumber, typeof monthNumber !== "undefined" ? monthNumber - 1 : 0, typeof dayNumber !== "undefined" ? dayNumber : 1)
|
||||
readonly property bool today: {
|
||||
const today = root.today;
|
||||
let result = true;
|
||||
if (dateMatchingPrecision >= Calendar.MatchYear) {
|
||||
result = result && today.getFullYear() === thisDate.getFullYear()
|
||||
}
|
||||
if (dateMatchingPrecision >= Calendar.MatchYearAndMonth) {
|
||||
result = result && today.getMonth() === thisDate.getMonth()
|
||||
}
|
||||
if (dateMatchingPrecision >= Calendar.MatchYearMonthAndDay) {
|
||||
result = result && today.getDate() === thisDate.getDate()
|
||||
}
|
||||
return result
|
||||
}
|
||||
readonly property bool selected: {
|
||||
const current = root.currentDate;
|
||||
let result = true;
|
||||
if (dateMatchingPrecision >= Calendar.MatchYear) {
|
||||
result = result && current.getFullYear() === thisDate.getFullYear()
|
||||
}
|
||||
if (dateMatchingPrecision >= Calendar.MatchYearAndMonth) {
|
||||
result = result && current.getMonth() === thisDate.getMonth()
|
||||
}
|
||||
if (dateMatchingPrecision >= Calendar.MatchYearMonthAndDay) {
|
||||
result = result && current.getDate() === thisDate.getDate()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
PlasmaExtras.Highlight {
|
||||
id: todayRect
|
||||
anchors.fill: parent
|
||||
hovered: true
|
||||
opacity: {
|
||||
if (today && !dayStyle.hovered && !selected) {
|
||||
return 0;
|
||||
} else if (selected) {
|
||||
return 0.8;
|
||||
} else if (dayStyle.pressed) {
|
||||
return 0.3;
|
||||
} else if (dayStyle.hovered) {
|
||||
return 0.6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
z: -1;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: currentDayRect
|
||||
anchors.fill: parent
|
||||
visible: today
|
||||
radius: 2
|
||||
border.color: "#0066cc"
|
||||
color: "transparent"
|
||||
}
|
||||
contentItem: PlasmaExtras.Heading {
|
||||
id: label
|
||||
horizontalAlignment: dateMatchingPrecision != Calendar.MatchYearMonthAndDay ? Text.AlignHCenter: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
bottomPadding: dateMatchingPrecision != Calendar.MatchYearMonthAndDay ? 0 : 1
|
||||
rightPadding: dateMatchingPrecision != Calendar.MatchYearMonthAndDay ? 0 : Kirigami.Units.smallSpacing+1
|
||||
wrapMode: Text.NoWrap
|
||||
elide: Text.ElideRight
|
||||
font.bold: calendar.showAgenda && model.eventCount !== undefined && model.eventCount > 0
|
||||
fontSizeMode: Text.Fit
|
||||
|
||||
color: today || (!dayStyle.pressed && dayStyle.hovered) ? "#0066cc" : Kirigami.Theme.textColor
|
||||
|
||||
text: {
|
||||
if(model.label) {
|
||||
if(dateMatchingPrecision == Calendar.MatchYearAndMonth) return model.label.substring(0, 3);
|
||||
return model.label;
|
||||
}
|
||||
return dayNumber;
|
||||
}
|
||||
opacity: isCurrent ? 1.0 : 0.5
|
||||
level: 5
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Heena Mahour <heena393@gmail.com>
|
||||
SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
|
||||
SPDX-FileCopyrightText: 2015, 2016 Kai Uwe Broulik <kde@privat.broulik.de>
|
||||
SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls as QQC1
|
||||
|
||||
import org.kde.plasma.workspace.calendar 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.ksvg as KSvg
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Item {
|
||||
id: daysCalendar
|
||||
|
||||
signal headerClicked
|
||||
signal scrollUp
|
||||
signal scrollDown
|
||||
signal activated(int index, var date, var item)
|
||||
// so it forwards it to the delegate which then emits activated with all the necessary data
|
||||
signal activateHighlightedItem
|
||||
|
||||
readonly property int gridColumns: showWeekNumbers ? calendarGrid.columns + 1 : calendarGrid.columns
|
||||
|
||||
property int rows
|
||||
property int columns
|
||||
|
||||
property bool showWeekNumbers
|
||||
|
||||
// how precise date matching should be, 3 = day+month+year, 2 = month+year, 1 = just year
|
||||
property int dateMatchingPrecision
|
||||
|
||||
property alias headerModel: days.model
|
||||
property alias gridModel: repeater.model
|
||||
|
||||
// Take the calendar width, subtract the inner and outer spacings and divide by number of columns (==days in week)
|
||||
readonly property int cellWidth: Math.floor((swipeView.width - (daysCalendar.columns + 1) * root.borderWidth) / (daysCalendar.columns + (showWeekNumbers ? 1 : 0)))
|
||||
// Take the calendar height, subtract the inner spacings and divide by number of rows (root.weeks + one row for day names)
|
||||
readonly property int cellHeight: Math.floor((swipeView.height - heading.height - calendarGrid.rows * root.borderWidth) / calendarGrid.rows)
|
||||
|
||||
KSvg.Svg {
|
||||
id: calendarSvg
|
||||
imagePath: "widgets/calendar"
|
||||
}
|
||||
|
||||
Column {
|
||||
id: weeksColumn
|
||||
visible: showWeekNumbers
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
// The borderWidth needs to be counted twice here because it goes
|
||||
// in fact through two lines - the topmost one (the outer edge)
|
||||
// and then the one below weekday strings
|
||||
topMargin: daysCalendar.cellHeight + root.borderWidth + root.borderWidth
|
||||
}
|
||||
spacing: root.borderWidth
|
||||
|
||||
Repeater {
|
||||
model: showWeekNumbers ? calendarBackend.weeksModel : []
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
height: daysCalendar.cellHeight
|
||||
width: daysCalendar.cellWidth
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
opacity: 0.4
|
||||
text: modelData
|
||||
font.pixelSize: Math.max(Kirigami.Theme.smallestFont.pixelSize, daysCalendar.cellHeight / 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: days.count > 0
|
||||
anchors.top: calendarGrid.top
|
||||
anchors.topMargin: daysCalendar.cellHeight
|
||||
height: 1
|
||||
anchors.left: calendarGrid.left
|
||||
anchors.right: calendarGrid.right
|
||||
color: "#f5f5f5"
|
||||
}
|
||||
Grid {
|
||||
id: calendarGrid
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
rightMargin: root.borderWidth
|
||||
bottom: parent.bottom
|
||||
bottomMargin: root.borderWidth
|
||||
}
|
||||
|
||||
columns: daysCalendar.columns
|
||||
rows: daysCalendar.rows + (daysCalendar.headerModel ? 1 : 0)
|
||||
|
||||
spacing: 0//root.borderWidth
|
||||
columnSpacing: parent.squareCell ? (daysCalendar.width - daysCalendar.columns * (daysCalendar.cellWidth - root.borderWidth)) / daysCalendar.columns : root.borderWidth
|
||||
property bool containsEventItems: false // FIXME
|
||||
property bool containsTodoItems: false // FIXME
|
||||
|
||||
Repeater {
|
||||
id: days
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
width: daysCalendar.cellWidth
|
||||
height: daysCalendar.cellHeight
|
||||
text: (Qt.locale(Qt.locale().uiLanguages[0]).dayName(((calendarBackend.firstDayOfWeek + index) % days.count), Locale.ShortFormat)).substring(0, 2);
|
||||
font.pixelSize: Math.max(Kirigami.Theme.smallestFont.pixelSize, daysCalendar.cellHeight / 3)
|
||||
//opacity: 0.8
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
fontSizeMode: Text.HorizontalFit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
|
||||
DayDelegate {
|
||||
id: delegate
|
||||
width: daysCalendar.cellWidth
|
||||
height: daysCalendar.cellHeight
|
||||
dayModel: repeater.model
|
||||
|
||||
Connections {
|
||||
target: daysCalendar
|
||||
function onActivateHighlightedItem(delegate) {
|
||||
if (delegate.containsMouse) {
|
||||
delegate.clicked(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
daysCalendar.activated(index, model, delegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,788 @@
|
|||
/*
|
||||
* 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.plasmoid
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||
import org.kde.plasma.private.digitalclock 1.0
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.ksvg as KSvg
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Item {
|
||||
id: main
|
||||
|
||||
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 int dateFormat: {
|
||||
if (Plasmoid.configuration.dateFormat === "longDate") {
|
||||
return Qt.SystemLocaleLongDate;
|
||||
} else if (Plasmoid.configuration.dateFormat === "isoDate") {
|
||||
return Qt.ISODate;
|
||||
}
|
||||
|
||||
return Qt.SystemLocaleShortDate;
|
||||
}
|
||||
|
||||
property string lastSelectedTimezone: Plasmoid.configuration.lastSelectedTimezone
|
||||
property bool displayTimezoneAsCode: Plasmoid.configuration.displayTimezoneAsCode
|
||||
property int use24hFormat: Plasmoid.configuration.use24hFormat
|
||||
|
||||
property string lastDate: ""
|
||||
property int tzOffset
|
||||
|
||||
// This is the index in the list of user selected timezones
|
||||
property int tzIndex: 0
|
||||
|
||||
// if the date/timezone cannot be fit with the smallest font to its designated space
|
||||
readonly property bool oneLineMode: Plasmoid.formFactor == PlasmaCore.Types.Horizontal &&
|
||||
main.height <= 2 * Kirigami.Theme.smallestFont.pixelSize &&
|
||||
(main.showDate || timezoneLabel.visible)
|
||||
|
||||
property QtObject dashWindow: null
|
||||
|
||||
function getCurrentTime(): date {
|
||||
const data = dataSource.data[Plasmoid.configuration.lastSelectedTimezone];
|
||||
// The order of signal propagation is unspecified, so we might get
|
||||
// here before the dataSource has updated. Alternatively, a buggy
|
||||
// configuration view might set lastSelectedTimezone to a new time
|
||||
// zone before applying the new list, or it may just be set to
|
||||
// something invalid in the config file.
|
||||
if (data === undefined) {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
// get the time for the given time zone from the dataengine
|
||||
const now = data["DateTime"];
|
||||
// get current UTC time
|
||||
const msUTC = now.getTime() + (now.getTimezoneOffset() * 60000);
|
||||
// add the dataengine TZ offset to it
|
||||
const currentTime = new Date(msUTC + (data["Offset"] * 1000));
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
|
||||
onDateFormatChanged: {
|
||||
setupLabels();
|
||||
}
|
||||
|
||||
onDisplayTimezoneAsCodeChanged: { setupLabels(); }
|
||||
onStateChanged: { 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.configuration
|
||||
function onSelectedTimeZonesChanged() {
|
||||
// If the currently selected timezone was removed,
|
||||
// default to the first one in the list
|
||||
var lastSelectedTimezone = Plasmoid.configuration.lastSelectedTimezone;
|
||||
if (Plasmoid.configuration.selectedTimeZones.indexOf(lastSelectedTimezone) == -1) {
|
||||
Plasmoid.configuration.lastSelectedTimezone = Plasmoid.configuration.selectedTimeZones[0];
|
||||
}
|
||||
|
||||
setupLabels();
|
||||
setTimezoneIndex();
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "horizontalPanel"
|
||||
when: Plasmoid.formFactor == PlasmaCore.Types.Horizontal && !main.oneLineMode
|
||||
|
||||
PropertyChanges {
|
||||
target: main
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: false
|
||||
Layout.minimumWidth: contentItem.width + 2
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: contentItem
|
||||
|
||||
height: timeLabel.height + (main.showDate || timezoneLabel.visible ? 0.8 * timeLabel.height : 0)
|
||||
width: Math.max(labelsGrid.width, timezoneLabel.paintedWidth, dateLabel.paintedWidth)
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: labelsGrid
|
||||
|
||||
rows: main.showDate ? 1 : 2
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: labelsGrid
|
||||
|
||||
anchors.horizontalCenter: contentItem.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timeLabel
|
||||
|
||||
height: sizehelper.height
|
||||
//width: sizehelper.contentWidth
|
||||
|
||||
font.pointSize: Math.min(Plasmoid.configuration.fontSize || Kirigami.Theme.defaultFont.pointSize, Math.round(timeLabel.height * 72 / 96))
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timezoneLabel
|
||||
|
||||
//height: main.showDate ? 0.7 * timeLabel.height : 0.8 * timeLabel.height
|
||||
//width: main.showDate ? timezoneLabel.paintedWidth : timeLabel.width
|
||||
|
||||
font.pointSize: Math.min(Plasmoid.configuration.fontSize || Kirigami.Theme.defaultFont.pointSize, Math.round(timezoneLabel.height * 72 / 96))
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: dateLabel
|
||||
|
||||
height: 0.8 * timeLabel.height
|
||||
width: dateLabel.paintedWidth
|
||||
|
||||
font.pointSize: Math.min(Plasmoid.configuration.fontSize || Kirigami.Theme.defaultFont.pointSize, Math.round(dateLabel.height * 72 / 96))
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: dateLabel
|
||||
|
||||
anchors.top: labelsGrid.bottom
|
||||
anchors.horizontalCenter: labelsGrid.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: sizehelper
|
||||
|
||||
/*
|
||||
* The value 0.71 was picked by testing to give the clock the right
|
||||
* size (aligned with tray icons).
|
||||
* Value 0.56 seems to be chosen rather arbitrary as well such that
|
||||
* the time label is slightly larger than the date or timezone label
|
||||
* and still fits well into the panel with all the applied margins.
|
||||
*/
|
||||
height: Math.min(main.showDate || timezoneLabel.visible ? main.height * 0.56 : main.height * 0.71,
|
||||
3 * Kirigami.Theme.defaultFont.pixelSize)
|
||||
|
||||
font.pixelSize: sizehelper.height
|
||||
}
|
||||
},
|
||||
|
||||
State {
|
||||
name: "horizontalPanelSmall"
|
||||
when: Plasmoid.formFactor == PlasmaCore.Types.Horizontal && main.oneLineMode
|
||||
|
||||
PropertyChanges {
|
||||
target: main
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: false
|
||||
Layout.minimumWidth: contentItem.width
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: contentItem
|
||||
|
||||
height: sizehelper.height
|
||||
width: dateLabel.width + dateLabel.anchors.rightMargin + labelsGrid.width
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: labelsGrid
|
||||
|
||||
anchors.right: contentItem.right
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: dateLabel
|
||||
|
||||
height: timeLabel.height
|
||||
width: dateLabel.paintedWidth
|
||||
|
||||
anchors.rightMargin: labelsGrid.columnSpacing
|
||||
|
||||
fontSizeMode: Text.VerticalFit
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: dateLabel
|
||||
|
||||
anchors.right: labelsGrid.left
|
||||
anchors.verticalCenter: labelsGrid.verticalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timeLabel
|
||||
|
||||
height: sizehelper.height
|
||||
width: sizehelper.contentWidth
|
||||
|
||||
fontSizeMode: Text.VerticalFit
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timezoneLabel
|
||||
|
||||
height: 0.7 * timeLabel.height
|
||||
width: timezoneLabel.paintedWidth
|
||||
|
||||
fontSizeMode: Text.VerticalFit
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: sizehelper
|
||||
|
||||
height: Math.min(main.height, 3 * Kirigami.Theme.defaultFont.pixelSize)
|
||||
|
||||
fontSizeMode: Text.VerticalFit
|
||||
font.pixelSize: 3 * Kirigami.Theme.defaultFont.pixelSize
|
||||
}
|
||||
},
|
||||
|
||||
State {
|
||||
name: "verticalPanel"
|
||||
when: Plasmoid.formFactor == PlasmaCore.Types.Vertical
|
||||
|
||||
PropertyChanges {
|
||||
target: main
|
||||
Layout.fillHeight: false
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumHeight: contentItem.height
|
||||
Layout.minimumHeight: Layout.maximumHeight
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: contentItem
|
||||
|
||||
height: main.showDate ? labelsGrid.height + dateLabel.height : labelsGrid.height
|
||||
width: main.width
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: labelsGrid
|
||||
|
||||
rows: 2
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timeLabel
|
||||
|
||||
height: sizehelper.contentHeight
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.HorizontalFit
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timezoneLabel
|
||||
|
||||
height: Math.max(0.7 * timeLabel.height, minimumPixelSize)
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: dateLabel.minimumPixelSize
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: dateLabel
|
||||
|
||||
// this can be marginal bigger than contentHeight because of the horizontal fit
|
||||
height: Math.max(0.8 * timeLabel.height, minimumPixelSize)
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: Math.min(0.7 * Kirigami.Theme.smallestFont.pixelSize, timeLabel.height)
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: dateLabel
|
||||
|
||||
anchors.top: labelsGrid.bottom
|
||||
anchors.horizontalCenter: labelsGrid.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: sizehelper
|
||||
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.HorizontalFit
|
||||
font.pixelSize: 3 * Kirigami.Theme.defaultFont.pixelSize
|
||||
}
|
||||
},
|
||||
|
||||
State {
|
||||
name: "other"
|
||||
when: Plasmoid.formFactor != PlasmaCore.Types.Vertical && Plasmoid.formFactor != PlasmaCore.Types.Horizontal
|
||||
|
||||
PropertyChanges {
|
||||
target: main
|
||||
Layout.fillHeight: false
|
||||
Layout.fillWidth: false
|
||||
Layout.minimumWidth: Kirigami.Units.iconSizes.small * 3
|
||||
Layout.minimumHeight: Kirigami.Units.iconSizes.small * 3
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: contentItem
|
||||
|
||||
height: main.height
|
||||
width: main.width
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: labelsGrid
|
||||
|
||||
rows: 2
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timeLabel
|
||||
|
||||
height: sizehelper.height
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timezoneLabel
|
||||
|
||||
height: 0.7 * timeLabel.height
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: 1
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: dateLabel
|
||||
|
||||
height: 0.8 * timeLabel.height
|
||||
width: Math.max(timeLabel.contentWidth, Kirigami.Units.iconSizes.small * 3)
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: 1
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: dateLabel
|
||||
|
||||
anchors.top: labelsGrid.bottom
|
||||
anchors.horizontalCenter: labelsGrid.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: sizehelper
|
||||
|
||||
height: {
|
||||
if (main.showDate) {
|
||||
if (timezoneLabel.visible) {
|
||||
return 0.4 * main.height
|
||||
}
|
||||
return 0.56 * main.height
|
||||
} else if (timezoneLabel.visible) {
|
||||
return 0.59 * main.height
|
||||
}
|
||||
return main.height
|
||||
}
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
font.pixelSize: 1024
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
Timer {
|
||||
id: tooltipTimer
|
||||
interval: 750
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: if(!dashWindow.visible) timeToolTip.showToolTip();
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
property int wheelDelta: 0
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
onClicked: {
|
||||
|
||||
Plasmoid.expanded = !Plasmoid.expanded
|
||||
dashWindow.visible = !dashWindow.visible;
|
||||
if(dashWindow.visible) timeToolTip.hideImmediately();
|
||||
}
|
||||
|
||||
onEntered: {
|
||||
tooltipTimer.start();
|
||||
}
|
||||
onExited: {
|
||||
tooltipTimer.stop();
|
||||
timeToolTip.hideToolTip();
|
||||
}
|
||||
onWheel: {
|
||||
if (!Plasmoid.configuration.wheelChangesTimezone) {
|
||||
return;
|
||||
}
|
||||
|
||||
var delta = wheel.angleDelta.y || wheel.angleDelta.x
|
||||
var newIndex = main.tzIndex;
|
||||
wheelDelta += delta;
|
||||
// magic number 120 for common "one click"
|
||||
// See: http://qt-project.org/doc/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop
|
||||
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();
|
||||
}
|
||||
}
|
||||
PlasmaCore.ToolTipArea {
|
||||
id: timeToolTip
|
||||
|
||||
mainText: {
|
||||
var now = dataSource.data[plasmoid.configuration.lastSelectedTimezone]["DateTime"];
|
||||
return Qt.formatDate(now, "dddd, MMMM dd, yyyy");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Visible elements
|
||||
*
|
||||
*/
|
||||
|
||||
//This FrameSvgItem uses a non-standard variant of the tabbar SVG file that includes a "pressed" state
|
||||
KSvg.FrameSvgItem {
|
||||
id: hoverIndicator
|
||||
imagePath: Qt.resolvedUrl("svgs/tabbar.svgz")
|
||||
visible: mouseArea.containsMouse || dashWindow.visible
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: -Kirigami.Units.smallSpacing
|
||||
anchors.rightMargin: -Kirigami.Units.smallSpacing+2
|
||||
z: -1
|
||||
prefix: mouseArea.containsPress ? "pressed-tab" : "active-tab";
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
anchors.verticalCenter: main.verticalCenter
|
||||
|
||||
Grid {
|
||||
id: labelsGrid
|
||||
|
||||
rows: 1
|
||||
horizontalItemAlignment: Grid.AlignHCenter
|
||||
verticalItemAlignment: Grid.AlignVCenter
|
||||
|
||||
flow: Grid.TopToBottom
|
||||
columnSpacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Rectangle {
|
||||
height: 0.8 * sizehelper.height
|
||||
width: 1
|
||||
visible: main.showDate && main.oneLineMode
|
||||
|
||||
color: Kirigami.Theme.textColor
|
||||
opacity: 0.4
|
||||
}
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
id: timeLabel
|
||||
|
||||
renderType: Text.NativeRendering
|
||||
font {
|
||||
family: Plasmoid.configuration.fontFamily || Kirigami.Theme.defaultFont.family
|
||||
weight: Plasmoid.configuration.boldText ? Font.Bold : Kirigami.Theme.defaultFont.weight
|
||||
italic: Plasmoid.configuration.italicText
|
||||
pointSize: Plasmoid.configuration.fontSize || Kirigami.Theme.defaultFont.pointSize
|
||||
hintingPreference: Font.PreferFullHinting
|
||||
}
|
||||
minimumPixelSize: 1
|
||||
style: Text.Outline
|
||||
styleColor: "transparent"
|
||||
text: {
|
||||
// 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
|
||||
var currentTime = new Date(msUTC + (dataSource.data[Plasmoid.configuration.lastSelectedTimezone]["Offset"] * 1000));
|
||||
|
||||
main.currentTime = currentTime;
|
||||
|
||||
var showTimezone = main.showLocalTimezone || (plasmoid.configuration.lastSelectedTimezone != "Local"
|
||||
&& dataSource.data["Local"]["Timezone City"] != dataSource.data[Plasmoid.configuration.lastSelectedTimezone]["Timezone City"]);
|
||||
|
||||
var timezoneString = "";
|
||||
var timezoneResult = "";
|
||||
|
||||
if (showTimezone) {
|
||||
timezoneString = Plasmoid.configuration.displayTimezoneAsCode ? dataSource.data[Plasmoid.configuration.lastSelectedTimezone]["Timezone Abbreviation"]
|
||||
: TimezonesI18n.i18nCity(dataSource.data[Plasmoid.configuration.lastSelectedTimezone]["Timezone City"]);
|
||||
timezoneResult = (main.showDate || main.oneLineMode) && Plasmoid.formFactor == PlasmaCore.Types.Horizontal ? timezoneString : timezoneString;
|
||||
} else {
|
||||
// this clears the label and that makes it hidden
|
||||
timezoneResult = timezoneString;
|
||||
}
|
||||
return Qt.formatTime(currentTime, main.timeFormat) + (showTimezone ? (" " + timezoneResult) : "");
|
||||
}
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
id: timezoneLabel
|
||||
|
||||
renderType: Text.NativeRendering
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
font.pixelSize: timeLabel.font.pixelSize
|
||||
font.hintingPreference: Font.PreferFullHinting
|
||||
minimumPixelSize: 1
|
||||
|
||||
style: Text.Outline
|
||||
styleColor: "transparent"
|
||||
visible: false
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
id: dateLabel
|
||||
|
||||
visible: main.showDate
|
||||
renderType: Text.NativeRendering
|
||||
font.family: timeLabel.font.family
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
font.pixelSize: timeLabel.font.pixelSize
|
||||
font.hintingPreference: Font.PreferFullHinting
|
||||
minimumPixelSize: 1
|
||||
style: Text.Outline
|
||||
styleColor: "transparent"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
/*
|
||||
* end: Visible Elements
|
||||
*
|
||||
*/
|
||||
|
||||
PlasmaComponents3.Label {
|
||||
id: sizehelper
|
||||
|
||||
font.family: timeLabel.font.family
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
minimumPixelSize: 1
|
||||
|
||||
visible: false
|
||||
}
|
||||
|
||||
FontMetrics {
|
||||
id: timeMetrics
|
||||
|
||||
font.family: timeLabel.font.family
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
}
|
||||
|
||||
// Qt's QLocale does not offer any modular time creating like Klocale did
|
||||
// eg. no "gimme time with seconds" or "gimme time without seconds and with timezone".
|
||||
// QLocale supports only two formats - Long and Short. Long is unusable in many situations
|
||||
// and Short does not provide seconds. So if seconds are enabled, we need to add it here.
|
||||
//
|
||||
// What happens here is that it looks for the delimiter between "h" and "m", takes it
|
||||
// and appends it after "mm" and then appends "ss" for the seconds.
|
||||
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;
|
||||
|
||||
// because QLocale is incredibly stupid and does not convert 12h/24h clock format
|
||||
// when uppercase H is used for hours, needs to be h or hh, so toLowerCase()
|
||||
var result = hours.toLowerCase() + delimiter + minutes;
|
||||
|
||||
if (main.showSeconds) {
|
||||
result += delimiter + seconds;
|
||||
}
|
||||
|
||||
// add "AM/PM" either if the setting is the default and locale uses it OR if the user unchecked "use 24h format"
|
||||
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 = (main.showDate || main.oneLineMode) && Plasmoid.formFactor == PlasmaCore.Types.Horizontal ? "(" + timezoneString + ")" : timezoneString;
|
||||
} else {
|
||||
// this clears the label and that makes it hidden
|
||||
timezoneLabel.text = timezoneString;
|
||||
}*/
|
||||
|
||||
|
||||
if (main.showDate) {
|
||||
dateLabel.text = Qt.formatDate(main.currentTime, main.dateFormat);
|
||||
} else {
|
||||
// clear it so it doesn't take space in the layout
|
||||
dateLabel.text = "";
|
||||
}
|
||||
|
||||
// find widest character between 0 and 9
|
||||
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;
|
||||
}
|
||||
}
|
||||
// replace all placeholders with the widest number (two digits)
|
||||
var format = main.timeFormat.replace(/(h+|m+|s+)/g, "" + maximumWidthNumber + maximumWidthNumber); // make sure maximumWidthNumber is formatted as string
|
||||
// build the time string twice, once with an AM time and once with a PM time
|
||||
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);
|
||||
// set the sizehelper's text to the widest time string
|
||||
if (advanceWidthAm > advanceWidthPm) {
|
||||
sizehelper.text = timeAm;
|
||||
} else {
|
||||
sizehelper.text = timePm;
|
||||
}
|
||||
}
|
||||
|
||||
function dateTimeChanged()
|
||||
{
|
||||
var doCorrections = false;
|
||||
|
||||
if (main.showDate) {
|
||||
// If the date has changed, force size recalculation, because the day name
|
||||
// or the month name can now be longer/shorter, so we need to adjust applet size
|
||||
var currentDate = Qt.formatDateTime(getCurrentTime(), "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(); // inform the QML JS engine about TZ change
|
||||
}
|
||||
|
||||
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: {
|
||||
|
||||
root.initTimezones();
|
||||
// Sort the timezones according to their offset
|
||||
// Calling sort() directly on plasmoid.configuration.selectedTimeZones
|
||||
// has no effect, so sort a copy and then assign the copy to it
|
||||
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);
|
||||
dashWindow = Qt.createQmlObject("CalendarView {}", root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,802 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Heena Mahour <heena393@gmail.com>
|
||||
SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
|
||||
SPDX-FileCopyrightText: 2013 Martin Klapetek <mklapetek@kde.org>
|
||||
SPDX-FileCopyrightText: 2014 David Edmundson <davidedmundson@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.2
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as Components
|
||||
import org.kde.plasma.private.digitalclock 1.0
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.ksvg as KSvg
|
||||
|
||||
MouseArea {
|
||||
id: main
|
||||
objectName: "digital-clock-compactrepresentation"
|
||||
|
||||
hoverEnabled: true
|
||||
property QtObject dashWindow: null
|
||||
|
||||
onClicked: {
|
||||
Plasmoid.expanded = !Plasmoid.expanded
|
||||
dashWindow.visible = !dashWindow.visible;
|
||||
}
|
||||
onEntered: {
|
||||
tooltipTimer.start();
|
||||
}
|
||||
onExited: {
|
||||
tooltipTimer.stop();
|
||||
timeToolTip.hideToolTip();
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: tooltipTimer
|
||||
interval: 750
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: if(!dashWindow.visible) timeToolTip.showToolTip();
|
||||
}
|
||||
PlasmaCore.ToolTipArea {
|
||||
id: timeToolTip
|
||||
|
||||
mainText: {
|
||||
var now = dataSource.data[Plasmoid.configuration.lastSelectedTimezone]["DateTime"];
|
||||
return Qt.formatDate(now, "dddd, MMMM dd, yyyy");
|
||||
}
|
||||
/*mainItem: PlasmaExtras.Heading {
|
||||
* level: 5
|
||||
* elide: Text.ElideRight
|
||||
* wrapMode: Text.Wrap
|
||||
* text: {
|
||||
* var now = dataSource.data[plasmoid.configuration.lastSelectedTimezone]["DateTime"];
|
||||
* return Qt.formatDate(now, "dddd, MMMM yyyy");
|
||||
}
|
||||
textFormat: Text.PlainText
|
||||
}*/
|
||||
}
|
||||
property string timeFormat
|
||||
property string timeFormatWithSeconds
|
||||
|
||||
property bool showLocalTimezone: Plasmoid.configuration.showLocalTimezone
|
||||
property bool showDate: Plasmoid.configuration.showDate
|
||||
// This is quite convoluted in Qt 6:
|
||||
// Qt.formatDate with locale only accepts Locale.FormatType as format type,
|
||||
// no Qt.DateFormat (ISODate) and no format string.
|
||||
// Locale.toString on the other hand only formats a date *with* time...
|
||||
property var dateFormatter: {
|
||||
if (Plasmoid.configuration.dateFormat === "custom") {
|
||||
Plasmoid.configuration.customDateFormat; // create a binding dependency on this property.
|
||||
return (d) => {
|
||||
return Qt.locale().toString(d, Plasmoid.configuration.customDateFormat);
|
||||
};
|
||||
} else if (Plasmoid.configuration.dateFormat === "isoDate") {
|
||||
return (d) => {
|
||||
return Qt.formatDate(d, Qt.ISODate);
|
||||
};
|
||||
} else if (Plasmoid.configuration.dateFormat === "longDate") {
|
||||
return (d) => {
|
||||
return Qt.formatDate(d, Qt.locale(), Locale.LongFormat);
|
||||
};
|
||||
} else {
|
||||
return (d) => {
|
||||
return Qt.formatDate(d, Qt.locale(), Locale.ShortFormat);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
property string lastSelectedTimezone: Plasmoid.configuration.lastSelectedTimezone
|
||||
property int displayTimezoneFormat: Plasmoid.configuration.displayTimezoneFormat
|
||||
property int use24hFormat: Plasmoid.configuration.use24hFormat
|
||||
|
||||
property string lastDate: ""
|
||||
property int tzOffset
|
||||
|
||||
// This is the index in the list of user selected timezones
|
||||
property int tzIndex: 0
|
||||
|
||||
// if showing the date and the time in one line or
|
||||
// if the date/timezone cannot be fit with the smallest font to its designated space
|
||||
property bool oneLineMode: {
|
||||
if (Plasmoid.configuration.dateDisplayFormat === 1) {
|
||||
// BesideTime
|
||||
return true;
|
||||
} else if (Plasmoid.configuration.dateDisplayFormat === 2) {
|
||||
// BelowTime
|
||||
return false;
|
||||
} else {
|
||||
// Adaptive
|
||||
return Plasmoid.formFactor === PlasmaCore.Types.Horizontal &&
|
||||
main.height <= 2 * Kirigami.Theme.smallFont.pixelSize &&
|
||||
(main.showDate || timezoneLabel.visible);
|
||||
}
|
||||
}
|
||||
|
||||
property bool wasExpanded
|
||||
property int wheelDelta: 0
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.onPressAction: main.clicked(null)
|
||||
|
||||
onDateFormatterChanged: {
|
||||
setupLabels();
|
||||
}
|
||||
|
||||
onDisplayTimezoneFormatChanged: { setupLabels(); }
|
||||
onStateChanged: { setupLabels(); }
|
||||
|
||||
onLastSelectedTimezoneChanged: { 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
|
||||
function onContextualActionsAboutToShow() {
|
||||
ClipboardMenu.secondsIncluded = (Plasmoid.configuration.showSeconds === 2);
|
||||
ClipboardMenu.currentDate = main.getCurrentTime();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Plasmoid.configuration
|
||||
function onSelectedTimeZonesChanged() {
|
||||
// If the currently selected timezone was removed,
|
||||
// default to the first one in the list
|
||||
const lastSelectedTimezone = Plasmoid.configuration.lastSelectedTimezone;
|
||||
if (Plasmoid.configuration.selectedTimeZones.indexOf(lastSelectedTimezone) === -1) {
|
||||
Plasmoid.configuration.lastSelectedTimezone = Plasmoid.configuration.selectedTimeZones[0];
|
||||
}
|
||||
|
||||
setupLabels();
|
||||
setTimezoneIndex();
|
||||
}
|
||||
}
|
||||
|
||||
function getCurrentTime() {
|
||||
// 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
|
||||
var currentTime = new Date(msUTC + (dataSource.data[Plasmoid.configuration.lastSelectedTimezone]["Offset"] * 1000));
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
function pointToPixel(pointSize) {
|
||||
var pixelsPerInch = Screen.pixelDensity * 25.4
|
||||
return Math.round(pointSize / 72 * pixelsPerInch)
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "horizontalPanel"
|
||||
when: Plasmoid.formFactor === PlasmaCore.Types.Horizontal && !main.oneLineMode
|
||||
|
||||
PropertyChanges {
|
||||
target: main
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: false
|
||||
Layout.minimumWidth: contentItem.width
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: contentItem
|
||||
|
||||
height: timeLabel.height + (main.showDate || timezoneLabel.visible ? 0.8 * timeLabel.height : 0)
|
||||
width: Math.max(timeLabel.width + (main.showDate ? timezoneLabel.paintedWidth : 0),
|
||||
timezoneLabel.paintedWidth, dateLabel.paintedWidth) + Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: labelsGrid
|
||||
|
||||
rows: main.showDate ? 1 : 2
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: labelsGrid
|
||||
|
||||
anchors.horizontalCenter: contentItem.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timeLabel
|
||||
|
||||
height: sizehelper.height
|
||||
width: timeLabel.paintedWidth
|
||||
|
||||
font.pixelSize: timeLabel.height
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timezoneLabel
|
||||
|
||||
height: main.showDate ? 0.7 * timeLabel.height : 0.8 * timeLabel.height
|
||||
width: main.showDate ? timezoneLabel.paintedWidth : timeLabel.width
|
||||
|
||||
font.pixelSize: timezoneLabel.height
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: dateLabel
|
||||
|
||||
height: 0.8 * timeLabel.height
|
||||
width: dateLabel.paintedWidth
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
font.pixelSize: dateLabel.height
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: dateLabel
|
||||
|
||||
anchors.top: labelsGrid.bottom
|
||||
anchors.horizontalCenter: labelsGrid.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: sizehelper
|
||||
|
||||
/*
|
||||
* The value 0.71 was picked by testing to give the clock the right
|
||||
* size (aligned with tray icons).
|
||||
* Value 0.56 seems to be chosen rather arbitrary as well such that
|
||||
* the time label is slightly larger than the date or timezone label
|
||||
* and still fits well into the panel with all the applied margins.
|
||||
*/
|
||||
height: Math.min(main.showDate || timezoneLabel.visible ? main.height * 0.56 : main.height * 0.71,
|
||||
fontHelper.font.pixelSize)
|
||||
|
||||
font.pixelSize: sizehelper.height
|
||||
}
|
||||
},
|
||||
|
||||
State {
|
||||
name: "oneLineDate"
|
||||
// the one-line mode has no effect on a vertical panel because it would never fit
|
||||
when: Plasmoid.formFactor !== PlasmaCore.Types.Vertical && main.oneLineMode
|
||||
|
||||
PropertyChanges {
|
||||
target: main
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: false
|
||||
Layout.minimumWidth: contentItem.width
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: contentItem
|
||||
|
||||
height: sizehelper.height
|
||||
width: dateLabel.width + dateLabel.anchors.rightMargin + labelsGrid.width
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: labelsGrid
|
||||
|
||||
anchors.right: contentItem.right
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: dateLabel
|
||||
|
||||
height: timeLabel.height
|
||||
width: dateLabel.paintedWidth
|
||||
|
||||
font.pixelSize: 1024
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
anchors.rightMargin: labelsGrid.columnSpacing
|
||||
|
||||
fontSizeMode: Text.VerticalFit
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: dateLabel
|
||||
|
||||
anchors.right: labelsGrid.left
|
||||
anchors.verticalCenter: labelsGrid.verticalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timeLabel
|
||||
|
||||
height: sizehelper.height
|
||||
width: timeLabel.paintedWidth
|
||||
|
||||
fontSizeMode: Text.VerticalFit
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timezoneLabel
|
||||
|
||||
height: 0.7 * timeLabel.height
|
||||
width: timezoneLabel.paintedWidth
|
||||
|
||||
fontSizeMode: Text.VerticalFit
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: sizehelper
|
||||
|
||||
height: Math.min(main.height, fontHelper.contentHeight)
|
||||
|
||||
fontSizeMode: Text.VerticalFit
|
||||
font.pixelSize: fontHelper.font.pixelSize
|
||||
}
|
||||
},
|
||||
|
||||
State {
|
||||
name: "verticalPanel"
|
||||
when: Plasmoid.formFactor === PlasmaCore.Types.Vertical
|
||||
|
||||
PropertyChanges {
|
||||
target: main
|
||||
Layout.fillHeight: false
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumHeight: contentItem.height
|
||||
Layout.minimumHeight: Layout.maximumHeight
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: contentItem
|
||||
|
||||
height: main.showDate ? labelsGrid.height + dateLabel.contentHeight : labelsGrid.height
|
||||
width: main.width
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: labelsGrid
|
||||
|
||||
rows: 2
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timeLabel
|
||||
|
||||
height: sizehelper.contentHeight
|
||||
width: main.width
|
||||
|
||||
font.pixelSize: Math.min(timeLabel.height, fontHelper.font.pixelSize)
|
||||
fontSizeMode: Text.VerticalFit
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timezoneLabel
|
||||
|
||||
height: Math.max(0.7 * timeLabel.height, minimumPixelSize)
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: dateLabel.minimumPixelSize
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: dateLabel
|
||||
|
||||
width: main.width
|
||||
//NOTE: in order for Text.Fit to work as intended, the actual height needs to be quite big, in order for the font to enlarge as much it needs for the available width, and then request a sensible height, for which contentHeight will need to be considered as opposed to height
|
||||
height: Kirigami.Units.iconSizes.small * 10
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
verticalAlignment: Text.AlignTop
|
||||
// Those magic numbers are purely what looks nice as maximum size, here we have it the smallest
|
||||
// between slightly bigger than the default font (1.4 times) and a bit smaller than the time font
|
||||
font.pixelSize: Math.min(0.7 * timeLabel.height, Kirigami.Theme.defaultFont.pixelSize * 1.4)
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: dateLabel
|
||||
|
||||
anchors.top: labelsGrid.bottom
|
||||
anchors.horizontalCenter: labelsGrid.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: sizehelper
|
||||
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.HorizontalFit
|
||||
font.pixelSize: fontHelper.font.pixelSize
|
||||
}
|
||||
},
|
||||
|
||||
State {
|
||||
name: "other"
|
||||
when: Plasmoid.formFactor !== PlasmaCore.Types.Vertical && Plasmoid.formFactor !== PlasmaCore.Types.Horizontal
|
||||
|
||||
PropertyChanges {
|
||||
target: main
|
||||
Layout.fillHeight: false
|
||||
Layout.fillWidth: false
|
||||
Layout.minimumWidth: Kirigami.Units.iconSizes.small * 3
|
||||
Layout.minimumHeight: Kirigami.Units.iconSizes.small * 3
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: contentItem
|
||||
|
||||
height: main.height
|
||||
width: main.width
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: labelsGrid
|
||||
|
||||
rows: 2
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timeLabel
|
||||
|
||||
height: sizehelper.height
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: timezoneLabel
|
||||
|
||||
height: 0.7 * timeLabel.height
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: 1
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: dateLabel
|
||||
|
||||
height: 0.7 * timeLabel.height
|
||||
font.pixelSize: 1024
|
||||
width: Math.max(timeLabel.contentWidth, Kirigami.Units.iconSizes.small * 3)
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: 1
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
AnchorChanges {
|
||||
target: dateLabel
|
||||
|
||||
anchors.top: labelsGrid.bottom
|
||||
anchors.horizontalCenter: labelsGrid.horizontalCenter
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: sizehelper
|
||||
|
||||
height: {
|
||||
if (main.showDate) {
|
||||
if (timezoneLabel.visible) {
|
||||
return 0.4 * main.height
|
||||
}
|
||||
return 0.56 * main.height
|
||||
} else if (timezoneLabel.visible) {
|
||||
return 0.59 * main.height
|
||||
}
|
||||
return main.height
|
||||
}
|
||||
width: main.width
|
||||
|
||||
fontSizeMode: Text.Fit
|
||||
font.pixelSize: 1024
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
//onPressed: wasExpanded = root.expanded
|
||||
//onClicked: root.expanded = !wasExpanded
|
||||
onWheel: wheel => {
|
||||
if (!Plasmoid.configuration.wheelChangesTimezone) {
|
||||
return;
|
||||
}
|
||||
|
||||
var delta = (wheel.inverted ? -1 : 1) * (wheel.angleDelta.y ? wheel.angleDelta.y : wheel.angleDelta.x);
|
||||
var newIndex = main.tzIndex;
|
||||
wheelDelta += delta;
|
||||
// magic number 120 for common "one click"
|
||||
// See: https://doc.qt.io/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Visible elements
|
||||
*
|
||||
*/
|
||||
|
||||
KSvg.FrameSvgItem {
|
||||
id: hoverIndicator
|
||||
imagePath: Qt.resolvedUrl("svgs/tabbar.svgz")
|
||||
visible: main.containsMouse || dashWindow.visible
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: main.showSeconds ? 0 : -Kirigami.Units.smallSpacing //To compensate for the shorter width of the clock when seconds are disabled
|
||||
anchors.rightMargin:main.showSeconds ? 0 : -Kirigami.Units.smallSpacing
|
||||
z: -1
|
||||
prefix: main.containsPress ? "pressed-tab" : "active-tab";
|
||||
}
|
||||
Item {
|
||||
id: contentItem
|
||||
anchors.verticalCenter: main.verticalCenter
|
||||
|
||||
Grid {
|
||||
id: labelsGrid
|
||||
|
||||
rows: 1
|
||||
horizontalItemAlignment: Grid.AlignHCenter
|
||||
verticalItemAlignment: Grid.AlignVCenter
|
||||
|
||||
flow: Grid.TopToBottom
|
||||
columnSpacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Components.Label {
|
||||
id: timeLabel
|
||||
|
||||
font {
|
||||
family: fontHelper.font.family
|
||||
weight: fontHelper.font.weight
|
||||
italic: fontHelper.font.italic
|
||||
pixelSize: 1024
|
||||
pointSize: -1 // Because we're setting the pixel size instead
|
||||
// TODO: remove once this label is ported to PC3
|
||||
}
|
||||
minimumPixelSize: 1
|
||||
|
||||
text: Qt.formatTime(main.getCurrentTime(), Plasmoid.configuration.showSeconds === 2 ? main.timeFormatWithSeconds : main.timeFormat)
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
Components.Label {
|
||||
id: timezoneLabel
|
||||
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
font.pixelSize: 1024
|
||||
font.pointSize: -1 // Because we're setting the pixel size instead
|
||||
// TODO: remove once this label is ported to PC3
|
||||
minimumPixelSize: 1
|
||||
|
||||
visible: text.length > 0
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Components.Label {
|
||||
id: dateLabel
|
||||
|
||||
visible: main.showDate
|
||||
|
||||
font.family: timeLabel.font.family
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
font.pixelSize: 1024
|
||||
font.pointSize: -1 // Because we're setting the pixel size instead
|
||||
// TODO: remove once this label is ported to PC3
|
||||
minimumPixelSize: 1
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
/*
|
||||
* end: Visible Elements
|
||||
*
|
||||
*/
|
||||
|
||||
Components.Label {
|
||||
id: sizehelper
|
||||
|
||||
font.family: timeLabel.font.family
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
minimumPixelSize: 1
|
||||
|
||||
visible: false
|
||||
}
|
||||
|
||||
// To measure Label.height for maximum-sized font in VerticalFit mode
|
||||
Components.Label {
|
||||
id: fontHelper
|
||||
|
||||
height: 1024
|
||||
|
||||
font.family: (Plasmoid.configuration.autoFontAndSize || Plasmoid.configuration.fontFamily.length === 0) ? Kirigami.Theme.defaultFont.family : Plasmoid.configuration.fontFamily
|
||||
font.weight: Plasmoid.configuration.autoFontAndSize ? Kirigami.Theme.defaultFont.weight : Plasmoid.configuration.fontWeight
|
||||
font.italic: Plasmoid.configuration.autoFontAndSize ? Kirigami.Theme.defaultFont.italic : Plasmoid.configuration.italicText
|
||||
font.pixelSize: Plasmoid.configuration.autoFontAndSize ? 3 * Kirigami.Theme.defaultFont.pixelSize : pointToPixel(Plasmoid.configuration.fontSize)
|
||||
font.pointSize: -1
|
||||
fontSizeMode: Text.VerticalFit
|
||||
|
||||
visible: false
|
||||
}
|
||||
|
||||
FontMetrics {
|
||||
id: timeMetrics
|
||||
|
||||
font.family: timeLabel.font.family
|
||||
font.weight: timeLabel.font.weight
|
||||
font.italic: timeLabel.font.italic
|
||||
}
|
||||
|
||||
// Qt's QLocale does not offer any modular time creating like Klocale did
|
||||
// eg. no "gimme time with seconds" or "gimme time without seconds and with timezone".
|
||||
// QLocale supports only two formats - Long and Short. Long is unusable in many situations
|
||||
// and Short does not provide seconds. So if seconds are enabled, we need to add it here.
|
||||
//
|
||||
// What happens here is that it looks for the delimiter between "h" and "m", takes it
|
||||
// and appends it after "mm" and then appends "ss" for the seconds.
|
||||
function timeFormatCorrection(timeFormatString) {
|
||||
const regexp = /(hh*)(.+)(mm)/i
|
||||
const match = regexp.exec(timeFormatString);
|
||||
|
||||
const hours = match[1];
|
||||
const delimiter = match[2];
|
||||
const minutes = match[3]
|
||||
const seconds = "ss";
|
||||
const amPm = "AP";
|
||||
const uses24hFormatByDefault = timeFormatString.toLowerCase().indexOf("ap") === -1;
|
||||
|
||||
// because QLocale is incredibly stupid and does not convert 12h/24h clock format
|
||||
// when uppercase H is used for hours, needs to be h or hh, so toLowerCase()
|
||||
let result = hours.toLowerCase() + delimiter + minutes;
|
||||
|
||||
let result_sec = result + delimiter + seconds;
|
||||
|
||||
// add "AM/PM" either if the setting is the default and locale uses it OR if the user unchecked "use 24h format"
|
||||
if ((main.use24hFormat == Qt.PartiallyChecked && !uses24hFormatByDefault) || main.use24hFormat == Qt.Unchecked) {
|
||||
result += " " + amPm;
|
||||
result_sec += " " + amPm;
|
||||
}
|
||||
|
||||
main.timeFormat = result;
|
||||
main.timeFormatWithSeconds = result_sec;
|
||||
setupLabels();
|
||||
}
|
||||
|
||||
function setupLabels() {
|
||||
const showTimezone = main.showLocalTimezone || (Plasmoid.configuration.lastSelectedTimezone !== "Local"
|
||||
&& dataSource.data["Local"]["Timezone City"] !== dataSource.data[Plasmoid.configuration.lastSelectedTimezone]["Timezone City"]);
|
||||
|
||||
let timezoneString = "";
|
||||
|
||||
if (showTimezone) {
|
||||
// format timezone as tz code, city or UTC offset
|
||||
if (displayTimezoneFormat === 0) {
|
||||
timezoneString = dataSource.data[lastSelectedTimezone]["Timezone Abbreviation"]
|
||||
} else if (displayTimezoneFormat === 1) {
|
||||
timezoneString = TimezonesI18n.i18nCity(dataSource.data[lastSelectedTimezone]["Timezone"]);
|
||||
} else if (displayTimezoneFormat === 2) {
|
||||
const lastOffset = dataSource.data[lastSelectedTimezone]["Offset"];
|
||||
const symbol = lastOffset > 0 ? '+' : '';
|
||||
const hours = Math.floor(lastOffset / 3600);
|
||||
const minutes = Math.floor(lastOffset % 3600 / 60);
|
||||
|
||||
timezoneString = "UTC" + symbol + hours.toString().padStart(2, '0') + ":" + minutes.toString().padStart(2, '0');
|
||||
}
|
||||
|
||||
timezoneLabel.text = (main.showDate || main.oneLineMode) && Plasmoid.formFactor === PlasmaCore.Types.Horizontal ? "(" + timezoneString + ")" : timezoneString;
|
||||
} else {
|
||||
// this clears the label and that makes it hidden
|
||||
timezoneLabel.text = timezoneString;
|
||||
}
|
||||
|
||||
if (main.showDate) {
|
||||
dateLabel.text = main.dateFormatter(main.getCurrentTime());
|
||||
} else {
|
||||
// clear it so it doesn't take space in the layout
|
||||
dateLabel.text = "";
|
||||
}
|
||||
|
||||
// find widest character between 0 and 9
|
||||
let maximumWidthNumber = 0;
|
||||
let maximumAdvanceWidth = 0;
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
const advanceWidth = timeMetrics.advanceWidth(i);
|
||||
if (advanceWidth > maximumAdvanceWidth) {
|
||||
maximumAdvanceWidth = advanceWidth;
|
||||
maximumWidthNumber = i;
|
||||
}
|
||||
}
|
||||
// replace all placeholders with the widest number (two digits)
|
||||
const format = main.timeFormat.replace(/(h+|m+|s+)/g, "" + maximumWidthNumber + maximumWidthNumber); // make sure maximumWidthNumber is formatted as string
|
||||
// build the time string twice, once with an AM time and once with a PM time
|
||||
const date = new Date(2000, 0, 1, 1, 0, 0);
|
||||
const timeAm = Qt.formatTime(date, format);
|
||||
const advanceWidthAm = timeMetrics.advanceWidth(timeAm);
|
||||
date.setHours(13);
|
||||
const timePm = Qt.formatTime(date, format);
|
||||
const advanceWidthPm = timeMetrics.advanceWidth(timePm);
|
||||
// set the sizehelper's text to the widest time string
|
||||
if (advanceWidthAm > advanceWidthPm) {
|
||||
sizehelper.text = timeAm;
|
||||
} else {
|
||||
sizehelper.text = timePm;
|
||||
}
|
||||
fontHelper.text = sizehelper.text
|
||||
}
|
||||
|
||||
function dateTimeChanged() {
|
||||
let doCorrections = false;
|
||||
|
||||
if (main.showDate) {
|
||||
// If the date has changed, force size recalculation, because the day name
|
||||
// or the month name can now be longer/shorter, so we need to adjust applet size
|
||||
const currentDate = Qt.formatDateTime(main.getCurrentTime(), "yyyy-MM-dd");
|
||||
if (main.lastDate !== currentDate) {
|
||||
doCorrections = true;
|
||||
main.lastDate = currentDate
|
||||
}
|
||||
}
|
||||
|
||||
const currentTZOffset = dataSource.data["Local"]["Offset"] / 60;
|
||||
if (currentTZOffset !== tzOffset) {
|
||||
doCorrections = true;
|
||||
tzOffset = currentTZOffset;
|
||||
Date.timeZoneUpdated(); // inform the QML JS engine about TZ change
|
||||
}
|
||||
|
||||
if (doCorrections) {
|
||||
timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat));
|
||||
}
|
||||
}
|
||||
|
||||
function setTimezoneIndex() {
|
||||
main.tzIndex = Plasmoid.configuration.selectedTimeZones.indexOf(Plasmoid.configuration.lastSelectedTimezone);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// Sort the timezones according to their offset
|
||||
// Calling sort() directly on Plasmoid.configuration.selectedTimeZones
|
||||
// has no effect, so sort a copy and then assign the copy to it
|
||||
const sortedTimeZones = Plasmoid.configuration.selectedTimeZones;
|
||||
const byOffset = (a, b) => dataSource.data[a]["Offset"] - dataSource.data[b]["Offset"];
|
||||
sortedTimeZones.sort(byOffset);
|
||||
Plasmoid.configuration.selectedTimeZones = sortedTimeZones;
|
||||
|
||||
setTimezoneIndex();
|
||||
tzOffset = -(new Date().getTimezoneOffset());
|
||||
dateTimeChanged();
|
||||
timeFormatCorrection(Qt.locale().timeFormat(Locale.ShortFormat));
|
||||
dataSource.onDataChanged.connect(dateTimeChanged);
|
||||
dashWindow = Qt.createQmlObject("CalendarView {}", root);
|
||||
}
|
||||
}
|
|
@ -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,58 @@
|
|||
/*import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQml.Models 2.2
|
||||
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
// for Highlight
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons
|
||||
*/
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.15
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.kirigami 2.5 as Kirigami // For Settings.tabletMode
|
||||
|
||||
MouseArea {
|
||||
id: toolButton
|
||||
|
||||
Layout.maximumWidth: Kirigami.Units.iconSizes.small+1;
|
||||
Layout.maximumHeight: Kirigami.Units.iconSizes.small;
|
||||
Layout.preferredWidth: Kirigami.Units.iconSizes.small+1;
|
||||
Layout.preferredHeight: Kirigami.Units.iconSizes.small;
|
||||
|
||||
//signal clicked
|
||||
property string buttonIcon: ""
|
||||
property bool checkable: false
|
||||
property bool checked: false
|
||||
property bool flat: false
|
||||
|
||||
hoverEnabled: true
|
||||
KSvg.FrameSvgItem {
|
||||
id: normalButton
|
||||
imagePath: Qt.resolvedUrl("svgs/button.svgz")
|
||||
anchors.fill: parent
|
||||
prefix: {
|
||||
if(parent.containsPress || (checkable && checked)) return "toolbutton-pressed";
|
||||
else return "toolbutton-hover";
|
||||
}
|
||||
visible: (parent.containsMouse || (checkable && checked)) && !flat
|
||||
}
|
||||
|
||||
KSvg.SvgItem {
|
||||
id: buttonIconSvg
|
||||
svg: buttonIcons
|
||||
elementId: buttonIcon
|
||||
width: 10;
|
||||
height: 10;
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
145
plasma/plasmoids/io.gitgud.wackyideas.digitalclocklite/contents/ui/Tooltip.qml
Executable file
145
plasma/plasmoids/io.gitgud.wackyideas.digitalclocklite/contents/ui/Tooltip.qml
Executable file
|
@ -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,288 @@
|
|||
/*
|
||||
* 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.15
|
||||
import QtQuick.Controls as QtControls
|
||||
import QtQuick.Layouts 1.15 as QtLayouts
|
||||
import QtQuick.Dialogs 6.3 as QtDialogs
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.kcmutils // For KCMLauncher
|
||||
import org.kde.config // For KAuthorized
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.plasma.workspace.calendar 2.0 as PlasmaCalendar
|
||||
|
||||
SimpleKCM {
|
||||
id: appearancePage
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
|
||||
signal configurationChanged
|
||||
|
||||
property string cfg_fontFamily
|
||||
property string cfg_fontSize
|
||||
property alias cfg_boldText: boldCheckBox.checked
|
||||
property string cfg_timeFormat: ""
|
||||
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 string cfg_dateFormat: "shortDate"
|
||||
property alias cfg_use24hFormat: use24hFormat.checkState
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: fontSizesModel
|
||||
Component.onCompleted: {
|
||||
var arr = [] // use temp array to avoid constant binding stuff
|
||||
arr.push({text: i18n("Use default font size"), value: ""})
|
||||
|
||||
var sizes = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '14', '16', '18', '20', '22', '24', '26', '28', '36', '48', '72']
|
||||
for (var i = 0, j = sizes.length; i < j; ++i) {
|
||||
arr.push({text: sizes[i], value: sizes[i]})
|
||||
}
|
||||
append(arr)
|
||||
}
|
||||
}
|
||||
|
||||
QtLayouts.ColumnLayout {
|
||||
anchors.left: parent.left
|
||||
|
||||
QtControls.GroupBox {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
title: i18n("Information")
|
||||
//flat: true
|
||||
|
||||
QtLayouts.ColumnLayout {
|
||||
QtControls.CheckBox {
|
||||
id: showDate
|
||||
text: i18n("Show date")
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: showLocalTimezone
|
||||
text: i18n("Show local time zone")
|
||||
}
|
||||
|
||||
/*QtControls.Label {
|
||||
text: i18n("Display time zone as:")
|
||||
}*/
|
||||
|
||||
|
||||
QtControls.ButtonGroup {
|
||||
buttons: timezoneColumn.children
|
||||
}
|
||||
QtControls.GroupBox {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
visible: false
|
||||
//flat: true
|
||||
QtLayouts.ColumnLayout {
|
||||
|
||||
id: timezoneColumn
|
||||
//QtControls.ExclusiveGroup { id: timezoneDisplayType }
|
||||
|
||||
QtControls.RadioButton {
|
||||
id: timezoneCityRadio
|
||||
text: i18n("Time zone city")
|
||||
//exclusiveGroup: timezoneDisplayType
|
||||
}
|
||||
|
||||
QtControls.RadioButton {
|
||||
id: timezoneCodeRadio
|
||||
text: i18n("Time zone code")
|
||||
//exclusiveGroup: timezoneDisplayType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtControls.Label {
|
||||
text: i18n("Date format:")
|
||||
}
|
||||
|
||||
QtControls.ComboBox {
|
||||
id: dateFormat
|
||||
enabled: showDate.checked
|
||||
textRole: "label"
|
||||
model: [
|
||||
{
|
||||
'label': i18n("Long Date"),
|
||||
'name': "longDate"
|
||||
},
|
||||
{
|
||||
'label': i18n("Short Date"),
|
||||
'name': "shortDate"
|
||||
},
|
||||
{
|
||||
'label': i18n("ISO Date"),
|
||||
'name': "isoDate"
|
||||
}
|
||||
]
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
QtControls.Label {
|
||||
text: i18n(" Font size px: ")
|
||||
}
|
||||
|
||||
QtControls.ComboBox {
|
||||
id: fontSizeComboBox
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
// ComboBox's sizing is just utterly broken
|
||||
QtLayouts.Layout.minimumWidth: Kirigami.Units.iconSizes.small * 10
|
||||
model: fontSizesModel
|
||||
// doesn't autodeduce from model because we manually populate it
|
||||
textRole: "text"
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
var current = model.get(currentIndex)
|
||||
if (current) {
|
||||
cfg_fontSize = current.value
|
||||
appearancePage.configurationChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
QtControls.Label {
|
||||
text: i18n(" Font style:")
|
||||
}
|
||||
|
||||
|
||||
QtControls.ComboBox {
|
||||
id: fontFamilyComboBox
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
// ComboBox's sizing is just utterly broken
|
||||
QtLayouts.Layout.minimumWidth: Kirigami.Units.iconSizes.small * 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
|
||||
//tooltip: i18n("Bold text")
|
||||
icon.name: "format-text-bold"
|
||||
checkable: true
|
||||
//Accessible.name: tooltip
|
||||
}
|
||||
|
||||
QtControls.Button {
|
||||
id: italicCheckBox
|
||||
//tooltip: i18n("Italic text")
|
||||
icon.name: "format-text-italic"
|
||||
checkable: true
|
||||
//Accessible.name: tooltip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (Plasmoid.configuration.displayTimezoneAsCode) {
|
||||
timezoneCodeRadio.checked = true;
|
||||
} else {
|
||||
timezoneCityRadio.checked = true;
|
||||
}
|
||||
|
||||
for(var i = 0; i < fontsModel.count; i++) {
|
||||
if(fontsModel.get(i).value == Plasmoid.configuration.fontFamily) {
|
||||
fontFamilyComboBox.currentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < fontSizesModel.count; i++) {
|
||||
|
||||
if(fontSizesModel.get(i).value == Plasmoid.configuration.fontSize) {
|
||||
fontSizeComboBox.currentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boldCheckBox.checked = Plasmoid.configuration.boldText;
|
||||
italicCheckBox.checked = Plasmoid.configuration.italicText;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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 as QtControls
|
||||
import QtQuick.Layouts 1.0 as QtLayouts
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.workspace.calendar 2.0 as PlasmaCalendar
|
||||
import org.kde.kcmutils as KCM
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
KCM.SimpleKCM {
|
||||
id: calendarPage
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
|
||||
signal configurationChanged()
|
||||
|
||||
property alias cfg_showWeekNumbers: showWeekNumbers.checked
|
||||
property int cfg_firstDayOfWeek
|
||||
|
||||
PlasmaCalendar.EventPluginsManager {
|
||||
id: eventPluginsManager
|
||||
Component.onCompleted: {
|
||||
populateEnabledPluginsList(Plasmoid.configuration.enabledCalendarPlugins);
|
||||
}
|
||||
}
|
||||
function saveConfig()
|
||||
{
|
||||
Plasmoid.configuration.enabledCalendarPlugins = eventPluginsManager.enabledPlugins;
|
||||
}
|
||||
|
||||
QtLayouts.ColumnLayout {
|
||||
anchors.left: parent.left
|
||||
QtControls.CheckBox {
|
||||
id: showWeekNumbers
|
||||
text: i18n("Show week numbers in Calendar")
|
||||
}
|
||||
|
||||
QtLayouts.RowLayout {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
|
||||
Text {
|
||||
text: i18n("First day of week:")
|
||||
}
|
||||
//Kirigami.FormData.label: i18n("First day of week:")
|
||||
|
||||
QtControls.ComboBox {
|
||||
id: firstDayOfWeekCombo
|
||||
textRole: "text"
|
||||
model: [-1, 0, 1, 5, 6].map(day => ({
|
||||
day,
|
||||
text: day === -1 ? i18n("Use Region Defaults") : Qt.locale().dayName(day),
|
||||
}))
|
||||
onActivated: cfg_firstDayOfWeek = model[index].day
|
||||
currentIndex: model.findIndex(item => item.day === cfg_firstDayOfWeek)
|
||||
}
|
||||
}
|
||||
|
||||
QtControls.GroupBox {
|
||||
QtLayouts.Layout.fillWidth: true
|
||||
title: i18n("Available Calendar Plugins")
|
||||
//flat: true
|
||||
|
||||
QtLayouts.ColumnLayout {
|
||||
Repeater {
|
||||
id: calendarPluginsRepeater
|
||||
model: 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: {
|
||||
eventPluginsManager.populateEnabledPluginsList(Plasmoid.configuration.enabledCalendarPlugins);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2013 Kai Uwe Broulik <kde@privat.broulik.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kquickcontrolsaddons 2.0 // For kcmshell
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.private.digitalclock 1.0
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.kcmutils as KCMUtils
|
||||
import org.kde.config // KAuthorized
|
||||
|
||||
KCMUtils.ScrollViewKCM {
|
||||
id: timeZonesPage
|
||||
|
||||
property alias cfg_selectedTimeZones: timeZones.selectedTimeZones
|
||||
property alias cfg_wheelChangesTimezone: enableWheelCheckBox.checked
|
||||
|
||||
TimeZoneModel {
|
||||
id: timeZones
|
||||
|
||||
onSelectedTimeZonesChanged: {
|
||||
if (selectedTimeZones.length === 0) {
|
||||
// Don't let the user remove all time zones
|
||||
messageWidget.visible = true;
|
||||
timeZones.selectLocalTimeZone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header: ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
text: i18n("Tip: if you travel frequently, add your home time zone to this list. It will only appear when you change the systemwide time zone to something else.")
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
|
||||
view: ListView {
|
||||
id: configuredTimezoneList
|
||||
clip: true // Avoid visual glitches
|
||||
focus: true // keyboard navigation
|
||||
activeFocusOnTab: true // keyboard navigation
|
||||
|
||||
model: TimeZoneFilterProxy {
|
||||
sourceModel: timeZones
|
||||
onlyShowChecked: true
|
||||
}
|
||||
// We have no concept of selection in this list, so don't pre-select
|
||||
// the first item
|
||||
currentIndex: -1
|
||||
|
||||
delegate: Kirigami.RadioSubtitleDelegate {
|
||||
id: timeZoneListItem
|
||||
|
||||
readonly property bool isCurrent: Plasmoid.configuration.lastSelectedTimezone === model.timeZoneId
|
||||
readonly property bool isIdenticalToLocal: !model.isLocalTimeZone && model.city === timeZones.localTimeZoneCity()
|
||||
|
||||
width: ListView.view.width
|
||||
|
||||
font.bold: isCurrent
|
||||
|
||||
// Stripes help the eye line up the text on the left and the button on the right
|
||||
Kirigami.Theme.useAlternateBackgroundColor: true
|
||||
|
||||
text: model.city
|
||||
subtitle: {
|
||||
if (configuredTimezoneList.count > 1) {
|
||||
if (isCurrent) {
|
||||
return i18n("Clock is currently using this time zone");
|
||||
} else if (isIdenticalToLocal) {
|
||||
return i18nc("@label This list item shows a time zone city name that is identical to the local time zone's city, and will be hidden in the timezone display in the plasmoid's popup", "Hidden while this is the local time zone's city");
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
checked: isCurrent
|
||||
onToggled: Plasmoid.configuration.lastSelectedTimezone = model.timeZoneId
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Kirigami.TitleSubtitle {
|
||||
Layout.fillWidth: true
|
||||
|
||||
opacity: timeZoneListItem.isIdenticalToLocal ? 0.6 : 1.0
|
||||
|
||||
title: timeZoneListItem.text
|
||||
subtitle: timeZoneListItem.subtitle
|
||||
|
||||
reserveSpaceForSubtitle: true
|
||||
}
|
||||
|
||||
QQC2.Button {
|
||||
visible: model.isLocalTimeZone && KAuthorized.authorizeControlModule("kcm_clock.desktop")
|
||||
text: i18n("Switch Systemwide Time Zone…")
|
||||
icon.name: "preferences-system-time"
|
||||
font.bold: false
|
||||
onClicked: KCMUtils.KCMLauncher.openSystemSettings("kcm_clock")
|
||||
}
|
||||
|
||||
QQC2.Button {
|
||||
visible: !model.isLocalTimeZone && configuredTimezoneList.count > 1
|
||||
icon.name: "edit-delete"
|
||||
font.bold: false
|
||||
onClicked: model.checked = false;
|
||||
QQC2.ToolTip {
|
||||
text: i18n("Remove this time zone")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
property: "isLocalTimeZone"
|
||||
delegate: Kirigami.ListSectionHeader {
|
||||
width: configuredTimezoneList.width
|
||||
label: section === "true" ? i18n("Systemwide Time Zone") : i18n("Additional Time Zones")
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
visible: configuredTimezoneList.count === 1
|
||||
anchors {
|
||||
top: parent.verticalCenter // Visual offset for system timezone and header
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: Kirigami.Units.largeSpacing * 6
|
||||
rightMargin: Kirigami.Units.largeSpacing * 6
|
||||
}
|
||||
text: i18n("Add more time zones to display all of them in the applet's pop-up, or use one of them for the clock itself")
|
||||
}
|
||||
}
|
||||
|
||||
footer: ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
QQC2.Button {
|
||||
Layout.alignment: Qt.AlignLeft // Explicitly set so it gets reversed for LTR mode
|
||||
text: i18n("Add Time Zones…")
|
||||
icon.name: "list-add"
|
||||
onClicked: timezoneSheet.open()
|
||||
}
|
||||
|
||||
QQC2.CheckBox {
|
||||
id: enableWheelCheckBox
|
||||
enabled: configuredTimezoneList.count > 1
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
||||
text: i18n("Switch displayed time zone by scrolling over clock applet")
|
||||
}
|
||||
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Kirigami.Units.largeSpacing * 2
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing * 2
|
||||
text: i18n("Using this feature does not change the systemwide time zone. When you travel, switch the systemwide time zone instead.")
|
||||
font: Kirigami.Theme.smallFont
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: timezoneSheet
|
||||
|
||||
parent: timeZonesPage.QQC2.Overlay.overlay
|
||||
|
||||
onVisibleChanged: {
|
||||
filter.text = "";
|
||||
messageWidget.visible = false;
|
||||
if (visible) {
|
||||
filter.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
header: ColumnLayout {
|
||||
Kirigami.Heading {
|
||||
Layout.fillWidth: true
|
||||
text: i18n("Add More Timezones")
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
Kirigami.SearchField {
|
||||
id: filter
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.InlineMessage {
|
||||
id: messageWidget
|
||||
Layout.fillWidth: true
|
||||
type: Kirigami.MessageType.Warning
|
||||
text: i18n("At least one time zone needs to be enabled. Your local timezone was enabled automatically.")
|
||||
showCloseButton: true
|
||||
}
|
||||
}
|
||||
|
||||
footer: QQC2.DialogButtonBox {
|
||||
standardButtons: QQC2.DialogButtonBox.Ok
|
||||
onAccepted: timezoneSheet.close()
|
||||
}
|
||||
|
||||
ListView {
|
||||
focus: true // keyboard navigation
|
||||
activeFocusOnTab: true // keyboard navigation
|
||||
clip: true
|
||||
implicitWidth: Math.max(timeZonesPage.width/2, Kirigami.Units.iconSizes.small * 25)
|
||||
|
||||
model: TimeZoneFilterProxy {
|
||||
sourceModel: timeZones
|
||||
filterString: filter.text
|
||||
}
|
||||
|
||||
delegate: QQC2.CheckDelegate {
|
||||
required property int index
|
||||
required property var model
|
||||
|
||||
required checked
|
||||
required property string city
|
||||
required property string comment
|
||||
required property string region
|
||||
|
||||
width: ListView.view.width
|
||||
focus: true // keyboard navigation
|
||||
text: {
|
||||
if (!city || city.indexOf("UTC") === 0) {
|
||||
return comment;
|
||||
} else if (comment) {
|
||||
return i18n("%1, %2 (%3)", city, region, comment);
|
||||
} else {
|
||||
return i18n("%1, %2", city, region)
|
||||
}
|
||||
}
|
||||
|
||||
onToggled: {
|
||||
model.checked = checked
|
||||
|
||||
ListView.view.currentIndex = index // highlight
|
||||
ListView.view.forceActiveFocus() // keyboard navigation
|
||||
}
|
||||
highlighted: ListView.isCurrentItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by intika <intika@librefox.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;
|
||||
*
|
||||
* 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.5
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls 1.4
|
||||
|
||||
Item {
|
||||
id: configPageUpdater
|
||||
|
||||
property alias cfg_checkUpdateStartup: checkUpdateStartupBox.checked
|
||||
|
||||
ColumnLayout {
|
||||
GroupBox {
|
||||
flat: true
|
||||
ColumnLayout {
|
||||
Label {
|
||||
text: i18n("\nUpdater")
|
||||
font.weight: Font.Bold
|
||||
}
|
||||
Label {
|
||||
text: i18n("Plasmoid: Digital Clock Lite\n")
|
||||
}
|
||||
Label {
|
||||
text: i18n("Version: 5.5")
|
||||
}
|
||||
Label {
|
||||
text: i18n("Author: Intika")
|
||||
}
|
||||
TextField {
|
||||
Layout.minimumWidth: 450
|
||||
text: 'https://github.com/Intika-Linux-Plasmoid/plasmoid-digital-clock-lite'
|
||||
}
|
||||
CheckBox {
|
||||
id: checkUpdateStartupBox
|
||||
text: i18n("Notify for update on startup (checked once on github, 5 min after startup)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
165
plasma/plasmoids/io.gitgud.wackyideas.digitalclocklite/contents/ui/main.qml
Executable file
165
plasma/plasmoids/io.gitgud.wackyideas.digitalclocklite/contents/ui/main.qml
Executable file
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* 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.15
|
||||
import QtQuick.Layouts 1.1
|
||||
import org.kde.plasma.plasmoid
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.plasma5support as P5Support
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.plasma.private.digitalclock 1.0
|
||||
import org.kde.kquickcontrolsaddons 2.0
|
||||
import org.kde.plasma.workspace.calendar 2.0 as PlasmaCalendar
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
|
||||
import org.kde.kcmutils // KCMLauncher
|
||||
import org.kde.config // KAuthorized
|
||||
|
||||
//import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
//import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
|
||||
|
||||
//import org.kde.plasma.calendar 2.0 as PlasmaCalendar
|
||||
|
||||
PlasmoidItem {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
|
||||
width: Kirigami.Units.iconSizes.small * 10
|
||||
height: Kirigami.Units.iconSizes.small * 4
|
||||
property string dateFormatString: setDateFormatString()
|
||||
property date tzDate: {
|
||||
const data = dataSource.data[Plasmoid.configuration.lastSelectedTimezone];
|
||||
if (data === undefined) {
|
||||
return new Date();
|
||||
}
|
||||
// get the time for the given timezone from the dataengine
|
||||
const now = data["DateTime"];
|
||||
// get current UTC time
|
||||
const msUTC = now.getTime() + (now.getTimezoneOffset() * 60000);
|
||||
// add the dataengine TZ offset to it
|
||||
return new Date(msUTC + (data["Offset"] * 1000));
|
||||
}
|
||||
|
||||
function initTimezones() {
|
||||
const tz = []
|
||||
|
||||
if (Plasmoid.configuration.selectedTimeZones.indexOf("Local") === -1) {
|
||||
tz.push("Local");
|
||||
}
|
||||
root.allTimezones = tz.concat(Plasmoid.configuration.selectedTimeZones);
|
||||
dataSource.connectedSources = root.allTimezones;
|
||||
}
|
||||
|
||||
//This is done to better control how the plasmoid should look and feel in a panel.
|
||||
//preferredRepresentation: fullRepresentation
|
||||
//compactRepresentation: null
|
||||
//fullRepresentation: smallRepresentation
|
||||
|
||||
preferredRepresentation: fullRepresentation
|
||||
compactRepresentation: null
|
||||
fullRepresentation: smallRepresentation
|
||||
|
||||
/*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"
|
||||
}*/
|
||||
KSvg.Svg {
|
||||
id: buttonIcons
|
||||
imagePath: Qt.resolvedUrl("svgs/icons.svg");
|
||||
}
|
||||
KSvg.Svg {
|
||||
id: clockSvg
|
||||
imagePath: Qt.resolvedUrl("svgs/clock.svg");
|
||||
}
|
||||
|
||||
//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
|
||||
function onSelectedTimeZonesChanged() { root.initTimezones(); }
|
||||
}
|
||||
Component {
|
||||
id: mainRepresentation
|
||||
CalendarView {
|
||||
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: smallRepresentation
|
||||
DigitalClock
|
||||
{}
|
||||
}
|
||||
|
||||
hideOnWindowDeactivate: !Plasmoid.configuration.pin
|
||||
|
||||
|
||||
P5Support.DataSource {
|
||||
id: dataSource
|
||||
engine: "time"
|
||||
connectedSources: allTimezones
|
||||
interval: Plasmoid.configuration.showSeconds ? 1000 : 60000
|
||||
intervalAlignment: Plasmoid.configuration.showSeconds ? P5Support.Types.NoAlignment : P5Support.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;
|
||||
}
|
||||
|
||||
Plasmoid.contextualActions: [
|
||||
PlasmaCore.Action {
|
||||
text: i18n("Adjust Date and Time…")
|
||||
icon.name: "clock"
|
||||
visible: KAuthorized.authorize("kcm_clock")
|
||||
onTriggered: KCMLauncher.openSystemSettings("kcm_clock")
|
||||
},
|
||||
PlasmaCore.Action {
|
||||
text: i18n("Set Time Format…")
|
||||
icon.name: "gnumeric-format-thousand-separator"
|
||||
visible: KAuthorized.authorizeControlModule("kcm_regionandlang")
|
||||
onTriggered: KCMLauncher.openSystemSettings("kcm_regionandlang")
|
||||
}
|
||||
]
|
||||
|
||||
PlasmaCalendar.EventPluginsManager {
|
||||
id: eventPluginsManager
|
||||
enabledPlugins: Plasmoid.configuration.enabledCalendarPlugins
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.initTimezones();
|
||||
|
||||
// Set the list of enabled plugins from config
|
||||
// to the manager
|
||||
eventPluginsManager.enabledPlugins = Plasmoid.configuration.enabledCalendarPlugins;
|
||||
|
||||
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,701 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="129"
|
||||
height="129"
|
||||
viewBox="0 0 129 129"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg63"
|
||||
sodipodi:docname="clock.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview63"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="5.6568543"
|
||||
inkscape:cx="78.400464"
|
||||
inkscape:cy="70.799066"
|
||||
inkscape:window-width="1880"
|
||||
inkscape:window-height="1032"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg63"
|
||||
showgrid="false"
|
||||
showguides="true"><inkscape:grid
|
||||
id="grid42"
|
||||
units="px"
|
||||
originx="0"
|
||||
originy="0"
|
||||
spacingx="1"
|
||||
spacingy="1"
|
||||
empcolor="#0099e5"
|
||||
empopacity="0.30196078"
|
||||
color="#e50000"
|
||||
opacity="0.14901961"
|
||||
empspacing="1"
|
||||
dotted="false"
|
||||
gridanglex="30"
|
||||
gridanglez="30"
|
||||
visible="true"
|
||||
snapvisiblegridlinesonly="true" /></sodipodi:namedview><g
|
||||
filter="url(#filter0_d_3_129)"
|
||||
id="clockface"
|
||||
style="display:inline"><mask
|
||||
id="path-1-inside-1_3_129"
|
||||
fill="#ffffff"><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 63.5,0 C 28.9822,0 1,27.9822 1,62.5 1,97.0178 28.9822,125 63.5,125 98.0178,125 126,97.0178 126,62.5 126,27.9822 98.0178,0 63.5,0 Z m 0,4 C 31.1913,4 5,30.1913 5,62.5 5,94.8087 31.1913,121 63.5,121 95.8087,121 122,94.8087 122,62.5 122,30.1913 95.8087,4 63.5,4 Z"
|
||||
id="path1" /></mask><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 63.5,0 C 28.9822,0 1,27.9822 1,62.5 1,97.0178 28.9822,125 63.5,125 98.0178,125 126,97.0178 126,62.5 126,27.9822 98.0178,0 63.5,0 Z m 0,4 C 31.1913,4 5,30.1913 5,62.5 5,94.8087 31.1913,121 63.5,121 95.8087,121 122,94.8087 122,62.5 122,30.1913 95.8087,4 63.5,4 Z"
|
||||
fill="url(#paint0_linear_3_129)"
|
||||
id="path2"
|
||||
style="display:inline;fill:url(#paint0_linear_3_129)" /><path
|
||||
d="M 2,62.5 C 2,28.5345 29.5345,1 63.5,1 V -1 C 28.4299,-1 0,27.4299 0,62.5 Z M 63.5,124 C 29.5345,124 2,96.4655 2,62.5 H 0 C 0,97.5701 28.4299,126 63.5,126 Z M 125,62.5 C 125,96.4655 97.4655,124 63.5,124 v 2 C 98.5701,126 127,97.5701 127,62.5 Z M 63.5,1 C 97.4655,1 125,28.5345 125,62.5 h 2 C 127,27.4299 98.5701,-1 63.5,-1 Z M 6,62.5 C 6,30.7436 31.7436,5 63.5,5 V 3 C 30.6391,3 4,29.6391 4,62.5 Z M 63.5,120 C 31.7436,120 6,94.2564 6,62.5 H 4 C 4,95.3609 30.6391,122 63.5,122 Z M 121,62.5 C 121,94.2564 95.2564,120 63.5,120 v 2 C 96.3609,122 123,95.3609 123,62.5 Z M 63.5,5 C 95.2564,5 121,30.7436 121,62.5 h 2 C 123,29.6391 96.3609,3 63.5,3 Z"
|
||||
fill="#798183"
|
||||
mask="url(#path-1-inside-1_3_129)"
|
||||
id="path3"
|
||||
style="display:inline" /><g
|
||||
filter="url(#filter1_i_3_129)"
|
||||
id="g3"
|
||||
style="display:inline"><circle
|
||||
cx="63.5"
|
||||
cy="62.5"
|
||||
r="58.5"
|
||||
fill="url(#paint1_linear_3_129)"
|
||||
id="circle3"
|
||||
style="display:inline" /></g><g
|
||||
filter="url(#filter2_f_3_129)"
|
||||
id="g4"><circle
|
||||
cx="63.5"
|
||||
cy="62.5"
|
||||
r="56"
|
||||
stroke="url(#paint2_linear_3_129)"
|
||||
stroke-opacity="0.3"
|
||||
id="circle4"
|
||||
style="display:inline;stroke:url(#paint2_linear_3_129)" /></g><mask
|
||||
id="mask0_3_129"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="11"
|
||||
y="10"
|
||||
width="105"
|
||||
height="105"><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 63.5,115 C 92.4949,115 116,91.4949 116,62.5 116,33.5051 92.4949,10 63.5,10 34.5051,10 11,33.5051 11,62.5 11,91.4949 34.5051,115 63.5,115 Z m 0,-8 C 88.0767,107 108,87.0767 108,62.5 108,37.9233 88.0767,18 63.5,18 38.9233,18 19,37.9233 19,62.5 19,87.0767 38.9233,107 63.5,107 Z"
|
||||
fill="#d9d9d9"
|
||||
id="path4" /></mask><g
|
||||
mask="url(#mask0_3_129)"
|
||||
id="g10"
|
||||
style="display:inline"><path
|
||||
d="M 64,10 V 115"
|
||||
stroke="#4b6b6e"
|
||||
stroke-width="2"
|
||||
id="path5" /><path
|
||||
d="m 37.75,17.0337 52.5,90.9323"
|
||||
stroke="#4b6b6e"
|
||||
stroke-width="2"
|
||||
id="path6" /><path
|
||||
d="m 18.5337,36.25 90.9323,52.5"
|
||||
stroke="#4b6b6e"
|
||||
stroke-width="2"
|
||||
id="path7" /><path
|
||||
d="m 11.5,62.5 h 105"
|
||||
stroke="#4b6b6e"
|
||||
stroke-width="2"
|
||||
id="path8" /><path
|
||||
d="M 18.5337,88.75 109.466,36.25"
|
||||
stroke="#4b6b6e"
|
||||
stroke-width="2"
|
||||
id="path9"
|
||||
style="display:inline" /><path
|
||||
d="M 37.75,107.966 90.25,17.0337"
|
||||
stroke="#4b6b6e"
|
||||
stroke-width="2"
|
||||
id="path10"
|
||||
style="display:inline" /></g><g
|
||||
filter="url(#filter3_di_3_129)"
|
||||
id="g42"
|
||||
style="display:inline"><mask
|
||||
id="mask1_3_129"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="10"
|
||||
y="9"
|
||||
width="107"
|
||||
height="107"><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 68.9895,114.712 C 97.8255,111.68 118.744,85.8466 115.712,57.0106 112.68,28.1746 86.8466,7.25606 58.0106,10.2878 29.1745,13.3195 8.25605,39.1535 11.2878,67.9895 14.3195,96.8255 40.1534,117.744 68.9895,114.712 Z M 68.692,111.883 C 95.9656,109.016 115.751,84.5816 112.883,57.308 110.016,30.0344 85.5816,10.2493 58.308,13.1168 31.0344,15.9843 11.2493,40.4184 14.1168,67.692 c 2.8675,27.2736 27.3016,47.059 54.5752,44.191 z"
|
||||
fill="#d9d9d9"
|
||||
id="path11" /></mask><g
|
||||
mask="url(#mask1_3_129)"
|
||||
id="g41"
|
||||
style="display:inline"><path
|
||||
d="M 58.5078,10.2355 69.4867,114.66"
|
||||
stroke="#4b6b6e"
|
||||
id="path12" /><path
|
||||
d="M 33.1371,19.9753 94.8574,104.92"
|
||||
stroke="#4b6b6e"
|
||||
id="path13" /><path
|
||||
d="M 16.0354,41.0956 111.959,83.7998"
|
||||
stroke="#4b6b6e"
|
||||
id="path14" /><path
|
||||
d="M 11.785,67.9372 116.209,56.9583"
|
||||
stroke="#4b6b6e"
|
||||
id="path15" /><path
|
||||
d="M 21.5249,93.3078 106.47,31.5876"
|
||||
stroke="#4b6b6e"
|
||||
id="path16" /><path
|
||||
d="M 42.6451,110.41 85.3494,14.4859"
|
||||
stroke="#4b6b6e"
|
||||
id="path17" /><path
|
||||
d="M 58.5078,10.2355 69.4867,114.66"
|
||||
stroke="#4b6b6e"
|
||||
id="path18" /><path
|
||||
d="M 33.1371,19.9753 94.8574,104.92"
|
||||
stroke="#4b6b6e"
|
||||
id="path19" /><path
|
||||
d="M 16.0354,41.0956 111.959,83.7998"
|
||||
stroke="#4b6b6e"
|
||||
id="path20" /><path
|
||||
d="M 11.785,67.9372 116.209,56.9583"
|
||||
stroke="#4b6b6e"
|
||||
id="path21" /><path
|
||||
d="M 21.5249,93.3078 106.47,31.5876"
|
||||
stroke="#4b6b6e"
|
||||
id="path22" /><path
|
||||
d="M 42.6451,110.41 85.3494,14.4859"
|
||||
stroke="#4b6b6e"
|
||||
id="path23" /><path
|
||||
d="M 53.0737,11.0433 74.9045,113.749"
|
||||
stroke="#4b6b6e"
|
||||
id="path24" /><path
|
||||
d="m 28.8597,23.381 70.2587,78.03"
|
||||
stroke="#4b6b6e"
|
||||
id="path25" /><path
|
||||
d="M 14.0586,46.1727 113.92,78.6194"
|
||||
stroke="#4b6b6e"
|
||||
id="path26" /><path
|
||||
d="M 12.6364,73.3114 115.342,51.4807"
|
||||
stroke="#4b6b6e"
|
||||
id="path27" /><path
|
||||
d="m 24.974,97.5254 78.03,-70.2587"
|
||||
stroke="#4b6b6e"
|
||||
id="path28" /><path
|
||||
d="M 47.7657,112.327 80.2125,12.4656"
|
||||
stroke="#4b6b6e"
|
||||
id="path29" /><path
|
||||
d="m 47.7521,12.415 32.4468,99.861"
|
||||
stroke="#4b6b6e"
|
||||
id="path30" /><path
|
||||
d="M 24.9604,27.2161 102.991,97.4749"
|
||||
stroke="#4b6b6e"
|
||||
id="path31" /><path
|
||||
d="M 12.6228,51.4301 115.328,73.2609"
|
||||
stroke="#4b6b6e"
|
||||
id="path32" /><path
|
||||
d="M 14.0451,78.5689 113.906,46.1221"
|
||||
stroke="#4b6b6e"
|
||||
id="path33" /><path
|
||||
d="M 28.8462,101.361 99.1049,23.3304"
|
||||
stroke="#4b6b6e"
|
||||
id="path34" /><path
|
||||
d="M 53.0602,113.698 74.8909,10.9928"
|
||||
stroke="#4b6b6e"
|
||||
id="path35" /><path
|
||||
d="M 42.6031,14.3355 85.3105,110.258"
|
||||
stroke="#4b6b6e"
|
||||
id="path36" /><path
|
||||
d="M 21.4834,31.4379 106.43,93.1554"
|
||||
stroke="#4b6b6e"
|
||||
id="path37" /><path
|
||||
d="M 11.7444,56.8089 116.169,67.7844"
|
||||
stroke="#4b6b6e"
|
||||
id="path38" /><path
|
||||
d="M 15.9956,83.6503 111.918,40.943"
|
||||
stroke="#4b6b6e"
|
||||
id="path39" /><path
|
||||
d="M 33.0981,104.77 94.8155,19.8232"
|
||||
stroke="#4b6b6e"
|
||||
id="path40" /><path
|
||||
d="M 58.4691,114.509 69.4446,10.0842"
|
||||
stroke="#4b6b6e"
|
||||
id="path41" /></g></g></g><g
|
||||
style="display:inline;fill:none"
|
||||
id="g44"
|
||||
transform="translate(4,3)"><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 119,59.5 C 119,92.3609 92.3609,119 59.5,119 43.1967,119 28.4249,112.443 17.6779,101.822 7.05708,91.0751 0.5,76.3033 0.5,60 0.5,27.1391 27.1391,0.5 60,0.5 76.3033,0.5 91.0751,7.05708 101.822,17.6779 112.443,28.4249 119,43.1967 119,59.5 Z M 118.5,60 C 118.5,92.3087 92.3087,118.5 60,118.5 27.6913,118.5 1.5,92.3087 1.5,60 1.5,27.6913 27.6913,1.5 60,1.5 c 32.3087,0 58.5,26.1913 58.5,58.5 z"
|
||||
fill="#b3b6bc"
|
||||
id="path1-3" /><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 59.5,118 C 91.8087,118 118,91.8087 118,59.5 118,27.1913 91.8087,1 59.5,1 27.1913,1 1,27.1913 1,59.5 1,91.8087 27.1913,118 59.5,118 Z m 0,1 C 92.3609,119 119,92.3609 119,59.5 119,26.6391 92.3609,0 59.5,0 26.6391,0 0,26.6391 0,59.5 0,92.3609 26.6391,119 59.5,119 Z"
|
||||
fill="#8892a3"
|
||||
id="path2-7" /></g><defs
|
||||
id="defs63"><filter
|
||||
id="filter0_d_3_129"
|
||||
x="0"
|
||||
y="0"
|
||||
width="129"
|
||||
height="129"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood43" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix43" /><feOffset
|
||||
dx="1"
|
||||
dy="2"
|
||||
id="feOffset43" /><feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur43" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite43" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"
|
||||
id="feColorMatrix44" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_129"
|
||||
id="feBlend44" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_129"
|
||||
result="shape"
|
||||
id="feBlend45" /></filter><filter
|
||||
id="filter1_i_3_129"
|
||||
x="5"
|
||||
y="4"
|
||||
width="117"
|
||||
height="117"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood45" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="BackgroundImageFix"
|
||||
result="shape"
|
||||
id="feBlend46" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix46" /><feOffset
|
||||
id="feOffset46" /><feGaussianBlur
|
||||
stdDeviation="1.5"
|
||||
id="feGaussianBlur46" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="arithmetic"
|
||||
k2="-1"
|
||||
k3="1"
|
||||
id="feComposite46" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"
|
||||
id="feColorMatrix47" /><feBlend
|
||||
mode="normal"
|
||||
in2="shape"
|
||||
result="effect1_innerShadow_3_129"
|
||||
id="feBlend47" /></filter><filter
|
||||
id="filter2_f_3_129"
|
||||
x="6"
|
||||
y="5"
|
||||
width="115"
|
||||
height="115"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood47" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="BackgroundImageFix"
|
||||
result="shape"
|
||||
id="feBlend48" /><feGaussianBlur
|
||||
stdDeviation="0.5"
|
||||
result="effect1_foregroundBlur_3_129"
|
||||
id="feGaussianBlur48" /></filter><filter
|
||||
id="filter3_di_3_129"
|
||||
x="10.8921"
|
||||
y="9.23197"
|
||||
width="105.312"
|
||||
height="105.68"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood48" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix48" /><feOffset
|
||||
dx="-0.8"
|
||||
dy="-0.8"
|
||||
id="feOffset48" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite48" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"
|
||||
id="feColorMatrix49" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_129"
|
||||
id="feBlend49" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_129"
|
||||
result="shape"
|
||||
id="feBlend50" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix50" /><feOffset
|
||||
dx="0.2"
|
||||
dy="0.2"
|
||||
id="feOffset50" /><feGaussianBlur
|
||||
stdDeviation="0.25"
|
||||
id="feGaussianBlur50" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="arithmetic"
|
||||
k2="-1"
|
||||
k3="1"
|
||||
id="feComposite50" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"
|
||||
id="feColorMatrix51" /><feBlend
|
||||
mode="normal"
|
||||
in2="shape"
|
||||
result="effect2_innerShadow_3_129"
|
||||
id="feBlend51" /></filter><linearGradient
|
||||
id="paint0_linear_3_129"
|
||||
x1="9.2331963"
|
||||
y1="19.919386"
|
||||
x2="86.97599"
|
||||
y2="68.179153"
|
||||
gradientUnits="userSpaceOnUse"><stop
|
||||
stop-color="#F8FEFF"
|
||||
id="stop51" /><stop
|
||||
offset="0.486626"
|
||||
stop-color="#E1E3E7"
|
||||
id="stop52" /><stop
|
||||
offset="0.782747"
|
||||
stop-color="#C2C6C7"
|
||||
id="stop53" /></linearGradient><linearGradient
|
||||
id="paint1_linear_3_129"
|
||||
x1="19.5"
|
||||
y1="18.5"
|
||||
x2="107.5"
|
||||
y2="106.5"
|
||||
gradientUnits="userSpaceOnUse"><stop
|
||||
stop-color="#E2EBEF"
|
||||
id="stop54" /><stop
|
||||
offset="0.23"
|
||||
stop-color="#ECF0F1"
|
||||
id="stop55" /><stop
|
||||
offset="0.38"
|
||||
stop-color="#D7E0E2"
|
||||
id="stop56" /><stop
|
||||
offset="0.5"
|
||||
stop-color="#CDD8DB"
|
||||
id="stop57" /><stop
|
||||
offset="0.63"
|
||||
stop-color="#D6DFE2"
|
||||
id="stop58" /><stop
|
||||
offset="0.91"
|
||||
stop-color="#FCFEFF"
|
||||
id="stop59" /></linearGradient><linearGradient
|
||||
id="paint2_linear_3_129"
|
||||
x1="47.008453"
|
||||
y1="30.222439"
|
||||
x2="82.889488"
|
||||
y2="91.564278"
|
||||
gradientUnits="userSpaceOnUse"><stop
|
||||
stop-color="#26444E"
|
||||
id="stop60" /><stop
|
||||
offset="0.5"
|
||||
stop-color="#26444E"
|
||||
stop-opacity="0"
|
||||
id="stop61" /></linearGradient><radialGradient
|
||||
id="paint3_radial_3_129"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(62.5 61.5) rotate(45) scale(3.53553)"><stop
|
||||
offset="0.025"
|
||||
stop-color="#579FA4"
|
||||
id="stop62" /><stop
|
||||
offset="0.64"
|
||||
stop-color="#213C3E"
|
||||
id="stop63" /></radialGradient><filter
|
||||
id="filter1_df_3_182"
|
||||
x="2"
|
||||
y="2"
|
||||
width="117.681"
|
||||
height="97.7024"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood4" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix4" /><feOffset
|
||||
dy="4"
|
||||
id="feOffset4" /><feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur5" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite5" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0"
|
||||
id="feColorMatrix5" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_182"
|
||||
id="feBlend5" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_182"
|
||||
result="shape"
|
||||
id="feBlend6" /><feGaussianBlur
|
||||
stdDeviation="1"
|
||||
result="effect2_foregroundBlur_3_182"
|
||||
id="feGaussianBlur6" /></filter><linearGradient
|
||||
id="paint1_linear_3_182"
|
||||
x1="37"
|
||||
y1="10.5"
|
||||
x2="67"
|
||||
y2="72.5"
|
||||
gradientUnits="userSpaceOnUse"><stop
|
||||
stop-color="white"
|
||||
stop-opacity="0"
|
||||
id="stop8" /><stop
|
||||
offset="1"
|
||||
stop-color="white"
|
||||
id="stop9" /></linearGradient><filter
|
||||
id="filter0_df_3_182"
|
||||
x="2"
|
||||
y="3"
|
||||
width="114.604"
|
||||
height="110.884"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood2" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix2" /><feOffset
|
||||
dy="4"
|
||||
id="feOffset2" /><feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur2" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite2" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0"
|
||||
id="feColorMatrix3" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_182"
|
||||
id="feBlend3" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_182"
|
||||
result="shape"
|
||||
id="feBlend4" /><feGaussianBlur
|
||||
stdDeviation="0.5"
|
||||
result="effect2_foregroundBlur_3_182"
|
||||
id="feGaussianBlur4" /></filter><filter
|
||||
id="filter1_df_3_182-3"
|
||||
x="2"
|
||||
y="2"
|
||||
width="117.681"
|
||||
height="97.7024"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood4-6" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix4-7" /><feOffset
|
||||
dy="4"
|
||||
id="feOffset4-5" /><feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur5-3" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite5-5" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0"
|
||||
id="feColorMatrix5-6" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_182"
|
||||
id="feBlend5-2" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_182"
|
||||
result="shape"
|
||||
id="feBlend6-9" /><feGaussianBlur
|
||||
stdDeviation="1"
|
||||
result="effect2_foregroundBlur_3_182"
|
||||
id="feGaussianBlur6-1" /></filter><filter
|
||||
id="filter0_df_3_182-0"
|
||||
x="2"
|
||||
y="3"
|
||||
width="114.604"
|
||||
height="110.884"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood2-9" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix2-3" /><feOffset
|
||||
dy="4"
|
||||
id="feOffset2-6" /><feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur2-0" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite2-6" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0"
|
||||
id="feColorMatrix3-2" /><feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_182"
|
||||
id="feBlend3-6" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_182"
|
||||
result="shape"
|
||||
id="feBlend4-1" /><feGaussianBlur
|
||||
stdDeviation="0.5"
|
||||
result="effect2_foregroundBlur_3_182"
|
||||
id="feGaussianBlur4-8" /></filter><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#paint1_linear_3_182"
|
||||
id="linearGradient1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="37"
|
||||
y1="10.5"
|
||||
x2="67"
|
||||
y2="72.5" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#paint1_linear_3_182"
|
||||
id="linearGradient2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="37"
|
||||
y1="10.5"
|
||||
x2="67"
|
||||
y2="72.5" /><filter
|
||||
id="filter1_i_3_129-2"
|
||||
x="5"
|
||||
y="4"
|
||||
width="117"
|
||||
height="117"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"><feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood45-0" /><feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="BackgroundImageFix"
|
||||
result="shape"
|
||||
id="feBlend46-2" /><feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix46-3" /><feOffset
|
||||
id="feOffset46-7" /><feGaussianBlur
|
||||
stdDeviation="1.5"
|
||||
id="feGaussianBlur46-5" /><feComposite
|
||||
in2="hardAlpha"
|
||||
operator="arithmetic"
|
||||
k2="-1"
|
||||
k3="1"
|
||||
id="feComposite46-9"
|
||||
k1="0"
|
||||
k4="0" /><feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"
|
||||
id="feColorMatrix47-2" /><feBlend
|
||||
mode="normal"
|
||||
in2="shape"
|
||||
result="effect1_innerShadow_3_129"
|
||||
id="feBlend47-2" /></filter></defs><circle
|
||||
cx="63.5"
|
||||
cy="62.5"
|
||||
r="2.5"
|
||||
fill="url(#paint3_radial_3_129)"
|
||||
id="clockdot" /><g
|
||||
id="clockshine"><g
|
||||
opacity="0.14"
|
||||
filter="url(#filter0_df_3_182)"
|
||||
id="g2"
|
||||
style="filter:url(#filter0_df_3_182-0)"><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 114.604,35.8755 C 98.6369,29.2336 73.1157,37.2154 52.1952,56.76 35.0872,72.7428 25.4849,92.3203 25.5839,107.884 12.4127,97.1568 4,80.8109 4,62.5 4,30.1913 30.1913,4 62.5,4 c 22.7201,0 42.415,12.9521 52.104,31.8755 z"
|
||||
fill="url(#paint0_linear_3_182)"
|
||||
shape-rendering="crispEdges"
|
||||
id="path1-7"
|
||||
style="fill:url(#linearGradient1)" /></g><g
|
||||
opacity="0.6"
|
||||
filter="url(#filter1_df_3_182)"
|
||||
id="g3-9"
|
||||
style="filter:url(#filter1_df_3_182-3)"><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 117.681,43.0287 C 104.615,41.2781 88.9173,42.3436 72.6911,46.6914 39.2424,55.6539 14.7141,75.572 13.0071,93.7024 7.30188,84.6718 4,73.9715 4,62.5 4,30.1913 30.1913,4 62.5,4 c 25.482,0 47.159,16.2924 55.181,39.0287 z"
|
||||
fill="url(#paint1_linear_3_182)"
|
||||
shape-rendering="crispEdges"
|
||||
id="path2-2"
|
||||
style="fill:url(#linearGradient2)" /></g><rect
|
||||
style="opacity:0;fill:#2c2c2c;stroke:#2c2c2c;stroke-width:0;stroke-opacity:0.984036"
|
||||
id="rect5"
|
||||
width="129"
|
||||
height="129"
|
||||
x="0"
|
||||
y="0" /></g></svg>
|
After Width: | Height: | Size: 24 KiB |
|
@ -0,0 +1,809 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="129"
|
||||
height="129"
|
||||
viewBox="0 0 129 129"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg63"
|
||||
sodipodi:docname="clock.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview63"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="5.4983399"
|
||||
inkscape:cx="83.388806"
|
||||
inkscape:cy="82.206631"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="838"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="clockface" />
|
||||
<g
|
||||
filter="url(#filter0_d_3_129)"
|
||||
id="clockface">
|
||||
<mask
|
||||
id="path-1-inside-1_3_129"
|
||||
fill="white">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M63.5 0C28.9822 0 1 27.9822 1 62.5C1 97.0178 28.9822 125 63.5 125C98.0178 125 126 97.0178 126 62.5C126 27.9822 98.0178 0 63.5 0ZM63.5 4C31.1913 4 5 30.1913 5 62.5C5 94.8087 31.1913 121 63.5 121C95.8087 121 122 94.8087 122 62.5C122 30.1913 95.8087 4 63.5 4Z"
|
||||
id="path1" />
|
||||
</mask>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M63.5 0C28.9822 0 1 27.9822 1 62.5C1 97.0178 28.9822 125 63.5 125C98.0178 125 126 97.0178 126 62.5C126 27.9822 98.0178 0 63.5 0ZM63.5 4C31.1913 4 5 30.1913 5 62.5C5 94.8087 31.1913 121 63.5 121C95.8087 121 122 94.8087 122 62.5C122 30.1913 95.8087 4 63.5 4Z"
|
||||
fill="url(#paint0_linear_3_129)"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M2 62.5C2 28.5345 29.5345 1 63.5 1V-1C28.4299 -1 0 27.4299 0 62.5H2ZM63.5 124C29.5345 124 2 96.4655 2 62.5H0C0 97.5701 28.4299 126 63.5 126V124ZM125 62.5C125 96.4655 97.4655 124 63.5 124V126C98.5701 126 127 97.5701 127 62.5H125ZM63.5 1C97.4655 1 125 28.5345 125 62.5H127C127 27.4299 98.5701 -1 63.5 -1V1ZM6 62.5C6 30.7436 31.7436 5 63.5 5V3C30.6391 3 4 29.6391 4 62.5H6ZM63.5 120C31.7436 120 6 94.2564 6 62.5H4C4 95.3609 30.6391 122 63.5 122V120ZM121 62.5C121 94.2564 95.2564 120 63.5 120V122C96.3609 122 123 95.3609 123 62.5H121ZM63.5 5C95.2564 5 121 30.7436 121 62.5H123C123 29.6391 96.3609 3 63.5 3V5Z"
|
||||
fill="#798183"
|
||||
mask="url(#path-1-inside-1_3_129)"
|
||||
id="path3" />
|
||||
<g
|
||||
filter="url(#filter1_i_3_129)"
|
||||
id="g3">
|
||||
<circle
|
||||
cx="63.5"
|
||||
cy="62.5"
|
||||
r="58.5"
|
||||
fill="url(#paint1_linear_3_129)"
|
||||
id="circle3" />
|
||||
</g>
|
||||
<g
|
||||
filter="url(#filter2_f_3_129)"
|
||||
id="g4">
|
||||
<circle
|
||||
cx="63.5"
|
||||
cy="62.5"
|
||||
r="56"
|
||||
stroke="url(#paint2_linear_3_129)"
|
||||
stroke-opacity="0.3"
|
||||
id="circle4" />
|
||||
</g>
|
||||
<mask
|
||||
id="mask0_3_129"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="11"
|
||||
y="10"
|
||||
width="105"
|
||||
height="105"
|
||||
style="mask-type:alpha">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M63.5 115C92.4949 115 116 91.4949 116 62.5C116 33.5051 92.4949 10 63.5 10C34.5051 10 11 33.5051 11 62.5C11 91.4949 34.5051 115 63.5 115ZM63.5 107C88.0767 107 108 87.0767 108 62.5C108 37.9233 88.0767 18 63.5 18C38.9233 18 19 37.9233 19 62.5C19 87.0767 38.9233 107 63.5 107Z"
|
||||
fill="#D9D9D9"
|
||||
id="path4" />
|
||||
</mask>
|
||||
<g
|
||||
mask="url(#mask0_3_129)"
|
||||
id="g10">
|
||||
<path
|
||||
d="M64 10V115"
|
||||
stroke="#4B6B6E"
|
||||
stroke-width="2"
|
||||
id="path5" />
|
||||
<path
|
||||
d="M37.75 17.0337L90.25 107.966"
|
||||
stroke="#4B6B6E"
|
||||
stroke-width="2"
|
||||
id="path6" />
|
||||
<path
|
||||
d="M18.5337 36.25L109.466 88.75"
|
||||
stroke="#4B6B6E"
|
||||
stroke-width="2"
|
||||
id="path7" />
|
||||
<path
|
||||
d="M11.5 62.5L116.5 62.5"
|
||||
stroke="#4B6B6E"
|
||||
stroke-width="2"
|
||||
id="path8" />
|
||||
<path
|
||||
d="M18.5337 88.75L109.466 36.25"
|
||||
stroke="#4B6B6E"
|
||||
stroke-width="2"
|
||||
id="path9" />
|
||||
<path
|
||||
d="M37.75 107.966L90.25 17.0337"
|
||||
stroke="#4B6B6E"
|
||||
stroke-width="2"
|
||||
id="path10" />
|
||||
</g>
|
||||
<g
|
||||
filter="url(#filter3_di_3_129)"
|
||||
id="g42">
|
||||
<mask
|
||||
id="mask1_3_129"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="10"
|
||||
y="9"
|
||||
width="107"
|
||||
height="107"
|
||||
style="mask-type:alpha">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M68.9895 114.712C97.8255 111.68 118.744 85.8466 115.712 57.0106C112.68 28.1746 86.8466 7.25606 58.0106 10.2878C29.1745 13.3195 8.25605 39.1535 11.2878 67.9895C14.3195 96.8255 40.1534 117.744 68.9895 114.712ZM68.692 111.883C95.9656 109.016 115.751 84.5816 112.883 57.308C110.016 30.0344 85.5816 10.2493 58.308 13.1168C31.0344 15.9843 11.2493 40.4184 14.1168 67.692C16.9843 94.9656 41.4184 114.751 68.692 111.883Z"
|
||||
fill="#D9D9D9"
|
||||
id="path11" />
|
||||
</mask>
|
||||
<g
|
||||
mask="url(#mask1_3_129)"
|
||||
id="g41">
|
||||
<path
|
||||
d="M58.5078 10.2355L69.4867 114.66"
|
||||
stroke="#4B6B6E"
|
||||
id="path12" />
|
||||
<path
|
||||
d="M33.1371 19.9753L94.8574 104.92"
|
||||
stroke="#4B6B6E"
|
||||
id="path13" />
|
||||
<path
|
||||
d="M16.0354 41.0956L111.959 83.7998"
|
||||
stroke="#4B6B6E"
|
||||
id="path14" />
|
||||
<path
|
||||
d="M11.785 67.9372L116.209 56.9583"
|
||||
stroke="#4B6B6E"
|
||||
id="path15" />
|
||||
<path
|
||||
d="M21.5249 93.3078L106.47 31.5876"
|
||||
stroke="#4B6B6E"
|
||||
id="path16" />
|
||||
<path
|
||||
d="M42.6451 110.41L85.3494 14.4859"
|
||||
stroke="#4B6B6E"
|
||||
id="path17" />
|
||||
<path
|
||||
d="M58.5078 10.2355L69.4867 114.66"
|
||||
stroke="#4B6B6E"
|
||||
id="path18" />
|
||||
<path
|
||||
d="M33.1371 19.9753L94.8574 104.92"
|
||||
stroke="#4B6B6E"
|
||||
id="path19" />
|
||||
<path
|
||||
d="M16.0354 41.0956L111.959 83.7998"
|
||||
stroke="#4B6B6E"
|
||||
id="path20" />
|
||||
<path
|
||||
d="M11.785 67.9372L116.209 56.9583"
|
||||
stroke="#4B6B6E"
|
||||
id="path21" />
|
||||
<path
|
||||
d="M21.5249 93.3078L106.47 31.5876"
|
||||
stroke="#4B6B6E"
|
||||
id="path22" />
|
||||
<path
|
||||
d="M42.6451 110.41L85.3494 14.4859"
|
||||
stroke="#4B6B6E"
|
||||
id="path23" />
|
||||
<path
|
||||
d="M53.0737 11.0433L74.9045 113.749"
|
||||
stroke="#4B6B6E"
|
||||
id="path24" />
|
||||
<path
|
||||
d="M28.8597 23.381L99.1184 101.411"
|
||||
stroke="#4B6B6E"
|
||||
id="path25" />
|
||||
<path
|
||||
d="M14.0586 46.1727L113.92 78.6194"
|
||||
stroke="#4B6B6E"
|
||||
id="path26" />
|
||||
<path
|
||||
d="M12.6364 73.3114L115.342 51.4807"
|
||||
stroke="#4B6B6E"
|
||||
id="path27" />
|
||||
<path
|
||||
d="M24.974 97.5254L103.004 27.2667"
|
||||
stroke="#4B6B6E"
|
||||
id="path28" />
|
||||
<path
|
||||
d="M47.7657 112.327L80.2125 12.4656"
|
||||
stroke="#4B6B6E"
|
||||
id="path29" />
|
||||
<path
|
||||
d="M47.7521 12.415L80.1989 112.276"
|
||||
stroke="#4B6B6E"
|
||||
id="path30" />
|
||||
<path
|
||||
d="M24.9604 27.2161L102.991 97.4749"
|
||||
stroke="#4B6B6E"
|
||||
id="path31" />
|
||||
<path
|
||||
d="M12.6228 51.4301L115.328 73.2609"
|
||||
stroke="#4B6B6E"
|
||||
id="path32" />
|
||||
<path
|
||||
d="M14.0451 78.5689L113.906 46.1221"
|
||||
stroke="#4B6B6E"
|
||||
id="path33" />
|
||||
<path
|
||||
d="M28.8462 101.361L99.1049 23.3304"
|
||||
stroke="#4B6B6E"
|
||||
id="path34" />
|
||||
<path
|
||||
d="M53.0602 113.698L74.8909 10.9928"
|
||||
stroke="#4B6B6E"
|
||||
id="path35" />
|
||||
<path
|
||||
d="M42.6031 14.3355L85.3105 110.258"
|
||||
stroke="#4B6B6E"
|
||||
id="path36" />
|
||||
<path
|
||||
d="M21.4834 31.4379L106.43 93.1554"
|
||||
stroke="#4B6B6E"
|
||||
id="path37" />
|
||||
<path
|
||||
d="M11.7444 56.8089L116.169 67.7844"
|
||||
stroke="#4B6B6E"
|
||||
id="path38" />
|
||||
<path
|
||||
d="M15.9956 83.6503L111.918 40.943"
|
||||
stroke="#4B6B6E"
|
||||
id="path39" />
|
||||
<path
|
||||
d="M33.0981 104.77L94.8155 19.8232"
|
||||
stroke="#4B6B6E"
|
||||
id="path40" />
|
||||
<path
|
||||
d="M58.4691 114.509L69.4446 10.0842"
|
||||
stroke="#4B6B6E"
|
||||
id="path41" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<defs
|
||||
id="defs63">
|
||||
<filter
|
||||
id="filter0_d_3_129"
|
||||
x="0"
|
||||
y="0"
|
||||
width="129"
|
||||
height="129"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood43" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix43" />
|
||||
<feOffset
|
||||
dx="1"
|
||||
dy="2"
|
||||
id="feOffset43" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur43" />
|
||||
<feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite43" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"
|
||||
id="feColorMatrix44" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_129"
|
||||
id="feBlend44" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_129"
|
||||
result="shape"
|
||||
id="feBlend45" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter1_i_3_129"
|
||||
x="5"
|
||||
y="4"
|
||||
width="117"
|
||||
height="117"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood45" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="BackgroundImageFix"
|
||||
result="shape"
|
||||
id="feBlend46" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix46" />
|
||||
<feOffset
|
||||
id="feOffset46" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="1.5"
|
||||
id="feGaussianBlur46" />
|
||||
<feComposite
|
||||
in2="hardAlpha"
|
||||
operator="arithmetic"
|
||||
k2="-1"
|
||||
k3="1"
|
||||
id="feComposite46" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"
|
||||
id="feColorMatrix47" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="shape"
|
||||
result="effect1_innerShadow_3_129"
|
||||
id="feBlend47" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter2_f_3_129"
|
||||
x="6"
|
||||
y="5"
|
||||
width="115"
|
||||
height="115"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood47" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="BackgroundImageFix"
|
||||
result="shape"
|
||||
id="feBlend48" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="0.5"
|
||||
result="effect1_foregroundBlur_3_129"
|
||||
id="feGaussianBlur48" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3_di_3_129"
|
||||
x="10.8921"
|
||||
y="9.23197"
|
||||
width="105.312"
|
||||
height="105.68"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood48" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix48" />
|
||||
<feOffset
|
||||
dx="-0.8"
|
||||
dy="-0.8"
|
||||
id="feOffset48" />
|
||||
<feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite48" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"
|
||||
id="feColorMatrix49" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_129"
|
||||
id="feBlend49" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_129"
|
||||
result="shape"
|
||||
id="feBlend50" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix50" />
|
||||
<feOffset
|
||||
dx="0.2"
|
||||
dy="0.2"
|
||||
id="feOffset50" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="0.25"
|
||||
id="feGaussianBlur50" />
|
||||
<feComposite
|
||||
in2="hardAlpha"
|
||||
operator="arithmetic"
|
||||
k2="-1"
|
||||
k3="1"
|
||||
id="feComposite50" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"
|
||||
id="feColorMatrix51" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="shape"
|
||||
result="effect2_innerShadow_3_129"
|
||||
id="feBlend51" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
id="paint0_linear_3_129"
|
||||
x1="1.08514"
|
||||
y1="50.7284"
|
||||
x2="124.915"
|
||||
y2="73.2716"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#F8FEFF"
|
||||
id="stop51" />
|
||||
<stop
|
||||
offset="0.486626"
|
||||
stop-color="#E1E3E7"
|
||||
id="stop52" />
|
||||
<stop
|
||||
offset="0.782747"
|
||||
stop-color="#C2C6C7"
|
||||
id="stop53" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint1_linear_3_129"
|
||||
x1="19.5"
|
||||
y1="18.5"
|
||||
x2="107.5"
|
||||
y2="106.5"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#E2EBEF"
|
||||
id="stop54" />
|
||||
<stop
|
||||
offset="0.23"
|
||||
stop-color="#ECF0F1"
|
||||
id="stop55" />
|
||||
<stop
|
||||
offset="0.38"
|
||||
stop-color="#D7E0E2"
|
||||
id="stop56" />
|
||||
<stop
|
||||
offset="0.5"
|
||||
stop-color="#CDD8DB"
|
||||
id="stop57" />
|
||||
<stop
|
||||
offset="0.63"
|
||||
stop-color="#D6DFE2"
|
||||
id="stop58" />
|
||||
<stop
|
||||
offset="0.91"
|
||||
stop-color="#FCFEFF"
|
||||
id="stop59" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint2_linear_3_129"
|
||||
x1="19"
|
||||
y1="18"
|
||||
x2="89"
|
||||
y2="88"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#26444E"
|
||||
id="stop60" />
|
||||
<stop
|
||||
offset="0.5"
|
||||
stop-color="#26444E"
|
||||
stop-opacity="0"
|
||||
id="stop61" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="paint3_radial_3_129"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(62.5 61.5) rotate(45) scale(3.53553)">
|
||||
<stop
|
||||
offset="0.025"
|
||||
stop-color="#579FA4"
|
||||
id="stop62" />
|
||||
<stop
|
||||
offset="0.64"
|
||||
stop-color="#213C3E"
|
||||
id="stop63" />
|
||||
</radialGradient>
|
||||
<filter
|
||||
id="filter1_df_3_182"
|
||||
x="2"
|
||||
y="2"
|
||||
width="117.681"
|
||||
height="97.7024"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood4" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix4" />
|
||||
<feOffset
|
||||
dy="4"
|
||||
id="feOffset4" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur5" />
|
||||
<feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite5" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0"
|
||||
id="feColorMatrix5" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_182"
|
||||
id="feBlend5" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_182"
|
||||
result="shape"
|
||||
id="feBlend6" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
result="effect2_foregroundBlur_3_182"
|
||||
id="feGaussianBlur6" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
id="paint1_linear_3_182"
|
||||
x1="37"
|
||||
y1="10.5"
|
||||
x2="67"
|
||||
y2="72.5"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="white"
|
||||
stop-opacity="0"
|
||||
id="stop8" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="white"
|
||||
id="stop9" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
id="filter0_df_3_182"
|
||||
x="2"
|
||||
y="3"
|
||||
width="114.604"
|
||||
height="110.884"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood2" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix2" />
|
||||
<feOffset
|
||||
dy="4"
|
||||
id="feOffset2" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur2" />
|
||||
<feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite2" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0"
|
||||
id="feColorMatrix3" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_182"
|
||||
id="feBlend3" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_182"
|
||||
result="shape"
|
||||
id="feBlend4" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="0.5"
|
||||
result="effect2_foregroundBlur_3_182"
|
||||
id="feGaussianBlur4" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter1_df_3_182-3"
|
||||
x="2"
|
||||
y="2"
|
||||
width="117.681"
|
||||
height="97.7024"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood4-6" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix4-7" />
|
||||
<feOffset
|
||||
dy="4"
|
||||
id="feOffset4-5" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur5-3" />
|
||||
<feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite5-5" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0"
|
||||
id="feColorMatrix5-6" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_182"
|
||||
id="feBlend5-2" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_182"
|
||||
result="shape"
|
||||
id="feBlend6-9" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
result="effect2_foregroundBlur_3_182"
|
||||
id="feGaussianBlur6-1" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter0_df_3_182-0"
|
||||
x="2"
|
||||
y="3"
|
||||
width="114.604"
|
||||
height="110.884"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood2-9" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix2-3" />
|
||||
<feOffset
|
||||
dy="4"
|
||||
id="feOffset2-6" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur2-0" />
|
||||
<feComposite
|
||||
in2="hardAlpha"
|
||||
operator="out"
|
||||
id="feComposite2-6" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.03 0"
|
||||
id="feColorMatrix3-2" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3_182"
|
||||
id="feBlend3-6" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3_182"
|
||||
result="shape"
|
||||
id="feBlend4-1" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="0.5"
|
||||
result="effect2_foregroundBlur_3_182"
|
||||
id="feGaussianBlur4-8" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#paint1_linear_3_182"
|
||||
id="linearGradient1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="37"
|
||||
y1="10.5"
|
||||
x2="67"
|
||||
y2="72.5" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#paint1_linear_3_182"
|
||||
id="linearGradient2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="37"
|
||||
y1="10.5"
|
||||
x2="67"
|
||||
y2="72.5" />
|
||||
</defs>
|
||||
<circle
|
||||
cx="63.5"
|
||||
cy="62.5"
|
||||
r="2.5"
|
||||
fill="url(#paint3_radial_3_129)"
|
||||
id="clockdot" />
|
||||
<g
|
||||
id="clockshine">
|
||||
<g
|
||||
opacity="0.14"
|
||||
filter="url(#filter0_df_3_182)"
|
||||
id="g2"
|
||||
style="filter:url(#filter0_df_3_182-0)">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 114.604,35.8755 C 98.6369,29.2336 73.1157,37.2154 52.1952,56.76 35.0872,72.7428 25.4849,92.3203 25.5839,107.884 12.4127,97.1568 4,80.8109 4,62.5 4,30.1913 30.1913,4 62.5,4 c 22.7201,0 42.415,12.9521 52.104,31.8755 z"
|
||||
fill="url(#paint0_linear_3_182)"
|
||||
shape-rendering="crispEdges"
|
||||
id="path1-7"
|
||||
style="fill:url(#linearGradient1)" />
|
||||
</g>
|
||||
<g
|
||||
opacity="0.6"
|
||||
filter="url(#filter1_df_3_182)"
|
||||
id="g3-9"
|
||||
style="filter:url(#filter1_df_3_182-3)">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M 117.681,43.0287 C 104.615,41.2781 88.9173,42.3436 72.6911,46.6914 39.2424,55.6539 14.7141,75.572 13.0071,93.7024 7.30188,84.6718 4,73.9715 4,62.5 4,30.1913 30.1913,4 62.5,4 c 25.482,0 47.159,16.2924 55.181,39.0287 z"
|
||||
fill="url(#paint1_linear_3_182)"
|
||||
shape-rendering="crispEdges"
|
||||
id="path2-2"
|
||||
style="fill:url(#linearGradient2)" />
|
||||
</g>
|
||||
<rect
|
||||
style="opacity:0;fill:#2c2c2c;stroke:#2c2c2c;stroke-width:0;stroke-opacity:0.984036"
|
||||
id="rect5"
|
||||
width="129"
|
||||
height="129"
|
||||
x="0"
|
||||
y="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 23 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue