File indexing completed on 2023-12-03 07:53:38

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