~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to libs/plasmaclock/clockapplet.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2007-2008 by Riccardo Iaconelli <riccardo@kde.org>      *
 
3
 *   Copyright (C) 2007-2008 by Sebastian Kuegler <sebas@kde.org>          *
 
4
 *   Copyright (C) 2008-2009 by Davide Bettio <davide.bettio@kdemail.net>  *
 
5
 *   Copyright (C) 2009 by John Layt <john@layt.net>                       *
 
6
 *                                                                         *
 
7
 *   This program is free software; you can redistribute it and/or modify  *
 
8
 *   it under the terms of the GNU General Public License as published by  *
 
9
 *   the Free Software Foundation; either version 2 of the License, or     *
 
10
 *   (at your option) any later version.                                   *
 
11
 *                                                                         *
 
12
 *   This program is distributed in the hope that it will be useful,       *
 
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
15
 *   GNU General Public License for more details.                          *
 
16
 *                                                                         *
 
17
 *   You should have received a copy of the GNU General Public License     *
 
18
 *   along with this program; if not, write to the                         *
 
19
 *   Free Software Foundation, Inc.,                                       *
 
20
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
 
21
 ***************************************************************************/
 
22
 
 
23
#include "clockapplet.h"
 
24
 
 
25
#include <math.h>
 
26
 
 
27
#include <QtGui/QPainter>
 
28
#include <QtGui/QStyleOptionGraphicsItem>
 
29
#include <QtGui/QSpinBox>
 
30
#include <QtGui/QClipboard>
 
31
#include <QtCore/QTimeLine>
 
32
#include <QtGui/QGraphicsProxyWidget>
 
33
#include <QtGui/QGraphicsSceneMouseEvent>
 
34
#include <QtGui/QGraphicsView>
 
35
#include <QtDBus/QDBusInterface>
 
36
#include <QtDBus/QDBusPendingCall>
 
37
#include <QtCore/QDate>
 
38
#include <QtCore/QTimer>
 
39
#include <QtDBus/QDBusConnectionInterface>
 
40
 
 
41
#include <KColorScheme>
 
42
#include <KConfigDialog>
 
43
#include <KConfigGroup>
 
44
#include <KDatePicker>
 
45
#include <KMenu>
 
46
#include <KDebug>
 
47
#include <KDialog>
 
48
#include <KGlobalSettings>
 
49
#include <KRun>
 
50
#include <KLocale>
 
51
#include <KPassivePopup>
 
52
#include <KService>
 
53
#include <KServiceTypeTrader>
 
54
#include <KTimeZone>
 
55
#include <KToolInvocation>
 
56
#include <KMessageBox>
 
57
 
 
58
#include <Plasma/Containment>
 
59
#include <Plasma/Corona>
 
60
#include <Plasma/DataEngine>
 
61
#include <Plasma/Dialog>
 
62
#include <Plasma/Extender>
 
63
#include <Plasma/ExtenderItem>
 
64
#include <Plasma/Theme>
 
65
#include <Plasma/Label>
 
66
 
 
67
#include "calendar.h"
 
68
 
 
69
#include "ui_timezonesConfig.h"
 
70
#include "ui_generalConfig.h"
 
71
 
 
72
class ClockApplet::Private
 
73
{
 
74
public:
 
75
    Private(ClockApplet *clockapplet)
 
76
        : q(clockapplet),
 
77
          timezone(ClockApplet::localTimezoneUntranslated()),
 
78
          clipboardMenu(0),
 
79
          adjustSystemTimeAction(0),
 
80
          label(0),
 
81
          calendarWidget(0),
 
82
          forceTzDisplay(false)
 
83
    {}
 
84
 
 
85
    ClockApplet *q;
 
86
    Ui::timezonesConfig timezonesUi;
 
87
    Ui::generalConfig generalUi;
 
88
    QString timezone;
 
89
    QString defaultTimezone;
 
90
    QPoint clicked;
 
91
    QStringList selectedTimezones;
 
92
    KMenu *clipboardMenu;
 
93
    QAction *adjustSystemTimeAction;
 
94
    QString prettyTimezone;
 
95
    Plasma::Label *label;
 
96
    Plasma::Calendar *calendarWidget;
 
97
    int announceInterval;
 
98
    QTime lastTimeSeen;
 
99
    bool forceTzDisplay : 1;
 
100
 
 
101
    void addTzToTipText(QString &subText, const QString& tz)
 
102
    {
 
103
        Plasma::DataEngine::Data data = q->dataEngine("time")->query(tz);
 
104
 
 
105
        subText.append("<tr><td align=\"right\">");
 
106
        if (tz == "UTC")  {
 
107
            subText.append("UTC");
 
108
        } else {
 
109
            subText.append(data["Timezone City"].toString().replace('_', "&nbsp;"));
 
110
        }
 
111
        subText.append(":</td><td>");
 
112
 
 
113
        subText.append(KGlobal::locale()->formatTime(data["Time"].toTime(), false).replace(' ', "&nbsp;"))
 
114
               .append(",&nbsp;")
 
115
               .append(q->calendar()->formatDate(data["Date"].toDate()).replace(' ', "&nbsp;"))
 
116
               .append("</td></tr>");
 
117
    }
 
118
 
 
119
    void createCalendarExtender()
 
120
    {
 
121
        if (!q->extender()->hasItem("calendar")) {
 
122
            Plasma::ExtenderItem *eItem = new Plasma::ExtenderItem(q->extender());
 
123
            eItem->setName("calendar");
 
124
            q->initExtenderItem(eItem);
 
125
        }
 
126
    }
 
127
 
 
128
    void createToday()
 
129
    {
 
130
        QString tmpStr = "isHoliday" + QString(':') + calendarWidget->holidaysRegions().join(QString(','))
 
131
                                     + QString(':') + QDate::currentDate().toString(Qt::ISODate);
 
132
        bool isHoliday = q->dataEngine("calendar")->query(tmpStr).value(tmpStr).toBool();
 
133
 
 
134
        Plasma::ExtenderItem *todayExtender = q->extender()->item("today");
 
135
 
 
136
        if (!todayExtender && isHoliday) {
 
137
            Plasma::ExtenderItem *eItem = new Plasma::ExtenderItem(q->extender());
 
138
            eItem->setName("today");
 
139
            q->initExtenderItem(eItem);
 
140
        } else if (todayExtender && !isHoliday) {
 
141
            todayExtender->destroy();
 
142
        }
 
143
    }
 
144
 
 
145
    void setPrettyTimezone()
 
146
    {
 
147
        QString timezonetranslated = i18n(timezone.toUtf8().data());
 
148
        if (timezone == "UTC")  {
 
149
            prettyTimezone = timezonetranslated;
 
150
        } else if (!q->isLocalTimezone()) {
 
151
            QStringList tzParts = timezonetranslated.split('/', QString::SkipEmptyParts);
 
152
            if (tzParts.count() == 1) {
 
153
                prettyTimezone = timezonetranslated;
 
154
            } else if (tzParts.count() > 0) {
 
155
                prettyTimezone = tzParts.last();
 
156
            } else {
 
157
                prettyTimezone = timezonetranslated;
 
158
            }
 
159
        } else {
 
160
            prettyTimezone = localTimezone();
 
161
        }
 
162
 
 
163
        prettyTimezone = prettyTimezone.replace('_', ' ');
 
164
    }
 
165
};
 
166
 
 
167
ClockApplet::ClockApplet(QObject *parent, const QVariantList &args)
 
168
    : Plasma::PopupApplet(parent, args),
 
169
      d(new Private(this))
 
170
{
 
171
    setPopupIcon(QIcon());
 
172
    setPassivePopup(true);
 
173
}
 
174
 
 
175
ClockApplet::~ClockApplet()
 
176
{
 
177
    delete d->clipboardMenu;
 
178
    delete d;
 
179
}
 
180
 
 
181
void ClockApplet::speakTime(const QTime &time)
 
182
{
 
183
    if (!d->announceInterval) {
 
184
        return;
 
185
    }
 
186
 
 
187
    if ((time.minute() % d->announceInterval) == 0) {
 
188
        // If KTTSD not running, start it.
 
189
        if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kttsd")) {
 
190
            QString error;
 
191
            if (KToolInvocation::startServiceByDesktopName("kttsd", QStringList(), &error)) {
 
192
                KPassivePopup::message(i18n("Starting Jovie Text-to-Speech Service Failed"), error, static_cast<QWidget *>(0));
 
193
                return;
 
194
            }
 
195
        }
 
196
 
 
197
        QDBusInterface ktts("org.kde.kttsd", "/KSpeech", "org.kde.KSpeech");
 
198
        ktts.asyncCall("setApplicationName", "plasmaclock");
 
199
        QString text;
 
200
        if (time.minute() == 0) {
 
201
            if (KGlobal::locale()->use12Clock()) {
 
202
                if (time.hour() < 12) {
 
203
                    text = i18ncp("Text sent to the text to speech service "
 
204
                                     "when minutes==0 and it is AM",
 
205
                                 "It is 1 o clock a m",
 
206
                                 "It is %1 o clock a m",
 
207
                                 time.hour());
 
208
                } else {
 
209
                    text = i18ncp("Text sent to the text to speech service "
 
210
                                     "when minutes==0 and it is PM",
 
211
                                 "It is 1 o clock p m",
 
212
                                 "It is %1 o clock p m",
 
213
                                 time.hour()-12);
 
214
                }
 
215
            } else {
 
216
                text = i18ncp("Text sent to the text to speech service "
 
217
                                 "when minutes==0 and it is the 24 hour clock",
 
218
                                 "It is 1 o clock",
 
219
                                 "It is %1 o clock",
 
220
                                 time.hour());
 
221
            }
 
222
        } else {
 
223
            if (KGlobal::locale()->use12Clock()) {
 
224
                if (time.hour() < 12) {
 
225
                    text = i18nc("Text sent to the text to speech service for AM",
 
226
                                "It is %1:%2 a m",
 
227
                                time.hour(),
 
228
                                time.minute());
 
229
                } else {
 
230
                    text = i18nc("Text sent to the text to speech service for PM",
 
231
                                "It is %1:%2 p m",
 
232
                                time.hour()-12,
 
233
                                time.minute());
 
234
                }
 
235
            } else {
 
236
                text = i18nc("Text sent to the text to speech service for the 24 hour clock",
 
237
                                "It is %1:%2",
 
238
                                time.hour(),
 
239
                                time.minute());
 
240
            }
 
241
        }
 
242
        ktts.asyncCall("say", text, 0);
 
243
    }
 
244
}
 
245
 
 
246
void ClockApplet::toolTipAboutToShow()
 
247
{
 
248
    updateTipContent();
 
249
}
 
250
 
 
251
void ClockApplet::toolTipHidden()
 
252
{
 
253
    Plasma::ToolTipManager::self()->clearContent(this);
 
254
}
 
255
 
 
256
void ClockApplet::updateTipContent()
 
257
{
 
258
    Plasma::ToolTipContent tipData;
 
259
 
 
260
    // the main text contains the current timezone's time and date
 
261
    Plasma::DataEngine::Data data = dataEngine("time")->query(currentTimezone());
 
262
    QString mainText = d->prettyTimezone + ' ';
 
263
    mainText += KGlobal::locale()->formatTime(data["Time"].toTime(), false) + "<br>";
 
264
    QDate tipDate = data["Date"].toDate();
 
265
    mainText += calendar()->formatDate(tipDate);
 
266
    tipData.setMainText(mainText);
 
267
 
 
268
    QString subText("<table>");
 
269
    if (!isLocalTimezone()) {
 
270
        d->addTzToTipText(subText, localTimezone());
 
271
    }
 
272
 
 
273
    foreach (const QString &tz, getSelectedTimezones()) {
 
274
        if (tz == currentTimezone()) {
 
275
            continue;
 
276
        }
 
277
 
 
278
        d->addTzToTipText(subText, tz);
 
279
    }
 
280
 
 
281
    if (!subText.isEmpty()) {
 
282
        subText.prepend("<table>");
 
283
        subText.append("</table>");
 
284
    }
 
285
 
 
286
    if (d->calendarWidget->dateHasDetails(tipDate)) {
 
287
        subText.append("<br>").append(d->calendarWidget->dateDetails(tipDate).join("<br>"));
 
288
    }
 
289
 
 
290
    tipData.setSubText(subText);
 
291
 
 
292
    // query for custom content
 
293
    Plasma::ToolTipContent customContent = toolTipContent();
 
294
    if (customContent.image().isNull()) {
 
295
        tipData.setImage(KIcon(icon()).pixmap(IconSize(KIconLoader::Desktop)));
 
296
    } else {
 
297
        tipData.setImage(customContent.image());
 
298
    }
 
299
 
 
300
    if (!customContent.mainText().isEmpty()) {
 
301
        // add their main text
 
302
        tipData.setMainText(customContent.mainText() + "<br>" + tipData.mainText());
 
303
    }
 
304
 
 
305
    if (!customContent.subText().isEmpty()) {
 
306
        // add their sub text
 
307
        tipData.setSubText(customContent.subText() + "<br>" + tipData.subText());
 
308
    }
 
309
 
 
310
    tipData.setAutohide(false);
 
311
    Plasma::ToolTipManager::self()->setContent(this, tipData);
 
312
}
 
313
 
 
314
void ClockApplet::updateClockApplet()
 
315
{
 
316
    Plasma::DataEngine::Data data = dataEngine("time")->query(currentTimezone());
 
317
    updateClockApplet(data);
 
318
}
 
319
 
 
320
void ClockApplet::updateClockApplet(const Plasma::DataEngine::Data &data)
 
321
{
 
322
    bool updateSelectedDate = (d->calendarWidget->currentDate() == d->calendarWidget->date());
 
323
    d->calendarWidget->setCurrentDate(data["Date"].toDate());
 
324
 
 
325
    if (updateSelectedDate){
 
326
        d->calendarWidget->setDate(d->calendarWidget->currentDate());
 
327
    }
 
328
 
 
329
    const QTime t = d->lastTimeSeen;
 
330
    d->lastTimeSeen = data["Time"].toTime();
 
331
    if (d->lastTimeSeen.minute() != t.minute() || d->lastTimeSeen.hour() != t.hour()) {
 
332
        speakTime(d->lastTimeSeen);
 
333
    }
 
334
}
 
335
 
 
336
QTime ClockApplet::lastTimeSeen() const
 
337
{
 
338
    return d->lastTimeSeen;
 
339
}
 
340
 
 
341
void ClockApplet::resetLastTimeSeen()
 
342
{
 
343
    d->lastTimeSeen = QTime();
 
344
}
 
345
 
 
346
Plasma::ToolTipContent ClockApplet::toolTipContent()
 
347
{
 
348
    return Plasma::ToolTipContent();
 
349
}
 
350
 
 
351
void ClockApplet::createConfigurationInterface(KConfigDialog *parent)
 
352
{
 
353
    createClockConfigurationInterface(parent);
 
354
 
 
355
    QWidget *generalWidget = new QWidget();
 
356
    d->generalUi.setupUi(generalWidget);
 
357
    parent->addPage(generalWidget, i18nc("General configuration page", "General"), Applet::icon());
 
358
    d->generalUi.interval->setValue(d->announceInterval);
 
359
 
 
360
    d->calendarWidget->createConfigurationInterface(parent);
 
361
 
 
362
    QWidget *widget = new QWidget();
 
363
    d->timezonesUi.setupUi(widget);
 
364
    d->timezonesUi.searchLine->addTreeWidget(d->timezonesUi.timeZones);
 
365
 
 
366
    parent->addPage(widget, i18n("Time Zones"), "preferences-desktop-locale");
 
367
 
 
368
    foreach (const QString &tz, d->selectedTimezones) {
 
369
        d->timezonesUi.timeZones->setSelected(tz, true);
 
370
    }
 
371
 
 
372
    updateClockDefaultsTo();
 
373
    int defaultSelection = d->timezonesUi.clockDefaultsTo->findData(d->defaultTimezone);
 
374
    if (defaultSelection < 0) {
 
375
        defaultSelection = 0; //if it's something unexpected default to local
 
376
        //kDebug() << d->defaultTimezone << "not in list!?";
 
377
    }
 
378
    d->timezonesUi.clockDefaultsTo->setCurrentIndex(defaultSelection);
 
379
 
 
380
    connect(d->generalUi.interval, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified()));
 
381
    connect(d->timezonesUi.timeZones, SIGNAL(itemChanged(QTreeWidgetItem*,int)), parent, SLOT(settingsModified()));
 
