2 # Copyright (C) 2005,2006,2007 by Siraj Razick
3 # Copyright 2008 Simon Edwards <simon@simonzone.com> (Translated to Python)
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU Library General Public License as
7 # published by the Free Software Foundation; either version 2, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details
15 # You should have received a copy of the GNU Library General Public
16 # License along with this program; if not, write to the
17 # Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 from PyQt4
.QtCore
import *
22 from PyQt4
.QtGui
import *
23 from PyKDE4
.kdecore
import *
24 from PyKDE4
.kdeui
import *
25 from PyKDE4
.plasma
import Plasma
26 from analog_clock_config_ui
import *
27 from calendar_ui
import *
28 from PyKDE4
import plasmascript
30 class AnalogClockConfig(QWidget
,Ui_clockConfig
):
31 def __init__(self
,parent
):
32 QWidget
.__init
__(self
,parent
)
34 self
.connect(self
.localTimeZone
, SIGNAL("stateChanged(int)"), self
, SLOT("slotLocalTimeZoneToggled(int)"))
36 @pyqtSignature("slotLocalTimeZoneToggled(int)")
37 def slotLocalTimeZoneToggled(self
,b
):
38 self
.timeZones
.setDisabled(b
)
40 class PyClockApplet(plasmascript
.Applet
):
41 def __init__(self
,parent
,args
=None):
42 plasmascript
.Applet
.__init
__(self
,parent
)
45 self
.currentTimezone
= "Local"
46 self
.clicked
= QPoint()
50 KGlobal
.locale().insertCatalog("libplasmaclock")
52 self
.setHasConfigurationInterface(True)
54 self
.setAspectRatioMode(Plasma
.Square
)
57 self
.showTimeString
= False
58 self
.showSecondHand
= False
61 self
.calendarUi
= Ui_calendar()
62 self
.lastTimeSeen
= QTime()
65 self
.theme
= Plasma
.Svg(self
)
66 #print("svg: "+str(self.package().filePath("images", "clock.svgz")))
67 #self.theme.setImagePath(self.package().filePath("images", "clock.svgz"))
69 self
.theme
.setImagePath("widgets/clock") # FIXME pull this out of this applet itself.
70 self
.theme
.setContainsMultipleImages(False)
71 self
.theme
.resize(self
.size())
74 self
.showTimeString
= cg
.readEntry("showTimeString", QVariant(False)).toBool()
75 self
.showSecondHand
= cg
.readEntry("showSecondHand", QVariant(False)).toBool()
76 self
.fancyHands
= cg
.readEntry("fancyHands", QVariant(False)).toBool()
77 self
.currentTimezone
= cg
.readEntry("timezone", self
.localTimezone())
79 self
.connectToEngine()
81 def connectToEngine(self
):
82 self
.timeEngine
= self
.dataEngine("time")
83 if self
.showSecondHand
:
84 self
.timeEngine
.connectSource(self
.currentTimezone
, self
, 500)
86 self
.timeEngine
.connectSource(self
.currentTimezone
, self
, 6000, Plasma
.AlignToMinute
)
88 def constraintsEvent(self
, constraints
):
89 if constraints
& Plasma
.FormFactorConstraint
:
90 self
.setBackgroundHints(Plasma
.Applet
.NoBackground
)
91 if constraints
& Plasma
.SizeConstraint
:
92 self
.theme
.resize(self
.size())
95 if self
.theme
.hasElement("hint-square-clock"):
96 return plasma
.Applet
.shape(self
)
99 path
.addEllipse(self
.boundingRect().adjusted(-2, -2, 2, 2))
102 @pyqtSignature("dataUpdated(const QString &, const Plasma::DataEngine::Data &)")
103 def dataUpdated(self
, sourceName
, data
):
104 self
.time
= data
[QString("Time")].toTime()
106 if self
.time
.minute() == self
.lastTimeSeen
.minute() and \
107 self
.time
.second() == self
.lastTimeSeen
.second():
108 # avoid unnecessary repaints
111 self
.lastTimeSeen
= self
.time
114 def updateToolTipContent(self
):
117 def mousePressEvent(self
,event
):
118 if event
.buttons() == Qt
.LeftButton
:
119 self
.clicked
= self
.scenePos().toPoint()
120 event
.setAccepted(True)
122 def mouseReleaseEvent(self
,event
):
123 if (self
.clicked
- self
.scenePos().toPoint()).manhattanLength() < \
124 KGlobalSettings
.dndEventDelay():
125 self
.showCalendar(event
)
127 def showCalendar(self
,event
):
128 if self
.calendar
is None:
129 self
.calendar
= Plasma
.Dialog()
130 self
.calendarUi
.setupUi(self
.calendar
)
131 self
.calendar
.setWindowFlags(Qt
.Popup
)
132 self
.calendar
.adjustSize()
134 if self
.calendar
.isVisible():
137 data
= self
.dataEngine("time").query(self
.currentTimezone
)
138 self
.calendarUi
.kdatepicker
.date
= data
[QString("Date")].toDate()
139 self
.calendar
.move(self
.popupPosition(self
.calendar
.sizeHint()))
142 def isLocalTimezone(self
):
143 return self
.currentTimezone
== self
.localTimezone()
145 def localTimezone(self
):
148 def showConfigurationInterface(self
):
149 windowTitle
= str(self
.applet
.name()) + " Settings" #i18nc("@title:window", "%s Settings" % str(self.applet.name()))
151 if self
.dialog
is None:
152 self
.dialog
= KDialog(None)
153 self
.dialog
.setWindowTitle(windowTitle
)
155 self
.ui
= AnalogClockConfig(self
.dialog
)
156 self
.dialog
.setMainWidget(self
.ui
)
158 self
.dialog
.setButtons(KDialog
.ButtonCodes(KDialog
.ButtonCode(KDialog
.Ok | KDialog
.Cancel | KDialog
.Apply
)))
159 self
.dialog
.showButton(KDialog
.Apply
, False)
161 self
.connect(self
.dialog
, SIGNAL("applyClicked()"), self
, SLOT("configAccepted()"))
162 self
.connect(self
.dialog
, SIGNAL("okClicked()"), self
, SLOT("configAccepted()"))
164 self
.ui
.showTimeStringCheckBox
.setChecked(self
.showTimeString
)
165 self
.ui
.showSecondHandCheckBox
.setChecked(self
.showSecondHand
)
166 self
.ui
.localTimeZone
.setChecked(self
.isLocalTimezone())
167 self
.ui
.timeZones
.setSelected(self
.currentTimezone
, True)
168 self
.ui
.timeZones
.setEnabled(not self
.isLocalTimezone())
172 @pyqtSignature("configAccepted()")
173 def configAccepted(self
):
177 self
.timeZones
= self
.ui
.timeZones
.selection()
178 cg
.writeEntry("timeZones", self
.timeZones
)
179 newTimezone
= self
.localTimezone()
180 if not self
.ui
.localTimeZone
.isChecked() and not self
.timeZones
.isEmpty():
181 newTimezone
= self
.timeZones
[0]
182 self
.changeEngineTimezone(self
.currentTimezone
, newTimezone
)
183 self
.currentTimezone
= newTimezone
184 cg
.writeEntry("currentTimezone", newTimezone
)
187 self
.showTimeString
= self
.ui
.showTimeStringCheckBox
.isChecked()
188 self
.showSecondHand
= self
.ui
.showSecondHandCheckBox
.isChecked()
189 cg
.writeEntry("showTimeString", QVariant(self
.showTimeString
))
190 cg
.writeEntry("showSecondHand", QVariant(self
.showSecondHand
))
192 self
.dataEngine("time").disconnectSource(self
.currentTimezone
, self
)
193 self
.connectToEngine()
195 self
.constraintsEvent(Plasma
.SizeConstraint
)
197 self
.emit(SIGNAL("configNeedsSaving()"))
199 def changeEngineTimezone(self
, oldTimezone
, newTimezone
):
200 self
.dataEngine("time").disconnectSource(oldTimezone
, self
)
201 self
.timeEngine
= self
.dataEngine("time")
202 if self
.showSecondHand
:
203 self
.timeEngine
.connectSource(newTimezone
, self
, 500)
205 self
.timeEngine
.connectSource(newTimezone
, self
, 6000, Plasma
.AlignToMinute
)
207 def drawHand(self
, painter
, rotation
, handName
, rect
):
209 elementRect
= self
.theme
.elementRect(handName
)
211 painter
.translate(rect
.width() / 2, rect
.height() / 2)
212 painter
.rotate(rotation
)
213 painter
.translate(-elementRect
.width() / 2, 0)
214 self
.theme
.paint(painter
, QRectF(QPointF(0.0, 0.0), elementRect
.size()), handName
)
218 def paintInterface(self
, painter
, option
, rect
):
219 tempRect
= QRectF(0, 0, 0, 0)
221 boundSize
= self
.size()
223 painter
.setRenderHint(QPainter
.SmoothPixmapTransform
)
225 minutes
= 6.0 * self
.time
.minute() - 180
226 hours
= 30.0 * self
.time
.hour() - 180 + ((self
.time
.minute() / 59.0) * 30.0)
228 self
.theme
.paint(painter
, QRectF(rect
), "ClockFace")
230 if self
.showTimeString
:
231 fm
= QFontMetrics(QApplication
.font())
233 if self
.showSecondHand
:
234 # FIXME: temporary time output
235 time
= self
.time
.toString()
237 time
= self
.time
.toString("hh:mm")
239 textRect
= QRect((rect
.width()/2 - fm
.width(time
) / 2),((rect
.height() / 2) - fm
.xHeight() * 4), fm
.width(time
), fm
.xHeight())
241 painter
.pen
= Qt
.NoPen
242 background
= Plasma
.Theme
.defaultTheme().color(Plasma
.Theme
.BackgroundColor
)
243 background
.setAlphaF(0.5)
244 painter
.brush
= QBrush(background
)
246 painter
.setRenderHint(QPainter
.Antialiasing
, True)
247 painter
.drawPath(Plasma
.PaintUtils
.roundedRectangle(QRectF(textRect
.adjusted(-margin
, -margin
, margin
, margin
)), margin
))
248 painter
.setRenderHint(QPainter
.Antialiasing
, False)
250 painter
.pen
= Plasma
.Theme
.defaultTheme().color(Plasma
.Theme
.TextColor
)
252 painter
.drawText(textRect
.bottomLeft(), time
)
254 # Make sure we paint the second hand on top of the others
255 if self
.showSecondHand
:
257 seconds
= anglePerSec
* self
.time
.second() - 180
259 if self
.theme
.hasElement("HourHandShadow"):
260 painter
.translate(1,3)
261 self
.drawHand(painter
, hours
, "HourHandShadow",rect
)
262 self
.drawHand(painter
, minutes
, "MinuteHandShadow",rect
)
264 if self
.showSecondHand
:
265 self
.drawHand(painter
, seconds
, "SecondHandShadow",rect
)
267 painter
.translate(-1,-3)
269 self
.drawHand(painter
, hours
, "HourHand",rect
)
270 self
.drawHand(painter
, minutes
, "MinuteHand",rect
)
271 if self
.showSecondHand
:
272 self
.drawHand(painter
, seconds
, "SecondHand",rect
)
275 self
.theme
.resize(boundSize
)
276 elementSize
= QSizeF(self
.theme
.elementSize("HandCenterScrew"))
277 tempRect
.size
= elementSize
278 painter
.translate(boundSize
.width() / 2.0 - elementSize
.width() / 2.0, boundSize
.height() / 2.0 - elementSize
.height() / 2.0)
279 self
.theme
.paint(painter
, tempRect
, "HandCenterScrew")
282 self
.theme
.paint(painter
, QRectF(rect
), "Glass")
284 def CreateApplet(parent
):
285 return PyClockApplet(parent
)