File indexing completed on 2025-01-19 06:54:46
0001 // 0002 // C++ Implementation: caliaseditor 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 "caliaseditor.h" 0024 0025 #include "cpattern.h" 0026 #include "cscripteditor.h" 0027 0028 #include <QCheckBox> 0029 #include <QComboBox> 0030 #include <QDialog> 0031 #include <QGridLayout> 0032 #include <QGroupBox> 0033 #include <QLabel> 0034 #include <QLineEdit> 0035 #include <QPushButton> 0036 #include <QSplitter> 0037 #include <QTabWidget> 0038 #include <QTreeWidget> 0039 #include <QVBoxLayout> 0040 0041 #include <KLocalizedString> 0042 #include <KTextEdit> 0043 0044 struct cAliasEditor::Private { 0045 // Basic 0046 QLineEdit *cmd; 0047 QComboBox *type; 0048 QLineEdit *condition; 0049 KTextEdit *rcmd; 0050 0051 // Basic - testarea 0052 QLineEdit *text; 0053 QLabel *matched, *replacement; 0054 QTreeWidget *variables; 0055 0056 // Script 0057 cScriptEditor *script; 0058 0059 // Options 0060 QCheckBox *check1, *check2, *check3, *check4, *check5; 0061 }; 0062 0063 cAliasEditor::cAliasEditor (QWidget *parent) 0064 : cListEditor (parent) 0065 { 0066 d = new Private; 0067 } 0068 0069 cAliasEditor::~cAliasEditor () 0070 { 0071 // the GUI elements will be destroyed automatically 0072 delete d; 0073 } 0074 0075 void cAliasEditor::createGUI(QWidget *parent) 0076 { 0077 QVBoxLayout *mainLayout = new QVBoxLayout (parent); 0078 QTabWidget *tabs = new QTabWidget (parent); 0079 mainLayout->addWidget (tabs); 0080 0081 // the Basic tab 0082 QSplitter *basicTab = new QSplitter (tabs); 0083 basicTab->setOrientation (Qt::Vertical); 0084 QFrame *basicPage = new QFrame (basicTab); 0085 QGridLayout *basiclayout = new QGridLayout (basicPage); 0086 0087 // command 0088 QLabel *cl = new QLabel (i18n ("&Alias text"), basicPage); 0089 d->cmd = new QLineEdit (basicPage); 0090 cl->setBuddy (d->cmd); 0091 d->cmd->setWhatsThis (i18n ("Command that will be replaced if you enter it.")); 0092 0093 //comparison type 0094 QWidget *hbComboEdit = new QWidget (basicPage); 0095 QHBoxLayout *comboEditLayout = new QHBoxLayout (hbComboEdit);; 0096 comboEditLayout->setSpacing(3); 0097 QLabel *ctl = new QLabel ("&Comparison type", basicPage); 0098 d->type = new QComboBox (hbComboEdit); 0099 ctl->setBuddy (d->type); 0100 d->type->clear (); 0101 d->type->addItem (i18n ("Exact match")); 0102 d->type->addItem (i18n ("Sub-string")); 0103 d->type->addItem (i18n ("Begins with")); 0104 d->type->addItem (i18n ("Ends with")); 0105 d->type->addItem (i18n ("Regular expression")); 0106 d->type->setWhatsThis( i18n ("Type of matching. Alias will only be activated " 0107 "if this passes this type of test. Note that aliases are always matched as whole words.")); 0108 comboEditLayout->addWidget (d->type); 0109 0110 //condition 0111 QLabel *cndl = new QLabel ("Con&dition", basicPage); 0112 d->condition = new QLineEdit (basicPage); 0113 cndl->setBuddy (d->condition); 0114 d->condition->setWhatsThis( i18n ("Conditional triggering. If this is set, the actions " 0115 "will only fire if the condition is true (that means, if it evaluates as non-zero).")); 0116 0117 //replacement command(s) 0118 QLabel *rcl = new QLabel (i18n ("&Replacement text(s)"), basicPage); 0119 d->rcmd = new KTextEdit (basicPage); 0120 d->rcmd->setWordWrapMode (QTextOption::NoWrap); 0121 rcl->setBuddy (d->rcmd); 0122 d->rcmd->setWhatsThis( i18n ("Command(s) that will replace command you have entered.")); 0123 0124 //test area 0125 QGroupBox *testarea = new QGroupBox (i18n ("Test area"), basicTab); 0126 QGridLayout *testlayout = new QGridLayout (testarea); 0127 QLabel *textlabel = new QLabel (i18n ("&Text: "), testarea); 0128 d->text = new QLineEdit (testarea); 0129 textlabel->setBuddy (d->text); 0130 d->matched = new QLabel ("", testarea); 0131 d->replacement = new QLabel ("", testarea); 0132 d->variables = new QTreeWidget (testarea); 0133 d->variables->setHeaderLabels (QStringList() << i18n ("Name") << i18n ("Value")); 0134 d->variables->setAllColumnsShowFocus (true); 0135 d->variables->setUniformRowHeights (true); 0136 d->variables->setRootIsDecorated (true); 0137 testarea->setWhatsThis( i18n("This is testing area. You can test your alias " 0138 "here to see if it does what you want it to do. Simply " 0139 "type in some text and see what happens.")); 0140 testlayout->setSpacing (5); 0141 testlayout->addWidget (textlabel, 0, 0); 0142 testlayout->addWidget (d->text, 0, 1); 0143 testlayout->addWidget (d->matched, 1, 0, 1, 2); 0144 testlayout->addWidget (d->replacement, 2, 0, 1, 2); 0145 testlayout->addWidget (d->variables, 3, 0, 1, 2); 0146 0147 basiclayout->setSpacing (5); 0148 basiclayout->addWidget (cl, 0, 0); 0149 basiclayout->addWidget (d->cmd, 0, 1); 0150 basiclayout->addWidget (ctl, 1, 0); 0151 basiclayout->addWidget (hbComboEdit, 1, 1); 0152 basiclayout->addWidget (cndl, 2, 0); 0153 basiclayout->addWidget (d->condition, 2, 1); 0154 basiclayout->addWidget (rcl, 3, 0); 0155 basiclayout->addWidget (d->rcmd, 4, 0, 1, 2); 0156 basiclayout->setRowStretch (4, 10); 0157 0158 basicTab->addWidget (basicPage); 0159 basicTab->addWidget (testarea); 0160 0161 // the Script tab 0162 QFrame *scriptPage = new QFrame (tabs); 0163 QVBoxLayout *scriptlayout = new QVBoxLayout (scriptPage); 0164 d->script = new cScriptEditor (scriptPage); 0165 scriptlayout->addWidget (d->script); 0166 0167 // the Options tab 0168 QFrame *optionsPage = new QFrame (tabs); 0169 QVBoxLayout *optionslayout = new QVBoxLayout (optionsPage); 0170 0171 QGroupBox *options = new QGroupBox (i18n ("&Options"), optionsPage); 0172 QGridLayout *optionsBoxLayout = new QGridLayout (options); 0173 0174 d->check1 = new QCheckBox (i18n ("Send original command"), options); 0175 d->check1->setWhatsThis( i18n ("If this alias matches your command, " 0176 "a replacement command will be sent. If you enable this option, " 0177 "both original and replacement commands are sent (original command " 0178 "is sent first).")); 0179 0180 d->check2 = new QCheckBox (i18n ("Whole words only"), options); 0181 d->check2->setWhatsThis( i18n("When enabled, this alias will only match " 0182 "the text if there are spaces or nothing before/after the matched string.")); 0183 0184 d->check3 = new QCheckBox (i18n ("Case sensitive"), options); 0185 d->check3->setWhatsThis( i18n ("When this option is on, upper case and " 0186 "lower case letters are treated as different characters, otherwise " 0187 "they're considered to be the same.")); 0188 0189 d->check4 = new QCheckBox (i18n ("Include prefix/suffix"), options); 0190 d->check4->setWhatsThis (i18n ("Prefix/suffix of matched text " 0191 "will be automatically appended to the expanded text.")); 0192 0193 d->check5 = new QCheckBox (i18n ("Global matching"), options); 0194 d->check5->setWhatsThis( i18n ("<p>With global matching, one alias/trigger can match multiple " 0195 "times, if it contains the pattern more than once. For example, if pattern is abc, " 0196 "it matches only once on abcdabcd of global matching is off, but twice if it is on. " 0197 "For each match, the requested actions are performed - so the commands can be sent " 0198 "multiple times, once per match.</p>" 0199 "<p>Note that failing the condition doesn't terminate scanning, so you can use " 0200 "this to highlight names from a list (using the condition to check if a match is in the " 0201 "list), or something like that.")); 0202 0203 optionsBoxLayout->addWidget (d->check1, 0, 1); 0204 optionsBoxLayout->addWidget (d->check2, 0, 0); 0205 optionsBoxLayout->addWidget (d->check3, 1, 0); 0206 optionsBoxLayout->addWidget (d->check4, 1, 1); 0207 optionsBoxLayout->addWidget (d->check5, 2, 0); 0208 0209 QWidget *commonEditor = createCommonAttribEditor (optionsPage); 0210 0211 optionslayout->setSpacing (10); 0212 optionslayout->addWidget (options); 0213 optionslayout->addWidget (commonEditor); 0214 0215 0216 //make testarea work! 0217 connect (d->text, &QLineEdit::textChanged, this, &cAliasEditor::updateTest); 0218 connect (d->cmd, &QLineEdit::textChanged, this, &cAliasEditor::updateTest); 0219 connect (d->rcmd, &KTextEdit::textChanged, this, &cAliasEditor::updateTest); 0220 connect (d->type, QOverload<int>::of(&QComboBox::activated), this, &cAliasEditor::updateTest); 0221 connect (d->check3, &QCheckBox::toggled, this, &cAliasEditor::updateTest); 0222 connect (d->check2, &QCheckBox::toggled, this, &cAliasEditor::updateTest); 0223 connect (d->check4, &QCheckBox::toggled, this, &cAliasEditor::updateTest); 0224 0225 0226 tabs->addTab (basicTab, i18n ("&Basic")); 0227 tabs->addTab (scriptPage, i18n ("&Script")); 0228 tabs->addTab (optionsPage, i18n ("&Options")); 0229 } 0230 0231 void cAliasEditor::updateTest () 0232 { 0233 QString txt = d->text->text(); 0234 // pattern used to test 0235 cPattern pattern; 0236 0237 //set it up with dialog data 0238 pattern.setPattern (d->cmd->text ()); 0239 cPattern::PatternType pt; 0240 switch (d->type->currentIndex ()) { 0241 case 0: pt = cPattern::exact; break; 0242 case 1: pt = cPattern::substring; break; 0243 case 2: pt = cPattern::begin; break; 0244 case 3: pt = cPattern::end; break; 0245 case 4: pt = cPattern::regexp; break; 0246 default: pt = cPattern::begin; 0247 } 0248 pattern.setMatching (pt); 0249 pattern.setCaseSensitive (d->check3->isChecked ()); 0250 0251 pattern.setWholeWords (d->check2->isChecked ()); 0252 0253 bool prefixsuffix = d->check4->isChecked (); 0254 0255 bool ismatch = pattern.match (txt); 0256 0257 //write results of the matching 0258 d->variables->clear (); 0259 if (!ismatch) { 0260 d->matched->setText (i18n ("This text did not match your alias.")); 0261 d->replacement->setText (""); 0262 return; 0263 } 0264 0265 d->matched->setText (i18n ("This text matches your alias.")); 0266 QStringList ntext = d->rcmd->toPlainText().split ("\n"); 0267 QString nt; 0268 QStringList::iterator it; 0269 //we cannot use QStringList::join because of prefix/suffix stuff 0270 for (it = ntext.begin(); it != ntext.end(); ++it) 0271 { 0272 QString text = *it; 0273 pattern.expandPseudoVariables (text); 0274 if (prefixsuffix) 0275 text = pattern.getPrefix() + text + pattern.getSuffix(); 0276 nt += text + "\n "; 0277 } 0278 0279 d->replacement->setText (i18n ("Command: ") + nt); 0280 QList<QTreeWidgetItem *> items; 0281 items << new QTreeWidgetItem (d->variables, QStringList() << "$matched" << pattern.getVariable ("matched")); 0282 items << new QTreeWidgetItem (d->variables, QStringList() << "$matched" << pattern.getVariable ("matched")); 0283 items << new QTreeWidgetItem (d->variables, QStringList() << "$prefix" << pattern.getVariable ("prefix")); 0284 items << new QTreeWidgetItem (d->variables, QStringList() << "$suffix" << pattern.getVariable ("suffix")); 0285 items << new QTreeWidgetItem (d->variables, QStringList() << "$prefixfull" << pattern.getVariable ("prefixfull")); 0286 items << new QTreeWidgetItem (d->variables, QStringList() << "$suffixfull" << pattern.getVariable ("suffixfull")); 0287 if (pattern.matching() == cPattern::regexp) 0288 for (int i = 0; i < pattern.getBackRefList().count(); i++) 0289 items << new QTreeWidgetItem (d->variables, QStringList() << "$"+QString::number(i) << pattern.getBackRefList()[i]); 0290 d->variables->addTopLevelItems (items); 0291 } 0292 0293 0294 void cAliasEditor::fillGUI (const cListObjectData &data) 0295 { 0296 // Common attributes 0297 fillCommonAttribEditor (data); 0298 0299 // Basic 0300 d->cmd->setText (data.strValue ("pattern")); 0301 d->type->setCurrentIndex (data.intValue ("matching")); 0302 d->condition->setText (data.strValue ("condition")); 0303 QStringList newtext; 0304 for (int i = 1; i <= data.intValue ("newtext-count"); ++i) 0305 newtext << data.strValue ("newtext-" + QString::number (i)); 0306 d->rcmd->setPlainText (newtext.join("\n")); 0307 0308 // Script 0309 d->script->setText (data.strValue ("script")); 0310 0311 // Options 0312 0313 d->check1->setChecked (data.boolValue ("orig")); 0314 d->check2->setChecked (data.boolValue ("whole-words")); 0315 d->check3->setChecked (data.boolValue ("cs")); 0316 d->check4->setChecked (data.boolValue ("prefix-suffix")); 0317 d->check5->setChecked (data.boolValue ("global")); 0318 } 0319 0320 void cAliasEditor::getDataFromGUI (cListObjectData *data) 0321 { 0322 // Comon attributes 0323 getDataFromCommonAttribEditor (data); 0324 0325 // Basic 0326 data->strValues["pattern"] = d->cmd->text(); 0327 data->intValues["matching"] = d->type->currentIndex(); 0328 data->strValues["condition"] = d->condition->text(); 0329 0330 QStringList ntext = d->rcmd->toPlainText().split ("\n"); 0331 data->intValues["newtext-count"] = ntext.size(); 0332 QStringList::iterator it; int i; 0333 for (i = 1, it = ntext.begin(); it != ntext.end(); ++i, ++it) 0334 data->strValues["newtext-" + QString::number (i)] = *it; 0335 0336 // Script 0337 data->strValues["script"] = d->script->text(); 0338 0339 // Options 0340 data->boolValues["orig"] = d->check1->isChecked(); 0341 data->boolValues["whole-words"] = d->check2->isChecked(); 0342 data->boolValues["cs"] = d->check3->isChecked(); 0343 data->boolValues["prefix-suffix"] = d->check4->isChecked(); 0344 data->boolValues["global"] = d->check5->isChecked(); 0345 } 0346 0347 #include "moc_caliaseditor.cpp"