Waste less space in nested layouts.
[kdepim.git] / kalarm / preferences.cpp
blob782cc0e2d98cb4d3dde4718f1d06826f08e2ddbd
1 /*
2 * preferences.cpp - program preference settings
3 * Program: kalarm
4 * Copyright © 2001-2010 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 <time.h>
24 #include <unistd.h>
26 #include <QByteArray>
28 #include <kglobal.h>
29 #include <kconfiggroup.h>
30 #include <kmessagebox.h>
31 #include <ksystemtimezone.h>
32 #include <kdebug.h>
34 #include <kpimidentities/identity.h>
35 #include <kpimidentities/identitymanager.h>
36 #include <kholidays/holidays.h>
37 using namespace KHolidays;
39 #include "functions.h"
40 #include "identities.h"
41 #include "kamail.h"
42 #include "messagebox.h"
43 #include "preferences.moc"
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 = QLatin1String("@SystemSettings");
54 static const QString FROM_KMAIL = QLatin1String("@KMail");
56 // Config file entry names for notification messages
57 const char* Preferences::QUIT_WARN = "QuitWarn";
58 const char* Preferences::ASK_AUTO_START = "AskAutoStart";
59 const char* Preferences::CONFIRM_ALARM_DELETION = "ConfirmAlarmDeletion";
60 const char* 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 = 0;
69 bool Preferences::mUsingDefaults = false;
70 KTimeZone Preferences::mSystemTimeZone;
71 HolidayRegion* Preferences::mHolidays = 0; // always non-null after Preferences initialisation
72 // Change tracking
73 bool Preferences::mAutoStartChangedByUser = false;
76 Preferences* Preferences::self()
78 if (!mInstance)
80 // Set the default button for the Quit warning message box to Cancel
81 MessageBox::setContinueDefault(QUIT_WARN, KMessageBox::Cancel);
82 MessageBox::setDefaultShouldBeShownContinue(QUIT_WARN, default_quitWarn);
83 MessageBox::setDefaultShouldBeShownContinue(EMAIL_QUEUED_NOTIFY, default_emailQueuedNotify);
84 MessageBox::setDefaultShouldBeShownContinue(CONFIRM_ALARM_DELETION, default_confirmAlarmDeletion);
86 mInstance = new Preferences;
87 mInstance->readConfig();
89 return mInstance;
92 Preferences::Preferences()
94 QObject::connect(this, SIGNAL(base_StartOfDayChanged(const QDateTime&)), SLOT(startDayChange(const QDateTime&)));
95 QObject::connect(this, SIGNAL(base_TimeZoneChanged(const QString&)), SLOT(timeZoneChange(const QString&)));
96 QObject::connect(this, SIGNAL(base_HolidayRegionChanged(const QString&)), SLOT(holidaysChange(const QString&)));
97 QObject::connect(this, SIGNAL(base_WorkTimeChanged(const QDateTime&, const QDateTime&, int)), SLOT(workTimeChange(const QDateTime&, const QDateTime&, int)));
100 void Preferences::setAskAutoStart(bool yes)
102 MessageBox::saveDontShowAgainYesNo(ASK_AUTO_START, !yes);
105 /******************************************************************************
106 * Get the user's time zone, or if none has been chosen, the system time zone.
107 * The system time zone is cached, and the cached value will be returned unless
108 * 'reload' is true, in which case the value is re-read from the system.
110 KTimeZone Preferences::timeZone(bool reload)
112 if (reload)
113 mSystemTimeZone = KTimeZone();
114 QString timeZone = self()->mBase_TimeZone;
115 KTimeZone tz;
116 if (!timeZone.isEmpty())
117 tz = KSystemTimeZones::zone(timeZone);
118 if (!tz.isValid())
120 if (!mSystemTimeZone.isValid())
121 mSystemTimeZone = KSystemTimeZones::local();
122 tz = mSystemTimeZone;
124 return tz;
127 void Preferences::setTimeZone(const KTimeZone& tz)
129 self()->setBase_TimeZone(tz.isValid() ? tz.name() : QString());
132 void Preferences::timeZoneChange(const QString& zone)
134 Q_UNUSED(zone);
135 emit mInstance->timeZoneChanged(timeZone(false));
138 const HolidayRegion& Preferences::holidays()
140 QString regionCode = self()->mBase_HolidayRegion;
141 if (!mHolidays || mHolidays->regionCode() != regionCode)
143 delete mHolidays;
144 mHolidays = new HolidayRegion(regionCode);
146 return *mHolidays;
149 void Preferences::setHolidayRegion(const QString& regionCode)
151 self()->setBase_HolidayRegion(regionCode);
154 void Preferences::holidaysChange(const QString& regionCode)
156 Q_UNUSED(regionCode);
157 emit mInstance->holidaysChanged(holidays());
160 void Preferences::setStartOfDay(const QTime& t)
162 if (t != self()->mBase_StartOfDay.time())
164 self()->setBase_StartOfDay(QDateTime(QDate(1900,1,1), t));
165 emit mInstance->startOfDayChanged(t);
169 // Called when the start of day value has changed in the config file
170 void Preferences::startDayChange(const QDateTime& dt)
172 emit mInstance->startOfDayChanged(dt.time());
175 QBitArray Preferences::workDays()
177 unsigned days = self()->base_WorkDays();
178 QBitArray dayBits(7);
179 for (int i = 0; i < 7; ++i)
180 dayBits.setBit(i, days & (1 << i));
181 return dayBits;
184 void Preferences::setWorkDays(const QBitArray& dayBits)
186 unsigned days = 0;
187 for (int i = 0; i < 7; ++i)
188 if (dayBits.testBit(i))
189 days |= 1 << i;
190 self()->setBase_WorkDays(days);
193 void Preferences::workTimeChange(const QDateTime& start, const QDateTime& end, int days)
195 QBitArray dayBits(7);
196 for (int i = 0; i < 7; ++i)
197 if (days & (1 << i))
198 dayBits.setBit(i);
199 emit mInstance->workTimeChanged(start.time(), end.time(), dayBits);
202 Preferences::MailFrom Preferences::emailFrom()
204 QString from = self()->mBase_EmailFrom;
205 if (from == FROM_KMAIL)
206 return MAIL_FROM_KMAIL;
207 if (from == FROM_SYS_SETTINGS)
208 return MAIL_FROM_SYS_SETTINGS;
209 return MAIL_FROM_ADDR;
212 /******************************************************************************
213 * Get user's default 'From' email address.
215 QString Preferences::emailAddress()
217 QString from = self()->mBase_EmailFrom;
218 if (from == FROM_KMAIL)
219 return Identities::identityManager()->defaultIdentity().fullEmailAddr();
220 if (from == FROM_SYS_SETTINGS)
221 return KAMail::controlCentreAddress();
222 return from;
225 void Preferences::setEmailAddress(Preferences::MailFrom from, const QString& address)
227 QString out;
228 switch (from)
230 case MAIL_FROM_KMAIL: out = FROM_KMAIL; break;
231 case MAIL_FROM_SYS_SETTINGS: out = FROM_SYS_SETTINGS; break;
232 case MAIL_FROM_ADDR: out = address; break;
233 default: return;
235 self()->setBase_EmailFrom(out);
238 Preferences::MailFrom Preferences::emailBccFrom()
240 QString from = self()->mBase_EmailBccAddress;
241 if (from == FROM_SYS_SETTINGS)
242 return MAIL_FROM_SYS_SETTINGS;
243 return MAIL_FROM_ADDR;
246 QString Preferences::emailBccAddress()
248 QString from = self()->mBase_EmailBccAddress;
249 if (from == FROM_SYS_SETTINGS)
250 return KAMail::controlCentreAddress();
251 return from;
254 bool Preferences::emailBccUseSystemSettings()
256 return self()->mBase_EmailBccAddress == FROM_SYS_SETTINGS;
259 void Preferences::setEmailBccAddress(bool useSystemSettings, const QString& address)
261 QString out;
262 if (useSystemSettings)
263 out = FROM_SYS_SETTINGS;
264 else
265 out = address;
266 self()->setBase_EmailBccAddress(out);
269 QString Preferences::cmdXTermCommand()
271 return translateXTermPath(self()->mBase_CmdXTermCommand, false);
274 void Preferences::setCmdXTermCommand(const QString& cmd)
276 self()->setBase_CmdXTermCommand(translateXTermPath(cmd, true));
280 void Preferences::connect(const char* signal, const QObject* receiver, const char* member)
282 QObject::connect(self(), signal, receiver, member);
285 /******************************************************************************
286 * Called to allow or suppress output of the specified message dialog, where the
287 * dialog has a checkbox to turn notification off.
289 void Preferences::setNotify(const QString& messageID, bool notify)
291 MessageBox::saveDontShowAgainContinue(messageID, !notify);
294 /******************************************************************************
295 * Return whether the specified message dialog is output, where the dialog has
296 * a checkbox to turn notification off.
297 * Reply = false if message has been suppressed (by preferences or by selecting
298 * "don't ask again")
299 * = true in all other cases.
301 bool Preferences::notifying(const QString& messageID)
303 return MessageBox::shouldBeShownContinue(messageID);
306 /******************************************************************************
307 * Translate an X terminal command path to/from config file format.
308 * Note that only a home directory specification at the start of the path is
309 * translated, so there's no need to worry about missing out some of the
310 * executable's path due to quotes etc.
311 * N.B. Calling KConfig::read/writePathEntry() on the entire command line
312 * causes a crash on some systems, so it's necessary to extract the
313 * executable path first before processing.
315 QString translateXTermPath(const QString& cmdline, bool write)
317 QString params;
318 QString cmd = cmdline;
319 if (cmdline.isEmpty())
320 return cmdline;
321 // Strip any leading quote
322 QChar quote = cmdline[0];
323 char q = quote.toLatin1();
324 bool quoted = (q == '"' || q == '\'');
325 if (quoted)
326 cmd = cmdline.mid(1);
327 // Split the command at the first non-escaped space
328 for (int i = 0, count = cmd.length(); i < count; ++i)
330 switch (cmd[i].toLatin1())
332 case '\\':
333 ++i;
334 continue;
335 case '"':
336 case '\'':
337 if (cmd[i] != quote)
338 continue;
339 // fall through to ' '
340 case ' ':
341 params = cmd.mid(i);
342 cmd = cmd.left(i);
343 break;
344 default:
345 continue;
347 break;
349 // Translate any home directory specification at the start of the
350 // executable's path.
351 KConfigGroup group(KGlobal::config(), GENERAL_SECTION);
352 if (write)
354 group.writePathEntry(TEMP, cmd);
355 cmd = group.readEntry(TEMP, QString());
357 else
359 group.writeEntry(TEMP, cmd);
360 cmd = group.readPathEntry(TEMP, QString());
362 group.deleteEntry(TEMP);
363 if (quoted)
364 return quote + cmd + params;
365 else
366 return cmd + params;