File indexing completed on 2024-03-24 15:43:31
0001 // 0002 // C++ Implementation: ctriggereditor 0003 // 0004 // Description: 0005 // 0006 /* 0007 Copyright 2002-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 "ctriggereditor.h" 0024 0025 #include "cactionmanager.h" 0026 #include "cpattern.h" 0027 #include "cscripteditor.h" 0028 #include "cwindowlist.h" 0029 0030 #include <QCheckBox> 0031 #include <QComboBox> 0032 #include <QDialog> 0033 #include <QFileDialog> 0034 #include <QGroupBox> 0035 #include <QLabel> 0036 #include <QGridLayout> 0037 #include <QHBoxLayout> 0038 #include <QLineEdit> 0039 #include <QPushButton> 0040 #include <QSpinBox> 0041 #include <QSplitter> 0042 #include <QTabWidget> 0043 #include <QTreeWidget> 0044 #include <QVBoxLayout> 0045 0046 #include <kcolorbutton.h> 0047 #include <KLocalizedString> 0048 #include <kmessagebox.h> 0049 #include <ktextedit.h> 0050 0051 struct cTriggerEditor::Private { 0052 // Basic 0053 QLineEdit *cmd; 0054 QComboBox *type; 0055 QLineEdit *condition; 0056 KTextEdit *rcmd; 0057 QPushButton *editregexp; 0058 0059 // Basic - testarea 0060 QLineEdit *text; 0061 QLabel *matched, *replacement; 0062 QTreeWidget *variables; 0063 0064 // Script 0065 cScriptEditor *script; 0066 0067 // Options 0068 QCheckBox *check1, *check2, *check3, *check4; 0069 QComboBox *actMatched, *actNotMatched; 0070 0071 // Colors 0072 QCheckBox *chkiscolor; 0073 QComboBox *clrtype, *fgselect, *bgselect; 0074 KColorButton *fgcolsel, *bgcolsel; 0075 QSpinBox *backrefno; 0076 QTreeWidget *colorizations; 0077 #define MAX_COLORIZATIONS 10 0078 int cnum; 0079 int fgcolor[MAX_COLORIZATIONS], bgcolor[MAX_COLORIZATIONS]; 0080 QColor fgc[MAX_COLORIZATIONS], bgc[MAX_COLORIZATIONS]; 0081 QString ctype[MAX_COLORIZATIONS]; 0082 0083 // Rewrite 0084 QCheckBox *chkrewrite; 0085 QComboBox *cbrewritevar; 0086 QSpinBox *rewritebackrefno; 0087 QLineEdit *edrewritetext; 0088 0089 // Special 0090 QCheckBox *chkgag, *chknotify, *chkprompt; 0091 QCheckBox *chksound; 0092 QLineEdit *edsoundname; 0093 0094 // Windows 0095 QCheckBox *chkwindow; 0096 QComboBox *windowlist; 0097 QCheckBox *chkgagoutput; 0098 QLineEdit *wname; 0099 }; 0100 0101 //color list 0102 QString *cltextk; 0103 // type list 0104 QString *ltype; 0105 0106 cTriggerEditor::cTriggerEditor (QWidget *parent) 0107 : cListEditor (parent) 0108 { 0109 d = new Private; 0110 0111 if (!cltextk) { 0112 cltextk = new QString[18]; 0113 int i = 0; 0114 cltextk[i++] = i18n("Keep"); 0115 cltextk[i++] = i18n("Black"); 0116 cltextk[i++] = i18n("Red"); 0117 cltextk[i++] = i18n("Green"); 0118 cltextk[i++] = i18n("Yellow"); 0119 cltextk[i++] = i18n("Blue"); 0120 cltextk[i++] = i18n("Magenta"); 0121 cltextk[i++] = i18n("Cyan"); 0122 cltextk[i++] = i18n("Gray"); 0123 cltextk[i++] = i18n("Dark gray"); 0124 cltextk[i++] = i18n("Bright red"); 0125 cltextk[i++] = i18n("Bright green"); 0126 cltextk[i++] = i18n("Bright yellow"); 0127 cltextk[i++] = i18n("Bright blue"); 0128 cltextk[i++] = i18n("Bright magenta"); 0129 cltextk[i++] = i18n("Bright cyan"); 0130 cltextk[i++] = i18n("White"); 0131 cltextk[i++] = i18n("Other"); 0132 } 0133 if (!ltype) { 0134 ltype = new QString[7]; 0135 int i = 0; 0136 ltype[i++] = i18n("Whole line"); 0137 ltype[i++] = i18n("Matching text"); 0138 ltype[i++] = i18n("Prefix"); 0139 ltype[i++] = i18n("Suffix"); 0140 ltype[i++] = i18n("Full prefix"); 0141 ltype[i++] = i18n("Full suffix"); 0142 ltype[i++] = i18n ("Backreference"); 0143 } 0144 } 0145 0146 cTriggerEditor::~cTriggerEditor () 0147 { 0148 // the GUI elements will be destroyed automatically 0149 delete d; 0150 } 0151 0152 void cTriggerEditor::createGUI(QWidget *parent) 0153 { 0154 QVBoxLayout *mainLayout = new QVBoxLayout (parent); 0155 QTabWidget *tabs = new QTabWidget (parent); 0156 mainLayout->addWidget (tabs); 0157 0158 // the Basic tab 0159 QSplitter *basicTab = new QSplitter (tabs); 0160 basicTab->setOrientation (Qt::Vertical); 0161 QFrame *basicPage = new QFrame (basicTab); 0162 QGridLayout *basiclayout = new QGridLayout (basicPage); 0163 0164 // command 0165 QLabel *cl = new QLabel (i18n ("&Trigger text"), basicPage); 0166 d->cmd = new QLineEdit (basicPage); 0167 cl->setBuddy (d->cmd); 0168 d->cmd->setWhatsThis (i18n ("Command that will be replaced if you enter it.")); 0169 0170 //comparison type 0171 QWidget *hbComboEdit = new QWidget (basicPage); 0172 QHBoxLayout *comboEditLayout = new QHBoxLayout (hbComboEdit);; 0173 comboEditLayout->setSpacing(3); 0174 QLabel *ctl = new QLabel ("&Comparison type", basicPage); 0175 d->type = new QComboBox (hbComboEdit); 0176 ctl->setBuddy (d->type); 0177 d->type->clear (); 0178 d->type->addItem (i18n ("Exact match")); 0179 d->type->addItem (i18n ("Sub-string")); 0180 d->type->addItem (i18n ("Begins with")); 0181 d->type->addItem (i18n ("Ends with")); 0182 d->type->addItem (i18n ("Regular expression")); 0183 d->type->setWhatsThis( i18n ("Type of matching. Trigger will only be activated " 0184 "if this passes this type of test. Note that triggers are always matched as whole words.")); 0185 comboEditLayout->addWidget (d->type); 0186 0187 //condition 0188 QLabel *cndl = new QLabel ("Con&dition", basicPage); 0189 d->condition = new QLineEdit (basicPage); 0190 cndl->setBuddy (d->condition); 0191 d->condition->setWhatsThis( i18n ("Conditional triggering. If this is set, the actions " 0192 "will only fire if the condition is true (that means, if it evaluates as non-zero).")); 0193 0194 //replacement command(s) 0195 QLabel *rcl = new QLabel (i18n ("&Command(s) to send:"), basicPage); 0196 d->rcmd = new KTextEdit (basicPage); 0197 d->rcmd->setWordWrapMode (QTextOption::NoWrap); 0198 rcl->setBuddy (d->rcmd); 0199 d->rcmd->setWhatsThis( i18n ("Command(s) that will replace command you've entered.")); 0200 0201 //test area 0202 QGroupBox *testarea = new QGroupBox (i18n ("Test area"), basicTab); 0203 QGridLayout *testlayout = new QGridLayout (testarea); 0204 QLabel *textlabel = new QLabel (i18n ("&Text: "), testarea); 0205 d->text = new QLineEdit (testarea); 0206 textlabel->setBuddy (d->text); 0207 d->matched = new QLabel ("", testarea); 0208 d->replacement = new QLabel ("", testarea); 0209 d->variables = new QTreeWidget (testarea); 0210 d->variables->setHeaderLabels (QStringList() << i18n ("Name") << i18n ("Value")); 0211 d->variables->setAllColumnsShowFocus (true); 0212 d->variables->setUniformRowHeights (true); 0213 d->variables->setRootIsDecorated (false); 0214 testarea->setWhatsThis( i18n("This is testing area. You can test your trigger " 0215 "here to see if it does what you want it to do. Simply " 0216 "type in some text and see what happens.")); 0217 testlayout->setSpacing (5); 0218 testlayout->addWidget (textlabel, 0, 0); 0219 testlayout->addWidget (d->text, 0, 1); 0220 testlayout->addWidget (d->matched, 1, 0, 1, 2); 0221 testlayout->addWidget (d->replacement, 2, 0, 1, 2); 0222 testlayout->addWidget (d->variables, 3, 0, 1, 2); 0223 0224 basiclayout->setSpacing (5); 0225 basiclayout->addWidget (cl, 0, 0); 0226 basiclayout->addWidget (d->cmd, 0, 1); 0227 basiclayout->addWidget (ctl, 1, 0); 0228 basiclayout->addWidget (hbComboEdit, 1, 1); 0229 basiclayout->addWidget (cndl, 2, 0); 0230 basiclayout->addWidget (d->condition, 2, 1); 0231 basiclayout->addWidget (rcl, 3, 0); 0232 basiclayout->addWidget (d->rcmd, 4, 0, 1, 2); 0233 basiclayout->setRowStretch (4, 10); 0234 0235 basicTab->addWidget (basicPage); 0236 basicTab->addWidget (testarea); 0237 0238 // the Script tab 0239 QFrame *scriptPage = new QFrame (tabs); 0240 QVBoxLayout *scriptlayout = new QVBoxLayout (scriptPage); 0241 d->script = new cScriptEditor (scriptPage); 0242 scriptlayout->addWidget (d->script); 0243 0244 // the Options tab 0245 QFrame *optionsPage = new QFrame (tabs); 0246 QVBoxLayout *optionslayout = new QVBoxLayout (optionsPage); 0247 0248 QGroupBox *options = new QGroupBox (i18n ("&Options"), optionsPage); 0249 QGridLayout *optionsBoxLayout = new QGridLayout (options); 0250 0251 d->check1 = new QCheckBox (i18n ("Whole words only"), options); 0252 d->check1->setWhatsThis( i18n("When enabled, this trigger will only match " 0253 "the text if there are spaces or nothing before/after the matched string.")); 0254 0255 d->check2 = new QCheckBox (i18n ("Case sensitive"), options); 0256 d->check2->setWhatsThis( i18n ("When this option is on, upper case and " 0257 "lower case letters are treated as different characters, otherwise " 0258 "they're considered to be the same.")); 0259 0260 d->check3 = new QCheckBox (i18n ("Show but do not send"), options); 0261 d->check3->setWhatsThis (i18n ("When enabled, the text will not be sent to the MUD, it will only be " 0262 "displayed on the screen.")); 0263 0264 d->check4 = new QCheckBox (i18n ("Global matching"), options); 0265 d->check4->setWhatsThis( i18n ("<p>With global matching, one trigger/trigger can match multiple " 0266 "times, if it contains the pattern more than once. For example, if pattern is abc, " 0267 "it matches only once on abcdabcd of global matching is off, but twice if it's on. " 0268 "For each match, the requested actions are performed - so the commands can be sent " 0269 "multiple times, once per match.</p>" 0270 "<p>Note that failing the condition does not terminate scanning, so you can use " 0271 "this to highlight names from a list (using the condition to check if a match is in the " 0272 "list), or something like that.")); 0273 0274 optionsBoxLayout->addWidget (d->check1, 0, 0); 0275 optionsBoxLayout->addWidget (d->check2, 0, 1); 0276 optionsBoxLayout->addWidget (d->check3, 1, 0); 0277 optionsBoxLayout->addWidget (d->check4, 1, 1); 0278 0279 QWidget *commonEditor = createCommonAttribEditor (optionsPage); 0280 0281 QWidget *matcheds = new QWidget (optionsPage); 0282 QGridLayout *matchedslayout = new QGridLayout (matcheds); 0283 0284 QLabel *m1l = new QLabel ("Action if &matched", matcheds); 0285 d->actMatched = new QComboBox (matcheds); 0286 m1l->setBuddy (d->actMatched); 0287 d->actMatched->addItem (i18n ("Continue matching")); 0288 d->actMatched->addItem (i18n ("Stop matching")); 0289 d->actMatched->addItem (i18n ("Leave group")); 0290 0291 QLabel *m2l = new QLabel ("Action if ¬ matched", matcheds); 0292 d->actNotMatched = new QComboBox (matcheds); 0293 m2l->setBuddy (d->actMatched); 0294 d->actNotMatched->addItem (i18n ("Continue matching")); 0295 d->actNotMatched->addItem (i18n ("Stop matching")); 0296 d->actNotMatched->addItem (i18n ("Leave group")); 0297 0298 matchedslayout->setSpacing (10); 0299 matchedslayout->addWidget (m1l, 0, 0); 0300 matchedslayout->addWidget (d->actMatched, 0, 1); 0301 matchedslayout->addWidget (m2l, 1, 0); 0302 matchedslayout->addWidget (d->actNotMatched, 1, 1); 0303 matchedslayout->setColumnStretch (1, 1); 0304 0305 optionslayout->setSpacing (10); 0306 optionslayout->addWidget (options); 0307 optionslayout->addWidget (matcheds); 0308 optionslayout->addWidget (commonEditor); 0309 0310 // the Color replacement tab 0311 // TODO: this page is very user unfriendly, improve it !!! 0312 QFrame *colorPage = new QFrame (tabs); 0313 QVBoxLayout *colorlayout = new QVBoxLayout (colorPage); 0314 0315 d->chkiscolor = new QCheckBox (i18n ("&Enable color replacement"), colorPage); 0316 QGroupBox *colorgroup = new QGroupBox (i18n ("Color replacement"), colorPage); 0317 QVBoxLayout *colorgroupLayout = new QVBoxLayout (colorgroup); 0318 0319 QStringList types; 0320 for (int i = 0; i < 7; i++) 0321 types.append (ltype[i]); 0322 QStringList colorlist; 0323 for (int i = 0; i < 18; i++) 0324 colorlist.append (cltextk[i]); 0325 0326 QWidget *onecolor = new QWidget (colorgroup); 0327 QGridLayout *onecolorlayout = new QGridLayout (onecolor); 0328 onecolorlayout->setSpacing (10); 0329 d->clrtype = new QComboBox (onecolor); 0330 d->clrtype->addItems (types); 0331 d->fgselect = new QComboBox (onecolor); 0332 d->fgselect->addItems (colorlist); 0333 d->bgselect = new QComboBox (onecolor); 0334 d->bgselect->addItems (colorlist); 0335 d->fgcolsel = new KColorButton (Qt::white, onecolor); 0336 d->bgcolsel = new KColorButton (Qt::black, onecolor); 0337 d->backrefno = new QSpinBox (onecolor); 0338 d->backrefno->setRange (0, 100); 0339 QPushButton *btadd = new QPushButton (i18n ("&Add"), onecolor); 0340 QPushButton *btremove = new QPushButton (i18n ("&Remove"), onecolor); 0341 QLabel *l1 = new QLabel (i18n ("&Colorize"), onecolor); 0342 l1->setBuddy (d->clrtype); 0343 QLabel *l2 = new QLabel (i18n ("&Foreground"), onecolor); 0344 l2->setBuddy (d->fgselect); 0345 QLabel *l3 = new QLabel (i18n ("&Background"), onecolor); 0346 l3->setBuddy (d->bgselect); 0347 QLabel *l4 = new QLabel (i18n ("&Back-reference"), onecolor); 0348 l4->setBuddy (d->backrefno); 0349 0350 onecolorlayout->addWidget (l1, 0, 0); 0351 onecolorlayout->addWidget (l2, 0, 1); 0352 onecolorlayout->addWidget (l3, 0, 2); 0353 onecolorlayout->addWidget (d->clrtype, 1, 0); 0354 onecolorlayout->addWidget (d->fgselect, 1, 1); 0355 onecolorlayout->addWidget (d->bgselect, 1, 2); 0356 onecolorlayout->addWidget (d->fgcolsel, 2, 1); 0357 onecolorlayout->addWidget (d->bgcolsel, 2, 2); 0358 onecolorlayout->addWidget (l4, 3, 0); 0359 onecolorlayout->addWidget (d->backrefno, 4, 0); 0360 onecolorlayout->addWidget (btadd, 4, 1); 0361 onecolorlayout->addWidget (btremove, 4, 2); 0362 0363 d->colorizations = new QTreeWidget (colorgroup); 0364 d->colorizations->setHeaderLabels (QStringList() << i18n ("Type") << i18n ("Foreground") << i18n ("Background")); 0365 d->colorizations->setAllColumnsShowFocus (true); 0366 d->colorizations->setUniformRowHeights (true); 0367 d->colorizations->setRootIsDecorated (false); 0368 0369 colorgroupLayout->addWidget (onecolor); 0370 colorgroupLayout->addWidget (d->colorizations); 0371 0372 colorlayout->setSpacing (10); 0373 colorlayout->addWidget (d->chkiscolor); 0374 colorlayout->addWidget (colorgroup); 0375 0376 connect (d->chkiscolor, &QCheckBox::toggled, colorgroup, &QGroupBox::setEnabled); 0377 connect (btadd, &QPushButton::clicked, this, &cTriggerEditor::addColorization); 0378 connect (btremove, &QPushButton::clicked, this, &cTriggerEditor::removeColorization); 0379 d->chkiscolor->setChecked (false); 0380 colorgroup->setEnabled (false); 0381 0382 // the Rewrite text tab 0383 QFrame *rewritePage = new QFrame (tabs); 0384 QVBoxLayout *rewritelayout = new QVBoxLayout (rewritePage); 0385 0386 d->chkrewrite = new QCheckBox (i18n ("Text &rewrite trigger"), rewritePage); 0387 connect (d->chkrewrite, &QCheckBox::toggled, this, &cTriggerEditor::rewriteChanged); 0388 0389 QGroupBox *rewritegroup = new QGroupBox (i18n ("Rewrite text"), rewritePage); 0390 QGridLayout *rewritegrouplayout = new QGridLayout (rewritegroup); 0391 rewritegrouplayout->setSpacing (10); 0392 0393 QLabel *l5 = new QLabel (i18n ("&Change this part of line:"), rewritegroup); 0394 d->cbrewritevar = new QComboBox (rewritegroup); 0395 d->cbrewritevar->addItems (types); 0396 l5->setBuddy (d->cbrewritevar); 0397 QLabel *l6 = new QLabel (i18n ("&Back-reference"), rewritegroup); 0398 d->rewritebackrefno = new QSpinBox (rewritegroup); 0399 d->rewritebackrefno->setRange (0, 100); 0400 l6->setBuddy(d->rewritebackrefno); 0401 QLabel *l7 = new QLabel (i18n ("&To this value:"), rewritegroup); 0402 d->edrewritetext = new QLineEdit (rewritegroup); 0403 l7->setBuddy (d->edrewritetext); 0404 0405 rewritegrouplayout->addWidget (l5, 0, 0); 0406 rewritegrouplayout->addWidget (l6, 1, 0); 0407 rewritegrouplayout->addWidget (l7, 2, 0); 0408 rewritegrouplayout->addWidget (d->cbrewritevar, 0, 1); 0409 rewritegrouplayout->addWidget (d->edrewritetext, 2, 1); 0410 rewritegrouplayout->addWidget (d->rewritebackrefno, 1, 1); 0411 rewritegrouplayout->addWidget (new QWidget (rewritegroup), 3, 0); 0412 rewritegrouplayout->setRowStretch (3, 0); 0413 0414 connect (d->chkrewrite, &QCheckBox::toggled, rewritegroup, &QGroupBox::setEnabled); 0415 d->chkrewrite->setChecked (false); 0416 rewritegroup->setEnabled (false); 0417 0418 rewritelayout->setSpacing (10); 0419 rewritelayout->addWidget (d->chkrewrite); 0420 rewritelayout->addWidget (rewritegroup); 0421 0422 0423 // the Special trigger tab 0424 QFrame *specialPage = new QFrame (tabs); 0425 QGridLayout *speciallayout = new QGridLayout (specialPage); 0426 d->chkgag = new QCheckBox (i18n ("Do not show (&gag) the line"), specialPage); 0427 d->chkgag->setWhatsThis( i18n ("This will prevent the matched line " 0428 "from being displayed in the output window.")); 0429 d->chknotify = new QCheckBox (i18n ("&Notify"), specialPage); 0430 d->chknotify->setWhatsThis( i18n ("This setting only takes effect if you " 0431 "have disabled the \"Always notify\" option in Global settings and " 0432 "at least one of global/local notification is enabled. It will " 0433 "activate notification if the KMuddy window and/or this session " 0434 "is not active at the moment.\nUseful if you only want to be notified " 0435 "of some events (tells, combat, ...).")); 0436 0437 d->chkprompt = new QCheckBox (i18n ("&Prompt-detection trigger"), specialPage); 0438 d->chkprompt->setWhatsThis( i18n ("Enabling this will turn this trigger " 0439 "into a prompt detection trigger, that is, text will be passed to these " 0440 "triggers even if no newline was received, the text will be displayed " 0441 "as a prompt if the trigger gets matched, and most other options will " 0442 "NOT be taken into effect - prompt-detect trigger cannot send out " 0443 "text, gag lines, do notification. Colorization is still possible.")); 0444 d->chksound = new QCheckBox (i18n ("Play s&ound file"), specialPage); 0445 d->chksound->setWhatsThis( i18n ("This trigger will play a sound. Useful " 0446 "as a notification of important events, or to assign sounds to some " 0447 "events.")); 0448 d->edsoundname = new QLineEdit (specialPage); 0449 QPushButton *button = new QPushButton ("&Browse...", specialPage); 0450 connect (button, &QPushButton::clicked, this, &cTriggerEditor::browseForSoundFile); 0451 0452 speciallayout->setSpacing (10); 0453 speciallayout->addWidget (d->chkgag, 0, 0); 0454 speciallayout->addWidget (d->chknotify, 1, 0); 0455 speciallayout->addWidget (d->chkprompt, 2, 0); 0456 speciallayout->addWidget (d->chksound, 3, 0); 0457 speciallayout->addWidget (d->edsoundname, 3, 1); 0458 speciallayout->addWidget (button, 3, 2); 0459 speciallayout->setRowStretch (4, 5); 0460 0461 // the Output windows tab 0462 QFrame *windowPage = new QFrame (tabs); 0463 QGridLayout *windowlayout = new QGridLayout (windowPage); 0464 d->chkwindow = new QCheckBox (i18n ("Send output to a separate window"), windowPage); 0465 d->chkwindow->setWhatsThis( i18n ("This will send the matched text to a separate output window")); 0466 0467 QGroupBox *outwindow = new QGroupBox(i18n ("Output Windows"), windowPage); 0468 QVBoxLayout *owlayout = new QVBoxLayout (outwindow); 0469 connect (d->chkwindow, &QCheckBox::toggled, outwindow, &QGroupBox::setEnabled); 0470 d->chkwindow->setChecked (false); 0471 outwindow->setEnabled (false); 0472 0473 QLabel *wll = new QLabel("&Select window", outwindow); 0474 d->windowlist = new QComboBox(outwindow); 0475 wll->setBuddy(d->windowlist); 0476 d->windowlist->clear(); 0477 0478 d->chkgagoutput = new QCheckBox (i18n ("&Gag output in main window"), outwindow); 0479 d->chkgagoutput->setWhatsThis( i18n ("This will cause output sent to a separate window not to " 0480 "be displayed in main KMuddy session window")); 0481 0482 QLabel *wnl = new QLabel (i18n ("&Window name"), outwindow); 0483 d->wname = new QLineEdit (outwindow); 0484 wnl->setBuddy(d->wname); 0485 0486 QPushButton *createwindow = new QPushButton (i18n ("&Create window"), outwindow); 0487 connect (createwindow, &QPushButton::clicked, this, &cTriggerEditor::createOutputWindow); 0488 0489 owlayout->addWidget (wll); 0490 owlayout->addWidget (d->windowlist); 0491 owlayout->addWidget (d->chkgagoutput); 0492 owlayout->addWidget (wnl); 0493 owlayout->addWidget (d->wname); 0494 owlayout->addWidget (createwindow); 0495 owlayout->addStretch (); 0496 0497 windowlayout->setSpacing(10); 0498 windowlayout->addWidget(d->chkwindow, 0, 0); 0499 windowlayout->addWidget(outwindow, 1, 0, 1, 3); 0500 0501 0502 //make testarea work! 0503 connect (d->text, &QLineEdit::textChanged, this, &cTriggerEditor::updateTest); 0504 connect (d->cmd, &QLineEdit::textChanged, this, &cTriggerEditor::updateTest); 0505 connect (d->rcmd, &KTextEdit::textChanged, this, &cTriggerEditor::updateTest); 0506 connect (d->type, QOverload<int>::of(&QComboBox::activated), this, &cTriggerEditor::updateTest); 0507 connect (d->check1, &QCheckBox::toggled, this, &cTriggerEditor::updateTest); 0508 connect (d->check2, &QCheckBox::toggled, this, &cTriggerEditor::updateTest); 0509 0510 0511 tabs->addTab (basicTab, i18n ("&Basic")); 0512 tabs->addTab (scriptPage, i18n ("&Script")); 0513 tabs->addTab (optionsPage, i18n ("&Options")); 0514 tabs->addTab (colorPage, i18n ("Color replacement")); 0515 tabs->addTab (rewritePage, i18n ("Rewrite text")); 0516 tabs->addTab (specialPage, i18n ("Special trigger")); 0517 tabs->addTab (windowPage, i18n ("Output windows")); 0518 } 0519 0520 void cTriggerEditor::updateTest () 0521 { 0522 QString txt = d->text->text(); 0523 // pattern used to test 0524 cPattern pattern; 0525 0526 //set it up with dialog data 0527 pattern.setPattern (d->cmd->text ()); 0528 cPattern::PatternType pt; 0529 switch (d->type->currentIndex ()) { 0530 case 0: pt = cPattern::exact; break; 0531 case 1: pt = cPattern::substring; break; 0532 case 2: pt = cPattern::begin; break; 0533 case 3: pt = cPattern::end; break; 0534 case 4: pt = cPattern::regexp; break; 0535 default: pt = cPattern::begin; 0536 } 0537 pattern.setMatching (pt); 0538 pattern.setCaseSensitive (d->check2->isChecked ()); 0539 0540 pattern.setWholeWords (d->check1->isChecked ()); 0541 0542 bool ismatch = pattern.match (txt); 0543 0544 //write results of the matching 0545 d->variables->clear (); 0546 if (!ismatch) { 0547 d->matched->setText (i18n ("This text did not match your trigger.")); 0548 d->replacement->setText (""); 0549 return; 0550 } 0551 0552 d->matched->setText (i18n ("This text matches your trigger.")); 0553 QStringList ntext = d->rcmd->toPlainText().split ("\n"); 0554 QStringList::iterator it; 0555 QString nt; 0556 for (it = ntext.begin(); it != ntext.end(); ++it) 0557 { 0558 QString text = *it; 0559 pattern.expandPseudoVariables (text); 0560 nt += text + "\n "; 0561 } 0562 0563 QList<QTreeWidgetItem *> items; 0564 items << new QTreeWidgetItem (d->variables, QStringList() << "$matched" << pattern.getVariable ("matched")); 0565 items << new QTreeWidgetItem (d->variables, QStringList() << "$matched" << pattern.getVariable ("matched")); 0566 items << new QTreeWidgetItem (d->variables, QStringList() << "$prefix" << pattern.getVariable ("prefix")); 0567 items << new QTreeWidgetItem (d->variables, QStringList() << "$suffix" << pattern.getVariable ("suffix")); 0568 items << new QTreeWidgetItem (d->variables, QStringList() << "$prefixfull" << pattern.getVariable ("prefixfull")); 0569 items << new QTreeWidgetItem (d->variables, QStringList() << "$suffixfull" << pattern.getVariable ("suffixfull")); 0570 if (pattern.matching() == cPattern::regexp) 0571 for (int i = 0; i < pattern.getBackRefList().count(); i++) 0572 items << new QTreeWidgetItem (d->variables, QStringList() << "$"+QString::number(i) << pattern.getBackRefList()[i]); 0573 d->variables->addTopLevelItems (items); 0574 } 0575 0576 void cTriggerEditor::addColorization () 0577 { 0578 if (d->cnum == MAX_COLORIZATIONS) //limit reached! 0579 { 0580 KMessageBox::error (this, i18n ("Maximum number of colorizations reached.")); 0581 return; 0582 } 0583 int fg = d->fgselect->currentIndex (); 0584 int bg = d->bgselect->currentIndex (); 0585 QString varname; 0586 int t = d->clrtype->currentIndex (); 0587 0588 switch (t) { 0589 case 0: varname = "$line"; break; 0590 case 1: varname = "$matched"; break; 0591 case 2: varname = "$prefix"; break; 0592 case 3: varname = "$suffix"; break; 0593 case 4: varname = "$prefixfull"; break; 0594 case 5: varname = "$suffixfull"; break; 0595 case 6: varname = "$"; break; 0596 }; 0597 if (t == 6) 0598 varname += QString::number (d->backrefno->value ()); 0599 0600 //values are ready, fill'em in! 0601 d->fgcolor[d->cnum] = fg; 0602 d->bgcolor[d->cnum] = bg; 0603 d->fgc[d->cnum] = d->fgcolsel->color(); 0604 d->bgc[d->cnum] = d->bgcolsel->color(); 0605 d->ctype[d->cnum] = varname; 0606 d->cnum++; 0607 updateColorizationsList (); 0608 } 0609 0610 void cTriggerEditor::removeColorization () 0611 { 0612 QTreeWidgetItem *item = d->colorizations->currentItem(); 0613 if (!item) return; 0614 int num = d->colorizations->indexOfTopLevelItem (item); 0615 if (num == -1) return; 0616 for (int i = num; i < d->cnum - 1; i++) 0617 { 0618 d->ctype[i] = d->ctype[i + 1]; 0619 d->fgcolor[i] = d->fgcolor[i + 1]; 0620 d->bgcolor[i] = d->bgcolor[i + 1]; 0621 d->fgc[i] = d->fgc[i + 1]; 0622 d->bgc[i] = d->bgc[i + 1]; 0623 } 0624 d->cnum--; 0625 //this will also fix item numbers 0626 updateColorizationsList (); 0627 } 0628 0629 void cTriggerEditor::updateColorizationsList () 0630 { 0631 //erase old data 0632 d->colorizations->clear (); 0633 0634 //now I fill in data, item by item... 0635 //for each item: 0636 for (int i = 0; i < d->cnum; i++) 0637 { 0638 QString stype, sfg, sbg; 0639 0640 //prepare strings 0641 QString varname = d->ctype[i]; 0642 if (varname == "$line") 0643 stype = ltype[0]; 0644 else if (varname == "$matched") 0645 stype = ltype[1]; 0646 else if ((varname == "$prefix") || (varname == "$prefixtrim")) 0647 stype = ltype[2]; 0648 else if ((varname == "$suffix") || (varname == "$suffixtrim")) 0649 stype = ltype[3]; 0650 else if (varname == "$prefixfull") 0651 stype = ltype[4]; 0652 else if (varname == "$suffixfull") 0653 stype = ltype[5]; 0654 else if (varname[0] == '$') 0655 { 0656 //now it *should* be a back-reference 0657 varname = varname.mid(1); 0658 bool ok; 0659 varname.toInt (&ok); 0660 if (ok) //back-ref -> good :) 0661 stype = ltype[6] + " " + varname; 0662 else 0663 stype = i18n ("Unknown"); 0664 } 0665 0666 //fg/bg color 0667 //custom color is displayed in #rrggbb format... we may need to invent something better 0668 int fg = d->fgcolor[i]; 0669 int bg = d->bgcolor[i]; 0670 sfg = (fg == 17) ? d->fgc[i].name() : cltextk[fg]; 0671 sbg = (bg == 17) ? d->bgc[i].name() : cltextk[bg]; 0672 0673 //fill'em in! 0674 QTreeWidgetItem *item = new QTreeWidgetItem (QStringList() << stype << sfg << sbg); 0675 d->colorizations->addTopLevelItem (item); 0676 if (i == d->cnum - 1) //last item shall be selected 0677 d->colorizations->setCurrentItem (item); 0678 } 0679 } 0680 0681 void cTriggerEditor::browseForSoundFile () 0682 { 0683 //open some file and place its name to the edit box 0684 QString fName = QFileDialog::getOpenFileName (this, i18n ("Choose sound file"), QString(), "audio/x-wav audio/mpeg audio/ogg"); 0685 if (!(fName.isEmpty())) 0686 d->edsoundname->setText (fName); 0687 } 0688 0689 void cTriggerEditor::createOutputWindow () 0690 { 0691 QString winname; 0692 0693 winname = d->wname->text(); 0694 if(!winname.isEmpty()) 0695 { 0696 cWindowList *list = dynamic_cast<cWindowList *>(cActionManager::self()->object ("windowlist", object()->list()->session())); 0697 list->add(winname); 0698 d->windowlist->clear(); 0699 QStringList wlist = list->windowList(); 0700 d->windowlist->addItems(wlist); 0701 } 0702 else 0703 KMessageBox::error(this, i18n("Window name is empty!")); 0704 } 0705 0706 void cTriggerEditor::rewriteChanged (bool val) 0707 { 0708 if (val) { 0709 d->check4->setChecked (false); 0710 d->check4->setEnabled (false); 0711 } 0712 else { 0713 d->check4->setEnabled (true); 0714 } 0715 } 0716 0717 0718 void cTriggerEditor::fillGUI (const cListObjectData &data) 0719 { 0720 // Common attributes 0721 fillCommonAttribEditor (data); 0722 0723 // Basic 0724 d->cmd->setText (data.strValue ("pattern")); 0725 d->type->setCurrentIndex (data.intValue ("matching")); 0726 d->condition->setText (data.strValue ("condition")); 0727 QStringList newtext; 0728 for (int i = 1; i <= data.intValue ("newtext-count"); ++i) 0729 newtext << data.strValue ("newtext-" + QString::number (i)); 0730 d->rcmd->setPlainText (newtext.join("\n")); 0731 0732 // Script 0733 d->script->setText (data.strValue ("script")); 0734 0735 // Options 0736 d->check1->setChecked (data.boolValue ("whole-words")); 0737 d->check2->setChecked (data.boolValue ("cs")); 0738 d->check3->setChecked (data.boolValue ("dont-send")); 0739 d->check4->setChecked (data.boolValue ("global")); 0740 d->actMatched->setCurrentIndex (data.intValue ("action-matched")); 0741 d->actNotMatched->setCurrentIndex (data.intValue ("action-not-matched")); 0742 0743 // Colors 0744 d->chkiscolor->setChecked (data.boolValue ("colorize")); 0745 d->cnum = 0; 0746 if (d->chkiscolor->isChecked()) { 0747 d->cnum = data.intValue ("colorize-count"); 0748 for (int i = 0; i < d->cnum; i++) { 0749 if (i >= MAX_COLORIZATIONS) break; // FIXME: limits are bad 0750 d->ctype[i] = data.strValue ("colorize-variable-"+QString::number(i+1)); 0751 int fg = data.intValue ("colorize-fg-"+QString::number(i+1)); 0752 int bg = data.intValue ("colorize-bg-"+QString::number(i+1)); 0753 if (fg == 0) 0754 d->fgcolor[i] = 0; 0755 else if (fg > 0) { // RGB 0756 d->fgcolor[i] = 17; 0757 fg--; 0758 d->fgc[i].setBlue (fg % 256); 0759 fg /= 256; 0760 d->fgc[i].setGreen (fg % 256); 0761 fg /= 256; 0762 d->fgc[i].setRed (fg % 256); 0763 } else // ANSI 0764 d->fgcolor[i] = fg + 17; 0765 if (bg == 0) 0766 d->bgcolor[i] = 0; 0767 else if (bg > 0) { // RGB 0768 d->bgcolor[i] = 17; 0769 bg--; 0770 d->bgc[i].setBlue (bg % 256); 0771 bg /= 256; 0772 d->bgc[i].setGreen (bg % 256); 0773 bg /= 256; 0774 d->bgc[i].setRed (bg % 256); 0775 } else // ANSI 0776 d->bgcolor[i] = bg + 17; 0777 } 0778 } 0779 updateColorizationsList (); 0780 0781 // Rewrite 0782 d->chkrewrite->setChecked (data.boolValue ("rewrite")); 0783 d->edrewritetext->setText (data.strValue ("rewrite-text")); 0784 QString varname = data.strValue ("rewrite-var"); 0785 bool ok = false; 0786 int number = varname.toInt (&ok); 0787 if (ok) { 0788 d->cbrewritevar->setCurrentIndex (6); 0789 d->rewritebackrefno->setValue (number); 0790 } else { 0791 int item = -1; 0792 if (varname == "line") item = 0; 0793 else if (varname == "matched") item = 1; 0794 else if ((varname == "prefix") || (varname == "prefixtrim")) item = 2; 0795 else if ((varname == "suffix") || (varname == "suffixtrim")) item = 3; 0796 else if (varname == "prefixfull") item = 4; 0797 else if (varname == "suffixfull") item = 5; 0798 d->cbrewritevar->setCurrentIndex (item); 0799 d->rewritebackrefno->setValue (0); 0800 } 0801 0802 // Special 0803 d->chkgag->setChecked (data.boolValue ("gag")); 0804 d->chknotify->setChecked (data.boolValue ("notify")); 0805 d->chkprompt->setChecked (data.boolValue ("prompt")); 0806 d->chksound->setChecked (data.boolValue ("sound")); 0807 d->edsoundname->setText (data.strValue ("sound-file")); 0808 0809 // Output windows 0810 d->chkwindow->setChecked (data.boolValue ("output-window")); 0811 d->chkgagoutput->setChecked (data.boolValue ("output-gag-in-main")); 0812 d->windowlist->clear(); 0813 cWindowList *list = dynamic_cast<cWindowList *>(cActionManager::self()->object ("windowlist", object()->list()->session())); 0814 if (list) { 0815 QStringList wlist = list->windowList(); 0816 d->windowlist->addItems(wlist); 0817 d->windowlist->setCurrentIndex (wlist.indexOf (data.strValue ("output-window-name"))); 0818 } 0819 0820 } 0821 0822 void cTriggerEditor::getDataFromGUI (cListObjectData *data) 0823 { 0824 // Comon attributes 0825 getDataFromCommonAttribEditor (data); 0826 0827 // Basic 0828 data->strValues["pattern"] = d->cmd->text(); 0829 data->intValues["matching"] = d->type->currentIndex(); 0830 data->strValues["condition"] = d->condition->text(); 0831 0832 QStringList ntext = d->rcmd->toPlainText().split ("\n"); 0833 data->intValues["newtext-count"] = ntext.size(); 0834 QStringList::iterator it; 0835 int i; 0836 for (it = ntext.begin(), i = 1; it != ntext.end(); ++i, ++it) 0837 data->strValues["newtext-" + QString::number (i)] = *it; 0838 0839 // Script 0840 data->strValues["script"] = d->script->text(); 0841 0842 // Options 0843 data->boolValues["whole-words"] = d->check1->isChecked(); 0844 data->boolValues["cs"] = d->check2->isChecked(); 0845 data->boolValues["dont-send"] = d->check3->isChecked(); 0846 data->boolValues["global"] = d->check4->isChecked(); 0847 data->intValues["action-matched"] = d->actMatched->currentIndex(); 0848 data->intValues["action-not-matched"] = d->actNotMatched->currentIndex(); 0849 0850 // Colors 0851 data->boolValues["colorize"] = d->chkiscolor->isChecked(); 0852 if (d->chkiscolor->isChecked()) { 0853 data->intValues["colorize-count"] = d->cnum; 0854 for (int i = 0; i < d->cnum; i++) { 0855 int fg = d->fgcolor[i]; 0856 if (fg == 17) { // RGB 0857 fg = d->fgc[i].red() * 256 * 256 + d->fgc[i].green() * 256 + d->fgc[i].blue()+ 1; 0858 } else if (fg > 0) fg -= 17; 0859 int bg = d->bgcolor[i]; 0860 if (bg == 17) { // RGB 0861 bg = d->bgc[i].red() * 256 * 256 + d->bgc[i].green() * 256 + d->bgc[i].blue()+ 1; 0862 } else if (bg > 0) bg -= 17; 0863 data->intValues["colorize-fg-"+QString::number(i+1)] = fg; 0864 data->intValues["colorize-bg-"+QString::number(i+1)] = bg; 0865 data->strValues["colorize-variable-"+QString::number(i+1)] = d->ctype[i]; 0866 } 0867 } 0868 0869 // Rewrite 0870 data->boolValues["rewrite"] = d->chkrewrite->isChecked (); 0871 data->strValues["rewrite-text"] = d->edrewritetext->text(); 0872 QString varname; 0873 switch (d->cbrewritevar->currentIndex ()) 0874 { 0875 case 0: varname = "line"; break; 0876 case 1: varname = "matched"; break; 0877 case 2: varname = "prefix"; break; 0878 case 3: varname = "suffix"; break; 0879 case 4: varname = "prefixfull"; break; 0880 case 5: varname = "suffixfull"; break; 0881 case 6: varname = QString::number (d->rewritebackrefno->value()); break; 0882 } 0883 data->strValues["rewrite-var"] = varname; 0884 0885 // Special 0886 data->boolValues["gag"] = d->chkgag->isChecked (); 0887 data->boolValues["notify"] = d->chknotify->isChecked (); 0888 data->boolValues["prompt"] = d->chkprompt->isChecked (); 0889 data->boolValues["sound"] = d->chksound->isChecked (); 0890 data->strValues["sound-file"] = d->edsoundname->text (); 0891 0892 // Output windows 0893 data->boolValues["output-window"] = d->chkwindow->isChecked (); 0894 data->boolValues["output-gag-in-main"] = d->chkgagoutput->isChecked(); 0895 data->strValues["output-window-name"] = d->windowlist->currentText(); 0896 0897 } 0898 0899 #include "moc_ctriggereditor.cpp"