1/* 2 SPDX-FileCopyrightText: 2012 Viranch Mehta <viranch.mehta@gmail.com> 3 SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org> 4 SPDX-FileCopyrightText: 2013 David Edmundson <davidedmundson@kde.org> 5 6 SPDX-License-Identifier: LGPL-2.0-or-later 7*/ 8 9import QtQuick 2.0 10import org.kde.plasma.plasmoid 2.0 11import org.kde.plasma.calendar 2.0 as PlasmaCalendar 12import QtQuick.Layouts 1.1 13 14import org.kde.plasma.core 2.0 as PlasmaCore 15import org.kde.plasma.components 3.0 as PlasmaComponents 16 17Item { 18 id: analogclock 19 20 width: PlasmaCore.Units.gridUnit * 15 21 height: PlasmaCore.Units.gridUnit * 15 22 property int hours 23 property int minutes 24 property int seconds 25 property bool showSecondsHand: plasmoid.configuration.showSecondHand 26 property bool showTimezone: plasmoid.configuration.showTimezoneString 27 property int tzOffset 28 29 Plasmoid.backgroundHints: "NoBackground"; 30 Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation 31 32 Plasmoid.toolTipMainText: Qt.formatDate(dataSource.data["Local"]["DateTime"],"dddd") 33 Plasmoid.toolTipSubText: Qt.formatTime(dataSource.data["Local"]["DateTime"], Qt.locale().timeFormat(Locale.LongFormat)) + "\n" + 34 Qt.formatDate(dataSource.data["Local"]["DateTime"], Qt.locale().dateFormat(Locale.LongFormat).replace(/(^dddd.?\s)|(,?\sdddd$)/, "")) 35 36 PlasmaCore.DataSource { 37 id: dataSource 38 engine: "time" 39 connectedSources: "Local" 40 interval: showSecondsHand ? 1000 : 30000 41 onDataChanged: { 42 var date = new Date(data["Local"]["DateTime"]); 43 hours = date.getHours(); 44 minutes = date.getMinutes(); 45 seconds = date.getSeconds(); 46 } 47 Component.onCompleted: { 48 onDataChanged(); 49 } 50 } 51 52 function dateTimeChanged() 53 { 54 //console.log("Date/time changed!"); 55 56 var currentTZOffset = dataSource.data["Local"]["Offset"] / 60; 57 if (currentTZOffset !== tzOffset) { 58 tzOffset = currentTZOffset; 59 //console.log("TZ offset changed: " + tzOffset); 60 Date.timeZoneUpdated(); // inform the QML JS engine about TZ change 61 } 62 } 63 64 Component.onCompleted: { 65 tzOffset = new Date().getTimezoneOffset(); 66 //console.log("Initial TZ offset: " + tzOffset); 67 dataSource.onDataChanged.connect(dateTimeChanged); 68 } 69 70 Plasmoid.compactRepresentation: Item { 71 id: representation 72 Layout.minimumWidth: plasmoid.formFactor !== PlasmaCore.Types.Vertical ? representation.height : PlasmaCore.Units.gridUnit 73 Layout.minimumHeight: plasmoid.formFactor === PlasmaCore.Types.Vertical ? representation.width : PlasmaCore.Units.gridUnit 74 75 MouseArea { 76 anchors.fill: parent 77 onClicked: plasmoid.expanded = !plasmoid.expanded 78 } 79 80 81 PlasmaCore.Svg { 82 id: clockSvg 83 imagePath: "widgets/clock" 84 function estimateHorizontalHandShadowOffset() { 85 var id = "hint-hands-shadow-offset-to-west"; 86 if (hasElement(id)) { 87 return -elementSize(id).width; 88 } 89 id = "hint-hands-shadows-offset-to-east"; 90 if (hasElement(id)) { 91 return elementSize(id).width; 92 } 93 return 0; 94 } 95 function estimateVerticalHandShadowOffset() { 96 var id = "hint-hands-shadow-offset-to-north"; 97 if (hasElement(id)) { 98 return -elementSize(id).height; 99 } 100 id = "hint-hands-shadow-offset-to-south"; 101 if (hasElement(id)) { 102 return elementSize(id).height; 103 } 104 return 0; 105 } 106 property double naturalHorizontalHandShadowOffset: estimateHorizontalHandShadowOffset() 107 property double naturalVerticalHandShadowOffset: estimateVerticalHandShadowOffset() 108 onRepaintNeeded: { 109 naturalHorizontalHandShadowOffset = estimateHorizontalHandShadowOffset(); 110 naturalVerticalHandShadowOffset = estimateVerticalHandShadowOffset(); 111 } 112 } 113 114 Item { 115 id: clock 116 width: parent.width 117 anchors { 118 top: parent.top 119 bottom: showTimezone ? timezoneBg.top : parent.bottom 120 } 121 readonly property double svgScale: face.width / face.naturalSize.width 122 readonly property double horizontalShadowOffset: 123 Math.round(clockSvg.naturalHorizontalHandShadowOffset * svgScale) + Math.round(clockSvg.naturalHorizontalHandShadowOffset * svgScale) % 2 124 readonly property double verticalShadowOffset: 125 Math.round(clockSvg.naturalVerticalHandShadowOffset * svgScale) + Math.round(clockSvg.naturalVerticalHandShadowOffset * svgScale) % 2 126 127 PlasmaCore.SvgItem { 128 id: face 129 anchors.centerIn: parent 130 width: Math.min(parent.width, parent.height) 131 height: Math.min(parent.width, parent.height) 132 svg: clockSvg 133 elementId: "ClockFace" 134 } 135 136 Hand { 137 elementId: "HourHandShadow" 138 rotationCenterHintId: "hint-hourhandshadow-rotation-center-offset" 139 horizontalRotationOffset: clock.horizontalShadowOffset 140 verticalRotationOffset: clock.verticalShadowOffset 141 rotation: 180 + hours * 30 + (minutes/2) 142 svgScale: clock.svgScale 143 144 } 145 Hand { 146 elementId: "HourHand" 147 rotationCenterHintId: "hint-hourhand-rotation-center-offset" 148 rotation: 180 + hours * 30 + (minutes/2) 149 svgScale: clock.svgScale 150 } 151 152 Hand { 153 elementId: "MinuteHandShadow" 154 rotationCenterHintId: "hint-minutehandshadow-rotation-center-offset" 155 horizontalRotationOffset: clock.horizontalShadowOffset 156 verticalRotationOffset: clock.verticalShadowOffset 157 rotation: 180 + minutes * 6 158 svgScale: clock.svgScale 159 } 160 Hand { 161 elementId: "MinuteHand" 162 rotationCenterHintId: "hint-minutehand-rotation-center-offset" 163 rotation: 180 + minutes * 6 164 svgScale: clock.svgScale 165 } 166 167 Hand { 168 elementId: "SecondHandShadow" 169 rotationCenterHintId: "hint-secondhandshadow-rotation-center-offset" 170 horizontalRotationOffset: clock.horizontalShadowOffset 171 verticalRotationOffset: clock.verticalShadowOffset 172 rotation: 180 + seconds * 6 173 visible: showSecondsHand 174 svgScale: clock.svgScale 175 } 176 Hand { 177 elementId: "SecondHand" 178 rotationCenterHintId: "hint-secondhand-rotation-center-offset" 179 rotation: 180 + seconds * 6 180 visible: showSecondsHand 181 svgScale: clock.svgScale 182 } 183 184 PlasmaCore.SvgItem { 185 id: center 186 width: naturalSize.width * clock.svgScale 187 height: naturalSize.height * clock.svgScale 188 anchors.centerIn: clock 189 svg: clockSvg 190 elementId: "HandCenterScrew" 191 z: 1000 192 } 193 194 PlasmaCore.SvgItem { 195 anchors.fill: face 196 svg: clockSvg 197 elementId: "Glass" 198 width: naturalSize.width * clock.svgScale 199 height: naturalSize.height * clock.svgScale 200 } 201 } 202 203 PlasmaCore.FrameSvgItem { 204 id: timezoneBg 205 anchors { 206 horizontalCenter: parent.horizontalCenter 207 bottom: parent.bottom 208 bottomMargin: 10 209 } 210 imagePath: "widgets/background" 211 width: childrenRect.width + margins.right + margins.left 212 height: childrenRect.height + margins.top + margins.bottom 213 visible: showTimezone 214 PlasmaComponents.Label { 215 id: timezoneText 216 x: timezoneBg.margins.left 217 y: timezoneBg.margins.top 218 text: dataSource.data["Local"]["Timezone"] 219 } 220 } 221 } 222 Plasmoid.fullRepresentation: PlasmaCalendar.MonthView { 223 Layout.minimumWidth: PlasmaCore.Units.gridUnit * 20 224 Layout.minimumHeight: PlasmaCore.Units.gridUnit * 20 225 226 today: dataSource.data["Local"]["DateTime"] 227 } 228 229} 230