Merge branch 'master' of git://anongit.kde.org/kdepim
[kdepim.git] / kalarm / preferences.cpp
blob0438bcb4af4307ccd2b474438b37646d42757585
1 /*
2 * preferences.cpp - program preference settings
3 * Program: kalarm
4 * Copyright © 2001-2011 by David Jarvie <djarvie@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "kalarm.h"
23 #include "functions.h"
24 #include "kamail.h"
25 #include "messagebox.h"
26 #include "preferences.h"
28 #include <kalarmcal/identities.h>
30 #include <KIdentityManagement/kidentitymanagement/identity.h>
31 #include <KIdentityManagement/kidentitymanagement/identitymanager.h>
32 #include <KHolidays/HolidayRegion>
34 #include <KSharedConfig>
35 #include <kconfiggroup.h>
36 #include <kmessagebox.h>
37 #include <ksystemtimezone.h>
38 #include "kalarm_debug.h"
40 #include <time.h>
41 #include <unistd.h>
43 using namespace KHolidays;
44 using namespace KAlarmCal;
46 // Config file entry names
47 static const char* GENERAL_SECTION = "General";
49 // Config file entry name for temporary use
50 static const char* TEMP = "Temp";
52 // Values for EmailFrom entry
53 static const QString FROM_SYS_SETTINGS(QStringLiteral("@SystemSettings"));
54 static const QString FROM_KMAIL(QStringLiteral("@KMail"));
56 // Config file entry names for notification messages
57 const QLatin1String Preferences::QUIT_WARN("QuitWarn");
58 const QLatin1String Preferences::ASK_AUTO_START("AskAutoStart");
59 const QLatin1String Preferences::CONFIRM_ALARM_DELETION("ConfirmAlarmDeletion");
60 const QLatin1String Preferences::EMAIL_QUEUED_NOTIFY("EmailQueuedNotify");
61 const bool default_quitWarn = true;
62 const bool default_emailQueuedNotify = false;
63 const bool default_confirmAlarmDeletion = true;
65 static QString translateXTermPath(const QString& cmdline, bool write);
68 Preferences* Preferences::mInstance = Q_NULLPTR;
69 bool Preferences::mUsingDefaults = false;
70 KTimeZone Preferences::mSystemTimeZone;
71 HolidayRegion* Preferences::mHolidays = Q_NULLPTR; // always non-null after Preferences initialisation
72 QString Preferences::mPreviousVersion;
73 Preferences::Backend Preferences::mPreviousBackend;
74 // Change tracking
75 bool Preferences::mAutoStartChangedByUser = false;
78 Preferences* Preferences::self()
80 if (!mInstance)
82 // Set the default button for the Quit warning message box to Cancel
83 KAMessageBox::setContinueDefault(QUIT_WARN, KMessageBox::Cancel);
84 KAMessageBox::setDefaultShouldBeShownContinue(QUIT_WARN, default_quitWarn);
85 KAMessageBox::setDefaultShouldBeShownContinue(EMAIL_QUEUED_NOTIFY, default_emailQueuedNotify);
86 KAMessageBox::setDefaultShouldBeShownContinue(CONFIRM_ALARM_DELETION, default_confirmAlarmDeletion);
88 mInstance = new Preferences;
90 return mInstance;
93 Preferences::Preferences()
95 QObject::connect(this, &Preferences::base_StartOfDayChanged, this, &Preferences::startDayChange);
96 QObject::connect(this, &Preferences::base_TimeZoneChanged, this, &Preferences::timeZoneChange);
97 QObject::connect(this, &Preferences::base_HolidayRegionChanged, this, &Preferences::holidaysChange);
98 QObject::connect(this, &Preferences::base_WorkTimeChanged, this, &Preferences::workTimeChange);
100 load();
101 // Fetch the KAlarm version and backend which wrote the previous config file
102 mPreviousVersion = version();
103 mPreviousBackend = backend();
104 // Update the KAlarm version in the config file, but don't call
105 // writeConfig() here - leave it to be written only if the config file
106 // is updated with other data.
107 setVersion(QStringLiteral(KALARM_VERSION));
110 void Preferences::setAskAutoStart(bool yes)
112 KAMessageBox::saveDontShowAgainYesNo(ASK_AUTO_START, !yes);
115 /******************************************************************************
116 * Get the user's time zone, or if none has been chosen, the system time zone.
117 * The system time zone is cached, and the cached value will be returned unless
118 * 'reload' is true, in which case the value is re-read from the system.
120 KTimeZone Preferences::timeZone(bool reload)
122 if (reload)
123 mSystemTimeZone = KTimeZone();
124 QString timeZone = self()->mBase_TimeZone;
125 KTimeZone tz;
126 if (!timeZone.isEmpty())
127 tz = KSystemTimeZones::zone(timeZone);
128 if (!tz.isValid())
130 if (!mSystemTimeZone.isValid())
131 mSystemTimeZone = KSystemTimeZones::local();
132 tz = mSystemTimeZone;
134 return tz;
137 void Preferences::setTimeZone(const KTimeZone& tz)
139 self()->setBase_TimeZone(tz.isValid() ? tz.name() : QString());
142 void Preferences::timeZoneChange(const QString& zone)
144 Q_UNUSED(zone);
145 Q_EMIT mInstance->timeZoneChanged(timeZone(false));
148 const HolidayRegion& Preferences::holidays()
150 QString regionCode = self()->mBase_HolidayRegion;
151 if (!mHolidays || mHolidays->regionCode() != regionCode)
153 delete mHolidays;
154 mHolidays = new HolidayRegion(regionCode);
156 return *mHolidays;
159 void Preferences::setHolidayRegion(const QString& regionCode)
161 self()->setBase_HolidayRegion(regionCode);
164 void Preferences::holidaysChange(const QString& regionCode)
166 Q_UNUSED(regionCode);
167 Q_EMIT mInstance->holidaysChanged(holidays());
170 void Preferences::setStartOfDay(const QTime& t)
172 if (t != self()->mBase_StartOfDay.time())
174 self()->setBase_StartOfDay(QDateTime(QDate(1900,1,1), t));
175 Q_EMIT mInstance->startOfDayChanged(t);
179 // Called when the start of day value has changed in the config file
180 void Preferences::startDayChange(const QDateTime& dt)
182 Q_EMIT mInstance->startOfDayChanged(dt.time());
185 QBitArray Preferences::workDays()
187 unsigned days = self()->base_WorkDays();
188 QBitArray dayBits(7);
189 for (int i = 0; i < 7; ++i)
190 dayBits.setBit(i, days & (1 << i));
191 return dayBits;
194 void Preferences::setWorkDays(const QBitArray& dayBits)
196 unsigned days = 0;
197 for (int i = 0; i < 7; ++i)
198 if (dayBits.testBit(i))
199 days |= 1 << i;
200 self()->setBase_WorkDays(days);
203 void Preferences::workTimeChange(const QDateTime& start, const QDateTime& end, int days)
205 QBitArray dayBits(7);
206 for (int i = 0; i < 7; ++i)
207 if (days & (1 << i))
208 dayBits.setBit(i);
209 Q_EMIT mInstance->workTimeChanged(start.time(), end.time(), dayBits);
212 Preferences::MailFrom Preferences::emailFrom()
214 QString from = self()->mBase_EmailFrom;
215 if (from == FROM_KMAIL)
216 return MAIL_FROM_KMAIL;
217 if (from == FROM_SYS_SETTINGS)
218 return MAIL_FROM_SYS_SETTINGS;
219 return MAIL_FROM_ADDR;
222 /******************************************************************************
223 * Get user's default 'From' email address.
225 QString Preferences::emailAddress()
227 QString from = self()->mBase_EmailFrom;
228 if (from == FROM_KMAIL)
229 return Identities::identityManager()->defaultIdentity().fullEmailAddr();
230 if (from == FROM_SYS_SETTINGS)
231 return KAMail::controlCentreAddress();
232 return from;
235 void Preferences::setEmailAddress(Preferences::MailFrom from, const QString& address)
237 QString out;
238 switch (from)
240 case MAIL_FROM_KMAIL: out = FROM_KMAIL; break;
241 case MAIL_FROM_SYS_SETTINGS: out = FROM_SYS_SETTINGS; break;
242 case MAIL_FROM_ADDR: out = address; break;
243 default: return;
245 self()->setBase_EmailFrom(out);
248 Preferences::MailFrom Preferences::emailBccFrom()
250 QString from = self()->mBase_EmailBccAddress;
251 if (from == FROM_SYS_SETTINGS)
252 return MAIL_FROM_SYS_SETTINGS;
253 return MAIL_FROM_ADDR;
256 QString Preferences::emailBccAddress()
258 QString from = self()->mBase_EmailBccAddress;
259 if (from == FROM_SYS_SETTINGS)
260 return KAMail::controlCentreAddress();
261 return from;
264 bool Preferences::emailBccUseSystemSettings()
266 return self()->mBase_EmailBccAddress == FROM_SYS_SETTINGS;
269 void Preferences::setEmailBccAddress(bool useSystemSettings, const QString& address)
271 QString out;
272 if (useSystemSettings)
273 out = FROM_SYS_SETTINGS;
274 else
275 out = address;
276 self()->setBase_EmailBccAddress(out);
279 QString Preferences::cmdXTermCommand()
281 return translateXTermPath(self()->mBase_CmdXTermCommand, false);
284 void Preferences::setCmdXTermCommand(const QString& cmd)
286 self()->setBase_CmdXTermCommand(translateXTermPath(cmd, true));
290 void Preferences::connect(const char* signal, const QObject* receiver, const char* member)
292 QObject::connect(self(), signal, receiver, member);
295 /******************************************************************************
296 * Called to allow or suppress output of the specified message dialog, where the
297 * dialog has a checkbox to turn notification off.
299 void Preferences::setNotify(const QString& messageID, bool notify)
301 KAMessageBox::saveDontShowAgainContinue(messageID, !notify);
304 /******************************************************************************
305 * Return whether the specified message dialog is output, where the dialog has
306 * a checkbox to turn notification off.
307 * Reply = false if message has been suppressed (by preferences or by selecting
308 * "don't ask again")
309 * = true in all other cases.
311 bool Preferences::notifying(const QString& messageID)
313 return KAMessageBox::shouldBeShownContinue(messageID);
316 /******************************************************************************
317 * Translate an X terminal command path to/from config file format.
318 * Note that only a home directory specification at the start of the path is
319 * translated, so there's no need to worry about missing out some of the
320 * executable's path due to quotes etc.
321 * N.B. Calling KConfig::read/writePathEntry() on the entire command line
322 * causes a crash on some systems, so it's necessary to extract the
323 * executable path first before processing.
325 QString translateXTermPath(const QString& cmdline, bool write)
327 QString params;
328 QString cmd = cmdline;
329 if (cmdline.isEmpty())
330 return cmdline;
331 // Strip any leading quote
332 QChar quote = cmdline[0];
333 char q = quote.toLatin1();
334 bool quoted = (q == '"' || q == '\'');
335 if (quoted)
336 cmd = cmdline.mid(1);
337 // Split the command at the first non-escaped space
338 for (int i = 0, count = cmd.length(); i < count; ++i)
340 switch (cmd[i].toLatin1())
342 case '\\':
343 ++i;
344 continue;
345 case '"':
346 case '\'':
347 if (cmd[i] != quote)
348 continue;
349 // fall through to ' '
350 case ' ':
351 params = cmd.mid(i);
352 cmd = cmd.left(i);
353 break;
354 default:
355 continue;
357 break;
359 // Translate any home directory specification at the start of the
360 // executable's path.
361 KConfigGroup group(KSharedConfig::openConfig(), GENERAL_SECTION);
362 if (write)
364 group.writePathEntry(TEMP, cmd);
365 cmd = group.readEntry(TEMP, QString());
367 else
369 group.writeEntry(TEMP, cmd);
370 cmd = group.readPathEntry(TEMP, QString());
372 group.deleteEntry(TEMP);
373 if (quoted)
374 return quote + cmd + params;
375 else
376 return cmd + params;
379 // vim: et sw=4: