File indexing completed on 2024-04-21 04:03:02

0001 //
0002 // C++ Implementation: converterplugin
0003 //
0004 // Description: Converter plugin.
0005 //
0006 /*
0007 Copyright 2008-2011 Tomas Mecir <kmuddy@kmuddy.com>
0008 
0009 This program is free software; you can redistribute it and/or
0010 modify it under the terms of the GNU General Public License as
0011 published by the Free Software Foundation; either version 2 of 
0012 the License, or (at your option) any later version.
0013 
0014 This program is distributed in the hope that it will be useful,
0015 but WITHOUT ANY WARRANTY; without even the implied warranty of
0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017 GNU General Public License for more details.
0018 
0019 You should have received a copy of the GNU General Public License
0020 along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #include "converterplugin.h"
0024 
0025 #include "converterdialog.h"
0026 
0027 #include "cactionmanager.h"
0028 #include "cmacromanager.h"
0029 #include "cmenumanager.h"
0030 #include "cprofilemanager.h"
0031 #include "cprofilesettings.h"
0032 
0033 #include "cgenericlist.h"
0034 #include "cgenericitem.h"
0035 
0036 #include "csaveablelist.h"
0037 #include "caction.h"
0038 #include "calias.h"
0039 #include "cconnprefs.h"
0040 #include "cgauge.h"
0041 #include "cscript.h"
0042 #include "cshortcut.h"
0043 #include "cstatusvar.h"
0044 #include "ctimer.h"
0045 #include "ctrigger.h"
0046 #include "cvariable.h"
0047 #include "cvartrigger.h"
0048 
0049 #include <QAction>
0050 #include <QDir>
0051 #include <QFile>
0052 #include <QXmlStreamWriter>
0053 
0054 #include <KLocalizedString>
0055 #include <kmessagebox.h>
0056 #include <kpluginfactory.h>
0057 #include <kpluginloader.h>
0058 
0059 K_PLUGIN_CLASS_WITH_JSON(cConverterPlugin, "converterplugin.json")
0060 
0061 
0062 // the main plug-in code which registers the functions:
0063 
0064 struct cConverterPluginPrivate {
0065   QAction *converter;
0066 };
0067 
0068 cConverterPlugin::cConverterPlugin (QObject *, const QVariantList &)
0069 {
0070   d = new cConverterPluginPrivate;
0071 
0072   d->converter = new QAction (this);
0073   d->converter->setText (i18n ("Profile &Converter..."));
0074   connect (d->converter, &QAction::triggered, this, &cConverterPlugin::converterDialog);
0075  
0076   cMenuManager *menu = cMenuManager::self();
0077   menu->plug (d->converter, "tools-slot3");
0078 } 
0079 
0080 cConverterPlugin::~cConverterPlugin()
0081 {
0082   cMenuManager *menu = cMenuManager::self();
0083   menu->unplug (d->converter);
0084   delete d;
0085 }
0086 
0087 void cConverterPlugin::converterDialog ()
0088 {
0089   // create the dialog
0090   // TODO: use the main window as a parent
0091   cConverterDialog *dlg = new cConverterDialog (cActionManager::self()->mainWidget());
0092 
0093   // search for profiles and fill in profile info
0094   std::list<ConversionDialogItem *> items;
0095   QStringList paths;
0096   paths << (QDir::homePath() + "/.kde/share/apps/kmuddy/profiles");
0097   paths << (QDir::homePath() + "/.kde3/share/apps/kmuddy/profiles");
0098   paths << (QDir::homePath() + "/.kde4/share/apps/kmuddy/profiles");
0099   QStringList::iterator pathit;
0100   for (pathit = paths.begin(); pathit != paths.end(); ++pathit) {
0101     QDir dir (*pathit);
0102     dir.setFilter (QDir::Dirs | QDir::NoDotAndDotDot);
0103     QFileInfoList list = dir.entryInfoList();
0104     for (int i = 0; i < list.size(); ++i) {
0105       ConversionDialogItem *item = new ConversionDialogItem;
0106       item->convert = false;
0107       item->name = list.at(i).fileName();
0108       item->path = dir.absolutePath() + "/" + item->name;
0109       items.push_back (item);
0110     }
0111   }
0112 
0113   // display it
0114   bool res = dlg->display (items);
0115 
0116   // TODO: display some progress dialog or something ... KProgressDialog likely
0117 
0118   int count = 0;
0119   if (res) {
0120     // we want to do the conversion
0121     std::list<ConversionDialogItem *>::iterator it;
0122     for (it = items.begin(); it != items.end(); ++it) {
0123       ConversionDialogItem *item = *it;
0124       if (!item->convert) continue;
0125       convertProfile (item->path, item->name);
0126       ++count;
0127     }
0128     if (count)
0129       KMessageBox::information (nullptr, i18n ("The profiles have been successfully converted."));
0130     else
0131       KMessageBox::error (nullptr, i18n ("You did not specify any profiles to convert."));
0132   }
0133 
0134   // delete the profile info
0135   std::list<ConversionDialogItem *>::iterator it;
0136   for (it = items.begin(); it != items.end(); ++it)
0137     delete *it;
0138 
0139   delete dlg;
0140 }
0141 
0142 void cConverterPlugin::convertProfile (const QString &path, const QString &name)
0143 {
0144   // TODO: what to do with the output windows ? They're not converted currently
0145   
0146   // load all the data
0147   cConnPrefs *cp = new cConnPrefs (path);
0148   cp->load ();
0149   cSaveableList *aliases = new cSaveableList (path + "/aliases", "Alias", new cAlias(0));
0150   cSaveableList *triggers = new cSaveableList (path + "/triggers", "Trigger", new cTrigger(0));
0151   cSaveableList *actions = new cSaveableList (path + "/actions", "Action", new cAction(0));
0152   cSaveableList *gauges = new cSaveableList (path + "/gauges", "Gauge", new cGauge(0));
0153   cSaveableList *scripts = new cSaveableList (path + "/scripts", "Script", new cScript(0));
0154   cSaveableList *shortcuts = new cSaveableList (path + "/macrokeys", "Macro key", new cShortcut(0));
0155   cSaveableList *statusvars = new cSaveableList (path + "/statusvars", "Status-var", new cStatusVar(0));
0156   cSaveableList *timers = new cSaveableList (path + "/timers", "Timer", new cTimer(0));
0157   cSaveableList *variables = new cSaveableList (path + "/variables", "Variable", new cVariable());
0158   cSaveableList *vartrigs = new cSaveableList (path + "/vartriggers", "Variable trigger", new cVarTrigger(0));
0159 
0160   // create the profile
0161   cProfileManager *pm = cProfileManager::self();
0162   QString profile = pm->newProfile (name);
0163   QString profilePath = pm->profilePath (profile);
0164   cProfileSettings *sett = pm->settings (profile);
0165 
0166   // fill in settings
0167   sett->setString ("server", cp->server());
0168   sett->setInt ("port", cp->port());
0169   sett->setString ("login", cp->login());
0170   sett->setString ("password", cp->password());
0171   QStringList con = cp->connStr();
0172   sett->setInt ("on-connect-count", con.size());
0173   for (int i = 0; i < con.size(); ++i)
0174     sett->setString ("on-connect-"+QString::number(i), con[i]);
0175 
0176   sett->setBool ("use-ansi", cp->ansiColors ());
0177   sett->setBool ("limit-repeater", cp->limitRepeater ());
0178   sett->setBool ("startup-negotiate", cp->negotiateOnStartup ());
0179   sett->setBool ("lpmud-style", cp->LPMudStyle());
0180   sett->setBool ("prompt-label", cp->promptLabel());
0181   sett->setBool ("prompt-status", cp->statusPrompt());
0182   sett->setBool ("prompt-console", cp->consolePrompt());
0183   sett->setBool ("auto-adv-transcript", cp->autoAdvTranscript());
0184 
0185   for (int i = 0; i < 10; i++)
0186     sett->setString ("movement-command-"+QString::number(i), cp->cmd (i));
0187   sett->setString ("script-directory", cp->scriptDir ());
0188   sett->setString ("script-working-directory", cp->workDir ());
0189   sett->setString ("transcript-directory", cp->transcriptDir ());
0190 
0191   QStringList sdirs = cp->soundDirs();
0192   sett->setInt ("sound-dir-count", sdirs.size());
0193   int idx = 0;
0194   QStringList::iterator it;
0195   for (it = sdirs.begin(); it != sdirs.end(); ++it)
0196     sett->setString ("sound-dir-" + QString::number (++idx), *it);
0197   sett->setBool ("use-msp", cp->useMSP());
0198   sett->setBool ("always-msp", cp->alwaysMSP());
0199   sett->setBool ("midline-msp", cp->midlineMSP());
0200 
0201   sett->setBool ("use-mxp", cp->useMXP());
0202   sett->setString ("mxp-variable-prefix", cp->varPrefix ());
0203 
0204   sett->save ();
0205 
0206   // fill in generic lists for that profile and store them
0207   cGenericList *list;
0208 
0209   // aliases
0210   list = new cGenericList;
0211   list->init ();
0212   list->intProperty ("matching", (int) cPattern::begin);
0213   list->boolProperty ("cs", true);
0214   list->boolProperty ("prefix-suffix", true);
0215   list->boolProperty ("whole-words", true);
0216  
0217   for (aliases->reset(); *aliases; (*aliases)++) {
0218     cAlias *alias = (cAlias *) **aliases;
0219     cListObject *obj = list->newObject();
0220     list->addToGroup (list->rootGroup(), obj);
0221     obj->setStr ("pattern", alias->getText());
0222     obj->setInt ("matching", alias->getType());
0223     obj->setStr ("condition", alias->cond());
0224 
0225     QStringList ntext = alias->getNewText();
0226     obj->setInt ("newtext-count", ntext.size());
0227     QStringList::iterator it; int i;
0228     for (i = 1, it = ntext.begin(); it != ntext.end(); ++i, ++it)
0229       obj->setStr ("newtext-" + QString::number (i), *it);
0230 
0231     // Options
0232     obj->setBool ("orig", alias->sendOriginal());
0233     obj->setBool ("whole-words", alias->wholeWords());
0234     obj->setBool ("cs", alias->caseSensitive());
0235     obj->setBool ("prefix-suffix", alias->includePrefixSuffix());
0236     obj->setBool ("global", alias->global());
0237   }
0238   list->saveList (profilePath + "/aliases.xml");
0239   delete list;
0240 
0241   // triggers
0242   list = new cGenericList;
0243   list->init ();
0244   list->intProperty ("matching", (int) cPattern::substring);
0245   list->boolProperty ("cs", true);
0246   list->boolProperty ("prefix-suffix", true);
0247   list->boolProperty ("whole-words", true);
0248   list->intProperty ("action-matched", (int) cList::Stop);
0249   list->intProperty ("action-not-matched", (int) cList::Continue);
0250  
0251   for (triggers->reset(); *triggers; (*triggers)++) {
0252     cTrigger *trigger = (cTrigger *) **triggers;
0253     cListObject *obj = list->newObject();
0254     list->addToGroup (list->rootGroup(), obj);
0255     obj->setStr ("pattern", trigger->getText());
0256     obj->setInt ("matching", trigger->getType());
0257     obj->setStr ("condition", trigger->cond());
0258 
0259     QStringList ntext = trigger->getNewText();
0260     obj->setInt ("newtext-count", ntext.size());
0261     QStringList::iterator it; int i;
0262     for (i = 1, it = ntext.begin(); it != ntext.end(); ++i, ++it)
0263       obj->setStr ("newtext-" + QString::number (i), *it);
0264 
0265     // Options
0266     obj->setBool ("dont-send", trigger->dontSend());
0267     obj->setBool ("cs", trigger->caseSensitive());
0268     obj->setBool ("global", trigger->global());
0269     obj->setInt ("action-matched", int (trigger->continueIfMatch() ? cList::Continue : cList::Stop));
0270     obj->setInt ("action-not-matched", int (trigger->continueIfNoMatch() ? cList::Continue : cList::Stop));
0271 
0272     // Colors
0273     obj->setBool ("colorize", trigger->isColorTrigger());
0274     if (trigger->isColorTrigger()) {
0275       obj->setInt ("colorize-count", trigger->getColorizationsCount());
0276       for (int i = 0; i < trigger->getColorizationsCount(); i++) {
0277         int fg = trigger->getColorizationColor(i) % 256;
0278         QColor fgc = trigger->getColorizationFg(i);
0279         if (fg == 16) {  // RGB
0280           fg = fgc.red() * 256 * 256 + fgc.green() * 256 + fgc.blue()+ 1;
0281         } else if (fg == 255)
0282           fg = 0;
0283         else
0284           fg -= 16;
0285         int bg = trigger->getColorizationColor(i) / 256;
0286         QColor bgc = trigger->getColorizationBg(i);
0287         if (bg == 16) {  // RGB
0288           bg = bgc.red() * 256 * 256 + bgc.green() * 256 + bgc.blue()+ 1;
0289         } else if (bg == 255) 
0290           bg = 0;
0291         else
0292           bg -= 16;
0293         obj->setInt ("colorize-fg-"+QString::number(i+1), fg);
0294         obj->setInt ("colorize-bg-"+QString::number(i+1), bg);
0295         obj->setStr ("colorize-variable-"+QString::number(i+1), trigger->getColorizationVariable (i));
0296       }
0297     }
0298 
0299     // Rewrite
0300     obj->setBool ("rewrite", trigger->isRewriteTrigger());
0301     obj->setStr ("rewrite-text", trigger->rewriteText());
0302     obj->setStr ("rewrite-var", trigger->rewriteVar());
0303 
0304     // Special
0305     obj->setBool ("gag", trigger->isGagTrigger());
0306     obj->setBool ("notify", trigger->isNotifyTrigger());
0307     obj->setBool ("prompt", trigger->isPromptDetectTrigger());
0308     obj->setBool ("sound", trigger->isSoundTrigger());
0309     obj->setStr ("sound-file", trigger->soundFileName());
0310  
0311     obj->setBool ("output-window", trigger->isOutputWindowTrigger());
0312     obj->setBool ("output-gag-in-main", trigger->isGagOutputWindow());
0313     obj->setStr ("output-window-name", trigger->getOutputWindowName());
0314   }
0315   list->saveList (profilePath + "/triggers.xml");
0316   delete list;
0317 
0318   // actions
0319   list = new cGenericList;
0320   list->init ();
0321  
0322   for (actions->reset(); *actions; (*actions)++) {
0323     cAction *action = (cAction *) **actions;
0324     cListObject *obj = list->newObject();
0325     list->addToGroup (list->rootGroup(), obj);
0326 
0327     obj->setStr ("command", action->getCommand());
0328     obj->setStr ("command-released", action->getCommand2());
0329     obj->setStr ("caption", action->getCaption());
0330     obj->setStr ("icon", action->getIconName());
0331     obj->setBool ("pushdown", action->isPushDown());
0332   }
0333   list->saveList (profilePath + "/buttons.xml");
0334   delete list;
0335 
0336   // gauges
0337   list = new cGenericList;
0338   list->init ();
0339  
0340   for (gauges->reset(); *gauges; (*gauges)++) {
0341     cGauge *gauge = (cGauge *) **gauges;
0342     cListObject *obj = list->newObject();
0343     list->addToGroup (list->rootGroup(), obj);
0344 
0345     obj->setStr ("variable", gauge->variable());
0346     obj->setStr ("max-variable", gauge->maxVariable());
0347     obj->setStr ("caption", gauge->caption());
0348     QColor c = gauge->color();
0349     obj->setInt ("color", c.red() * 256 * 256 + c.green() * 256 + c.blue());
0350     if (gauge->hidden()) obj->setEnabled (false);
0351   }
0352   list->saveList (profilePath + "/gauges.xml");
0353   delete list;
0354 
0355   // shortcuts
0356   list = new cGenericList;
0357   list->init ();
0358   list->boolProperty ("send", true);
0359  
0360   for (shortcuts->reset(); *shortcuts; (*shortcuts)++) {
0361     cShortcut *shortcut = (cShortcut *) **shortcuts;
0362     cListObject *obj = list->newObject();
0363     list->addToGroup (list->rootGroup(), obj);
0364 
0365     obj->setStr ("command", shortcut->getText());
0366     int key = shortcut->key();
0367     int state = shortcut->state();
0368     // convert from Qt3 key codes to Qt4
0369     if (key > 0xff) {
0370       if (key & 0x1000 && (key % 0x1000 <= 0xff))
0371         key -= 0x1000;
0372       key |= 0x1000000;
0373     }
0374    int modifiers = 0;
0375     if (state & 0x0100)  // Shift
0376       modifiers |= Qt::ShiftModifier;
0377     if (state & 0x0200)  // Ctrl
0378       modifiers |= Qt::ControlModifier;
0379     if (state & 0x0400)  // Alt
0380       modifiers |= Qt::AltModifier;
0381     if (state & 0x0800)  // Meta
0382       modifiers |= Qt::MetaModifier;
0383     if (state & 0x4000)  // Keypad
0384       modifiers |= Qt::KeypadModifier;
0385     obj->setInt ("key", key);
0386     obj->setInt ("modifiers", modifiers);
0387     obj->setBool ("send", shortcut->sendIt());
0388     obj->setBool ("overwrite", shortcut->overwriteInput());
0389   }
0390   list->saveList (profilePath + "/macrokeys.xml");
0391   delete list;
0392 
0393  
0394   // status variables
0395   list = new cGenericList;
0396   list->init ();
0397  
0398   for (statusvars->reset(); *statusvars; (*statusvars)++) {
0399     cStatusVar *statusvar = (cStatusVar *) **statusvars;
0400     cListObject *obj = list->newObject();
0401     list->addToGroup (list->rootGroup(), obj);
0402 
0403     obj->setStr ("variable", statusvar->variable());
0404     obj->setStr ("max-variable", statusvar->maxVariable());
0405     obj->setStr ("caption", statusvar->caption());
0406     obj->setBool ("percentage", statusvar->percentage());
0407     if (statusvar->hidden()) obj->setEnabled (false);
0408   }
0409   list->saveList (profilePath + "/statusvars.xml");
0410   delete list;
0411  
0412   // timers
0413   list = new cGenericList;
0414   list->init ();
0415   list->intProperty ("interval", 60);
0416  
0417   for (timers->reset(); *timers; (*timers)++) {
0418     cTimer *timer = (cTimer *) **timers;
0419     cListObject *obj = list->newObject();
0420     list->addToGroup (list->rootGroup(), obj);
0421 
0422     obj->setStr ("command", timer->command());
0423     obj->setInt ("interval", timer->interval());
0424     obj->setBool ("single-shot", timer->singleShot());
0425     if (!timer->active()) obj->setEnabled (false);
0426   }
0427   list->saveList (profilePath + "/timers.xml");
0428   delete list;
0429 
0430   // variable triggers
0431   list = new cGenericList;
0432   list->init ();
0433  
0434   for (vartrigs->reset(); *vartrigs; (*vartrigs)++) {
0435     cVarTrigger *vartrigger = (cVarTrigger *) **vartrigs;
0436     cListObject *obj = list->newObject();
0437     list->addToGroup (list->rootGroup(), obj);
0438 
0439     obj->setStr ("variable", vartrigger->varName());
0440     QStringList ntext = vartrigger->getNewText();
0441     obj->setInt ("command-count", ntext.size());
0442     QStringList::iterator it; int i;
0443     for (i = 1, it = ntext.begin(); it != ntext.end(); ++i, ++it)
0444       obj->setStr ("command-" + QString::number (i), *it);
0445   }
0446   list->saveList (profilePath + "/vartriggers.xml");
0447   delete list;
0448 
0449   // scripts
0450   list = new cGenericList;
0451   list->init ();
0452   list->boolProperty ("flow-control", true);
0453  
0454   for (scripts->reset(); *scripts; (*scripts)++) {
0455     cScript *script = (cScript *) **scripts;
0456     cListObject *obj = list->newObject();
0457     list->addToGroup (list->rootGroup(), obj);
0458 
0459     list->setObjectName (obj, script->getName());
0460     obj->setStr ("command", script->getCommand());
0461     obj->setStr ("work-directory", script->getWorkDir());
0462     obj->setBool ("send-user-commands", script->getSendUserCommands());
0463     obj->setBool ("adv-comunication", script->getUseAdvComm());
0464     obj->setBool ("flow-control", !script->getNoFlowControl());
0465     obj->setBool ("enable-variables", script->getAllowVars());
0466     obj->setBool ("single-instance", script->getSingleInstance());
0467   }
0468   list->saveList (profilePath + "/scripts.xml");
0469   delete list;
0470 
0471  
0472   // variables - these are saved differently
0473   QFile f (profilePath + "/variables.xml");
0474   if (f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
0475     QXmlStreamWriter *writer = new QXmlStreamWriter (&f);
0476     writer->setAutoFormatting (true);  // make the generated XML more readable
0477     writer->writeStartDocument ();
0478 
0479     writer->writeStartElement ("variables");
0480     writer->writeAttribute ("version", "1.0");
0481 
0482     for (variables->reset(); *variables; (*variables)++) {
0483       cVariable *variable = (cVariable *) **variables;
0484       variable->getValue()->save (writer, variable->name());
0485     }
0486 
0487     writer->writeEndElement ();
0488     writer->writeEndDocument ();
0489 
0490     f.close ();
0491     delete writer;
0492   } 
0493  
0494   // clean up
0495   delete cp;
0496   delete aliases;
0497   delete gauges;
0498   delete shortcuts;
0499   delete statusvars;
0500   delete timers;
0501   delete triggers;
0502   delete variables;
0503   delete vartrigs;
0504 }
0505 
0506 #include "converterplugin.moc"
0507 #include "moc_converterplugin.cpp"