~kubuntu-members/korundum/4.11

« back to all changes in this revision

Viewing changes to korundum/modules/plasma/examples/applets/digital-clock/clock.rb

  • Committer: Ian Monroe
  • Date: 2010-11-21 15:55:01 UTC
  • Revision ID: git-v1:c37670e4e3c59f5eb2ba112f5341a5e706217f6f
Split up Smoke into Qt and KDE directories. 
Move libsmoke stuff into the generator directory
Split up Ruby into qtruby and korundum directories

svn path=/trunk/KDE/kdebindings/ruby/; revision=1199320

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
=begin
 
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>               *
 
6
 *                                                                         *
 
7
 *   Translated to Ruby by Richard Dale                                    *
 
8
 *                                                                         *
 
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.                                   *
 
13
 *                                                                         *
 
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.                          *
 
18
 *                                                                         *
 
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
 ***************************************************************************/
 
24
=end
 
25
 
 
26
require 'plasma_applet'
 
27
require 'digital_clock_config.rb'
 
28
require 'calendar.rb'
 
29
 
 
30
module PlasmaRubyDigitalClock
 
31
 
 
32
class Clock < Plasma::Applet
 
33
 
 
34
  slots 'dataUpdated(QString,Plasma::DataEngine::Data)',
 
35
        'showCalendar(QGraphicsSceneMouseEvent *)',
 
36
        'createConfigurationInterface(KConfigDialog *)',
 
37
        :configAccepted,
 
38
        :updateColors
 
39
 
 
40
  def initialize(parent, args)
 
41
    super
 
42
    @plainClockFont = KDE::GlobalSettings.generalFont
 
43
    @useCustomColor = false
 
44
    @plainClockColor = Qt::Color.new(Qt::white)
 
45
    @showDate = false
 
46
    @showYear = false
 
47
    @showDay = false
 
48
    @showSeconds = false
 
49
    @showTimezone = false
 
50
    @lastTimeSeen = Qt::Time.new
 
51
    @ui = Ui::DigitalClockConfig.new
 
52
    @calendarUi = Ui::Calendar.new
 
53
 
 
54
    setHasConfigurationInterface(true)
 
55
    resize(90, 44)
 
56
  end
 
57
 
 
58
  def init
 
59
    cg = config
 
60
    @localTimeZone = cg.readEntry("localTimeZone", Qt::Variant.new(true))
 
61
    @timezone = cg.readEntry("timezone", Qt::Variant.new("Local")).value
 
62
    @timeZones = cg.readEntry("timeZones", [])
 
63
 
 
64
    @showTimezone = cg.readEntry("showTimezone", Qt::Variant.new((@timezone != "Local"))).value
 
65
 
 
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
 
69
 
 
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
 
73
    if @useCustomColor
 
74
        @plainClockColor = cg.readEntry("plainClockColor", Qt::Variant.fromValue(@plainClockColor)).value
 
75
    else
 
76
        @plainClockColor = KDE::ColorScheme.new(Qt::Palette::Active, KDE::ColorScheme::View, Plasma::Theme.defaultTheme.colorScheme).foreground.color
 
77
    end
 
78
 
 
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))
 
82
 
 
83
    @toolTipIcon = KDE::Icon.new("chronometer").pixmap(KDE::IconSize(KDE::IconLoader::Desktop))
 
84
 
 
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))
 
88
  end
 
89
 
 
90
  def constraintsEvent(constraints)
 
91
    if constraints & Plasma::SizeConstraint.to_i
 
92
      aspect = 2
 
93
      if @showSeconds
 
94
        aspect = 3
 
95
      end
 
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)
 
102
      end
 
103
    end
 
104
  end
 
105
 
 
106
  def updateToolTipContent
 
107
    timeString = KDE::Global.locale.formatTime(@time, @showSeconds)
 
108
    # FIXME Port to future tooltip manager
 
109
=begin
 
