File indexing completed on 2024-03-24 15:43:42

0001 /***************************************************************************
0002                           cglobalsettings.cpp  -  global application settings
0003     This file is a part of KMuddy distribution.
0004                              -------------------
0005     begin                : St Aug 14 2002
0006     copyright            : (C) 2002-2007 by Tomas Mecir
0007     email                : kmuddy@kmuddy.com
0008  ***************************************************************************/
0009 
0010 /***************************************************************************
0011  *                                                                         *
0012  *   This program is free software; you can redistribute it and/or modify  *
0013  *   it under the terms of the GNU General Public License as published by  *
0014  *   the Free Software Foundation; either version 2 of the License, or     *
0015  *   (at your option) any later version.                                   *
0016  *                                                                         *
0017  ***************************************************************************/
0018 
0019 #include "cglobalsettings.h"
0020 
0021 #include "cactionmanager.h"
0022 // cansiparser.h needed for color constants
0023 #include "cansiparser.h"
0024 #include "cpluginmanager.h"
0025 
0026 #include <kactioncollection.h>
0027 #include <kconfig.h>
0028 #include <kconfiggroup.h>
0029 #include <KSharedConfig>
0030 
0031 #include <QDir>
0032 #include <QFontDatabase>
0033 
0034 #include <map>
0035 
0036 using namespace std;
0037 
0038 struct cGlobalSettings::Private {
0039   map<QString, bool> boolValues;
0040   map<QString, int> intValues;
0041   map<QString, QString> stringValues;
0042   map<QString, QColor> colorValues;
0043   map<QString, QFont> fontValues;
0044   map<QString, bool> defaultBoolValues;
0045   map<QString, int> defaultIntValues;
0046   map<QString, QString> defaultStringValues;
0047   map<QString, QColor> defaultColorValues;
0048   map<QString, QFont> defaultFontValues;
0049   bool allowEvents, pendingNotify;
0050 };
0051 
0052 cGlobalSettings *cGlobalSettings::_self = nullptr;
0053 
0054 cGlobalSettings *cGlobalSettings::self()
0055 {
0056   if (_self == nullptr)
0057     _self = new cGlobalSettings;
0058   return _self;
0059 }
0060 
0061 cGlobalSettings::cGlobalSettings()
0062 {
0063   _self = this;
0064   d = new Private;
0065   d->allowEvents = true;
0066   d->pendingNotify = false;
0067   load ();
0068 }
0069 
0070 cGlobalSettings::~cGlobalSettings()
0071 {
0072   save ();
0073   delete d;
0074   _self = nullptr;
0075 }
0076 
0077 void cGlobalSettings::setBool (const QString &name, bool value)
0078 {
0079   d->boolValues[name] = value;
0080   notifyChange ();
0081 }
0082 
0083 void cGlobalSettings::setInt (const QString &name, int value)
0084 {
0085   d->intValues[name] = value;
0086   notifyChange ();
0087 }
0088 
0089 void cGlobalSettings::setString (const QString &name, const QString &value)
0090 {
0091   d->stringValues[name] = value;
0092   notifyChange ();
0093 }
0094 
0095 void cGlobalSettings::setColor (const QString &name, QColor value)
0096 {
0097   d->colorValues[name] = value;
0098   notifyChange ();
0099 }
0100 
0101 void cGlobalSettings::setFont (const QString &name, QFont value)
0102 {
0103   d->fontValues[name] = value;
0104   notifyChange ();
0105 }
0106 
0107 bool cGlobalSettings::getBool (const QString &name)
0108 {
0109   if (d->boolValues.count (name))
0110     return d->boolValues[name];
0111   if (d->defaultBoolValues.count (name))
0112     return d->defaultBoolValues[name];
0113   return false;
0114 }
0115 
0116 int cGlobalSettings::getInt (const QString &name)
0117 {
0118   if (d->intValues.count (name))
0119     return d->intValues[name];
0120   if (d->defaultIntValues.count (name))
0121     return d->defaultIntValues[name];
0122   return 0;
0123 }
0124 
0125 QString cGlobalSettings::getString (const QString &name)
0126 {
0127   if (d->stringValues.count (name))
0128     return d->stringValues[name];
0129   if (d->defaultStringValues.count (name))
0130     return d->defaultStringValues[name];
0131   return QString();
0132 }
0133 
0134 QColor cGlobalSettings::getColor (const QString &name)
0135 {
0136   if (d->colorValues.count (name))
0137     return d->colorValues[name];
0138   if (d->defaultColorValues.count (name))
0139     return d->defaultColorValues[name];
0140   return Qt::black;
0141 }
0142 
0143 QFont cGlobalSettings::getFont (const QString &name)
0144 {
0145   if (d->fontValues.count (name))
0146     return d->fontValues[name];
0147   if (d->defaultFontValues.count (name))
0148     return d->defaultFontValues[name];
0149   return QFontDatabase::systemFont (QFontDatabase::FixedFont);
0150 }
0151 
0152 void cGlobalSettings::setDefaultBool (const QString &name, bool val)
0153 {
0154   d->defaultBoolValues[name] = val;
0155 }
0156 
0157 void cGlobalSettings::setDefaultInt (const QString &name, int val)
0158 {
0159   d->defaultIntValues[name] = val;
0160 }
0161 
0162 void cGlobalSettings::setDefaultString (const QString &name, const QString &val)
0163 {
0164   d->defaultStringValues[name] = val;
0165 }
0166 
0167 void cGlobalSettings::setDefaultColor (const QString &name, const QColor &val)
0168 {
0169   d->defaultColorValues[name] = val;
0170 }
0171 
0172 void cGlobalSettings::setDefaultFont (const QString &name, const QFont &val)
0173 {
0174   d->defaultFontValues[name] = val;
0175 }
0176 
0177 // this contains default options for all global settings
0178 void cGlobalSettings::setDefaultOptions ()
0179 {
0180   // Default profile path
0181   setDefaultString ("profile-path", QDir::homePath() + "/.kmuddy");
0182 
0183   // Window
0184   setDefaultBool ("always-tab-bar", true);
0185   setDefaultBool ("aux-input", false);
0186   setDefaultBool ("always-notify", true);
0187   setDefaultBool ("local-notify", true);
0188   setDefaultBool ("global-notify", true);
0189   setDefaultBool ("systray-enabled", false);
0190   setDefaultBool ("passive-popup", false);
0191   setDefaultString ("auto-connect", QString());
0192 
0193   //Output area
0194   setDefaultInt ("fg-color", CL_WHITE);
0195   setDefaultInt ("bg-color", CL_BLACK);
0196   setDefaultInt ("echo-color", CL_YELLOW | CL_BRIGHT);
0197   setDefaultInt ("system-color", CL_CYAN | CL_BRIGHT);
0198   setDefaultBool ("allow-blink", true);
0199   setDefaultBool ("command-echo", true);
0200   setDefaultBool ("show-messages", true);
0201   setDefaultInt ("indent", 0);
0202   setDefaultInt ("history-size", 1000);
0203   setDefaultInt ("force-redraw", 10);
0204 
0205   //Fonts
0206   QFont f = QFontDatabase::systemFont (QFontDatabase::FixedFont);
0207   setDefaultFont ("console-font", f);
0208   setDefaultFont ("input-font", f);
0209   setDefaultFont ("multi-line-font", f);
0210 
0211   //Input line
0212   setDefaultBool ("keep-text", true);
0213   setDefaultBool ("select-kept", true);
0214   setDefaultBool ("cursors-browse", true);
0215   setDefaultBool ("auto-completion", false);
0216   setDefaultInt ("auto-completion-type", 0);
0217   setDefaultBool ("telnet-style-paste", false);
0218   setDefaultBool ("trim-spaces", false);
0219   setDefaultInt ("input-bg-color", CL_BLACK);
0220   setDefaultInt ("input-fg-color", CL_YELLOW | CL_BRIGHT);
0221   setDefaultBool ("swap-enters", false);
0222 
0223   //Colors
0224   setDefaultColor ("color-0", Qt::black);
0225   setDefaultColor ("color-1", Qt::darkRed);
0226   setDefaultColor ("color-2", Qt::darkGreen);
0227   setDefaultColor ("color-3", Qt::darkYellow);
0228   setDefaultColor ("color-4", Qt::darkBlue);
0229   setDefaultColor ("color-5", Qt::darkMagenta);
0230   setDefaultColor ("color-6", Qt::darkCyan);
0231   setDefaultColor ("color-7", Qt::lightGray);
0232   setDefaultColor ("color-8", Qt::darkGray);
0233   setDefaultColor ("color-9", Qt::red);
0234   setDefaultColor ("color-10", Qt::green);
0235   setDefaultColor ("color-11", Qt::yellow);
0236   setDefaultColor ("color-12", Qt::blue);
0237   setDefaultColor ("color-13", Qt::magenta);
0238   setDefaultColor ("color-14", Qt::cyan);
0239   setDefaultColor ("color-15", Qt::white);
0240 
0241   //Characters
0242   setDefaultString ("str-separator", ";");
0243   setDefaultString ("str-speedwalk", ".");
0244   setDefaultString ("str-macro", "/");
0245   setDefaultString ("str-multi", "#");
0246   setDefaultString ("str-focus", ":");
0247   setDefaultString ("str-noparse", "'");
0248 
0249   //MSP
0250   setDefaultInt ("smd-path-count", 0);
0251   setDefaultBool ("msp-allow", true);
0252   setDefaultBool ("msp-allow-downloads", false);
0253 }
0254 
0255 QString cGlobalSettings::profilePath ()
0256 {
0257   // by default, we store profiles in a .kmuddy directory in the homedir
0258   return getString ("profile-path");
0259 }
0260 
0261 void cGlobalSettings::setProfilePath (const QString &path)
0262 {
0263   setString ("profile-path", path);
0264 }
0265 
0266 void cGlobalSettings::load ()
0267 {
0268   // loads settings from kmuddyrc
0269   KSharedConfig::Ptr config = KSharedConfig::openConfig();
0270 
0271   //reparse config configuration - needed to make updating of settings
0272   //via IPC work
0273   config->reparseConfiguration ();
0274 
0275   setDefaultOptions ();
0276 
0277   if (!config->hasGroup ("Version Info")) {
0278     disableEvents ();
0279     // load old-style configuration instead
0280     loadOldConfig ();
0281     // old settings won't be deleted, so that previous KMuddy versions work
0282     enableEvents ();
0283     return;
0284   }
0285   // we have version info - this is a new-style config file
0286   KConfigGroup g = config->group ("Version Info");
0287   int version = g.readEntry ("Version", 0);
0288   if (version < 1) return;  // something is wrong - unable to read settings
0289 
0290   disableEvents ();
0291 
0292   QMap<QString, QString> entries;
0293   QMap<QString, QString>::iterator it;
0294   g = config->group ("Boolean values");
0295   entries = g.entryMap ();
0296   for (it = entries.begin(); it != entries.end(); ++it)
0297     setBool (it.key(), g.readEntry (it.key(), false));
0298   g = config->group ("Numeric values");
0299   entries = g.entryMap ();
0300   for (it = entries.begin(); it != entries.end(); ++it)
0301     setInt (it.key(), g.readEntry (it.key(), 0));
0302   g = config->group ("String values");
0303   entries = g.entryMap ();
0304   for (it = entries.begin(); it != entries.end(); ++it)
0305     setString (it.key(), g.readEntry (it.key(), QString()));
0306   g = config->group ("Color values");
0307   entries = g.entryMap ();
0308   for (it = entries.begin(); it != entries.end(); ++it)
0309     setColor (it.key(), g.readEntry (it.key(), getColor(it.key())));
0310   QFont f = QFontDatabase::systemFont (QFontDatabase::FixedFont);
0311   g = config->group ("Font values");
0312   entries = g.entryMap ();
0313   for (it = entries.begin(); it != entries.end(); ++it)
0314     setFont (it.key(), g.readEntry (it.key(), f));
0315 
0316   d->pendingNotify = false;  // we do not need to notify ...
0317   enableEvents ();
0318 
0319   // Plugins
0320   g = config->group ("Plugins");
0321   cPluginManager::self()->setConfigGroup(g);
0322 }
0323 
0324 // TODO: what to do with this ? KDE4 apps can't read old config, can they ?
0325 void cGlobalSettings::loadOldConfig ()
0326 {
0327   //Loads settings from kmuddyrc. Defaults are used if necessary.
0328   KSharedConfig::Ptr config = KSharedConfig::openConfig();
0329 
0330   //reparse config configuration - needed to make updating of settings
0331   //via IPC work
0332   config->reparseConfiguration ();
0333 
0334   //Window
0335   KConfigGroup g = config->group ("Window");
0336   setBool ("always-tab-bar", g.readEntry ("Always show tab bar", true));
0337   setBool ("aux-input", g.readEntry ("Auxiliary input", false));
0338   setBool ("global-notify", g.readEntry ("Global notification", true));
0339   setBool ("local-notify", g.readEntry ("Local notification", true));
0340   setBool ("always-notify", g.readEntry ("Always notify", true));
0341   setString ("auto-connect",  g.readEntry ("Auto connect", QString()));
0342   //all these are kept in Window group for historical reasons
0343   // (it used to be there in 0.3.1 and before :))
0344   setInt ("bg-color", g.readEntry ("Background color index", CL_BLACK));
0345   setInt ("fg-color", g.readEntry ("Foreground color index", CL_WHITE));
0346   setInt ("echo-color", g.readEntry ("Echo color index", CL_YELLOW | CL_BRIGHT));
0347   setInt ("system-color", g.readEntry ("System color index", CL_CYAN | CL_BRIGHT));
0348   setBool ("command-echo", g.readEntry ("Command echo", true));
0349   setBool ("lpmud-style", g.readEntry("LPMud style", false));
0350   setBool ("show-messages", g.readEntry ("Display messages", true));
0351   setBool ("allow-blink", g.readEntry ("Allow blinking", true));
0352   setInt ("indent", g.readEntry ("Indentation", 0));
0353   setInt ("history-size", g.readEntry ("History size", 1000));
0354   setInt ("force-redraw", g.readEntry ("Force redraw", 10));
0355   
0356   //Fonts
0357   g = config->group ("Fonts");
0358   QFont f = QFontDatabase::systemFont (QFontDatabase::FixedFont);
0359   setFont ("console-font", g.readEntry ("Console font", f));
0360   setFont ("input-font", g.readEntry ("Input line font", f));
0361   setFont ("multi-line-font", g.readEntry ("Multi-line input font", f));
0362 
0363   //Input line
0364   g = config->group ("Input line");
0365   setBool ("keep-text", g.readEntry ("Keep text", true));
0366   setBool ("select-kept", g.readEntry ("Select kept text", true));
0367   setBool ("cursors-browse", g.readEntry ("Cursor keys browse history", true));
0368   setBool ("auto-completion", g.readEntry ("Use auto-completion", false));
0369   setInt ("auto-completion-type", g.readEntry ("Auto-completion type", 0));
0370   setBool ("telnet-style-paste", g.readEntry ("Telnet-style paste", false));
0371   setBool ("trim-spaces", g.readEntry ("Trim spaces", false));
0372   setInt ("input-bg-color", g.readEntry ("Background color", CL_BLACK));
0373   setInt ("input-fg-color", g.readEntry ("Text color", CL_YELLOW | CL_BRIGHT));
0374   setBool ("swap-enters", g.readEntry ("Swap ENTERs", false));
0375 
0376   g = config->group ("Colors");
0377   setColor ("color-0", g.readEntry ("Black", (QColor) Qt::black));
0378   setColor ("color-1", g.readEntry ("Red", (QColor) Qt::darkRed));
0379   setColor ("color-2", g.readEntry ("Green", (QColor) Qt::darkGreen));
0380   setColor ("color-3", g.readEntry ("Yellow", (QColor) Qt::darkYellow));
0381   setColor ("color-4", g.readEntry ("Blue", (QColor) Qt::darkBlue));
0382   setColor ("color-5", g.readEntry ("Magenta", (QColor) Qt::darkMagenta));
0383   setColor ("color-6", g.readEntry ("Cyan", (QColor) Qt::darkCyan));
0384   setColor ("color-7", g.readEntry ("Gray", (QColor) Qt::lightGray));
0385   setColor ("color-8", g.readEntry ("Dark gray", (QColor) Qt::darkGray));
0386   setColor ("color-9", g.readEntry ("Bright red", (QColor) Qt::red));
0387   setColor ("color-10", g.readEntry ("Bright green", (QColor) Qt::green));
0388   setColor ("color-11", g.readEntry ("Bright yellow", (QColor) Qt::yellow));
0389   setColor ("color-12", g.readEntry ("Bright blue", (QColor) Qt::blue));
0390   setColor ("color-13", g.readEntry ("Bright magenta", (QColor) Qt::magenta));
0391   setColor ("color-14", g.readEntry ("Bright cyan", (QColor) Qt::cyan));
0392   setColor ("color-15", g.readEntry ("White", (QColor) Qt::white));
0393 
0394   //Characters (these are no longer characters, name wasn't changed
0395   //to make upgrading easier)
0396   g = config->group ("Characters");
0397   setString ("str-separator", g.readEntry ("Command separator", ";"));
0398   setString ("str-speedwalk", g.readEntry ("Speed walking", "."));
0399   setString ("str-macro", g.readEntry ("Macro character", "/"));
0400   setString ("str-multi", g.readEntry ("Multi-command", "#"));
0401   setString ("str-focus", g.readEntry ("Focus command", ":"));
0402   setString ("str-noparse", g.readEntry ("No-parse prefix", "'"));
0403   setBool ("empty-walk", g.readEntry ("Empty walkstring", false));
0404   setBool ("expand-backslashes", g.readEntry ("Expand backslashes", true));
0405 
0406   //MSP
0407   g = config->group ("Sound Protocol");
0408   setBool ("msp-allow", g.readEntry ("Allow MSP", true));
0409   setBool ("msp-allow-downloads", g.readEntry ("Allow downloads", false));
0410   int count = g.readEntry ("Path count", -1);
0411   if (count == -1)
0412   {
0413     // count = 1;
0414     // sounddirs << "/usr/share/sounds";
0415     setInt ("snd-path-count", 0);
0416   }
0417   else
0418   {
0419     setInt ("snd-path-count", count);
0420     for (int i = 1; i <= count; i++)
0421       setString ("snd-path-"+QString::number(i), g.readEntry (QString("Path ") + QString::number(i),
0422             QString()));
0423   }
0424 }
0425 
0426 void cGlobalSettings::save ()
0427 {
0428   //Saves settings back to kmuddyrc.
0429   KSharedConfig::Ptr config = KSharedConfig::openConfig();
0430 
0431   config->deleteGroup ("Boolean values");
0432   KConfigGroup g = config->group ("Boolean values");
0433   map<QString, bool>::iterator it1;
0434   for (it1 = d->boolValues.begin(); it1 != d->boolValues.end(); ++it1)
0435     g.writeEntry (it1->first, it1->second);
0436   config->deleteGroup ("Numeric values");
0437   g = config->group ("Numeric values");
0438   map<QString, int>::iterator it2;
0439   for (it2 = d->intValues.begin(); it2 != d->intValues.end(); ++it2)
0440     g.writeEntry (it2->first, it2->second);
0441   config->deleteGroup ("String values");
0442   g = config->group ("String values");
0443   map<QString, QString>::iterator it3;
0444   for (it3 = d->stringValues.begin(); it3 != d->stringValues.end(); ++it3)
0445     g.writeEntry (it3->first, it3->second);
0446   config->deleteGroup ("Color values");
0447   g = config->group ("Color values");
0448   map<QString, QColor>::iterator it4;
0449   for (it4 = d->colorValues.begin(); it4 != d->colorValues.end(); ++it4)
0450     g.writeEntry (it4->first, it4->second);
0451   g = config->group ("Font values");
0452   map<QString, QFont>::iterator it5;
0453   for (it5 = d->fontValues.begin(); it5 != d->fontValues.end(); ++it5)
0454     g.writeEntry (it5->first, it5->second);
0455 
0456   g = config->group ("Version Info");
0457   g.writeEntry ("Version", 1);
0458 
0459   //Shortcuts
0460   KActionCollection *acol = cActionManager::self()->getACol ();
0461   acol->setConfigGroup ("Shortcuts");
0462   acol->writeSettings ();
0463 
0464   //Plugins save automatically
0465 
0466   config->sync ();
0467 }
0468 
0469 void cGlobalSettings::disableEvents ()
0470 {
0471   d->allowEvents = false;
0472 }
0473 
0474 void cGlobalSettings::enableEvents ()
0475 {
0476   d->allowEvents = true;
0477   if (d->pendingNotify)
0478     notifyChange ();
0479 }
0480 
0481 void cGlobalSettings::notifyChange ()
0482 {
0483   if (!d->allowEvents) {
0484     d->pendingNotify = true;
0485   } else {
0486     d->pendingNotify = false;
0487     cActionManager::self()->invokeEvent ("global-settings-changed", 0);
0488     save ();
0489   }
0490 }
0491