2
/***************************************************************************
3
* Copyright (C) 2005,2006,2007 by Siraj Razick <siraj@kdemail.net> *
4
* Copyright (C) 2007 by Riccardo Iaconelli <riccardo@kde.org> *
5
* Copyright (C) 2007 by Sebastian Kuegler <sebas@kde.org> *
7
* Translated to Ruby by Richard Dale *
9
* This program is free software; you can redistribute it and/or modify *
10
* it under the terms of the GNU General Public License as published by *
11
* the Free Software Foundation; either version 2 of the License, or *
12
* (at your option) any later version. *
14
* This program is distributed in the hope that it will be useful, *
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17
* GNU General Public License for more details. *
19
* You should have received a copy of the GNU General Public License *
20
* along with this program; if not, write to the *
21
* Free Software Foundation, Inc., *
22
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
23
***************************************************************************/
26
require 'plasma_applet'
27
require 'digital_clock_config.rb'
30
module PlasmaRubyDigitalClock
32
class Clock < Plasma::Applet
34
slots 'dataUpdated(QString,Plasma::DataEngine::Data)',
35
'showCalendar(QGraphicsSceneMouseEvent *)',
36
'createConfigurationInterface(KConfigDialog *)',
40
def initialize(parent, args)
42
@plainClockFont = KDE::GlobalSettings.generalFont
43
@useCustomColor = false
44
@plainClockColor = Qt::Color.new(Qt::white)
50
@lastTimeSeen = Qt::Time.new
51
@ui = Ui::DigitalClockConfig.new
52
@calendarUi = Ui::Calendar.new
54
setHasConfigurationInterface(true)
60
@localTimeZone = cg.readEntry("localTimeZone", Qt::Variant.new(true))
61
@timezone = cg.readEntry("timezone", Qt::Variant.new("Local")).value
62
@timeZones = cg.readEntry("timeZones", [])
64
@showTimezone = cg.readEntry("showTimezone", Qt::Variant.new((@timezone != "Local"))).value
66
@showDate = cg.readEntry("showDate", Qt::Variant.new(false)).value
67
@showYear = cg.readEntry("showYear", Qt::Variant.new(false)).value
68
@showDay = cg.readEntry("showDay", Qt::Variant.new(true)).value
70
@showSeconds = cg.readEntry("showSeconds", Qt::Variant.new(false)).value
71
@plainClockFont = cg.readEntry("plainClockFont", Qt::Variant.fromValue(@plainClockFont)).value
72
@useCustomColor = cg.readEntry("useCustomColor", Qt::Variant.new(false)).value
74
@plainClockColor = cg.readEntry("plainClockColor", Qt::Variant.fromValue(@plainClockColor)).value
76
@plainClockColor = KDE::ColorScheme.new(Qt::Palette::Active, KDE::ColorScheme::View, Plasma::Theme.defaultTheme.colorScheme).foreground.color
79
metrics = Qt::FontMetricsF.new(KDE::GlobalSettings.smallestReadableFont)
80
timeString = KDE::Global.locale.formatTime(Qt::Time.new(23, 59), @showSeconds)
81
setMinimumSize(metrics.size(Qt::TextSingleLine, timeString))
83
@toolTipIcon = KDE::Icon.new("chronometer").pixmap(KDE::IconSize(KDE::IconLoader::Desktop))
85
# Use 'dataEngine("ruby-time")' for the ruby version of the engine
86
dataEngine("time").connectSource(@timezone, self, updateInterval, intervalAlignment)
87
connect(Plasma::Theme.defaultTheme, SIGNAL(:themeChanged), self, SLOT(:updateColors))
90
def constraintsEvent(constraints)
91
if constraints & Plasma::SizeConstraint.to_i
96
if formFactor == Plasma::Horizontal
97
# We have a fixed height, set some sensible width
98
setMinimumWidth(geometry.height * aspect)
99
elsif formFactor == Plasma::Vertical
100
# We have a fixed width, set some sensible height
101
setMinimumHeight(geometry.width / aspect)
106
def updateToolTipContent
107
timeString = KDE::Global.locale.formatTime(@time, @showSeconds)
108
# FIXME Port to future tooltip manager
110
tipData = Plasma::ToolTipData.new
111
tipData.mainText = @time.toString(timeString)
112
tipData.subText = @date.toString
113
tipData.image = @toolTipIcon
119
def dataUpdated(source, data)
120
@time = data["Time"].toTime
121
@date = data["Date"].toDate
122
@prettyTimezone = data["Timezone City"].toString
123
@prettyTimezone.gsub!("_", " ")
127
# avoid unnecessary repaints
128
if @showSeconds || @time.minute != @lastTimeSeen.minute
129
@lastTimeSeen = @time
134
def mousePressEvent(event)
135
if event.buttons == Qt::LeftButton
142
def showCalendar(event)
144
@calendar = Plasma::Dialog.new
145
# @calendar.setStyleSheet("{ border : 0px }") # FIXME: crashes
146
@layout = Qt::VBoxLayout.new
150
@calendarUi.setupUi(@calendar)
151
@calendar.layout = @layout
152
@calendar.windowFlags = Qt::Popup
156
if @calendar.visible?
159
@calendarUi.kdatepicker.date = Qt::Date.currentDate
160
@calendar.move(popupPosition(@calendar.sizeHint))
165
def createConfigurationInterface(parent)
166
widget = Qt::Widget.new
168
parent.buttons = KDE::Dialog::Ok | KDE::Dialog::Cancel | KDE::Dialog::Apply
169
parent.addPage(widget, parent.windowTitle, "chronometer")
170
connect(parent, SIGNAL(:applyClicked), self, SLOT(:configAccepted))
171
connect(parent, SIGNAL(:okClicked), self, SLOT(:configAccepted))
173
@ui.showDate.checked = @showDate
174
@ui.showYear.checked = @showYear
175
@ui.showDay.checked = @showDay
176
@ui.secondsCheckbox.checked = @showSeconds
177
@ui.showTimezone.checked = @showTimezone
178
@ui.plainClockFontBold.checked = @plainClockFont.bold
179
@ui.plainClockFontItalic.checked = @plainClockFont.italic
180
@ui.plainClockFont.currentFont = @plainClockFont
181
@ui.useCustomColor.checked = @useCustomColor
182
@ui.plainClockColor.color = @plainClockColor
183
@ui.timeZones.enabled = @timezone != "Local"
184
@ui.localTimeZone.checked = @timezone == "Local"
185
@timeZones.each do |str|
186
@ui.timeZones.setSelected(str, true)
193
#We need this to happen before we disconnect/reconnect sources to ensure
194
#that the update interval is set properly.
195
@showSeconds = @ui.secondsCheckbox.checkState == Qt::Checked
196
cg.writeEntry("showSeconds", Qt::Variant.new(@showSeconds))
198
@localTimeZone = @ui.localTimeZone.checkState == Qt::Checked
199
cg.writeEntry("localTimeZone", Qt::Variant.new(@localTimeZone))
201
@timeZones = @ui.timeZones.selection
202
cg.writeEntry("timeZones", Qt::Variant.new(@timeZones))
205
dataEngine("time").disconnectSource(@timezone, self)
207
dataEngine("time").connectSource(@timezone, self, updateInterval, intervalAlignment)
208
cg.writeEntry("timezone", Qt::Variant.new(@timezone))
209
elsif @timeZones.length > 0
210
dataEngine("time").disconnectSource(@timezone, self)
211
# We have changed the timezone, show that in the clock, but only if this
212
# setting hasn't been changed.
213
@ui.showTimezone.checkState = Qt::Checked
215
cg.writeEntry("timezone", Qt::Variant.new(@timezone))
216
dataEngine("time").connectSource(@timezone, self, updateInterval, intervalAlignment)
217
elsif @timezone != "Local"
218
dataEngine("time").disconnectSource(@timezone, self)
220
dataEngine("time").connectSource(@timezone, self, updateInterval, intervalAlignment)
221
cg.writeEntry("timezone", Qt::Variant.new(@timezone))
223
puts "User didn't use local timezone but also didn't select any other."
226
@showDate = @ui.showDate.checkState == Qt::Checked
227
cg.writeEntry("showDate", Qt::Variant.new(@showDate))
228
@showYear = @ui.showYear.checkState == Qt::Checked
229
cg.writeEntry("showYear", Qt::Variant.new(@showYear))
230
@showDay = @ui.showDay.checkState == Qt::Checked
231
cg.writeEntry("showDay", Qt::Variant.new(@showDay))
232
@showSeconds = @ui.secondsCheckbox.checkState == Qt::Checked
233
cg.writeEntry("showSeconds", Qt::Variant.new(@showSeconds))
235
if @showTimezone != (@ui.showTimezone.checkState == Qt::Checked)
236
@showTimezone = @ui.showTimezone.checkState == Qt::Checked
237
cg.writeEntry("showTimezone", Qt::Variant.new(@showTimezone))
238
puts "Saving show timezone: %s" % @showTimezone;
241
@plainClockFont = @ui.plainClockFont.currentFont
242
@useCustomColor = @ui.useCustomColor.checkState == Qt::Checked;
244
@plainClockColor = @ui.plainClockColor.color
246
@plainClockColor = KDE::ColorScheme.new(Qt::Palette::Active, KDE::ColorScheme::View, Plasma::Theme.defaultTheme.colorScheme).foreground.color
248
@plainClockFont.bold = @ui.plainClockFontBold.checkState == Qt::Checked
249
@plainClockFont.italic = @ui.plainClockFontItalic.checkState == Qt::Checked
251
cg.writeEntry("plainClockFont", Qt::Variant.fromValue(@plainClockFont))
252
cg.writeEntry("useCustomColor", Qt::Variant.new(@useCustomColor))
253
cg.writeEntry("plainClockColor", Qt::Variant.fromValue(@plainClockColor))
255
constraintsEvent(Plasma::SizeConstraint)
257
emit configNeedsSaving
261
def paintInterface(p, option, contentsRect)
262
if @time.valid? && @date.valid?
263
p.pen = Qt::Pen.new(@plainClockColor)
264
p.renderHint = Qt::Painter::SmoothPixmapTransform
265
p.renderHint = Qt::Painter::Antialiasing
267
timeRect = Qt::Rect.new
269
# Paint the date, conditionally, and let us know afterwards how much
270
# space is left for painting the time on top of it.
271
if @showDate || @showTimezone
274
day = @date.toString("d")
275
month = @date.toString("MMM")
278
year = @date.toString("yyyy")
279
dateString = i18nc("@label Short date: " +
280
"%s day in the month, %2 short month name, %3 year" % [day, month, year],
281
"%s %s %s" % [day, month, year])
283
dateString = i18nc("@label Short date: " +
284
"%s day in the month, %s short month name" % [day, month],
285
"%s %s" % [day, month])
289
weekday = Qt::Date.shortDayName(@date.dayOfWeek)
290
dateString = i18nc("@label Day of the week with date: " +
291
"%s short day name, %s short date" % [weekday, dateString],
292
"%s, %s" % [weekday, dateString])
296
timezone = @prettyTimezone
297
dateString = i18nc("@label Date with timezone: " +
298
"%s day of the week with date, %s timezone" % [dateString, timezone],
299
"%s %s" % [dateString, timezone])
302
dateString = @prettyTimezone
306
dateRect = preparePainter(p, contentsRect, KDE::GlobalSettings.smallestReadableFont, dateString)
307
subtitleHeight = dateRect.height
309
p.drawText(Qt::RectF.new(0,
310
contentsRect.bottom-subtitleHeight,
312
contentsRect.bottom) ,
314
Qt::TextOption.new(Qt::AlignHCenter)
317
# Now find out how much space is left for painting the time
318
timeRect = Qt::Rect.new( contentsRect.left,
321
(contentsRect.height-subtitleHeight+4))
323
timeRect = contentsRect
326
timeString = KDE::Global.locale.formatTime(@time, @showSeconds)
328
# Choose a relatively big font size to start with
329
@plainClockFont.pointSizeF = [timeRect.height, KDE::GlobalSettings.smallestReadableFont.pointSize].max
330
preparePainter(p, timeRect, @plainClockFont, timeString)
332
p.drawText(Qt::RectF.new(timeRect),
334
Qt::TextOption.new(Qt::AlignCenter)
339
def preparePainter(p, rect, font, text)
340
tmpRect = Qt::Rect.new
343
# Starting with the given font, decrease its size until it'll fit in the
344
# given rect allowing wrapping where possible
347
tmpFont.pointSize = [KDE::GlobalSettings.smallestReadableFont.pointSize, tmpFont.pointSize - 1].max
348
tmpRect = p.boundingRect(rect, Qt::TextWordWrap, text)
349
end while tmpFont.pointSize > KDE::GlobalSettings.smallestReadableFont.pointSize && (tmpRect.width > rect.width ||
350
tmpRect.height > rect.height)
356
return @showSeconds ? 1000 : 60000
359
def intervalAlignment
360
return @showSeconds ? Plasma::NoAlignment : Plasma::AlignToMinute;
365
@plainClockColor = KDE::ColorScheme(Qt::Palette::Active, KDE::ColorScheme::View, Plasma::Theme.self.colorScheme).foreground.color