382
    connect(d->timezonesUi.timeZones, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(updateClockDefaultsTo()));
 
383
    connect(d->timezonesUi.clockDefaultsTo,SIGNAL(activated(const QString &)), parent, SLOT(settingsModified()));
 
384
}
 
385
 
 
386
void ClockApplet::createClockConfigurationInterface(KConfigDialog *parent)
 
387
{
 
388
    Q_UNUSED(parent)
 
389
}
 
390
 
 
391
void ClockApplet::clockConfigChanged()
 
392
{
 
393
 
 
394
}
 
395
 
 
396
void ClockApplet::configChanged()
 
397
{
 
398
    if (isUserConfiguring()) {
 
399
        configAccepted();
 
400
    }
 
401
 
 
402
    KConfigGroup cg = config();
 
403
    d->selectedTimezones = cg.readEntry("timeZones", QStringList() << "UTC");
 
404
    d->timezone = cg.readEntry("timezone", d->timezone);
 
405
    d->defaultTimezone = cg.readEntry("defaultTimezone", d->timezone);
 
406
    d->forceTzDisplay = d->timezone != d->defaultTimezone;
 
407
    d->setPrettyTimezone();
 
408
    d->announceInterval = cg.readEntry("announceInterval", 0);
 
409
 
 
410
    clockConfigChanged();
 
411
 
 
412
    if (isUserConfiguring()) {
 
413
        constraintsEvent(Plasma::SizeConstraint);
 
414
        update();
 
415
    } else {
 
416
        // d->calendarWidget->configAccepted(cg); is called in configAccepted(), 
 
417
        // as is setCurrentTimezone
 
418
        // so we only need to do this in the case where the user hasn't been
 
419
        // configuring things
 
420
        d->calendarWidget->applyConfiguration(cg);
 
421
        Plasma::DataEngine::Data data = dataEngine("time")->query(d->timezone);
 
422
        d->calendarWidget->setDate(data["Date"].toDate());
 
423
    }
 
424
}
 
425
 
 
426
void ClockApplet::clockConfigAccepted()
 
427
{
 
428
 
 
429
}
 
430
 
 
431
void ClockApplet::configAccepted()
 
432
{
 
433
    KConfigGroup cg = config();
 
434
 
 
435
    cg.writeEntry("timeZones", d->timezonesUi.timeZones->selection());
 
436
 
 
437
    if (d->timezonesUi.clockDefaultsTo->currentIndex() == 0) {
 
438
        //The first position in timezonesUi.clockDefaultsTo is "Local"
 
439
        d->defaultTimezone = localTimezoneUntranslated();
 
440
    } else {
 
441
        d->defaultTimezone = d->timezonesUi.clockDefaultsTo->itemData(d->timezonesUi.clockDefaultsTo->currentIndex()).toString();
 
442
    }
 
443
 
 
444
    cg.writeEntry("defaultTimezone", d->defaultTimezone);
 
445
    QString cur = currentTimezone();
 
446
    setCurrentTimezone(d->defaultTimezone);
 
447
    changeEngineTimezone(cur, d->defaultTimezone);
 
448
 
 
449
    d->calendarWidget->configAccepted(cg);
 
450
 
 
451
    cg.writeEntry("announceInterval", d->generalUi.interval->value());
 
452
 
 
453
    clockConfigAccepted();
 
454
 
 
455
    emit configNeedsSaving();
 
456
}
 
457
 
 
458
void ClockApplet::updateClockDefaultsTo()
 
459
{
 
460
    QString oldSelection = d->timezonesUi.clockDefaultsTo->currentText();
 
461
    d->timezonesUi.clockDefaultsTo->clear();
 
462
    d->timezonesUi.clockDefaultsTo->addItem(localTimezone(), localTimezone());
 
463
    foreach(const QString &tz, d->timezonesUi.timeZones->selection()) {
 
464
        d->timezonesUi.clockDefaultsTo->addItem(KTimeZoneWidget::displayName(KTimeZone(tz)), tz);
 
465
    }
 
466
    int newPosition = d->timezonesUi.clockDefaultsTo->findText(oldSelection);
 
467
    if (newPosition >= 0) {
 
468
        d->timezonesUi.clockDefaultsTo->setCurrentIndex(newPosition);
 
469
    }
 
470
    if (d->timezonesUi.clockDefaultsTo->count() > 1) {
 
471
        d->timezonesUi.clockDefaultsTo->setEnabled(true);
 
472
    } else {
 
473
        // Only "Local" in timezonesUi.clockDefaultsTo
 
474
        d->timezonesUi.clockDefaultsTo->setEnabled(false);
 
475
    }
 
476
}
 
