Changeset View
Changeset View
Standalone View
Standalone View
runners/datetime/datetimerunner.cpp
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | * Copyright (C) 2006 Aaron Seigo <aseigo@kde.org> | 2 | * Copyright (C) 2006 Aaron Seigo <aseigo@kde.org> | ||
3 | * Copyright (C) 2010 Marco Martin <notmart@gmail.com> | 3 | * Copyright (C) 2010 Marco Martin <notmart@gmail.com> | ||
4 | * Copyright (C) 2015 Vishesh Handa <vhanda@kde.org> | 4 | * Copyright (C) 2015 Vishesh Handa <vhanda@kde.org> | ||
5 | * Copyright (C) 2018 James D. Smith <smithjd15@gmail.com> | ||||
5 | * | 6 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Library General Public License version 2 as | 8 | * it under the terms of the GNU Library General Public License version 2 as | ||
8 | * published by the Free Software Foundation | 9 | * published by the Free Software Foundation | ||
9 | * | 10 | * | ||
10 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
Show All 19 Lines | |||||
32 | DateTimeRunner::DateTimeRunner(QObject *parent, const QVariantList &args) | 33 | DateTimeRunner::DateTimeRunner(QObject *parent, const QVariantList &args) | ||
33 | : Plasma::AbstractRunner(parent, args) | 34 | : Plasma::AbstractRunner(parent, args) | ||
34 | { | 35 | { | ||
35 | setObjectName(QLatin1String( "DataTimeRunner" )); | 36 | setObjectName(QLatin1String( "DataTimeRunner" )); | ||
36 | 37 | | |||
37 | addSyntax(Plasma::RunnerSyntax(dateWord, i18n("Displays the current date"))); | 38 | addSyntax(Plasma::RunnerSyntax(dateWord, i18n("Displays the current date"))); | ||
38 | addSyntax(Plasma::RunnerSyntax(dateWord + QLatin1String( " :q:" ), i18n("Displays the current date in a given timezone"))); | 39 | addSyntax(Plasma::RunnerSyntax(dateWord + QLatin1String( " :q:" ), i18n("Displays the current date in a given timezone"))); | ||
39 | addSyntax(Plasma::RunnerSyntax(timeWord, i18n("Displays the current time"))); | 40 | addSyntax(Plasma::RunnerSyntax(timeWord, i18n("Displays the current time"))); | ||
41 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " 24" ), i18n("Displays the current time, in 24 hour time"))); | ||||
40 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ), i18n("Displays the current time in a given timezone"))); | 42 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ), i18n("Displays the current time in a given timezone"))); | ||
43 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ) + QLatin1String( " 24" ), i18n("Displays the local time from the given time of the form hh:mm [am/pm] or HH:mm, in 24 hour time"))); | ||||
44 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ) + QLatin1String( " 24" ), i18n("Displays the current time in a given timezone, in 24 hour time"))); | ||||
45 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ), i18n("Displays the local time from the given time of the form hh:mm [am/pm] or HH:mm"))); | ||||
46 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ) + QLatin1String( " :q:" ), i18n("Displays the time in the given timezone converted from the given local time of the form hh:mm [am/pm] or HH:mm"))); | ||||
47 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ) + QLatin1String( " :q:" ), i18n("Displays the given time of the form hh:mm [am/pm] or HH:mm converted from the given timezone to the local time"))); | ||||
48 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ) + QLatin1String( " :q:" ) + QLatin1String( " 24" ), i18n("Displays the time in the given timezone converted from the given local time of the form hh:mm [am/pm] or HH:mm, in 24 hour time"))); | ||||
49 | addSyntax(Plasma::RunnerSyntax(timeWord + QLatin1String( " :q:" ) + QLatin1String( " :q:" ) + QLatin1String( " 24" ), i18n("Displays the given time of the form hh:mm [am/pm] or HH:mm converted from the given timezone to the local time, in 24 hour time"))); | ||||
41 | } | 50 | } | ||
42 | 51 | | |||
43 | DateTimeRunner::~DateTimeRunner() | 52 | DateTimeRunner::~DateTimeRunner() | ||
44 | { | 53 | { | ||
45 | } | 54 | } | ||
46 | 55 | | |||
47 | void DateTimeRunner::match(Plasma::RunnerContext &context) | 56 | void DateTimeRunner::match(Plasma::RunnerContext &context) | ||
48 | { | 57 | { | ||
49 | const QString term = context.query(); | 58 | const QStringList terms = context.query().split(QChar::Space, QString::SkipEmptyParts); | ||
50 | if (term.compare(dateWord, Qt::CaseInsensitive) == 0) { | 59 | bool is24Hr = terms.contains(QStringLiteral("24")); | ||
51 | const QString date = QLocale().toString(QDate::currentDate()); | 60 | bool toLocalTime = QChar(terms.value(1).at(0)).isNumber(); | ||
52 | addMatch(i18n("Today's date is %1", date), date, context, QStringLiteral("view-calendar-day")); | 61 | | ||
53 | } else if (term.startsWith(dateWord + QLatin1Char( ' ' ), Qt::CaseInsensitive)) { | 62 | QDateTime dt; | ||
63 | QTime t; | ||||
64 | QTimeZone tz; | ||||
54 | QString tzName; | 65 | QString tzName; | ||
55 | QString tz = term.right(term.length() - dateWord.length() - 1); | 66 | QString time; | ||
56 | QDateTime dt = datetime(tz, tzName); | 67 | | ||
57 | if (dt.isValid()) { | 68 | for (const QString &term : terms) { | ||
69 | if (term.contains(QStringLiteral(":"))) { | ||||
70 | time = term; | ||||
71 | } else if (term.compare(QStringLiteral("am"), Qt::CaseInsensitive) == 0) { | ||||
72 | time += QChar::Space + term; | ||||
73 | } else if (term.compare(QStringLiteral("pm"), Qt::CaseInsensitive) == 0) { | ||||
74 | time += QChar::Space + term; | ||||
75 | } else if (timeZone(term, tzName).isValid()) { | ||||
76 | tz = timeZone(term, tzName); | ||||
77 | } | ||||
78 | } | ||||
79 | | ||||
80 | // Possible time formats. | ||||
81 | QTime hmmapTime = QTime::fromString(time, QStringLiteral("h:mm ap")); | ||||
82 | QTime hhmmapTime = QTime::fromString(time, QStringLiteral("hh:mm ap")); | ||||
83 | QTime hmmTime = QTime::fromString(time, QStringLiteral("h:mm")); | ||||
84 | QTime hhmmTime = QTime::fromString(time, QStringLiteral("hh:mm")); | ||||
85 | | ||||
86 | if (hmmapTime.isValid()) { | ||||
87 | t = hmmapTime; | ||||
88 | } else if (hhmmapTime.isValid()) { | ||||
89 | t = hhmmapTime; | ||||
90 | } else if (hmmTime.isValid()) { | ||||
91 | t = hmmTime; | ||||
92 | } else if (hhmmTime.isValid()) { | ||||
93 | t = hhmmTime; | ||||
94 | } | ||||
95 | | ||||
96 | if ((terms.size() == 1) || ((terms.size() == 2) && is24Hr)) { | ||||
97 | dt = QDateTime::currentDateTime(); | ||||
98 | } if (toLocalTime && t.isValid()) { | ||||
99 | dt = QDateTime(QDateTime::currentDateTime().date(), t, tz).toLocalTime(); | ||||
100 | } else if (!toLocalTime && t.isValid() && tz.isValid()) { | ||||
101 | dt = QDateTime(QDateTime::currentDateTime().date(), t).toTimeZone(tz); | ||||
102 | } else if (!toLocalTime && !t.isValid() && tz.isValid()) { | ||||
103 | dt = QDateTime::currentDateTime().toTimeZone(tz); | ||||
104 | } | ||||
105 | | ||||
106 | if (!dt.isValid()) { | ||||
107 | return; | ||||
108 | } | ||||
109 | | ||||
58 | const QString date = QLocale().toString(dt.date()); | 110 | const QString date = QLocale().toString(dt.date()); | ||
111 | | ||||
112 | if (terms.value(0).compare(dateWord, Qt::CaseInsensitive) == 0) { | ||||
113 | if (dt.timeZone() == QDateTime::currentDateTime().timeZone()) { | ||||
114 | addMatch(i18n("Today's date: %1", date), date, context, QStringLiteral("view-calendar-day")); | ||||
115 | } else { | ||||
59 | addMatch(QStringLiteral("%1 - %2").arg(tzName, date), date, context, QStringLiteral("view-calendar-day")); | 116 | addMatch(QStringLiteral("%1 - %2").arg(tzName, date), date, context, QStringLiteral("view-calendar-day")); | ||
60 | } | 117 | } | ||
61 | } else if (term.compare(timeWord, Qt::CaseInsensitive) == 0) { | 118 | } else if (terms.value(0).compare(timeWord, Qt::CaseInsensitive) == 0) { | ||
62 | const QString time = QLocale().toString(QTime::currentTime()); | 119 | QString timeFormat24hr = QLocale().timeFormat(); | ||
63 | addMatch(i18n("Current time is %1", time), time, context, QStringLiteral("clock")); | 120 | timeFormat24hr.remove(QStringLiteral("a"), Qt::CaseInsensitive); | ||
64 | } else if (term.startsWith(timeWord + QLatin1Char( ' ' ), Qt::CaseInsensitive)) { | 121 | timeFormat24hr.remove(QStringLiteral("p"), Qt::CaseInsensitive); | ||
65 | QString tzName; | 122 | timeFormat24hr = timeFormat24hr.simplified(); | ||
66 | QString tz = term.right(term.length() - timeWord.length() - 1); | 123 | QString time; | ||
67 | QDateTime dt = datetime(tz, tzName); | 124 | | ||
68 | if (dt.isValid()) { | 125 | if (dt.timeZone() == QDateTime::currentDateTime().timeZone()) { | ||
69 | const QString time = QLocale().toString(dt.time(),QLocale::ShortFormat); | 126 | if (is24Hr) { | ||
127 | time = QLocale().toString(dt.time(), timeFormat24hr); | ||||
128 | } else { | ||||
129 | time = QLocale().toString(dt.time()); | ||||
130 | } | ||||
131 | | ||||
132 | addMatch(i18n("Local time: %1", time), time, context, QStringLiteral("clock")); | ||||
133 | } else { | ||||
134 | if (is24Hr) { | ||||
135 | timeFormat24hr.remove(QStringLiteral("t")); | ||||
136 | timeFormat24hr = timeFormat24hr.simplified(); | ||||
137 | | ||||
138 | time = QLocale().toString(dt.time(), timeFormat24hr); | ||||
139 | } else { | ||||
140 | time = QLocale().toString(dt.time(), QLocale::ShortFormat); | ||||
141 | } | ||||
142 | | ||||
70 | addMatch(QStringLiteral("%1 - %2").arg(tzName, time), time, context, QStringLiteral("clock")); | 143 | addMatch(QStringLiteral("%1 - %2").arg(tzName, time), time, context, QStringLiteral("clock")); | ||
144 | | ||||
145 | } | ||||
146 | | ||||
147 | if (dt.date() != QDateTime::currentDateTime().date()) { | ||||
148 | if (toLocalTime) { | ||||
149 | tzName = QDateTime::currentDateTime().time().toString(QStringLiteral("t")); | ||||
150 | } | ||||
151 | | ||||
152 | addMatch(QStringLiteral("%1 - %2").arg(tzName, date), date, context, QStringLiteral("view-calendar-day")); | ||||
71 | } | 153 | } | ||
72 | } | 154 | } | ||
73 | } | 155 | } | ||
74 | 156 | | |||
75 | QDateTime DateTimeRunner::datetime(const QString &tz, QString &tzName) | 157 | QTimeZone DateTimeRunner::timeZone(const QString &tz, QString &tzName) | ||
76 | { | 158 | { | ||
159 | if (tz.isEmpty()) { | ||||
160 | return QTimeZone(); | ||||
161 | } | ||||
162 | | ||||
77 | // | 163 | // | ||
78 | // KTimeZone gives us the actual timezone names such as "Asia/Kolkatta" and does | 164 | // KTimeZone gives us the actual timezone names such as "Asia/Kolkatta" and does | ||
79 | // not give us country info. QTimeZone does not give us the actual timezone name | 165 | // not give us country info. QTimeZone does not give us the actual timezone name | ||
80 | // This is why we are using both for now. | 166 | // This is why we are using both for now. | ||
81 | // | 167 | // | ||
82 | QList<QByteArray> timeZoneIds = QTimeZone::availableTimeZoneIds(); | 168 | QList<QByteArray> timeZoneIds = QTimeZone::availableTimeZoneIds(); | ||
83 | for (const QByteArray& zoneId : timeZoneIds) { | 169 | for (const QByteArray& zoneId : timeZoneIds) { | ||
84 | QTimeZone timeZone(zoneId); | 170 | QTimeZone timeZone(zoneId); | ||
85 | 171 | | |||
86 | const QString zoneName = QString::fromUtf8(zoneId); | 172 | const QString zoneName = QString::fromUtf8(zoneId); | ||
87 | if (zoneName.startsWith(tz, Qt::CaseInsensitive)) { | 173 | if (zoneName.startsWith(tz, Qt::CaseInsensitive)) { | ||
88 | tzName = zoneName; | 174 | tzName = zoneName; | ||
89 | return QDateTime::currentDateTimeUtc().toTimeZone(timeZone); | 175 | return timeZone; | ||
90 | } | 176 | } | ||
91 | 177 | | |||
92 | const QString country = QLocale::countryToString(timeZone.country()); | 178 | const QString country = QLocale::countryToString(timeZone.country()); | ||
93 | if (country.startsWith(tz, Qt::CaseInsensitive)) { | 179 | if (country.startsWith(tz, Qt::CaseInsensitive)) { | ||
94 | tzName = country; | 180 | tzName = country; | ||
95 | return QDateTime::currentDateTimeUtc().toTimeZone(timeZone); | 181 | return timeZone; | ||
96 | } | 182 | } | ||
97 | 183 | | |||
98 | // FIXME: This only includes the current abbreviation and not old abbreviation or | 184 | // FIXME: This only includes the current abbreviation and not old abbreviation or | ||
99 | // other possible names. | 185 | // other possible names. | ||
100 | // Eg - depending on the current date, only CET or CEST will work | 186 | // Eg - depending on the current date, only CET or CEST will work | ||
101 | const QString abbr = timeZone.abbreviation(QDateTime::currentDateTime()); | 187 | const QString abbr = timeZone.abbreviation(QDateTime::currentDateTime()); | ||
102 | if (abbr.startsWith(tz, Qt::CaseInsensitive)) { | 188 | if (abbr.startsWith(tz, Qt::CaseInsensitive)) { | ||
103 | tzName = abbr; | 189 | tzName = abbr; | ||
104 | return QDateTime::currentDateTimeUtc().toTimeZone(timeZone); | 190 | return timeZone; | ||
105 | } | 191 | } | ||
106 | } | 192 | } | ||
107 | 193 | | |||
108 | for (const QByteArray& zoneId : timeZoneIds) { | 194 | for (const QByteArray& zoneId : timeZoneIds) { | ||
109 | QTimeZone timeZone(zoneId); | 195 | QTimeZone timeZone(zoneId); | ||
110 | 196 | | |||
111 | const QString zoneName = QString::fromUtf8(zoneId); | 197 | const QString zoneName = QString::fromUtf8(zoneId); | ||
112 | if (zoneName.contains(tz, Qt::CaseInsensitive)) { | 198 | if (zoneName.contains(tz, Qt::CaseInsensitive)) { | ||
113 | tzName = zoneName; | 199 | tzName = zoneName; | ||
114 | return QDateTime::currentDateTimeUtc().toTimeZone(timeZone); | 200 | return timeZone; | ||
115 | } | 201 | } | ||
116 | } | 202 | } | ||
117 | 203 | | |||
118 | return QDateTime(); | 204 | return QTimeZone(); | ||
119 | } | 205 | } | ||
120 | 206 | | |||
121 | void DateTimeRunner::addMatch(const QString &text, const QString &clipboardText, | 207 | void DateTimeRunner::addMatch(const QString &text, const QString &clipboardText, | ||
122 | Plasma::RunnerContext &context, const QString& iconName) | 208 | Plasma::RunnerContext &context, const QString& iconName) | ||
123 | { | 209 | { | ||
124 | Plasma::QueryMatch match(this); | 210 | Plasma::QueryMatch match(this); | ||
125 | match.setText(text); | 211 | match.setText(text); | ||
126 | match.setData(clipboardText); | 212 | match.setData(clipboardText); | ||
Show All 10 Lines |