kalarm

preferences.cpp
00001 /*
00002  *  preferences.cpp  -  program preference settings
00003  *  Program:  kalarm
00004  *  Copyright © 2001-2008 by David Jarvie <djarvie@kde.org>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "kalarm.h"
00022 
00023 #include <tdeglobal.h>
00024 #include <tdeconfig.h>
00025 #include <kstandarddirs.h>
00026 #include <tdeapplication.h>
00027 #include <tdeglobalsettings.h>
00028 #include <tdemessagebox.h>
00029 
00030 #include <libkpimidentities/identity.h>
00031 #include <libkpimidentities/identitymanager.h>
00032 
00033 #include "daemon.h"
00034 #include "functions.h"
00035 #include "kamail.h"
00036 #include "messagebox.h"
00037 #include "preferences.moc"
00038 
00039 
00040 static TQString translateXTermPath(TDEConfig*, const TQString& cmdline, bool write);
00041 
00042 Preferences* Preferences::mInstance = 0;
00043 
00044 // Default config file settings
00045 TQColor defaultMessageColours[] = { TQt::red, TQt::green, TQt::blue, TQt::cyan, TQt::magenta, TQt::yellow, TQt::white, TQt::lightGray, TQt::black, TQColor() };
00046 const ColourList                 Preferences::default_messageColours(defaultMessageColours);
00047 const TQColor                     Preferences::default_defaultBgColour(TQt::red);
00048 const TQColor                     Preferences::default_defaultFgColour(TQt::black);
00049 TQFont                            Preferences::mDefault_messageFont;    // initialised in constructor
00050 const TQTime                      Preferences::default_startOfDay(0, 0);
00051 const bool                       Preferences::default_runInSystemTray         = true;
00052 const bool                       Preferences::default_disableAlarmsIfStopped  = true;
00053 const bool                       Preferences::default_quitWarn                = true;
00054 const bool                       Preferences::default_autostartTrayIcon       = true;
00055 const bool                       Preferences::default_confirmAlarmDeletion    = true;
00056 const bool                       Preferences::default_modalMessages           = true;
00057 const int                        Preferences::default_messageButtonDelay      = 0;     // (seconds)
00058 const int                        Preferences::default_tooltipAlarmCount       = 5;
00059 const bool                       Preferences::default_showTooltipAlarmTime    = true;
00060 const bool                       Preferences::default_showTooltipTimeToAlarm  = true;
00061 const TQString                    Preferences::default_tooltipTimeToPrefix     = TQString::fromLatin1("+");
00062 const int                        Preferences::default_daemonTrayCheckInterval = 10;     // (seconds)
00063 const bool                       Preferences::default_emailCopyToKMail        = false;
00064 const bool                       Preferences::default_emailQueuedNotify       = false;
00065 const TQColor                     Preferences::default_disabledColour(TQt::lightGray);
00066 const TQColor                     Preferences::default_expiredColour(TQt::darkRed);
00067 const int                        Preferences::default_expiredKeepDays         = 7;
00068 const TQString                    Preferences::default_defaultSoundFile        = TQString();
00069 const float                      Preferences::default_defaultSoundVolume      = -1;
00070 const int                        Preferences::default_defaultLateCancel       = 0;
00071 const bool                       Preferences::default_defaultAutoClose        = false;
00072 const bool                       Preferences::default_defaultCopyToKOrganizer = false;
00073 const bool                       Preferences::default_defaultSoundRepeat      = false;
00074 const SoundPicker::Type          Preferences::default_defaultSoundType        = SoundPicker::NONE;
00075 const bool                       Preferences::default_defaultConfirmAck       = false;
00076 const bool                       Preferences::default_defaultCmdScript        = false;
00077 const EditAlarmDlg::CmdLogType   Preferences::default_defaultCmdLogType       = EditAlarmDlg::DISCARD_OUTPUT;
00078 const bool                       Preferences::default_defaultEmailBcc         = false;
00079 const TQString                    Preferences::default_emailAddress            = TQString();
00080 const TQString                    Preferences::default_emailBccAddress         = TQString();
00081 const Preferences::MailClient    Preferences::default_emailClient             = KMAIL;
00082 const Preferences::MailFrom      Preferences::default_emailBccFrom            = MAIL_FROM_CONTROL_CENTRE;
00083 const RecurrenceEdit::RepeatType Preferences::default_defaultRecurPeriod      = RecurrenceEdit::NO_RECUR;
00084 const KARecurrence::Feb29Type    Preferences::default_defaultFeb29Type        = KARecurrence::FEB29_MAR1;
00085 const TimePeriod::Units          Preferences::default_defaultReminderUnits    = TimePeriod::HOURS_MINUTES;
00086 const TQString                    Preferences::default_defaultPreAction;
00087 const TQString                    Preferences::default_defaultPostAction;
00088 
00089 Preferences::MailFrom Preferences::default_emailFrom()
00090 {
00091     return KAMail::identitiesExist() ? MAIL_FROM_KMAIL : MAIL_FROM_CONTROL_CENTRE;
00092 }
00093 
00094 // Active config file settings
00095 ColourList                 Preferences::mMessageColours;
00096 TQColor                     Preferences::mDefaultBgColour;
00097 TQFont                      Preferences::mMessageFont;
00098 TQTime                      Preferences::mStartOfDay;
00099 bool                       Preferences::mRunInSystemTray;
00100 bool                       Preferences::mDisableAlarmsIfStopped;
00101 bool                       Preferences::mAutostartTrayIcon;
00102 KARecurrence::Feb29Type    Preferences::mDefaultFeb29Type;
00103 bool                       Preferences::mModalMessages;
00104 int                        Preferences::mMessageButtonDelay;
00105 int                        Preferences::mTooltipAlarmCount;
00106 bool                       Preferences::mShowTooltipAlarmTime;
00107 bool                       Preferences::mShowTooltipTimeToAlarm;
00108 TQString                    Preferences::mTooltipTimeToPrefix;
00109 int                        Preferences::mDaemonTrayCheckInterval;
00110 TQString                    Preferences::mEmailAddress;
00111 TQString                    Preferences::mEmailBccAddress;
00112 Preferences::MailClient    Preferences::mEmailClient;
00113 Preferences::MailFrom      Preferences::mEmailFrom;
00114 Preferences::MailFrom      Preferences::mEmailBccFrom;
00115 bool                       Preferences::mEmailCopyToKMail;
00116 TQString                    Preferences::mCmdXTermCommand;
00117 TQColor                     Preferences::mDisabledColour;
00118 TQColor                     Preferences::mExpiredColour;
00119 int                        Preferences::mExpiredKeepDays;
00120 // Default settings for Edit Alarm dialog
00121 TQString                    Preferences::mDefaultSoundFile;
00122 float                      Preferences::mDefaultSoundVolume;
00123 int                        Preferences::mDefaultLateCancel;
00124 bool                       Preferences::mDefaultAutoClose;
00125 bool                       Preferences::mDefaultCopyToKOrganizer;
00126 SoundPicker::Type          Preferences::mDefaultSoundType;
00127 bool                       Preferences::mDefaultSoundRepeat;
00128 bool                       Preferences::mDefaultConfirmAck;
00129 bool                       Preferences::mDefaultEmailBcc;
00130 bool                       Preferences::mDefaultCmdScript;
00131 EditAlarmDlg::CmdLogType   Preferences::mDefaultCmdLogType;
00132 TQString                    Preferences::mDefaultCmdLogFile;
00133 RecurrenceEdit::RepeatType Preferences::mDefaultRecurPeriod;
00134 TimePeriod::Units          Preferences::mDefaultReminderUnits;
00135 TQString                    Preferences::mDefaultPreAction;
00136 TQString                    Preferences::mDefaultPostAction;
00137 // Change tracking
00138 TQTime                      Preferences::mOldStartOfDay;
00139 bool                       Preferences::mStartOfDayChanged;
00140 
00141 
00142 static const TQString defaultFeb29RecurType    = TQString::fromLatin1("Mar1");
00143 static const TQString defaultEmailClient       = TQString::fromLatin1("kmail");
00144 
00145 // Config file entry names
00146 static const TQString GENERAL_SECTION          = TQString::fromLatin1("General");
00147 static const TQString VERSION_NUM              = TQString::fromLatin1("Version");
00148 static const TQString MESSAGE_COLOURS          = TQString::fromLatin1("MessageColours");
00149 static const TQString MESSAGE_BG_COLOUR        = TQString::fromLatin1("MessageBackgroundColour");
00150 static const TQString MESSAGE_FONT             = TQString::fromLatin1("MessageFont");
00151 static const TQString RUN_IN_SYSTEM_TRAY       = TQString::fromLatin1("RunInSystemTray");
00152 static const TQString DISABLE_IF_STOPPED       = TQString::fromLatin1("DisableAlarmsIfStopped");
00153 static const TQString AUTOSTART_TRAY           = TQString::fromLatin1("AutostartTray");
00154 static const TQString FEB29_RECUR_TYPE         = TQString::fromLatin1("Feb29Recur");
00155 static const TQString MODAL_MESSAGES           = TQString::fromLatin1("ModalMessages");
00156 static const TQString MESSAGE_BUTTON_DELAY     = TQString::fromLatin1("MessageButtonDelay");
00157 static const TQString TOOLTIP_ALARM_COUNT      = TQString::fromLatin1("TooltipAlarmCount");
00158 static const TQString TOOLTIP_ALARM_TIME       = TQString::fromLatin1("ShowTooltipAlarmTime");
00159 static const TQString TOOLTIP_TIME_TO_ALARM    = TQString::fromLatin1("ShowTooltipTimeToAlarm");
00160 static const TQString TOOLTIP_TIME_TO_PREFIX   = TQString::fromLatin1("TooltipTimeToPrefix");
00161 static const TQString DAEMON_TRAY_INTERVAL     = TQString::fromLatin1("DaemonTrayCheckInterval");
00162 static const TQString EMAIL_CLIENT             = TQString::fromLatin1("EmailClient");
00163 static const TQString EMAIL_COPY_TO_KMAIL      = TQString::fromLatin1("EmailCopyToKMail");
00164 static const TQString EMAIL_FROM               = TQString::fromLatin1("EmailFrom");
00165 static const TQString EMAIL_BCC_ADDRESS        = TQString::fromLatin1("EmailBccAddress");
00166 static const TQString CMD_XTERM_COMMAND        = TQString::fromLatin1("CmdXTerm");
00167 static const TQString START_OF_DAY             = TQString::fromLatin1("StartOfDay");
00168 static const TQString START_OF_DAY_CHECK       = TQString::fromLatin1("Sod");
00169 static const TQString DISABLED_COLOUR          = TQString::fromLatin1("DisabledColour");
00170 static const TQString EXPIRED_COLOUR           = TQString::fromLatin1("ExpiredColour");
00171 static const TQString EXPIRED_KEEP_DAYS        = TQString::fromLatin1("ExpiredKeepDays");
00172 static const TQString DEFAULTS_SECTION         = TQString::fromLatin1("Defaults");
00173 static const TQString DEF_LATE_CANCEL          = TQString::fromLatin1("DefLateCancel");
00174 static const TQString DEF_AUTO_CLOSE           = TQString::fromLatin1("DefAutoClose");
00175 static const TQString DEF_CONFIRM_ACK          = TQString::fromLatin1("DefConfirmAck");
00176 static const TQString DEF_COPY_TO_KORG         = TQString::fromLatin1("DefCopyKOrg");
00177 static const TQString DEF_SOUND_TYPE           = TQString::fromLatin1("DefSoundType");
00178 static const TQString DEF_SOUND_FILE           = TQString::fromLatin1("DefSoundFile");
00179 static const TQString DEF_SOUND_VOLUME         = TQString::fromLatin1("DefSoundVolume");
00180 static const TQString DEF_SOUND_REPEAT         = TQString::fromLatin1("DefSoundRepeat");
00181 static const TQString DEF_CMD_SCRIPT           = TQString::fromLatin1("DefCmdScript");
00182 static const TQString DEF_CMD_LOG_TYPE         = TQString::fromLatin1("DefCmdLogType");
00183 static const TQString DEF_LOG_FILE             = TQString::fromLatin1("DefLogFile");
00184 static const TQString DEF_EMAIL_BCC            = TQString::fromLatin1("DefEmailBcc");
00185 static const TQString DEF_RECUR_PERIOD         = TQString::fromLatin1("DefRecurPeriod");
00186 static const TQString DEF_REMIND_UNITS         = TQString::fromLatin1("RemindUnits");
00187 static const TQString DEF_PRE_ACTION           = TQString::fromLatin1("DefPreAction");
00188 static const TQString DEF_POST_ACTION          = TQString::fromLatin1("DefPostAction");
00189 
00190 // Config file entry name for temporary use
00191 static const TQString TEMP                     = TQString::fromLatin1("Temp");
00192 
00193 // Values for EmailFrom entry
00194 static const TQString FROM_CONTROL_CENTRE      = TQString::fromLatin1("@ControlCenter");
00195 static const TQString FROM_KMAIL               = TQString::fromLatin1("@KMail");
00196 
00197 // Config file entry names for notification messages
00198 const TQString Preferences::QUIT_WARN              = TQString::fromLatin1("QuitWarn");
00199 const TQString Preferences::CONFIRM_ALARM_DELETION = TQString::fromLatin1("ConfirmAlarmDeletion");
00200 const TQString Preferences::EMAIL_QUEUED_NOTIFY    = TQString::fromLatin1("EmailQueuedNotify");
00201 
00202 static const int SODxor = 0x82451630;
00203 inline int Preferences::startOfDayCheck()
00204 {
00205     // Combine with a 'random' constant to prevent 'clever' people fiddling the
00206     // value, and thereby screwing things up.
00207     return TQTime().msecsTo(mStartOfDay) ^ SODxor;
00208 }
00209 
00210 
00211 void Preferences::initialise()
00212 {
00213     if (!mInstance)
00214     {
00215         // Initialise static variables here to avoid static initialisation
00216         // sequencing errors.
00217         mDefault_messageFont = TQFont(TDEGlobalSettings::generalFont().family(), 16, TQFont::Bold);
00218 
00219         mInstance = new Preferences;
00220 
00221         convertOldPrefs();    // convert preferences written by previous KAlarm versions
00222         read();
00223 
00224         // Set the default button for the Quit warning message box to Cancel
00225         MessageBox::setContinueDefault(QUIT_WARN, KMessageBox::Cancel);
00226         MessageBox::setDefaultShouldBeShownContinue(QUIT_WARN, default_quitWarn);
00227         MessageBox::setDefaultShouldBeShownContinue(EMAIL_QUEUED_NOTIFY, default_emailQueuedNotify);
00228         MessageBox::setDefaultShouldBeShownContinue(CONFIRM_ALARM_DELETION, default_confirmAlarmDeletion);
00229     }
00230 }
00231 
00232 void Preferences::connect(const char* signal, const TQObject* receiver, const char* member)
00233 {
00234     initialise();
00235     TQObject::connect(mInstance, signal, receiver, member);
00236 }
00237 
00238 void Preferences::emitStartOfDayChanged()
00239 {
00240     emit startOfDayChanged(mOldStartOfDay);
00241 }
00242 
00243 void Preferences::emitPreferencesChanged()
00244 {
00245     emit preferencesChanged();
00246 }
00247 
00248 /******************************************************************************
00249 * Read preference values from the config file.
00250 */
00251 void Preferences::read()
00252 {
00253     initialise();
00254 
00255     TDEConfig* config = TDEGlobal::config();
00256     config->setGroup(GENERAL_SECTION);
00257     TQStringList cols = config->readListEntry(MESSAGE_COLOURS);
00258     if (!cols.count())
00259         mMessageColours = default_messageColours;
00260     else
00261     {
00262         mMessageColours.clear();
00263         for (TQStringList::Iterator it = cols.begin();  it != cols.end();  ++it)
00264         {
00265             TQColor c((*it));
00266             if (c.isValid())
00267                 mMessageColours.insert(c);
00268         }
00269     }
00270     mDefaultBgColour          = config->readColorEntry(MESSAGE_BG_COLOUR, &default_defaultBgColour);
00271     mMessageFont              = config->readFontEntry(MESSAGE_FONT, &mDefault_messageFont);
00272     mRunInSystemTray          = config->readBoolEntry(RUN_IN_SYSTEM_TRAY, default_runInSystemTray);
00273     mDisableAlarmsIfStopped   = config->readBoolEntry(DISABLE_IF_STOPPED, default_disableAlarmsIfStopped);
00274     mAutostartTrayIcon        = config->readBoolEntry(AUTOSTART_TRAY, default_autostartTrayIcon);
00275     mModalMessages            = config->readBoolEntry(MODAL_MESSAGES, default_modalMessages);
00276     mMessageButtonDelay       = config->readNumEntry(MESSAGE_BUTTON_DELAY, default_messageButtonDelay);
00277     if (mMessageButtonDelay > 10)
00278         mMessageButtonDelay = 10;    // prevent windows being unusable for a long time
00279     if (mMessageButtonDelay < -1)
00280         mMessageButtonDelay = -1;
00281     mTooltipAlarmCount        = static_cast<int>(config->readUnsignedNumEntry(TOOLTIP_ALARM_COUNT, default_tooltipAlarmCount));
00282     if (mTooltipAlarmCount < 1)
00283         mTooltipAlarmCount = 1;
00284     mShowTooltipAlarmTime     = config->readBoolEntry(TOOLTIP_ALARM_TIME, default_showTooltipAlarmTime);
00285     mShowTooltipTimeToAlarm   = config->readBoolEntry(TOOLTIP_TIME_TO_ALARM, default_showTooltipTimeToAlarm);
00286     mTooltipTimeToPrefix      = config->readEntry(TOOLTIP_TIME_TO_PREFIX, default_tooltipTimeToPrefix);
00287     mDaemonTrayCheckInterval  = static_cast<int>(config->readUnsignedNumEntry(DAEMON_TRAY_INTERVAL, default_daemonTrayCheckInterval));
00288     if (mDaemonTrayCheckInterval < 1)
00289         mDaemonTrayCheckInterval = 1;
00290     TQCString client           = config->readEntry(EMAIL_CLIENT, defaultEmailClient).local8Bit();  // don't use readPathEntry() here (values are hard-coded)
00291     mEmailClient              = (client == "sendmail" ? SENDMAIL : KMAIL);
00292     mEmailCopyToKMail         = config->readBoolEntry(EMAIL_COPY_TO_KMAIL, default_emailCopyToKMail);
00293     TQString from              = config->readEntry(EMAIL_FROM, emailFrom(default_emailFrom(), false, false));
00294     mEmailFrom                = emailFrom(from);
00295     TQString bccFrom           = config->readEntry(EMAIL_BCC_ADDRESS, emailFrom(default_emailBccFrom, false, true));
00296     mEmailBccFrom             = emailFrom(bccFrom);
00297     if (mEmailFrom == MAIL_FROM_CONTROL_CENTRE  ||  mEmailBccFrom == MAIL_FROM_CONTROL_CENTRE)
00298         mEmailAddress = mEmailBccAddress = KAMail::controlCentreAddress();
00299     if (mEmailFrom == MAIL_FROM_ADDR)
00300         mEmailAddress     = from;
00301     if (mEmailBccFrom == MAIL_FROM_ADDR)
00302         mEmailBccAddress  = bccFrom;
00303     mCmdXTermCommand          = translateXTermPath(config, config->readEntry(CMD_XTERM_COMMAND), false);
00304     TQDateTime defStartOfDay(TQDate(1900,1,1), default_startOfDay);
00305     mStartOfDay               = config->readDateTimeEntry(START_OF_DAY, &defStartOfDay).time();
00306     mOldStartOfDay.setHMS(0,0,0);
00307     int sod = config->readNumEntry(START_OF_DAY_CHECK, 0);
00308     if (sod)
00309         mOldStartOfDay    = mOldStartOfDay.addMSecs(sod ^ SODxor);
00310     mDisabledColour           = config->readColorEntry(DISABLED_COLOUR, &default_disabledColour);
00311     mExpiredColour            = config->readColorEntry(EXPIRED_COLOUR, &default_expiredColour);
00312     mExpiredKeepDays          = config->readNumEntry(EXPIRED_KEEP_DAYS, default_expiredKeepDays);
00313 
00314     config->setGroup(DEFAULTS_SECTION);
00315     mDefaultLateCancel        = static_cast<int>(config->readUnsignedNumEntry(DEF_LATE_CANCEL, default_defaultLateCancel));
00316     mDefaultAutoClose         = config->readBoolEntry(DEF_AUTO_CLOSE, default_defaultAutoClose);
00317     mDefaultConfirmAck        = config->readBoolEntry(DEF_CONFIRM_ACK, default_defaultConfirmAck);
00318     mDefaultCopyToKOrganizer  = config->readBoolEntry(DEF_COPY_TO_KORG, default_defaultCopyToKOrganizer);
00319     int soundType             = config->readNumEntry(DEF_SOUND_TYPE, default_defaultSoundType);
00320     mDefaultSoundType         = (soundType < 0 || soundType > SoundPicker::SPEAK)
00321                               ? default_defaultSoundType : (SoundPicker::Type)soundType;
00322     mDefaultSoundVolume       = static_cast<float>(config->readDoubleNumEntry(DEF_SOUND_VOLUME, default_defaultSoundVolume));
00323 #ifdef WITHOUT_ARTS
00324     mDefaultSoundRepeat       = false;
00325 #else
00326     mDefaultSoundRepeat       = config->readBoolEntry(DEF_SOUND_REPEAT, default_defaultSoundRepeat);
00327 #endif
00328     mDefaultSoundFile         = config->readPathEntry(DEF_SOUND_FILE);
00329     mDefaultCmdScript         = config->readBoolEntry(DEF_CMD_SCRIPT, default_defaultCmdScript);
00330     int logType               = config->readNumEntry(DEF_CMD_LOG_TYPE, default_defaultCmdLogType);
00331     mDefaultCmdLogType        = (logType < EditAlarmDlg::DISCARD_OUTPUT || logType > EditAlarmDlg::EXEC_IN_TERMINAL)
00332                               ? default_defaultCmdLogType : (EditAlarmDlg::CmdLogType)logType;
00333     mDefaultCmdLogFile        = config->readPathEntry(DEF_LOG_FILE);
00334     mDefaultEmailBcc          = config->readBoolEntry(DEF_EMAIL_BCC, default_defaultEmailBcc);
00335     int recurPeriod           = config->readNumEntry(DEF_RECUR_PERIOD, default_defaultRecurPeriod);
00336     mDefaultRecurPeriod       = (recurPeriod < RecurrenceEdit::SUBDAILY || recurPeriod > RecurrenceEdit::ANNUAL)
00337                               ? default_defaultRecurPeriod : (RecurrenceEdit::RepeatType)recurPeriod;
00338     TQCString feb29            = config->readEntry(FEB29_RECUR_TYPE, defaultFeb29RecurType).local8Bit();
00339     mDefaultFeb29Type         = (feb29 == "Mar1") ? KARecurrence::FEB29_MAR1 : (feb29 == "Feb28") ? KARecurrence::FEB29_FEB28 : KARecurrence::FEB29_FEB29;
00340     TQString remindUnits       = config->readEntry(DEF_REMIND_UNITS);
00341     mDefaultReminderUnits     = (remindUnits == TQString::fromLatin1("Minutes"))      ? TimePeriod::MINUTES
00342                               : (remindUnits == TQString::fromLatin1("HoursMinutes")) ? TimePeriod::HOURS_MINUTES
00343                               : (remindUnits == TQString::fromLatin1("Days"))         ? TimePeriod::DAYS
00344                               : (remindUnits == TQString::fromLatin1("Weeks"))        ? TimePeriod::WEEKS : default_defaultReminderUnits;
00345     mDefaultPreAction         = config->readEntry(DEF_PRE_ACTION, default_defaultPreAction);
00346     mDefaultPostAction        = config->readEntry(DEF_POST_ACTION, default_defaultPostAction);
00347     mInstance->emitPreferencesChanged();
00348     mStartOfDayChanged = (mStartOfDay != mOldStartOfDay);
00349     if (mStartOfDayChanged)
00350     {
00351         mInstance->emitStartOfDayChanged();
00352         mOldStartOfDay = mStartOfDay;
00353     }
00354 }
00355 
00356 /******************************************************************************
00357 * Save preference values to the config file.
00358 */
00359 void Preferences::save(bool syncToDisc)
00360 {
00361     TDEConfig* config = TDEGlobal::config();
00362     config->setGroup(GENERAL_SECTION);
00363     config->writeEntry(VERSION_NUM, KALARM_VERSION);
00364     TQStringList colours;
00365     for (ColourList::const_iterator it = mMessageColours.begin();  it != mMessageColours.end();  ++it)
00366         colours.append(TQColor(*it).name());
00367     config->writeEntry(MESSAGE_COLOURS, colours);
00368     config->writeEntry(MESSAGE_BG_COLOUR, mDefaultBgColour);
00369     config->writeEntry(MESSAGE_FONT, mMessageFont);
00370     config->writeEntry(RUN_IN_SYSTEM_TRAY, mRunInSystemTray);
00371     config->writeEntry(DISABLE_IF_STOPPED, mDisableAlarmsIfStopped);
00372     config->writeEntry(AUTOSTART_TRAY, mAutostartTrayIcon);
00373     config->writeEntry(MODAL_MESSAGES, mModalMessages);
00374     config->writeEntry(MESSAGE_BUTTON_DELAY, mMessageButtonDelay);
00375     config->writeEntry(TOOLTIP_ALARM_COUNT, mTooltipAlarmCount);
00376     config->writeEntry(TOOLTIP_ALARM_TIME, mShowTooltipAlarmTime);
00377     config->writeEntry(TOOLTIP_TIME_TO_ALARM, mShowTooltipTimeToAlarm);
00378     config->writeEntry(TOOLTIP_TIME_TO_PREFIX, mTooltipTimeToPrefix);
00379     config->writeEntry(DAEMON_TRAY_INTERVAL, mDaemonTrayCheckInterval);
00380     config->writeEntry(EMAIL_CLIENT, (mEmailClient == SENDMAIL ? "sendmail" : "kmail"));
00381     config->writeEntry(EMAIL_COPY_TO_KMAIL, mEmailCopyToKMail);
00382     config->writeEntry(EMAIL_FROM, emailFrom(mEmailFrom, true, false));
00383     config->writeEntry(EMAIL_BCC_ADDRESS, emailFrom(mEmailBccFrom, true, true));
00384     config->writeEntry(CMD_XTERM_COMMAND, translateXTermPath(config, mCmdXTermCommand, true));
00385     config->writeEntry(START_OF_DAY, TQDateTime(TQDate(1900,1,1), mStartOfDay));
00386     // Start-of-day check value is only written once the start-of-day time has been processed.
00387     config->writeEntry(DISABLED_COLOUR, mDisabledColour);
00388     config->writeEntry(EXPIRED_COLOUR, mExpiredColour);
00389     config->writeEntry(EXPIRED_KEEP_DAYS, mExpiredKeepDays);
00390 
00391     config->setGroup(DEFAULTS_SECTION);
00392     config->writeEntry(DEF_LATE_CANCEL, mDefaultLateCancel);
00393     config->writeEntry(DEF_AUTO_CLOSE, mDefaultAutoClose);
00394     config->writeEntry(DEF_CONFIRM_ACK, mDefaultConfirmAck);
00395     config->writeEntry(DEF_COPY_TO_KORG, mDefaultCopyToKOrganizer);
00396     config->writeEntry(DEF_SOUND_TYPE, mDefaultSoundType);
00397     config->writePathEntry(DEF_SOUND_FILE, mDefaultSoundFile);
00398     config->writeEntry(DEF_SOUND_VOLUME, static_cast<double>(mDefaultSoundVolume));
00399     config->writeEntry(DEF_SOUND_REPEAT, mDefaultSoundRepeat);
00400     config->writeEntry(DEF_CMD_SCRIPT, mDefaultCmdScript);
00401     config->writeEntry(DEF_CMD_LOG_TYPE, mDefaultCmdLogType);
00402     config->writePathEntry(DEF_LOG_FILE, mDefaultCmdLogFile);
00403     config->writeEntry(DEF_EMAIL_BCC, mDefaultEmailBcc);
00404     config->writeEntry(DEF_RECUR_PERIOD, mDefaultRecurPeriod);
00405     config->writeEntry(FEB29_RECUR_TYPE, (mDefaultFeb29Type == KARecurrence::FEB29_MAR1 ? "Mar1" : mDefaultFeb29Type == KARecurrence::FEB29_FEB28 ? "Feb28" : "None"));
00406     TQString value;
00407     switch (mDefaultReminderUnits)
00408     {
00409         case TimePeriod::MINUTES:       value = TQString::fromLatin1("Minutes");      break;
00410         case TimePeriod::HOURS_MINUTES: value = TQString::fromLatin1("HoursMinutes"); break;
00411         case TimePeriod::DAYS:          value = TQString::fromLatin1("Days");         break;
00412         case TimePeriod::WEEKS:         value = TQString::fromLatin1("Weeks");        break;
00413         default:                        value = TQString(); break;
00414     }
00415     config->writeEntry(DEF_REMIND_UNITS, value);
00416     config->writeEntry(DEF_PRE_ACTION, mDefaultPreAction);
00417     config->writeEntry(DEF_POST_ACTION, mDefaultPostAction);
00418 
00419     if (syncToDisc)
00420         config->sync();
00421     mInstance->emitPreferencesChanged();
00422     if (mStartOfDay != mOldStartOfDay)
00423     {
00424         mInstance->emitStartOfDayChanged();
00425         mOldStartOfDay = mStartOfDay;
00426     }
00427 }
00428 
00429 void Preferences::syncToDisc()
00430 {
00431     TDEGlobal::config()->sync();
00432 }
00433 
00434 void Preferences::updateStartOfDayCheck()
00435 {
00436     TDEConfig* config = TDEGlobal::config();
00437     config->setGroup(GENERAL_SECTION);
00438     config->writeEntry(START_OF_DAY_CHECK, startOfDayCheck());
00439     config->sync();
00440     mStartOfDayChanged = false;
00441 }
00442 
00443 TQString Preferences::emailFrom(Preferences::MailFrom from, bool useAddress, bool bcc)
00444 {
00445     switch (from)
00446     {
00447         case MAIL_FROM_KMAIL:
00448             return FROM_KMAIL;
00449         case MAIL_FROM_CONTROL_CENTRE:
00450             return FROM_CONTROL_CENTRE;
00451         case MAIL_FROM_ADDR:
00452             return useAddress ? (bcc ? mEmailBccAddress : mEmailAddress) : TQString();
00453         default:
00454             return TQString();
00455     }
00456 }
00457 
00458 Preferences::MailFrom Preferences::emailFrom(const TQString& str)
00459 {
00460     if (str == FROM_KMAIL)
00461         return MAIL_FROM_KMAIL;
00462     if (str == FROM_CONTROL_CENTRE)
00463         return MAIL_FROM_CONTROL_CENTRE;
00464     return MAIL_FROM_ADDR;
00465 }
00466 
00467 /******************************************************************************
00468 * Get user's default 'From' email address.
00469 */
00470 TQString Preferences::emailAddress()
00471 {
00472     switch (mEmailFrom)
00473     {
00474         case MAIL_FROM_KMAIL:
00475             return KAMail::identityManager()->defaultIdentity().fullEmailAddr();
00476         case MAIL_FROM_CONTROL_CENTRE:
00477             return KAMail::controlCentreAddress();
00478         case MAIL_FROM_ADDR:
00479             return mEmailAddress;
00480         default:
00481             return TQString();
00482     }
00483 }
00484 
00485 TQString Preferences::emailBccAddress()
00486 {
00487     switch (mEmailBccFrom)
00488     {
00489         case MAIL_FROM_CONTROL_CENTRE:
00490             return KAMail::controlCentreAddress();
00491         case MAIL_FROM_ADDR:
00492             return mEmailBccAddress;
00493         default:
00494             return TQString();
00495     }
00496 }
00497 
00498 void Preferences::setEmailAddress(Preferences::MailFrom from, const TQString& address)
00499 {
00500     switch (from)
00501     {
00502         case MAIL_FROM_KMAIL:
00503             break;
00504         case MAIL_FROM_CONTROL_CENTRE:
00505             mEmailAddress = KAMail::controlCentreAddress();
00506             break;
00507         case MAIL_FROM_ADDR:
00508             mEmailAddress = address;
00509             break;
00510         default:
00511             return;
00512     }
00513     mEmailFrom = from;
00514 }
00515 
00516 void Preferences::setEmailBccAddress(bool useControlCentre, const TQString& address)
00517 {
00518     if (useControlCentre)
00519         mEmailBccAddress = KAMail::controlCentreAddress();
00520     else
00521         mEmailBccAddress = address;
00522     mEmailBccFrom = useControlCentre ? MAIL_FROM_CONTROL_CENTRE : MAIL_FROM_ADDR;
00523 }
00524 
00525 /******************************************************************************
00526 * Called to allow or suppress output of the specified message dialog, where the
00527 * dialog has a checkbox to turn notification off.
00528 */
00529 void Preferences::setNotify(const TQString& messageID, bool notify)
00530 {
00531     MessageBox::saveDontShowAgainContinue(messageID, !notify);
00532 }
00533 
00534 /******************************************************************************
00535 * Return whether the specified message dialog is output, where the dialog has
00536 * a checkbox to turn notification off.
00537 * Reply = false if message has been suppressed (by preferences or by selecting
00538 *               "don't ask again")
00539 *       = true in all other cases.
00540 */
00541 bool Preferences::notifying(const TQString& messageID)
00542 {
00543     return MessageBox::shouldBeShownContinue(messageID);
00544 }
00545 
00546 /******************************************************************************
00547 * If the preferences were written by a previous version of KAlarm, do any
00548 * necessary conversions.
00549 */
00550 void Preferences::convertOldPrefs()
00551 {
00552     TDEConfig* config = TDEGlobal::config();
00553     config->setGroup(GENERAL_SECTION);
00554     int version = KAlarm::getVersionNumber(config->readEntry(VERSION_NUM));
00555     if (version >= KAlarm::Version(1,4,22))
00556         return;     // config format is up to date
00557 
00558     if (version <= KAlarm::Version(1,4,21))
00559     {
00560         // Convert KAlarm 1.4.21 preferences
00561         static const TQString OLD_REMIND_UNITS = TQString::fromLatin1("DefRemindUnits");
00562         config->setGroup(DEFAULTS_SECTION);
00563         int intUnit     = config->readNumEntry(OLD_REMIND_UNITS, 0);
00564         TQString strUnit = (intUnit == 1) ? TQString::fromLatin1("Days")
00565                         : (intUnit == 2) ? TQString::fromLatin1("Weeks")
00566                         :                  TQString::fromLatin1("HoursMinutes");
00567         config->deleteEntry(OLD_REMIND_UNITS);
00568         config->writeEntry(DEF_REMIND_UNITS, strUnit);
00569     }
00570 
00571     if (version <= KAlarm::Version(1,4,20))
00572     {
00573         // Convert KAlarm 1.4.20 preferences
00574         static const TQString VIEW_SECTION = TQString::fromLatin1("View");
00575         static const TQString SHOW_ARCHIVED_ALARMS = TQString::fromLatin1("ShowArchivedAlarms");
00576         static const TQString SHOW_EXPIRED_ALARMS  = TQString::fromLatin1("ShowExpiredAlarms");
00577         static const TQString SHOW_ALARM_TIME      = TQString::fromLatin1("ShowAlarmTime");
00578         static const TQString SHOW_TIME_TO_ALARM   = TQString::fromLatin1("ShowTimeToAlarm");
00579         config->setGroup(GENERAL_SECTION);
00580         bool showExpired = config->readBoolEntry(SHOW_EXPIRED_ALARMS, false);
00581         bool showTime    = config->readBoolEntry(SHOW_ALARM_TIME, true);
00582         bool showTimeTo  = config->readBoolEntry(SHOW_TIME_TO_ALARM, false);
00583         config->deleteEntry(SHOW_EXPIRED_ALARMS);
00584         config->deleteEntry(SHOW_ALARM_TIME);
00585         config->deleteEntry(SHOW_TIME_TO_ALARM);
00586         config->setGroup(VIEW_SECTION);
00587         config->writeEntry(SHOW_ARCHIVED_ALARMS, showExpired);
00588         config->writeEntry(SHOW_ALARM_TIME, showTime);
00589         config->writeEntry(SHOW_TIME_TO_ALARM, showTimeTo);
00590     }
00591 
00592     if (version <= KAlarm::Version(1,4,5))
00593     {
00594         // Convert KAlarm 1.4.5 preferences
00595         static const TQString DEF_SOUND = TQString::fromLatin1("DefSound");
00596         config->setGroup(DEFAULTS_SECTION);
00597         bool sound = config->readBoolEntry(DEF_SOUND, false);
00598         if (!sound)
00599             config->writeEntry(DEF_SOUND_TYPE, SoundPicker::NONE);
00600         config->deleteEntry(DEF_SOUND);
00601     }
00602 
00603     if (version < KAlarm::Version(1,3,0))
00604     {
00605         // Convert KAlarm pre-1.3 preferences
00606         static const TQString EMAIL_ADDRESS             = TQString::fromLatin1("EmailAddress");
00607         static const TQString EMAIL_USE_CTRL_CENTRE     = TQString::fromLatin1("EmailUseControlCenter");
00608         static const TQString EMAIL_BCC_USE_CTRL_CENTRE = TQString::fromLatin1("EmailBccUseControlCenter");
00609         TQMap<TQString, TQString> entries = config->entryMap(GENERAL_SECTION);
00610         if (entries.find(EMAIL_FROM) == entries.end()
00611         &&  entries.find(EMAIL_USE_CTRL_CENTRE) != entries.end())
00612         {
00613             // Preferences were written by KAlarm pre-1.2.1
00614             config->setGroup(GENERAL_SECTION);
00615             bool useCC = false;
00616             bool bccUseCC = false;
00617             const bool default_emailUseControlCentre    = true;
00618             const bool default_emailBccUseControlCentre = true;
00619             useCC = config->readBoolEntry(EMAIL_USE_CTRL_CENTRE, default_emailUseControlCentre);
00620             // EmailBccUseControlCenter was missing in preferences written by KAlarm pre-0.9.5
00621             bccUseCC = config->hasKey(EMAIL_BCC_USE_CTRL_CENTRE)
00622                      ? config->readBoolEntry(EMAIL_BCC_USE_CTRL_CENTRE, default_emailBccUseControlCentre)
00623                  : useCC;
00624             config->writeEntry(EMAIL_FROM, (useCC ? FROM_CONTROL_CENTRE : config->readEntry(EMAIL_ADDRESS)));
00625             config->writeEntry(EMAIL_BCC_ADDRESS, (bccUseCC ? FROM_CONTROL_CENTRE : config->readEntry(EMAIL_BCC_ADDRESS)));
00626             config->deleteEntry(EMAIL_ADDRESS);
00627             config->deleteEntry(EMAIL_BCC_USE_CTRL_CENTRE);
00628             config->deleteEntry(EMAIL_USE_CTRL_CENTRE);
00629         }
00630         // Convert KAlarm 1.2 preferences
00631         static const TQString DEF_CMD_XTERM = TQString::fromLatin1("DefCmdXterm");
00632         config->setGroup(DEFAULTS_SECTION);
00633         if (config->hasKey(DEF_CMD_XTERM))
00634         {
00635             config->writeEntry(DEF_CMD_LOG_TYPE,
00636                 (config->readBoolEntry(DEF_CMD_XTERM, false) ? EditAlarmDlg::EXEC_IN_TERMINAL : EditAlarmDlg::DISCARD_OUTPUT));
00637             config->deleteEntry(DEF_CMD_XTERM);
00638         }
00639     }
00640     config->setGroup(GENERAL_SECTION);
00641     config->writeEntry(VERSION_NUM, KALARM_VERSION);
00642     config->sync();
00643 }
00644 
00645 /******************************************************************************
00646 * Translate an X terminal command path to/from config file format.
00647 * Note that only a home directory specification at the start of the path is
00648 * translated, so there's no need to worry about missing out some of the
00649 * executable's path due to quotes etc.
00650 * N.B. Calling TDEConfig::read/writePathEntry() on the entire command line
00651 *      causes a crash on some systems, so it's necessary to extract the
00652 *      executable path first before processing.
00653 */
00654 TQString translateXTermPath(TDEConfig* config, const TQString& cmdline, bool write)
00655 {
00656     TQString params;
00657     TQString cmd = cmdline;
00658     if (cmdline.isEmpty())
00659         return cmdline;
00660     // Strip any leading quote
00661     TQChar quote = cmdline[0];
00662     char q = static_cast<char>(quote);
00663     bool quoted = (q == '"' || q == '\'');
00664     if (quoted)
00665         cmd = cmdline.mid(1);
00666     // Split the command at the first non-escaped space
00667     for (int i = 0, count = cmd.length();  i < count;  ++i)
00668     {
00669         switch (cmd[i].latin1())
00670         {
00671             case '\\':
00672                 ++i;
00673                 continue;
00674             case '"':
00675             case '\'':
00676                 if (cmd[i] != quote)
00677                     continue;
00678                 // fall through to ' '
00679             case ' ':
00680                 params = cmd.mid(i);
00681                 cmd = cmd.left(i);
00682                 break;
00683             default:
00684                 continue;
00685         }
00686         break;
00687     }
00688     // Translate any home directory specification at the start of the
00689     // executable's path.
00690     if (write)
00691     {
00692         config->writePathEntry(TEMP, cmd);
00693         cmd = config->readEntry(TEMP);
00694     }
00695     else
00696     {
00697         config->writeEntry(TEMP, cmd);
00698         cmd = config->readPathEntry(TEMP);
00699     }
00700     config->deleteEntry(TEMP);
00701     if (quoted)
00702         return quote + cmd + params;
00703     else
00704         return cmd + params;
00705 }