477
 
 
478
void ClockApplet::changeEngineTimezone(const QString &oldTimezone, const QString &newTimezone)
 
479
{
 
480
    // reimplemented by subclasses to get the new data
 
481
    Q_UNUSED(oldTimezone);
 
482
    Q_UNUSED(newTimezone);
 
483
}
 
484
 
 
485
bool ClockApplet::shouldDisplayTimezone() const
 
486
{
 
487
    return d->forceTzDisplay;
 
488
}
 
489
 
 
490
QList<QAction *> ClockApplet::contextualActions()
 
491
{
 
492
    if (!d->clipboardMenu) {
 
493
        d->clipboardMenu = new KMenu(i18n("C&opy to Clipboard"));
 
494
        d->clipboardMenu->setIcon(KIcon("edit-copy"));
 
495
        connect(d->clipboardMenu, SIGNAL(aboutToShow()), this, SLOT(updateClipboardMenu()));
 
496
        connect(d->clipboardMenu, SIGNAL(triggered(QAction*)), this, SLOT(copyToClipboard(QAction*)));
 
497
 
 
498
        KService::List offers = KServiceTypeTrader::self()->query("KCModule", "Library == 'kcm_clock'");
 
499
        if (!offers.isEmpty() && hasAuthorization("LaunchApp")) {
 
500
            d->adjustSystemTimeAction = new QAction(this);
 
501
            d->adjustSystemTimeAction->setText(i18n("Adjust Date and Time..."));
 
502
            d->adjustSystemTimeAction->setIcon(KIcon(icon()));
 
503
            connect(d->adjustSystemTimeAction, SIGNAL(triggered()), this, SLOT(launchTimeControlPanel()));
 
504
        }
 
505
    }
 
506
 
 
507
    QList<QAction*> contextualActions;
 
508
    contextualActions << d->clipboardMenu->menuAction();
 
509
 
 
510
    if (d->adjustSystemTimeAction) {
 
511
        contextualActions << d->adjustSystemTimeAction;
 
512
    }
 
513
    return contextualActions;
 
514
}
 
515
 
 
516
void ClockApplet::launchTimeControlPanel()
 
517
{
 
518
    KService::List offers = KServiceTypeTrader::self()->query("KCModule", "Library == 'kcm_clock'");
 
519
    if (offers.isEmpty()) {
 
520
        kDebug() << "fail";
 
521
        return;
 
522
    }
 
523
 
 
524
    KUrl::List urls;
 
525
    KService::Ptr service = offers.first();
 
526
    KRun::run(*service, urls, 0);
 
527
}
 
528
 
 
529
void ClockApplet::wheelEvent(QGraphicsSceneWheelEvent *event)
 
530
{
 
531
    if (d->selectedTimezones.count() < 1) {
 
532
        return;
 
533
    }
 
534
 
 
535
    QString newTimezone;
 
536
 
 
537
    if (isLocalTimezone()) {
 
538
        if (event->delta() > 0) {
 
539
            newTimezone = d->selectedTimezones.last();
 
540
        } else {
 
541
            newTimezone = d->selectedTimezones.first();
 
542
        }
 
543
    } else {
 
544
        int current = d->selectedTimezones.indexOf(currentTimezone());
 
545
 
 
546
        if (event->delta() > 0) {
 
547
            int previous = current - 1;
 
548
            if (previous < 0) {
 
549
                newTimezone = localTimezoneUntranslated();
 
550
            } else {
 
551
                newTimezone = d->selectedTimezones.at(previous);
 
552
            }
 
553
        } else {
 
554
            int next = current + 1;
 
555
            if (next > d->selectedTimezones.count() - 1) {
 
556
                newTimezone = localTimezoneUntranslated();
 
557
            } else {
 
558
                newTimezone = d->selectedTimezones.at(next);
 
559
            }
 
560
        }
 
561
    }
 
562
 
 
563
    QString cur = currentTimezone();
 
564
    setCurrentTimezone(newTimezone);
 
565
    changeEngineTimezone(cur, newTimezone);
 
566
    update();
 
567
}
 
568
 
 
569
void ClockApplet::initExtenderItem(Plasma::ExtenderItem *item)
 
570
{
 
571
    if (item->name() == "calendar") {
 
572
        item->setTitle(i18n("Calendar"));
 
573
        item->setIcon("view-pim-calendar");
 
574
        item->setWidget(d->calendarWidget);
 
575
    } else if (item->name() == "today") {
 
576
        item->setTitle(i18n("Today"));
 
577
        item->setIcon("view-pim-calendar");
 
578
        d->label = new Plasma::Label();
 
579
        item->setWidget(d->label);
 
580
    }
 
581
}
 
582
 
 
583
void ClockApplet::init()
 
584
{
 
585
    Plasma::ToolTipManager::self()->registerWidget(this);
 
586
 
 
587
    d->calendarWidget = new Plasma::Calendar();
 
588
    d->calendarWidget->setAutomaticUpdateEnabled(false);
 
589
    d->calendarWidget->setMinimumSize(QSize(230, 220));
 
590
    d->createCalendarExtender();
 
591
 
 
592
    extender();
 
593
 
 
594
    configChanged();
 
595
    QTimer::singleShot(0, this, SLOT(createToday()));
 
596
}
 
597
 
 
598
void ClockApplet::focusInEvent(QFocusEvent* event)
 
599
{
 
600
    Q_UNUSED(event);
 
601
    d->calendarWidget->setFlag(QGraphicsItem::ItemIsFocusable);
 
602
    d->calendarWidget->setFocus();
 
603
}
 
604
 
 
605
void ClockApplet::popupEvent(bool show)
 
606
{
 
607
    if (!show) {
 
608
        return;
 
609
    }
 
610
 
 
611
    Plasma::DataEngine::Data data = dataEngine("time")->query(currentTimezone());
 
612
    d->calendarWidget->setDate(data["Date"].toDate());
 
613
}
 
614
 
 
615
void ClockApplet::constraintsEvent(Plasma::Constraints constraints)
 
616
{
 
617
    Q_UNUSED(constraints)
 
618
}
 
619
 
 
620
void ClockApplet::setCurrentTimezone(const QString &tz)
 
621
{
 
622
    if (d->timezone == tz) {
 
623
        return;
 
624
    }
 
625
 
 
626
    if (tz == localTimezone()) {
 
627
        // catch people accidentally passing in the translation of "Local"
 
628
        d->timezone = localTimezoneUntranslated();
 
629
    } else {
 
630
        d->timezone = tz;
 
631
    }
 
632
 
 
633
    d->forceTzDisplay = d->timezone != d->defaultTimezone;
 
634
    d->setPrettyTimezone();
 
635
 
 
636
    Plasma::DataEngine::Data data = dataEngine("time")->query(d->timezone);
 
637
    d->calendarWidget->setDate(data["Date"].toDate());
 
638
 
 
639
    KConfigGroup cg = config();
 
640
    cg.writeEntry("timezone", d->timezone);
 
641
    emit configNeedsSaving();
 
642
}
 
643
 
 
644
QString ClockApplet::currentTimezone() const
 
645
{
 
646
    return d->timezone;
 
647
}
 
648
 
 
649
QString ClockApplet::prettyTimezone() const
 
650
{
 
651
    return d->prettyTimezone;
 
652
}
 
653
 
 
654
QStringList ClockApplet::getSelectedTimezones() const
 
655
{
 
656
    return d->selectedTimezones;
 
657
}
 
658
 
 
659
bool ClockApplet::isLocalTimezone() const
 
660
{
 
661
    return d->timezone == localTimezoneUntranslated();
 
662
}
 
663
 
 
664
QString ClockApplet::localTimezone()
 
665
{
 
666
    return i18nc("Local time zone", "Local");
 
667
}
 
668
 
 
669
QString ClockApplet::localTimezoneUntranslated()
 
