File indexing completed on 2024-05-12 05:14:55
0001 /* 0002 * preferences.cpp - program preference settings 0003 * Program: kalarm 0004 * SPDX-FileCopyrightText: 2001-2024 David Jarvie <djarvie@kde.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "preferences.h" 0010 0011 #include "kalarm.h" 0012 #include "kamail.h" 0013 #include "pluginmanager.h" 0014 #include "lib/desktop.h" 0015 #include "lib/messagebox.h" 0016 #include "lib/shellprocess.h" 0017 #include "kalarmcalendar/holidays.h" 0018 #include "kalarmcalendar/identities.h" 0019 #include "kalarm_debug.h" 0020 0021 #include <KIdentityManagementCore/Identity> 0022 #include <KIdentityManagementCore/IdentityManager> 0023 0024 #include <KSharedConfig> 0025 #include <KConfigGroup> 0026 #include <KMessageBox> 0027 #include <KWindowSystem> 0028 #include <KShell> 0029 0030 #include <QFile> 0031 #include <QSaveFile> 0032 #include <QDir> 0033 #include <QStandardPaths> 0034 0035 #include <time.h> 0036 0037 using namespace KAlarmCal; 0038 0039 //clazy:excludeall=non-pod-global-static 0040 0041 namespace 0042 { 0043 0044 // Config file entry names 0045 const QLatin1String GENERAL_GROUP("General"); 0046 0047 // Config file entry name for temporary use 0048 const char* TEMP = "Temp"; 0049 0050 const QString AUTOSTART_FILE(QStringLiteral("kalarm.autostart.desktop")); 0051 0052 // Values for EmailFrom entry 0053 const QString FROM_SYS_SETTINGS(QStringLiteral("@SystemSettings")); 0054 const QString FROM_KMAIL(QStringLiteral("@KMail")); 0055 0056 // Command strings for executing commands in different types of terminal windows. 0057 // %t = window title parameter 0058 // %c = command to execute in terminal 0059 // %w = command to execute in terminal, with 'sleep 86400' appended 0060 // %C = temporary command file to execute in terminal 0061 // %W = temporary command file to execute in terminal, with 'sleep 86400' appended 0062 const QList<QString> xtermCommands { 0063 QStringLiteral("xterm -sb -hold -title %t -e %c"), 0064 QStringLiteral("konsole --noclose -p tabtitle=%t -e ${SHELL:-sh} -c %c"), 0065 QStringLiteral("gnome-terminal -t %t -e %W"), 0066 QStringLiteral("eterm --pause -T %t -e %C"), // some systems use eterm... 0067 QStringLiteral("Eterm --pause -T %t -e %C"), // while some use Eterm 0068 QStringLiteral("rxvt -title %t -e ${SHELL:-sh} -c %w"), 0069 QStringLiteral("xfce4-terminal -T %t -H -e %c") 0070 }; 0071 0072 QList<QString> xtermCommandExes; // initialised to hold executables in xtermCommands 0073 0074 void splitXTermCommands(); 0075 0076 } // namespace 0077 0078 // Config file entry names for notification messages 0079 const QLatin1String Preferences::QUIT_WARN("QuitWarn"); 0080 const QLatin1String Preferences::ASK_AUTO_START("AskAutoStart"); 0081 const QLatin1String Preferences::CONFIRM_ALARM_DELETION("ConfirmAlarmDeletion"); 0082 const QLatin1String Preferences::EMAIL_QUEUED_NOTIFY("EmailQueuedNotify"); 0083 const bool default_quitWarn = true; 0084 const bool default_emailQueuedNotify = false; 0085 const bool default_confirmAlarmDeletion = true; 0086 0087 static QString translateXTermPath(const QString& cmdline, bool write); 0088 0089 0090 Preferences* Preferences::mInstance = nullptr; 0091 bool Preferences::mUsingDefaults = false; 0092 Holidays* Preferences::mHolidays = nullptr; // always non-null after Preferences initialisation 0093 QString Preferences::mPreviousVersion; 0094 Preferences::Backend Preferences::mPreviousBackend; 0095 // Change tracking 0096 bool Preferences::mAutoStartChangedByUser = false; 0097 0098 0099 Preferences* Preferences::self() 0100 { 0101 if (!mInstance) 0102 { 0103 // Set the default button for the Quit warning message box to Cancel 0104 KAMessageBox::setContinueDefault(QUIT_WARN, KMessageBox::Cancel); 0105 KAMessageBox::setDefaultShouldBeShownContinue(QUIT_WARN, default_quitWarn); 0106 KAMessageBox::setDefaultShouldBeShownContinue(EMAIL_QUEUED_NOTIFY, default_emailQueuedNotify); 0107 KAMessageBox::setDefaultShouldBeShownContinue(CONFIRM_ALARM_DELETION, default_confirmAlarmDeletion); 0108 0109 mInstance = new Preferences; 0110 } 0111 return mInstance; 0112 } 0113 0114 Preferences::Preferences() 0115 { 0116 QObject::connect(this, &Preferences::base_StartOfDayChanged, this, &Preferences::startDayChange); 0117 QObject::connect(this, &Preferences::base_TimeZoneChanged, this, &Preferences::timeZoneChange); 0118 QObject::connect(this, &Preferences::base_HolidayRegionChanged, this, &Preferences::holidaysChange); 0119 QObject::connect(this, &Preferences::base_WorkTimeChanged, this, &Preferences::workTimeChange); 0120 0121 load(); 0122 // Fetch the KAlarm version and backend which wrote the previous config file 0123 mPreviousVersion = version(); 0124 mPreviousBackend = backend(); 0125 // Update the KAlarm version in the config file, but don't call 0126 // writeConfig() here - leave it to be written only if the config file 0127 // is updated with other data. 0128 setVersion(QStringLiteral(KALARM_VERSION)); 0129 } 0130 0131 /****************************************************************************** 0132 * Get whether the Akonadi plugin should be used, if available. 0133 */ 0134 bool Preferences::useAkonadi() 0135 { 0136 return self()->mUseAkonadiIfAvailable && PluginManager::instance()->akonadiPlugin(); 0137 } 0138 0139 /****************************************************************************** 0140 * Return the Akonadi plugin to use, or null if not being used or not available. 0141 */ 0142 AkonadiPlugin* Preferences::akonadiPlugin() 0143 { 0144 if (!self()->mUseAkonadiIfAvailable) 0145 return nullptr; 0146 return PluginManager::instance()->akonadiPlugin(); 0147 } 0148 0149 void Preferences::setUseAkonadi(bool yes) 0150 { 0151 if (PluginManager::instance()->akonadiPlugin()) 0152 self()->setUseAkonadiIfAvailable(yes); 0153 } 0154 0155 /****************************************************************************** 0156 * Auto hiding of the system tray icon is only allowed on desktops which provide 0157 * GUI controls to show hidden icons. 0158 */ 0159 int Preferences::autoHideSystemTray() 0160 { 0161 if (noAutoHideSystemTrayDesktops().contains(Desktop::currentIdentityName())) 0162 return 0; // never hide 0163 return self()->mBase_AutoHideSystemTray; 0164 } 0165 0166 /****************************************************************************** 0167 * Auto hiding of the system tray icon is only allowed on desktops which provide 0168 * GUI controls to show hidden icons, so while KAlarm is running on such a 0169 * desktop, don't allow changes to the setting. 0170 */ 0171 void Preferences::setAutoHideSystemTray(int timeout) 0172 { 0173 if (noAutoHideSystemTrayDesktops().contains(Desktop::currentIdentityName())) 0174 return; 0175 self()->setBase_AutoHideSystemTray(timeout); 0176 } 0177 0178 void Preferences::setAskAutoStart(bool yes) 0179 { 0180 KAMessageBox::saveDontShowAgainYesNo(ASK_AUTO_START, !yes); 0181 } 0182 0183 /****************************************************************************** 0184 * Set the NoAutoStart condition. 0185 * On KDE desktops, the "X-KDE-autostart-condition" entry in 0186 * kalarm.autostart.desktop references this to determine whether to autostart KAlarm. 0187 * On non-KDE desktops, the "X-KDE-autostart-condition" entry in 0188 * kalarm.autostart.desktop doesn't have any effect, so that KAlarm will be 0189 * autostarted even if it is set not to autostart. Adding a "Hidden" entry to, 0190 * and removing the "OnlyShowIn=KDE" entry from, a user-modifiable copy of the 0191 * file fixes this. 0192 */ 0193 void Preferences::setNoAutoStart(bool yes) 0194 { 0195 // Find the existing kalarm.autostart.desktop file, and whether it's writable. 0196 bool existingRO = true; // whether the existing file is read-only 0197 QString autostartFile; 0198 QString configDirRW; 0199 const QStringList autostartDirs = QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation); 0200 for (const QString& dir : autostartDirs) 0201 { 0202 const QString file = dir + QLatin1String("/autostart/") + AUTOSTART_FILE; 0203 if (QFile::exists(file)) 0204 { 0205 QFileInfo info(file); 0206 if (info.isReadable()) 0207 { 0208 autostartFile = file; 0209 existingRO = !info.isWritable(); 0210 if (!existingRO) 0211 configDirRW = dir; 0212 break; 0213 } 0214 } 0215 } 0216 0217 // If the existing file isn't writable, find the path to create a writable copy 0218 QString autostartFileRW = autostartFile; 0219 if (existingRO) 0220 { 0221 configDirRW = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); 0222 autostartFileRW = configDirRW + QLatin1String("/autostart/") + AUTOSTART_FILE; 0223 if (configDirRW.isEmpty()) 0224 { 0225 qCWarning(KALARM_LOG) << "Preferences::setNoAutoStart: No writable autostart file path"; 0226 return; 0227 } 0228 if (QFile::exists(autostartFileRW)) 0229 { 0230 QFileInfo info(autostartFileRW); 0231 if (!info.isReadable() || !info.isWritable()) 0232 { 0233 qCWarning(KALARM_LOG) << "Preferences::setNoAutoStart: Autostart file is not read/write:" << autostartFileRW; 0234 return; 0235 } 0236 } 0237 } 0238 0239 // Read the existing file and remove any "Hidden=" and "OnlyShowIn=" entries 0240 bool update = false; 0241 QStringList lines; 0242 { 0243 QFile file(autostartFile); 0244 if (!file.open(QIODevice::ReadOnly)) 0245 { 0246 qCWarning(KALARM_LOG) << "Preferences::setNoAutoStart: Error reading autostart file:" << autostartFile; 0247 return; 0248 } 0249 QTextStream stream(&file); 0250 stream.setAutoDetectUnicode(true); 0251 lines = stream.readAll().split(QLatin1Char('\n')); 0252 for (int i = 0; i < lines.size(); ++i) 0253 { 0254 const QString line = lines.at(i).trimmed(); 0255 if (line.isEmpty()) 0256 { 0257 lines.removeAt(i); 0258 --i; 0259 } 0260 else if (line.startsWith(QLatin1String("Hidden=")) 0261 || line.startsWith(QLatin1String("OnlyShowIn="))) 0262 { 0263 lines.removeAt(i); 0264 update = true; 0265 --i; 0266 } 0267 } 0268 } 0269 0270 if (yes) 0271 { 0272 // Add a "Hidden" entry to the local kalarm.autostart.desktop file, to 0273 // prevent autostart from happening. 0274 lines += QStringLiteral("Hidden=true"); 0275 update = true; 0276 } 0277 if (update) 0278 { 0279 // Write the updated file 0280 QFileInfo info(configDirRW + QLatin1String("/autostart")); 0281 if (!info.exists()) 0282 { 0283 // First, create the directory for it. 0284 if (!QDir(configDirRW).mkdir(QStringLiteral("autostart"))) 0285 { 0286 qCWarning(KALARM_LOG) << "Preferences::setNoAutoStart: Error creating autostart file directory:" << info.filePath(); 0287 return; 0288 } 0289 } 0290 QSaveFile file(autostartFileRW); 0291 if (!file.open(QIODevice::WriteOnly)) 0292 { 0293 qCWarning(KALARM_LOG) << "Preferences::setNoAutoStart: Error writing autostart file:" << autostartFileRW; 0294 return; 0295 } 0296 QTextStream stream(&file); 0297 stream << lines.join(QLatin1Char('\n')) << "\n"; 0298 // QSaveFile doesn't report a write error when the device is full (see Qt 0299 // bug 75077), so check that the data can actually be written by flush(). 0300 if (!file.flush() || !file.commit()) // save the file 0301 { 0302 qCWarning(KALARM_LOG) << "Preferences::setNoAutoStart: Error writing autostart file:" << autostartFileRW; 0303 return; 0304 } 0305 qCDebug(KALARM_LOG) << "Preferences::setNoAutoStart: Written" << autostartFileRW; 0306 } 0307 0308 self()->setBase_NoAutoStart(yes); 0309 } 0310 0311 /****************************************************************************** 0312 * Get whether message windows should have a title bar and take keyboard focus. 0313 */ 0314 bool Preferences::modalMessages() 0315 { 0316 return !KWindowSystem::isPlatformX11() || self()->base_ModalMessages(); 0317 } 0318 0319 /****************************************************************************** 0320 * Set whether message windows should have a title bar and take keyboard focus. 0321 */ 0322 void Preferences::setModalMessages(bool yes) 0323 { 0324 if (KWindowSystem::isPlatformX11()) 0325 self()->setBase_ModalMessages(yes); 0326 } 0327 0328 /****************************************************************************** 0329 * Get the delay in seconds after a message window is displayed before its 0330 * buttons are activated. 0331 * Reply = 0 for no delay, but position windows as far from cursor as possible. 0332 */ 0333 int Preferences::messageButtonDelay() 0334 { 0335 const int delay = self()->base_MessageButtonDelay(); 0336 // On Wayland, window positions can't be set, so return a minimum delay of 1 second. 0337 return (delay <= 0 && KWindowSystem::isPlatformWayland()) ? 1 : delay; 0338 } 0339 0340 /****************************************************************************** 0341 * Get the user's time zone, or if none has been chosen, the system time zone. 0342 * Reply = time zone, or invalid to use the local time zone. 0343 */ 0344 KADateTime::Spec Preferences::timeSpec() 0345 { 0346 const QByteArray zoneId = self()->mBase_TimeZone.toLatin1(); 0347 return zoneId.isEmpty() ? KADateTime::LocalZone : KADateTime::Spec(QTimeZone(zoneId)); 0348 } 0349 0350 QTimeZone Preferences::timeSpecAsZone() 0351 { 0352 const QByteArray zoneId = self()->mBase_TimeZone.toLatin1(); 0353 return zoneId.isEmpty() ? QTimeZone::systemTimeZone() : QTimeZone(zoneId); 0354 } 0355 0356 void Preferences::setTimeSpec(const KADateTime::Spec& spec) 0357 { 0358 self()->setBase_TimeZone(spec.type() == KADateTime::TimeZone ? QString::fromLatin1(spec.timeZone().id()) : QString()); 0359 } 0360 0361 void Preferences::timeZoneChange(const QString& zone) 0362 { 0363 Q_UNUSED(zone); 0364 Q_EMIT mInstance->timeZoneChanged(timeSpec()); 0365 } 0366 0367 const Holidays& Preferences::holidays() 0368 { 0369 const QString regionCode = self()->mBase_HolidayRegion; 0370 if (!mHolidays) 0371 mHolidays = new Holidays(regionCode); 0372 else if (mHolidays->regionCode() != regionCode) 0373 mHolidays->setRegion(regionCode); 0374 return *mHolidays; 0375 } 0376 0377 void Preferences::setHolidayRegion(const QString& regionCode) 0378 { 0379 self()->setBase_HolidayRegion(regionCode); 0380 } 0381 0382 void Preferences::holidaysChange(const QString& regionCode) 0383 { 0384 Q_UNUSED(regionCode); 0385 Q_EMIT mInstance->holidaysChanged(holidays()); 0386 } 0387 0388 void Preferences::setStartOfDay(const QTime& t) 0389 { 0390 if (t != self()->mBase_StartOfDay.time()) 0391 { 0392 self()->setBase_StartOfDay(QDateTime(QDate(1900,1,1), t)); 0393 Q_EMIT mInstance->startOfDayChanged(t); 0394 } 0395 } 0396 0397 // Called when the start of day value has changed in the config file 0398 void Preferences::startDayChange(const QDateTime& dt) 0399 { 0400 Q_EMIT mInstance->startOfDayChanged(dt.time()); 0401 } 0402 0403 QBitArray Preferences::workDays() 0404 { 0405 unsigned days = self()->base_WorkDays(); 0406 QBitArray dayBits(7); 0407 for (int i = 0; i < 7; ++i) 0408 dayBits.setBit(i, days & (1 << i)); 0409 return dayBits; 0410 } 0411 0412 void Preferences::setWorkDays(const QBitArray& dayBits) 0413 { 0414 if (dayBits.size() != 7) 0415 { 0416 qCWarning(KALARM_LOG) << "Preferences::setWorkDays: Error! 'dayBits' parameter must have 7 elements: actual size" << dayBits.size(); 0417 return; 0418 } 0419 unsigned days = 0; 0420 for (int i = 0; i < 7; ++i) 0421 if (dayBits.testBit(i)) 0422 days |= 1 << i; 0423 self()->setBase_WorkDays(days); 0424 } 0425 0426 void Preferences::workTimeChange(const QDateTime& start, const QDateTime& end, int days) 0427 { 0428 QBitArray dayBits(7); 0429 for (int i = 0; i < 7; ++i) 0430 if (days & (1 << i)) 0431 dayBits.setBit(i); 0432 Q_EMIT mInstance->workTimeChanged(start.time(), end.time(), dayBits); 0433 } 0434 0435 Preferences::MailClient Preferences::emailClient() 0436 { 0437 if (!useAkonadi()) 0438 return sendmail; 0439 return static_cast<MailClient>(self()->mBase_EmailClient); 0440 } 0441 0442 void Preferences::setEmailClient(MailClient client) 0443 { 0444 if (!useAkonadi()) 0445 client = sendmail; 0446 self()->setBase_EmailClient(client); 0447 } 0448 0449 bool Preferences::emailCopyToKMail() 0450 { 0451 if (!useAkonadi()) 0452 return false; 0453 return self()->mBase_EmailCopyToKMail && static_cast<MailClient>(self()->mBase_EmailClient) == sendmail; 0454 } 0455 0456 void Preferences::setEmailCopyToKMail(bool yes) 0457 { 0458 if (!useAkonadi()) 0459 yes = false; 0460 self()->setBase_EmailCopyToKMail(yes); 0461 } 0462 0463 Preferences::MailFrom Preferences::emailFrom() 0464 { 0465 const QString from = self()->mBase_EmailFrom; 0466 if (from == FROM_KMAIL) 0467 return MAIL_FROM_KMAIL; 0468 if (from == FROM_SYS_SETTINGS) 0469 return MAIL_FROM_SYS_SETTINGS; 0470 return MAIL_FROM_ADDR; 0471 } 0472 0473 /****************************************************************************** 0474 * Get user's default 'From' email address. 0475 */ 0476 QString Preferences::emailAddress() 0477 { 0478 const QString from = self()->mBase_EmailFrom; 0479 if (from == FROM_KMAIL) 0480 return Identities::identityManager()->defaultIdentity().fullEmailAddr(); 0481 if (from == FROM_SYS_SETTINGS) 0482 return KAMail::controlCentreAddress(); 0483 return from; 0484 } 0485 0486 void Preferences::setEmailAddress(Preferences::MailFrom from, const QString& address) 0487 { 0488 QString out; 0489 switch (from) 0490 { 0491 case MAIL_FROM_KMAIL: out = FROM_KMAIL; break; 0492 case MAIL_FROM_SYS_SETTINGS: out = FROM_SYS_SETTINGS; break; 0493 case MAIL_FROM_ADDR: out = address; break; 0494 default: return; 0495 } 0496 self()->setBase_EmailFrom(out); 0497 } 0498 0499 Preferences::MailFrom Preferences::emailBccFrom() 0500 { 0501 const QString from = self()->mBase_EmailBccAddress; 0502 if (from == FROM_SYS_SETTINGS) 0503 return MAIL_FROM_SYS_SETTINGS; 0504 return MAIL_FROM_ADDR; 0505 } 0506 0507 QString Preferences::emailBccAddress() 0508 { 0509 const QString from = self()->mBase_EmailBccAddress; 0510 if (from == FROM_SYS_SETTINGS) 0511 return KAMail::controlCentreAddress(); 0512 return from; 0513 } 0514 0515 bool Preferences::emailBccUseSystemSettings() 0516 { 0517 return self()->mBase_EmailBccAddress == FROM_SYS_SETTINGS; 0518 } 0519 0520 void Preferences::setEmailBccAddress(bool useSystemSettings, const QString& address) 0521 { 0522 QString out; 0523 if (useSystemSettings) 0524 out = FROM_SYS_SETTINGS; 0525 else 0526 out = address; 0527 self()->setBase_EmailBccAddress(out); 0528 } 0529 0530 QString Preferences::cmdXTermCommand() 0531 { 0532 QString cmd = translateXTermPath(self()->mBase_CmdXTermCommand, false); 0533 if (cmd.isEmpty()) 0534 { 0535 // No terminal command is specified. If there is only one standard 0536 // terminal executable installed, set it as the default. 0537 const auto cmds = cmdXTermStandardCommands(); 0538 if (cmds.size() == 1) 0539 { 0540 cmd = cmds.constBegin().value(); 0541 self()->setBase_CmdXTermCommand(translateXTermPath(cmd, true)); 0542 self()->save(); 0543 } 0544 } 0545 return cmd; 0546 } 0547 0548 std::pair<int, QString> Preferences::cmdXTermCommandIndex() 0549 { 0550 const QString xtermCmd = cmdXTermCommand(); 0551 if (xtermCmd.isEmpty()) 0552 return std::make_pair(-1, QString()); 0553 int id = 0; 0554 for (const QString& cmd : xtermCommands) 0555 { 0556 ++id; 0557 if (xtermCmd == cmd) 0558 return std::make_pair(id, xtermCmd); // index is 1 greater than the index into xtermCommands 0559 } 0560 return std::make_pair(0, xtermCmd); 0561 } 0562 0563 void Preferences::setCmdXTermSpecialCommand(const QString& cmd) 0564 { 0565 self()->setBase_CmdXTermCommand(translateXTermPath(cmd, true)); 0566 } 0567 0568 void Preferences::setCmdXTermCommand(int index) 0569 { 0570 --index; // convert to an index into xtermCommands 0571 if (index >= 0 && index < xtermCommands.size()) 0572 setCmdXTermSpecialCommand(xtermCommands[index]); 0573 } 0574 0575 QString Preferences::cmdXTermStandardCommand(int index) 0576 { 0577 --index; // convert to an index into xtermCommands 0578 if (index >= 0 && index < xtermCommands.size()) 0579 { 0580 splitXTermCommands(); 0581 const QString exe = xtermCommandExes.at(index); 0582 if (!exe.isEmpty() && !QStandardPaths::findExecutable(exe).isEmpty()) 0583 return xtermCommands[index]; 0584 } 0585 return {}; 0586 } 0587 0588 QHash<int, QString> Preferences::cmdXTermStandardCommands() 0589 { 0590 QHash<int, QString> result; 0591 splitXTermCommands(); 0592 for (int i = 0, count = xtermCommands.count(); i < count; ++i) 0593 { 0594 const QString exe = xtermCommandExes.at(i); 0595 if (!exe.isEmpty() && !QStandardPaths::findExecutable(exe).isEmpty()) 0596 result[i + 1] = xtermCommands[i]; // index is 1 greater than the index into xtermCommands 0597 } 0598 return result; 0599 } 0600 0601 namespace 0602 { 0603 void splitXTermCommands() 0604 { 0605 if (xtermCommandExes.isEmpty()) 0606 { 0607 for (const QString& cmd : xtermCommands) 0608 { 0609 const QStringList args = KShell::splitArgs(cmd); 0610 xtermCommandExes.append(args.isEmpty() ? QString() : args[0]); 0611 } 0612 } 0613 } 0614 } 0615 0616 Preferences::SoundType Preferences::defaultSoundType() 0617 { 0618 #ifdef HAVE_TEXT_TO_SPEECH_SUPPORT 0619 return self()->base_DefaultSoundType(); 0620 #else 0621 SoundType type = self()->base_DefaultSoundType(); 0622 return (type == Sound_Speak) ? Sound_None : type; 0623 #endif 0624 } 0625 0626 void Preferences::setDefaultSoundType(SoundType type) 0627 { 0628 #ifndef HAVE_TEXT_TO_SPEECH_SUPPORT 0629 if (type == Sound_Speak) 0630 return; 0631 #endif 0632 self()->setBase_DefaultSoundType(type); 0633 } 0634 0635 void Preferences::connect(const char* signal, const QObject* receiver, const char* member) 0636 { 0637 QObject::connect(self(), signal, receiver, member); 0638 } 0639 0640 /****************************************************************************** 0641 * Called to allow or suppress output of the specified message dialog, where the 0642 * dialog has a checkbox to turn notification off. 0643 */ 0644 void Preferences::setNotify(const QString& messageID, bool notify) 0645 { 0646 KAMessageBox::saveDontShowAgainContinue(messageID, !notify); 0647 } 0648 0649 /****************************************************************************** 0650 * Return whether the specified message dialog is output, where the dialog has 0651 * a checkbox to turn notification off. 0652 * Reply = false if message has been suppressed (by preferences or by selecting 0653 * "don't ask again") 0654 * = true in all other cases. 0655 */ 0656 bool Preferences::notifying(const QString& messageID) 0657 { 0658 return KAMessageBox::shouldBeShownContinue(messageID); 0659 } 0660 0661 /****************************************************************************** 0662 * Translate an X terminal command path to/from config file format. 0663 * Note that only a home directory specification at the start of the path is 0664 * translated, so there's no need to worry about missing out some of the 0665 * executable's path due to quotes etc. 0666 * N.B. Calling KConfig::read/writePathEntry() on the entire command line 0667 * causes a crash on some systems, so it's necessary to extract the 0668 * executable path first before processing. 0669 */ 0670 QString translateXTermPath(const QString& cmdline, bool write) 0671 { 0672 QString params = cmdline; 0673 QString cmd = ShellProcess::splitCommandLine(params); 0674 0675 // Translate any home directory specification at the start of the 0676 // executable's path. 0677 KConfigGroup group(KSharedConfig::openConfig(), GENERAL_GROUP); 0678 if (write) 0679 { 0680 group.writePathEntry(TEMP, cmd); 0681 cmd = group.readEntry(TEMP, QString()); 0682 } 0683 else 0684 { 0685 group.writeEntry(TEMP, cmd); 0686 cmd = group.readPathEntry(TEMP, QString()); 0687 } 0688 group.deleteEntry(TEMP); 0689 return cmd + params; 0690 } 0691 0692 #include "moc_preferences.cpp" 0693 0694 // vim: et sw=4: