1 /* BEGIN_COMMON_COPYRIGHT_HEADER
2  * (c)LGPL2+
3  *
4  * LXQt - a lightweight, Qt based, desktop toolset
5  * https://lxqt.org
6  *
7  * Copyright: 2012-2013 Razor team
8  *            2014 LXQt team
9  * Authors:
10  *   Kuzma Shapran <kuzma.shapran@gmail.com>
11  *
12  * This program or library is free software; you can redistribute it
13  * and/or modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21 
22  * You should have received a copy of the GNU Lesser General
23  * Public License along with this library; if not, write to the
24  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301 USA
26  *
27  * END_COMMON_COPYRIGHT_HEADER */
28 
29 #include "lxqtworldclock.h"
30 
31 #include <LXQt/Globals>
32 
33 #include <QCalendarWidget>
34 #include <QDate>
35 #include <QDesktopWidget>
36 #include <QDialog>
37 #include <QEvent>
38 #include <QHBoxLayout>
39 #include <QLocale>
40 #include <QScopedArrayPointer>
41 #include <QTimer>
42 #include <QWheelEvent>
43 #include <QToolTip>
44 
45 
LXQtWorldClock(const ILXQtPanelPluginStartupInfo & startupInfo)46 LXQtWorldClock::LXQtWorldClock(const ILXQtPanelPluginStartupInfo &startupInfo):
47     QObject(),
48     ILXQtPanelPlugin(startupInfo),
49     mPopup(nullptr),
50     mTimer(new QTimer(this)),
51     mUpdateInterval(1),
52     mAutoRotate(true),
53     mShowWeekNumber(true),
54     mShowTooltip(false),
55     mPopupContent(nullptr)
56 {
57     mMainWidget = new QWidget();
58     mMainWidget->installEventFilter(this);
59     mContent = new ActiveLabel();
60     mRotatedWidget = new LXQt::RotatedWidget(*mContent, mMainWidget);
61 
62     QVBoxLayout *borderLayout = new QVBoxLayout(mMainWidget);
63     borderLayout->setContentsMargins(0, 0, 0, 0);
64     borderLayout->setSpacing(0);
65     borderLayout->addWidget(mRotatedWidget, 0, Qt::AlignCenter);
66 
67     mContent->setObjectName(QLatin1String("WorldClockContent"));
68 
69     mContent->setAlignment(Qt::AlignCenter);
70 
71     settingsChanged();
72 
73     mTimer->setTimerType(Qt::PreciseTimer);
74     connect(mTimer, &QTimer::timeout, this, &LXQtWorldClock::timeout);
75 
76     connect(mContent, &ActiveLabel::wheelScrolled, this, &LXQtWorldClock::wheelScrolled);
77 }
78 
~LXQtWorldClock()79 LXQtWorldClock::~LXQtWorldClock()
80 {
81     delete mMainWidget;
82 }
83 
timeout()84 void LXQtWorldClock::timeout()
85 {
86     if (QDateTime{}.time().msec() > 500)
87         restartTimer();
88     updateTimeText();
89 }
90 
updateTimeText()91 void LXQtWorldClock::updateTimeText()
92 {
93     QDateTime now = QDateTime::currentDateTime();
94     QString timeZoneName = mActiveTimeZone;
95     if (timeZoneName == QLatin1String("local"))
96         timeZoneName = QString::fromLatin1(QTimeZone::systemTimeZoneId());
97     QTimeZone timeZone(timeZoneName.toLatin1());
98     QDateTime tzNow = now.toTimeZone(timeZone);
99 
100     bool isUpToDate(true);
101     if (!mShownTime.isValid()) // first time or forced update
102     {
103         isUpToDate = false;
104         if (mUpdateInterval < 60000)
105             mShownTime = tzNow.addSecs(-tzNow.time().msec()); // s
106         else if (mUpdateInterval < 3600000)
107             mShownTime = tzNow.addSecs(-tzNow.time().second()); // m
108         else
109             mShownTime = tzNow.addSecs(-tzNow.time().minute() * 60 - tzNow.time().second()); // h
110     }
111     else
112     {
113         qint64 diff = mShownTime.secsTo(tzNow);
114         if (mUpdateInterval < 60000)
115         {
116             if (diff < 0 || diff >= 1)
117             {
118                 isUpToDate = false;
119                 mShownTime = tzNow.addSecs(-tzNow.time().msec());
120             }
121         }
122         else if (mUpdateInterval < 3600000)
123         {
124             if (diff < 0 || diff >= 60)
125             {
126                 isUpToDate = false;
127                 mShownTime = tzNow.addSecs(-tzNow.time().second());
128             }
129         }
130         else if (diff < 0 || diff >= 3600)
131         {
132             isUpToDate = false;
133             mShownTime = tzNow.addSecs(-tzNow.time().minute() * 60 - tzNow.time().second());
134         }
135     }
136     if (!isUpToDate)
137     {
138         const QSize old_size = mContent->sizeHint();
139         mContent->setText(tzNow.toString(preformat(mFormat, timeZone, tzNow)));
140         if (old_size != mContent->sizeHint())
141             mRotatedWidget->adjustContentSize();
142         mRotatedWidget->update();
143         updatePopupContent();
144 
145     }
146 }
147 
setTimeText()148 void LXQtWorldClock::setTimeText()
149 {
150     mShownTime = QDateTime(); // force an update
151     updateTimeText();
152 }
153 
restartTimer()154 void LXQtWorldClock::restartTimer()
155 {
156     mTimer->stop();
157     // check the time every second even if the clock doesn't show seconds
158     // because otherwise, the shown time might be vey wrong after resume
159     mTimer->setInterval(1000);
160 
161     int delay = static_cast<int>(1000 - (static_cast<long long>(QTime::currentTime().msecsSinceStartOfDay()) % 1000));
162     QTimer::singleShot(delay, Qt::PreciseTimer, this, &LXQtWorldClock::updateTimeText);
163     QTimer::singleShot(delay, Qt::PreciseTimer, mTimer, SLOT(start()));
164 }
165 
settingsChanged()166 void LXQtWorldClock::settingsChanged()
167 {
168     PluginSettings *_settings = settings();
169 
170     QString oldFormat = mFormat;
171 
172     mTimeZones.clear();
173 
174     const QList<QMap<QString, QVariant> > array = _settings->readArray(QLatin1String("timeZones"));
175     for (const auto &map : array)
176     {
177         QString timeZoneName = map.value(QLatin1String("timeZone"), QString()).toString();
178         mTimeZones.append(timeZoneName);
179         mTimeZoneCustomNames[timeZoneName] = map.value(QLatin1String("customName"),
180                                                        QString()).toString();
181     }
182 
183     if (mTimeZones.isEmpty())
184         mTimeZones.append(QLatin1String("local"));
185 
186     mDefaultTimeZone = _settings->value(QLatin1String("defaultTimeZone"), QString()).toString();
187     if (mDefaultTimeZone.isEmpty())
188         mDefaultTimeZone = mTimeZones[0];
189     mActiveTimeZone = mDefaultTimeZone;
190 
191 
192     bool longTimeFormatSelected = false;
193 
194     QString formatType = _settings->value(QLatin1String("formatType"), QString()).toString();
195     QString dateFormatType = _settings->value(QLatin1String("dateFormatType"), QString()).toString();
196     bool advancedManual = _settings->value(QLatin1String("useAdvancedManualFormat"), false).toBool();
197 
198     // backward compatibility
199     if (formatType == QLatin1String("custom"))
200     {
201         formatType = QLatin1String("short-timeonly");
202         dateFormatType = QLatin1String("short");
203         advancedManual = true;
204     }
205     else if (formatType == QLatin1String("short"))
206     {
207         formatType = QLatin1String("short-timeonly");
208         dateFormatType = QLatin1String("short");
209         advancedManual = false;
210     }
211     else if ((formatType == QLatin1String("full")) ||
212              (formatType == QLatin1String("long")) ||
213              (formatType == QLatin1String("medium")))
214     {
215         formatType = QLatin1String("long-timeonly");
216         dateFormatType = QLatin1String("long");
217         advancedManual = false;
218     }
219 
220     if (formatType == QLatin1String("long-timeonly"))
221         longTimeFormatSelected = true;
222 
223     bool timeShowSeconds = _settings->value(QLatin1String("timeShowSeconds"), false).toBool();
224     bool timePadHour = _settings->value(QLatin1String("timePadHour"), false).toBool();
225     bool timeAMPM = _settings->value(QLatin1String("timeAMPM"), false).toBool();
226     mShowTooltip = _settings->value(QLatin1String("showTooltip"), false).toBool();
227     // timezone
228     bool showTimezone = _settings->value(QLatin1String("showTimezone"), false).toBool() && !longTimeFormatSelected;
229 
230     QString timezonePosition = _settings->value(QLatin1String("timezonePosition"), QString()).toString();
231     QString timezoneFormatType = _settings->value(QLatin1String("timezoneFormatType"), QString()).toString();
232 
233     // date
234     bool showDate = _settings->value(QLatin1String("showDate"), false).toBool();
235 
236     QString datePosition = _settings->value(QLatin1String("datePosition"), QString()).toString();
237 
238     bool dateShowYear = _settings->value(QLatin1String("dateShowYear"), false).toBool();
239     bool dateShowDoW = _settings->value(QLatin1String("dateShowDoW"), false).toBool();
240     bool datePadDay = _settings->value(QLatin1String("datePadDay"), false).toBool();
241     bool dateLongNames = _settings->value(QLatin1String("dateLongNames"), false).toBool();
242 
243     // advanced
244     QString customFormat = _settings->value(QLatin1String("customFormat"), tr("'<b>'HH:mm:ss'</b><br/><font size=\"-2\">'ddd, d MMM yyyy'<br/>'TT'</font>'")).toString();
245 
246     if (advancedManual)
247         mFormat = customFormat;
248     else
249     {
250         QLocale locale = QLocale(QLocale::AnyLanguage, QLocale().country());
251 
252         if (formatType == QLatin1String("short-timeonly"))
253             mFormat = locale.timeFormat(QLocale::ShortFormat);
254         else if (formatType == QLatin1String("long-timeonly"))
255             mFormat = locale.timeFormat(QLocale::LongFormat);
256         else // if (formatType == QLatin1String("custom-timeonly"))
257             mFormat = QString(QLatin1String("%1:mm%2%3")).arg(timePadHour ? QLatin1String("hh") : QLatin1String("h")).arg(timeShowSeconds ? QLatin1String(":ss") : QLatin1String("")).arg(timeAMPM ? QLatin1String(" A") : QLatin1String(""));
258 
259         if (showTimezone)
260         {
261             QString timezonePortion;
262             if (timezoneFormatType == QLatin1String("short"))
263                 timezonePortion = QLatin1String("TTTT");
264             else if (timezoneFormatType == QLatin1String("long"))
265                 timezonePortion = QLatin1String("TTTTT");
266             else if (timezoneFormatType == QLatin1String("offset"))
267                 timezonePortion = QLatin1String("T");
268             else if (timezoneFormatType == QLatin1String("abbreviation"))
269                 timezonePortion = QLatin1String("TTT");
270             else if (timezoneFormatType == QLatin1String("iana"))
271                 timezonePortion = QLatin1String("TT");
272             else // if (timezoneFormatType == QLatin1String("custom"))
273                 timezonePortion = QLatin1String("TTTTTT");
274 
275             if (timezonePosition == QLatin1String("below"))
276                 mFormat = mFormat + QLatin1String("'<br/>'") + timezonePortion;
277             else if (timezonePosition == QLatin1String("above"))
278                 mFormat = timezonePortion + QLatin1String("'<br/>'") + mFormat;
279             else if (timezonePosition == QLatin1String("before"))
280                 mFormat = timezonePortion + QLatin1String(" ") + mFormat;
281             else // if (timezonePosition == QLatin1String("after"))
282                 mFormat = mFormat + QLatin1String(" ") + timezonePortion;
283         }
284 
285         if (showDate)
286         {
287             QString datePortion;
288             if (dateFormatType == QLatin1String("short"))
289                 datePortion = locale.dateFormat(QLocale::ShortFormat);
290             else if (dateFormatType == QLatin1String("long"))
291                 datePortion = locale.dateFormat(QLocale::LongFormat);
292             else if (dateFormatType == QLatin1String("iso"))
293                 datePortion = QLatin1String("yyyy-MM-dd");
294             else // if (dateFormatType == QLatin1String("custom"))
295             {
296                 QString datePortionOrder;
297                 QString dateLocale = locale.dateFormat(QLocale::ShortFormat).toLower();
298                 int yearIndex = dateLocale.indexOf(QLatin1String("y"));
299                 int monthIndex = dateLocale.indexOf(QLatin1String("m"));
300                 int dayIndex = dateLocale.indexOf(QLatin1String("d"));
301                 if (yearIndex < dayIndex)
302                 // Big-endian (year, month, day) (yyyy MMMM dd, dddd) -> in some Asia countires like China or Japan
303                     datePortionOrder = QLatin1String("%1%2%3 %4%5%6");
304                 else if (monthIndex < dayIndex)
305                 // Middle-endian (month, day, year) (dddd, MMMM dd yyyy) -> USA
306                     datePortionOrder = QLatin1String("%6%5%3 %4%2%1");
307                 else
308                 // Little-endian (day, month, year) (dddd, dd MMMM yyyy) -> most of Europe
309                     datePortionOrder = QLatin1String("%6%5%4 %3%2%1");
310                 datePortion = datePortionOrder.arg(dateShowYear ? QLatin1String("yyyy") : QLatin1String("")).arg(dateShowYear ? QLatin1String(" ") : QLatin1String("")).arg(dateLongNames ? QLatin1String("MMMM") : QLatin1String("MMM")).arg(datePadDay ? QLatin1String("dd") : QLatin1String("d")).arg(dateShowDoW ? QLatin1String(", ") : QLatin1String("")).arg(dateShowDoW ? (dateLongNames ? QLatin1String("dddd") : QLatin1String("ddd")) : QLatin1String(""));
311             }
312 
313             if (datePosition == QLatin1String("below"))
314                 mFormat = mFormat + QLatin1String("'<br/>'") + datePortion;
315             else if (datePosition == QLatin1String("above"))
316                 mFormat = datePortion + QLatin1String("'<br/>'") + mFormat;
317             else if (datePosition == QLatin1String("before"))
318                 mFormat = datePortion + QLatin1String(" ") + mFormat;
319             else // if (datePosition == QLatin1String("after"))
320                 mFormat = mFormat + QLatin1String(" ") + datePortion;
321         }
322     }
323 
324 
325     if ((oldFormat != mFormat))
326     {
327         int update_interval;
328         QString format = mFormat;
329         format.replace(QRegExp(QLatin1String("'[^']*'")), QString());
330         //don't support updating on milisecond basis -> big performance hit
331         if (format.contains(QLatin1String("s")))
332             update_interval = 1000;
333         else if (format.contains(QLatin1String("m")))
334             update_interval = 60000;
335         else
336             update_interval = 3600000;
337 
338         if (update_interval != mUpdateInterval)
339         {
340             mUpdateInterval = update_interval;
341             restartTimer();
342         }
343     }
344 
345     bool autoRotate = settings()->value(QLatin1String("autoRotate"), true).toBool();
346     if (autoRotate != mAutoRotate)
347     {
348         mAutoRotate = autoRotate;
349         realign();
350     }
351 
352     bool showWeekNumber = settings()->value(QL1S("showWeekNumber"), true).toBool();
353     if (showWeekNumber != mShowWeekNumber)
354     {
355         mShowWeekNumber = showWeekNumber;
356     }
357 
358     if (mPopup)
359     {
360         updatePopupContent();
361         mPopup->adjustSize();
362         mPopup->setGeometry(calculatePopupWindowPos(mPopup->size()));
363     }
364 
365     setTimeText();
366 }
367 
configureDialog()368 QDialog *LXQtWorldClock::configureDialog()
369 {
370     return new LXQtWorldClockConfiguration(settings());
371 }
372 
wheelScrolled(int delta)373 void LXQtWorldClock::wheelScrolled(int delta)
374 {
375     if (mTimeZones.count() > 1)
376     {
377         mActiveTimeZone = mTimeZones[(mTimeZones.indexOf(mActiveTimeZone) + ((delta > 0) ? -1 : 1) + mTimeZones.size()) % mTimeZones.size()];
378         setTimeText();
379     }
380 }
381 
activated(ActivationReason reason)382 void LXQtWorldClock::activated(ActivationReason reason)
383 {
384     switch (reason)
385     {
386     case ILXQtPanelPlugin::Trigger:
387     case ILXQtPanelPlugin::MiddleClick:
388         break;
389 
390     default:
391         return;
392     }
393 
394     if (!mPopup)
395     {
396         mPopup = new LXQtWorldClockPopup(mContent);
397         connect(mPopup, &LXQtWorldClockPopup::deactivated, this, &LXQtWorldClock::deletePopup);
398 
399         if (reason == ILXQtPanelPlugin::Trigger)
400         {
401             mPopup->setObjectName(QLatin1String("WorldClockCalendar"));
402 
403             mPopup->layout()->setContentsMargins(0, 0, 0, 0);
404             QCalendarWidget *calendarWidget = new QCalendarWidget(mPopup);
405             if (!mShowWeekNumber)
406                 calendarWidget->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
407             mPopup->layout()->addWidget(calendarWidget);
408 
409             QString timeZoneName = mActiveTimeZone;
410             if (timeZoneName == QLatin1String("local"))
411                 timeZoneName = QString::fromLatin1(QTimeZone::systemTimeZoneId());
412 
413             QTimeZone timeZone(timeZoneName.toLatin1());
414             calendarWidget->setFirstDayOfWeek(QLocale(QLocale::AnyLanguage, timeZone.country()).firstDayOfWeek());
415             calendarWidget->setSelectedDate(QDateTime::currentDateTime().toTimeZone(timeZone).date());
416         }
417         else
418         {
419             mPopup->setObjectName(QLatin1String("WorldClockPopup"));
420 
421             mPopupContent = new QLabel(mPopup);
422             mPopup->layout()->addWidget(mPopupContent);
423             mPopupContent->setAlignment(mContent->alignment());
424 
425             updatePopupContent();
426         }
427 
428         mPopup->adjustSize();
429         mPopup->setGeometry(calculatePopupWindowPos(mPopup->size()));
430 
431         willShowWindow(mPopup);
432         mPopup->show();
433     }
434     else
435     {
436         deletePopup();
437     }
438 }
439 
deletePopup()440 void LXQtWorldClock::deletePopup()
441 {
442     mPopupContent = nullptr;
443     mPopup->deleteLater();
444     mPopup = nullptr;
445 }
446 
formatDateTime(const QDateTime & datetime,const QString & timeZoneName)447 QString LXQtWorldClock::formatDateTime(const QDateTime &datetime, const QString &timeZoneName)
448 {
449     QTimeZone timeZone(timeZoneName.toLatin1());
450     QDateTime tzNow = datetime.toTimeZone(timeZone);
451     return tzNow.toString(preformat(mFormat, timeZone, tzNow));
452 }
453 
updatePopupContent()454 void LXQtWorldClock::updatePopupContent()
455 {
456     if (mPopupContent)
457     {
458         QDateTime now = QDateTime::currentDateTime();
459         QStringList allTimeZones;
460         bool hasTimeZone = formatHasTimeZone(mFormat);
461 
462         for (QString timeZoneName : qAsConst(mTimeZones))
463         {
464             if (timeZoneName == QLatin1String("local"))
465                 timeZoneName = QString::fromLatin1(QTimeZone::systemTimeZoneId());
466 
467             QString formatted = formatDateTime(now, timeZoneName);
468 
469             if (!hasTimeZone)
470                 formatted += QLatin1String("<br/>") + QString::fromLatin1(QTimeZone(timeZoneName.toLatin1()).id());
471 
472             allTimeZones.append(formatted);
473         }
474 
475         mPopupContent->setText(allTimeZones.join(QLatin1String("<hr/>")));
476     }
477 }
478 
formatHasTimeZone(QString format)479 bool LXQtWorldClock::formatHasTimeZone(QString format)
480 {
481     format.replace(QRegExp(QLatin1String("'[^']*'")), QString());
482     return format.contains(QLatin1Char('t'), Qt::CaseInsensitive);
483 }
484 
preformat(const QString & format,const QTimeZone & timeZone,const QDateTime & dateTime)485 QString LXQtWorldClock::preformat(const QString &format, const QTimeZone &timeZone, const QDateTime &dateTime)
486 {
487     QString result = format;
488     int from = 0;
489     for (;;)
490     {
491         int apos = result.indexOf(QLatin1Char('\''), from);
492         int tz = result.indexOf(QLatin1Char('T'), from);
493         if ((apos != -1) && (tz != -1))
494         {
495             if (apos > tz)
496                 apos = -1;
497             else
498                 tz = -1;
499         }
500         if (apos != -1)
501         {
502             from = apos + 1;
503             apos = result.indexOf(QLatin1Char('\''), from);
504             if (apos == -1) // misformat
505                 break;
506             from = apos + 1;
507         }
508         else if (tz != -1)
509         {
510             int length = 1;
511             for (; result[tz + length] == QLatin1Char('T'); ++length);
512             if (length > 6)
513                 length = 6;
514             QString replacement;
515             switch (length)
516             {
517             case 1:
518                 replacement = timeZone.displayName(dateTime, QTimeZone::OffsetName);
519                 if (replacement.startsWith(QLatin1String("UTC")))
520                     replacement = replacement.mid(3);
521                 break;
522 
523             case 2:
524                 replacement = QString::fromLatin1(timeZone.id());
525                 break;
526 
527             case 3:
528                 replacement = timeZone.abbreviation(dateTime);
529                 break;
530 
531             case 4:
532                 replacement = timeZone.displayName(dateTime, QTimeZone::ShortName);
533                 break;
534 
535             case 5:
536                 replacement = timeZone.displayName(dateTime, QTimeZone::LongName);
537                 break;
538 
539             case 6:
540                 replacement = mTimeZoneCustomNames[QString::fromLatin1(timeZone.id())];
541             }
542 
543             if ((tz > 0) && (result[tz - 1] == QLatin1Char('\'')))
544             {
545                 --tz;
546                 ++length;
547             }
548             else
549                 replacement.prepend(QLatin1Char('\''));
550 
551             if (result[tz + length] == QLatin1Char('\''))
552                 ++length;
553             else
554                 replacement.append(QLatin1Char('\''));
555 
556             result.replace(tz, length, replacement);
557             from = tz + replacement.length();
558         }
559         else
560             break;
561     }
562     return result;
563 }
564 
realign()565 void LXQtWorldClock::realign()
566 {
567     if (mAutoRotate)
568         switch (panel()->position())
569         {
570         case ILXQtPanel::PositionTop:
571         case ILXQtPanel::PositionBottom:
572             mRotatedWidget->setOrigin(Qt::TopLeftCorner);
573             break;
574 
575         case ILXQtPanel::PositionLeft:
576             mRotatedWidget->setOrigin(Qt::BottomLeftCorner);
577             break;
578 
579         case ILXQtPanel::PositionRight:
580             mRotatedWidget->setOrigin(Qt::TopRightCorner);
581             break;
582         }
583     else
584         mRotatedWidget->setOrigin(Qt::TopLeftCorner);
585     if (mContent->size() != mContent->sizeHint())
586         mRotatedWidget->adjustContentSize();
587 }
588 
ActiveLabel(QWidget * parent)589 ActiveLabel::ActiveLabel(QWidget *parent) :
590     QLabel(parent)
591 {
592 }
593 
wheelEvent(QWheelEvent * event)594 void ActiveLabel::wheelEvent(QWheelEvent *event)
595 {
596     QPoint angleDelta = event->angleDelta();
597     Qt::Orientation orient = (qAbs(angleDelta.x()) > qAbs(angleDelta.y()) ? Qt::Horizontal : Qt::Vertical);
598     int delta = (orient == Qt::Horizontal ? angleDelta.x() : angleDelta.y());
599 
600     emit wheelScrolled(delta);
601 
602     QLabel::wheelEvent(event);
603 }
604 
mouseReleaseEvent(QMouseEvent * event)605 void ActiveLabel::mouseReleaseEvent(QMouseEvent* event)
606 {
607     switch (event->button())
608     {
609     case Qt::LeftButton:
610         emit leftMouseButtonClicked();
611         break;
612 
613     case Qt::MidButton:
614         emit middleMouseButtonClicked();
615         break;
616 
617     default:;
618     }
619 
620     QLabel::mouseReleaseEvent(event);
621 }
622 
LXQtWorldClockPopup(QWidget * parent)623 LXQtWorldClockPopup::LXQtWorldClockPopup(QWidget *parent) :
624     QDialog(parent, Qt::Window | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::Popup | Qt::X11BypassWindowManagerHint)
625 {
626     setLayout(new QHBoxLayout(this));
627     layout()->setMargin(1);
628 }
629 
show()630 void LXQtWorldClockPopup::show()
631 {
632     QDialog::show();
633     activateWindow();
634 }
635 
event(QEvent * event)636 bool LXQtWorldClockPopup::event(QEvent *event)
637 {
638     if (event->type() == QEvent::Close)
639         emit deactivated();
640 
641     return QDialog::event(event);
642 }
643 
eventFilter(QObject * watched,QEvent * event)644 bool LXQtWorldClock::eventFilter(QObject * watched, QEvent * event)
645 {
646     if (mShowTooltip && watched == mMainWidget && event->type() == QEvent::ToolTip)
647     {
648         QHelpEvent *helpEvent = static_cast<QHelpEvent*>(event);
649         QDateTime now = QDateTime::currentDateTime();
650         QString timeZoneName = mActiveTimeZone;
651         if (timeZoneName == QLatin1String("local"))
652             timeZoneName = QString::fromLatin1(QTimeZone::systemTimeZoneId());
653         QTimeZone timeZone(timeZoneName.toLatin1());
654         QDateTime tzNow = now.toTimeZone(timeZone);
655         QToolTip::showText(helpEvent->globalPos(), tzNow.toString(QLocale(QLocale::AnyLanguage, QLocale().country()).dateTimeFormat(QLocale::ShortFormat)));
656         return false;
657     }
658     return QObject::eventFilter(watched, event);
659 }
660