670
{
 
671
    return "Local";
 
672
}
 
673
 
 
674
void ClockApplet::updateClipboardMenu()
 
675
{
 
676
    d->clipboardMenu->clear();
 
677
    QList<QAction*> actions;
 
678
    Plasma::DataEngine::Data data = dataEngine("time")->query(currentTimezone());
 
679
    QDateTime dateTime = QDateTime(data["Date"].toDate(), data["Time"].toTime());
 
680
 
 
681
    d->clipboardMenu->addAction(calendar()->formatDate(dateTime.date(), KLocale::LongDate));
 
682
    d->clipboardMenu->addAction(calendar()->formatDate(dateTime.date(), KLocale::ShortDate));
 
683
    // Display ISO Date format if not already displayed
 
684
    if (KGlobal::locale()->dateFormatShort() != "%Y-%m-%d") {
 
685
        d->clipboardMenu->addAction(calendar()->formatDate(dateTime.date(), "%Y-%m-%d"));
 
686
    }
 
687
 
 
688
    QAction *sep0 = new QAction(this);
 
689
    sep0->setSeparator(true);
 
690
    d->clipboardMenu->addAction(sep0);
 
691
 
 
692
    d->clipboardMenu->addAction(KGlobal::locale()->formatTime(dateTime.time(), false));
 
693
    d->clipboardMenu->addAction(KGlobal::locale()->formatTime(dateTime.time(), true));
 
694
 
 
695
    QAction *sep1 = new QAction(this);
 
696
    sep1->setSeparator(true);
 
697
    d->clipboardMenu->addAction(sep1);
 
698
 
 
699
    KLocale tempLocale(*KGlobal::locale());
 
700
    tempLocale.setCalendar(calendar()->calendarType());
 
701
    d->clipboardMenu->addAction(tempLocale.formatDateTime(dateTime, KLocale::LongDate));
 
702
    d->clipboardMenu->addAction(tempLocale.formatDateTime(dateTime, KLocale::LongDate, true));
 
703
    d->clipboardMenu->addAction(tempLocale.formatDateTime(dateTime, KLocale::ShortDate));
 
704
    d->clipboardMenu->addAction(tempLocale.formatDateTime(dateTime, KLocale::ShortDate, true));
 
705
    // Display ISO DateTime format if not already displayed
 
706
    if (tempLocale.dateFormatShort() != "%Y-%m-%d") {
 
707
        tempLocale.setDateFormatShort("%Y-%m-%d");
 
708
        d->clipboardMenu->addAction(tempLocale.formatDateTime(dateTime, KLocale::ShortDate, true));
 
709
    }
 
710
 
 
711
    QAction *sep2 = new QAction(this);
 
712
    sep2->setSeparator(true);
 
713
    d->clipboardMenu->addAction(sep2);
 
714
 
 
715
    QMenu *calendarMenu = d->clipboardMenu->addMenu( i18nc( "@item:inmenu Submenu for alternative calendar dates", "Other Calendars" ) );
 
716
    QStringList calendars = KCalendarSystem::calendarSystems();
 
717
    foreach ( const QString &cal, calendars ) {
 
718
        if (cal != calendar()->calendarType()) {
 
719
            KCalendarSystem *tempCal = KCalendarSystem::create(cal);
 
720
            QString text = tempCal->formatDate(dateTime.date(), KLocale::LongDate) + " (" + KCalendarSystem::calendarLabel(cal) + ')';
 
721
            calendarMenu->addAction(text);
 
722
            text = tempCal->formatDate(dateTime.date(), KLocale::ShortDate) + " (" + KCalendarSystem::calendarLabel(cal) + ')';
 
723
            calendarMenu->addAction(text);
 
724
            delete tempCal;
 
725
        }
 
726
    }
 
727
}
 
728
 
 
729
void ClockApplet::copyToClipboard(QAction* action)
 
730
{
 
731
    QString text = action->text();
 
732
    text.remove(QChar('&'));
 
733
 
 
734
    QApplication::clipboard()->setText(text);
 
735
}
 
736
 
 
737
const KCalendarSystem *ClockApplet::calendar() const
 
738
{
 
739
    return d->calendarWidget->calendar();
 
740
}
 
741
 
 
742
#include "clockapplet.moc"