110
    tipData = Plasma::ToolTipData.new
 
111
    tipData.mainText = @time.toString(timeString)
 
112
    tipData.subText = @date.toString
 
113
    tipData.image = @toolTipIcon
 
114
 
 
115
    setToolTip(tipData)
 
116
=end
 
117
  end
 
118
 
 
119
  def dataUpdated(source, data)
 
120
    @time = data["Time"].toTime
 
121
    @date = data["Date"].toDate
 
122
    @prettyTimezone = data["Timezone City"].toString
 
123
    @prettyTimezone.gsub!("_", " ")
 
124
 
 
125
    updateToolTipContent
 
126
 
 
127
    # avoid unnecessary repaints
 
128
    if @showSeconds || @time.minute != @lastTimeSeen.minute
 
129
        @lastTimeSeen = @time
 
130
        update
 
131
    end
 
132
  end
 
133
 
 
134
  def mousePressEvent(event)
 
135
    if event.buttons == Qt::LeftButton
 
136
        showCalendar(event)
 
137
    else
 
138
        event.ignore
 
139
    end
 
140
  end
 
141
 
 
142
  def showCalendar(event)
 
143
    if @calendar.nil?
 
144
        @calendar = Plasma::Dialog.new
 
145
        # @calendar.setStyleSheet("{ border : 0px }") # FIXME: crashes
 
146
        @layout = Qt::VBoxLayout.new
 
147
        @layout.spacing = 0
 
148
        @layout.margin = 0
 
149
 
 
150
        @calendarUi.setupUi(@calendar)
 
151
        @calendar.layout = @layout
 
152
        @calendar.windowFlags = Qt::Popup
 
153
        @calendar.adjustSize
 
154
    end
 
155
 
 
156
    if @calendar.visible?
 
157
        @calendar.hide
 
158
    else
 
159
        @calendarUi.kdatepicker.date = Qt::Date.currentDate
 
160
        @calendar.move(popupPosition(@calendar.sizeHint))
 
161
        @calendar.show
 
162
    end
 
163
  end
 
164
 
 
165
  def createConfigurationInterface(parent)
 
166
    widget = Qt::Widget.new
 
167
    @ui.setupUi(widget)
 
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))
 
172
 
 
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)
 
187
    end
 
188
  end
 
189
 
 
190
  def configAccepted
 
191
    cg = config
 
192
 
 
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))
 
197
 
 
198
    @localTimeZone = @ui.localTimeZone.checkState == Qt::Checked
 
199
    cg.writeEntry("localTimeZone", Qt::Variant.new(@localTimeZone))
 
200
 
 
201
    @timeZones = @ui.timeZones.selection
 
202
    cg.writeEntry("timeZones", Qt::Variant.new(@timeZones))
 
203
 
 
204
    if @localTimeZone
 
205
        dataEngine("time").disconnectSource(@timezone, self)
 
206
        @timezone = "Local";
 
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
 
214
        tz = @timeZones[0]
 
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)
 
219
        @timezone = "Local"
 
220
        dataEngine("time").connectSource(@timezone, self, updateInterval, intervalAlignment)
 
221
        cg.writeEntry("timezone", Qt::Variant.new(@timezone))
 
222
    else
 
223
        puts "User didn't use local timezone but also didn't select any other."
 
224
    end
 
225
 
 
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))
 
234
 
 
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;
 
239
    end
 
240
 
 
241
    @plainClockFont = @ui.plainClockFont.currentFont
 
242
    @useCustomColor = @ui.useCustomColor.checkState == Qt::Checked;
 
243
    if @useCustomColor
 
244
        @plainClockColor = @ui.plainClockColor.color
 
245
    else
 
246
        @plainClockColor = KDE::ColorScheme.new(Qt::Palette::Active, KDE::ColorScheme::View, Plasma::Theme.defaultTheme.colorScheme).foreground.color
 
247
    end
 
248
    @plainClockFont.bold = @ui.plainClockFontBold.checkState == Qt::Checked
 
249
    @plainClockFont.italic = @ui.plainClockFontItalic.checkState == Qt::Checked
 
250
 
 
251
    cg.writeEntry("plainClockFont", Qt::Variant.fromValue(@plainClockFont))
 
252
    cg.writeEntry("useCustomColor", Qt::Variant.new(@useCustomColor))
 
253
    cg.writeEntry("plainClockColor", Qt::Variant.fromValue(@plainClockColor))
 
254
 
 
255
    constraintsEvent(Plasma::SizeConstraint)
 
256
    update
 
257
    emit configNeedsSaving
 
258
  end
 
259
 
 
260
 
 
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
 
266
 
 
267
        timeRect = Qt::Rect.new
 
268
 
 
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
 
272
            dateString = ""
 
273
            if @showDate
 
274
                day = @date.toString("d")
 
275
                month = @date.toString("MMM")
 
276
 
 
277
                if @showYear
 
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])
 
282
                else
 
283
                    dateString = i18nc("@label Short date: " +
 
284
                                       "%s day in the month, %s short month name" % [day, month],
 
285
                                       "%s %s" % [day, month])
 
286
                end
 
287
 
 
288
                if @showDay
 
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])
 
293
                end
 
294
 
 
295
                if @showTimezone
 
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])
 
300
                end
 
301
            elsif @showTimezone
 
302
                dateString = @prettyTimezone
 
303
            end
 
304
 
 
305
            # Check sizes
 
306
            dateRect = preparePainter(p, contentsRect, KDE::GlobalSettings.smallestReadableFont, dateString)
 
307
            subtitleHeight = dateRect.height
 
308
 
 
309
            p.drawText(Qt::RectF.new(0,
 
310
                                contentsRect.bottom-subtitleHeight,
 
311
                                contentsRect.right,
 
312
                                contentsRect.bottom) ,
 
313
                        dateString,
 
314
                        Qt::TextOption.new(Qt::AlignHCenter)
 
315
                    )
 
316
 
 
317
            # Now find out how much space is left for painting the time
 
318
            timeRect = Qt::Rect.new(   contentsRect.left,
 
319
                                       contentsRect.top,
 
320
                                       contentsRect.width,
 
321
                                       (contentsRect.height-subtitleHeight+4))
 
322
        else
 
323
            timeRect = contentsRect
 
324
        end
 
325
 
 
326
        timeString = KDE::Global.locale.formatTime(@time, @showSeconds)
 
327
 
 
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)
 
331
 
 
332
        p.drawText(Qt::RectF.new(timeRect),
 
333
                    timeString,
 
334
                    Qt::TextOption.new(Qt::AlignCenter)
 
335
                )
 
336
    end
 
337
  end
 
338
 
 
339
  def preparePainter(p, rect, font, text)
 
340
    tmpRect = Qt::Rect.new
 
341
    tmpFont = font
 
342
 
 
343
    # Starting with the given font, decrease its size until it'll fit in the
 
344
    # given rect allowing wrapping where possible
 
345
    begin
 
346
        p.font = tmpFont
 
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)
 
351
 
 
352
    return tmpRect
 
353
  end
 
354
 
 
355
  def updateInterval
 
356
    return @showSeconds ? 1000 : 60000
 
357
  end
 
358
 
 
359
  def intervalAlignment
 
360
    return @showSeconds ? Plasma::NoAlignment : Plasma::AlignToMinute;
 
361
  end
 
362
 
 
363
  def updateColors
 
364
    if !@useCustomColor
 
365
        @plainClockColor = KDE::ColorScheme(Qt::Palette::Active, KDE::ColorScheme::View, Plasma::Theme.self.colorScheme).foreground.color
 
366
        update
 
367
    end
 
368
  end
 
369
end
 
370
 
 
371
end