Fix some bugs.
[kdeaccessibility.git] / kttsd / filters / stringreplacer / stringreplacerconf.cpp
blob70906434f9ac2d294d2ceff8ecd4056f40eed88d
1 /***************************************************** vim:set ts=4 sw=4 sts=4:
2 Generic String Replacement Filter Configuration class.
3 -------------------
4 Copyright:
5 (C) 2005 by Gary Cramblitt <garycramblitt@comcast.net>
6 -------------------
7 Original author: Gary Cramblitt <garycramblitt@comcast.net>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 ******************************************************************************/
24 // Qt includes.
25 #include <QFile>
26 #include <QFileInfo>
27 #include <QString>
28 #include <QDomDocument>
29 #include <QFile>
30 #include <QRadioButton>
31 #include <QTextStream>
32 #include <QTableWidget>
33 #include <QHeaderView>
35 // KDE includes.
36 #include <kglobal.h>
37 #include <klocale.h>
38 #include <klineedit.h>
39 #include <kdialog.h>
40 #include <kpushbutton.h>
41 #include <kconfig.h>
42 #include <kstandarddirs.h>
43 #include <kregexpeditorinterface.h>
44 #include <ktrader.h>
45 #include <kparts/componentfactory.h>
46 #include <kfiledialog.h>
47 #include <kmessagebox.h>
48 #include <khbox.h>
50 // KTTS includes.
51 #include "filterconf.h"
53 // StringReplacer includes.
54 #include "stringreplacerconf.h"
55 #include "stringreplacerconf.moc"
57 /**
58 * Constructor
60 StringReplacerConf::StringReplacerConf( QWidget *parent, const QStringList& args ) :
61 KttsFilterConf(parent),
62 m_editDlg(0),
63 m_editWidget(0)
65 Q_UNUSED(args);
66 // kDebug() << "StringReplacerConf::StringReplacerConf: Running" << endl;
68 // Create configuration widget.
69 setupUi(this);
71 substLView->setSortingEnabled(false);
72 substLView->verticalHeader()->hide();
74 connect(nameLineEdit, SIGNAL(textChanged(const QString&)),
75 this, SLOT(configChanged()));
76 connect(languageBrowseButton, SIGNAL(clicked()),
77 this, SLOT(slotLanguageBrowseButton_clicked()));
78 connect(addButton, SIGNAL(clicked()),
79 this, SLOT(slotAddButton_clicked()));
80 connect(upButton, SIGNAL(clicked()),
81 this, SLOT(slotUpButton_clicked()));
82 connect(downButton, SIGNAL(clicked()),
83 this, SLOT(slotDownButton_clicked()));
84 connect(editButton, SIGNAL(clicked()),
85 this, SLOT(slotEditButton_clicked()));
86 connect(removeButton, SIGNAL(clicked()),
87 this, SLOT(slotRemoveButton_clicked()));
88 connect(loadButton, SIGNAL(clicked()),
89 this, SLOT(slotLoadButton_clicked()));
90 connect(saveButton, SIGNAL(clicked()),
91 this, SLOT(slotSaveButton_clicked()));
92 connect(clearButton, SIGNAL(clicked()),
93 this, SLOT(slotClearButton_clicked()));
94 connect(substLView, SIGNAL(currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)),
95 this, SLOT(enableDisableButtons()));
96 connect(appIdLineEdit, SIGNAL(textChanged(const QString&)),
97 this, SLOT(configChanged()));
99 // Determine if kdeutils Regular Expression Editor is installed.
100 m_reEditorInstalled = !KTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty();
102 // Set up defaults.
103 defaults();
107 * Destructor.
109 StringReplacerConf::~StringReplacerConf(){
110 // kDebug() << "StringReplacerConf::~StringReplacerConf: Running" << endl;
114 * This method is invoked whenever the module should read its
115 * configuration (most of the times from a config file) and update the
116 * user interface. This happens when the user clicks the "Reset" button in
117 * the control center, to undo all of his changes and restore the currently
118 * valid settings. Note that kttsmgr calls this when the plugin is
119 * loaded, so it not necessary to call it in your constructor.
120 * The plugin should read its configuration from the specified group
121 * in the specified config file.
122 * @param config Pointer to a KConfig object.
123 * @param configGroup Call config->setGroup with this argument before
124 * loading your configuration.
126 void StringReplacerConf::load(KConfig* config, const QString& configGroup){
127 // kDebug() << "StringReplacerConf::load: Running" << endl;
128 // See if this filter previously save its word list.
129 config->setGroup( configGroup );
130 QString wordsFilename = config->readEntry( "WordListFile" );
131 if ( !wordsFilename.isEmpty() )
133 QString errMsg = loadFromFile( wordsFilename, true );
134 if ( !errMsg.isEmpty() )
135 kDebug() << "StringReplacerConf::load: " << errMsg << endl;
136 enableDisableButtons();
140 // Loads word list and settings from a file. Clearing configuration if clear is True.
141 QString StringReplacerConf::loadFromFile( const QString& filename, bool clear)
143 // Open existing word list.
144 QFile file( filename );
145 if ( !file.open( QIODevice::ReadOnly ) )
147 return i18n("Unable to open file.") + filename;
149 // QDomDocument doc( "http://www.kde.org/share/apps/kttsd/stringreplacer/wordlist.dtd []" );
150 QDomDocument doc( "" );
151 if ( !doc.setContent( &file ) ) {
152 file.close();
153 return i18n("File not in proper XML format.");
155 // kDebug() << "StringReplacerConf::load: document successfully parsed." << endl;
156 file.close();
158 // Clear list view.
159 if ( clear ) substLView->setRowCount(0);
161 // Name setting.
162 QDomNodeList nameList = doc.elementsByTagName( "name" );
163 QDomNode nameNode = nameList.item( 0 );
164 nameLineEdit->setText( nameNode.toElement().text() );
165 // kDebug() << "StringReplacerConf::load: name = " << nameNode.toElement().text() << endl;
167 // Language Codes setting. List may be single element of comma-separated values,
168 // or multiple elements.
169 QString languageCodes;
170 QDomNodeList languageList = doc.elementsByTagName( "language-code" );
171 for ( int ndx=0; ndx < languageList.count(); ++ndx )
173 QDomNode languageNode = languageList.item( ndx );
174 if (!languageCodes.isEmpty()) languageCodes += ",";
175 languageCodes += languageNode.toElement().text();
177 if ( clear )
178 m_languageCodeList = languageCodes.split(',', QString::SkipEmptyParts);
179 else
180 m_languageCodeList += languageCodes.split(',', QString::SkipEmptyParts);
181 QString language;
182 m_languageCodeList.sort();
183 // Eliminate dups.
185 int ndx = m_languageCodeList.count() - 2;
186 while ( ndx >= 0 ) {
187 if ( m_languageCodeList[ndx] == m_languageCodeList[ndx+1] )
188 m_languageCodeList.removeAt(ndx+1);
189 else
190 ndx--;
193 for ( int ndx=0; ndx < m_languageCodeList.count(); ++ndx )
195 if (!language.isEmpty()) language += ",";
196 language += KGlobal::locale()->twoAlphaToLanguageName(m_languageCodeList[ndx]);
198 languageLineEdit->setText(language);
200 // AppId. Apply this filter only if DCOP appId of application that queued
201 // the text contains this string. List may be single element of comma-separated values,
202 // or multiple elements.
203 QDomNodeList appIdList = doc.elementsByTagName( "appid" );
204 QString appIds;
205 for ( int ndx=0; ndx < appIdList.count(); ++ndx )
207 QDomNode appIdNode = appIdList.item( ndx );
208 if (!appIds.isEmpty()) appIds += ",";
209 appIds += appIdNode.toElement().text();
211 if ( !clear ) appIds = appIdLineEdit->text() + appIds;
212 appIdLineEdit->setText( appIds );
214 // Word list.
215 QDomNodeList wordList = doc.elementsByTagName( "word" );
216 const int wordListCount = wordList.count();
217 for ( int wordIndex = 0; wordIndex < wordListCount; ++wordIndex )
219 // kDebug() << "StringReplacerConf::load: start parsing of word " << wordIndex << endl;
220 QDomNode wordNode = wordList.item(wordIndex);
221 QDomNodeList propList = wordNode.childNodes();
222 QString wordType;
223 QString match;
224 QString subst;
225 const int propListCount = propList.count();
226 for ( int propIndex = 0; propIndex < propListCount; ++propIndex )
228 QDomNode propNode = propList.item(propIndex);
229 QDomElement prop = propNode.toElement();
230 if (prop.tagName() == "type") wordType = prop.text();
231 if (prop.tagName() == "match") match = prop.text();
232 if (prop.tagName() == "subst") subst = prop.text();
234 int tableRow = substLView->rowCount();
235 substLView->setRowCount( tableRow + 1 );
236 substLView->setItem( tableRow, 0, new QTableWidgetItem( wordType ) );
237 substLView->setItem( tableRow, 1, new QTableWidgetItem( match ) );
238 substLView->setItem( tableRow, 2, new QTableWidgetItem( subst ) );
241 return QString();
245 * This function gets called when the user wants to save the settings in
246 * the user interface, updating the config files or wherever the
247 * configuration is stored. The method is called when the user clicks "Apply"
248 * or "Ok". The plugin should save its configuration in the specified
249 * group of the specified config file.
250 * @param config Pointer to a KConfig object.
251 * @param configGroup Call config->setGroup with this argument before
252 * saving your configuration.
254 void StringReplacerConf::save(KConfig* config, const QString& configGroup){
255 // kDebug() << "StringReplacerConf::save: Running" << endl;
256 QString wordsFilename =
257 KGlobal::dirs()->saveLocation( "data" ,"kttsd/stringreplacer/", true );
258 if ( wordsFilename.isEmpty() )
260 kDebug() << "StringReplacerConf::save: no save location" << endl;
261 return;
263 wordsFilename += configGroup;
264 QString errMsg = saveToFile( wordsFilename );
265 if ( errMsg.isEmpty() )
267 config->setGroup( configGroup );
268 config->writeEntry( "WordListFile", realFilePath(wordsFilename) );
270 else
271 kDebug() << "StringReplacerConf::save: " << errMsg << endl;
274 // Saves word list and settings to a file.
275 QString StringReplacerConf::saveToFile(const QString& filename)
277 // kDebug() << "StringReplacerConf::saveToFile: saving to file " << wordsFilename << endl;
279 QFile file( filename );
280 if ( !file.open( QIODevice::WriteOnly ) )
281 return i18n("Unable to open file ") + filename;
283 // QDomDocument doc( "http://www.kde.org/share/apps/kttsd/stringreplacer/wordlist.dtd []" );
284 QDomDocument doc( "" );
286 QDomElement root = doc.createElement( "wordlist" );
287 doc.appendChild( root );
289 // Name.
290 QDomElement name = doc.createElement( "name" );
291 root.appendChild( name );
292 QDomText t = doc.createTextNode( nameLineEdit->text() );
293 name.appendChild( t );
295 // Language code.
296 for ( int ndx=0; ndx < m_languageCodeList.count(); ++ndx )
298 QDomElement languageCode = doc.createElement( "language-code" );
299 root.appendChild( languageCode );
300 t = doc.createTextNode( m_languageCodeList[ndx] );
301 languageCode.appendChild( t );
304 // Application ID
305 QString appId = appIdLineEdit->text().replace(" ", "");
306 if ( !appId.isEmpty() )
308 QStringList appIdList = appId.split( ",", QString::SkipEmptyParts );
309 for ( int ndx=0; ndx < appIdList.count(); ++ndx )
311 QDomElement appIdElem = doc.createElement( "appid" );
312 root.appendChild( appIdElem );
313 t = doc.createTextNode( appIdList[ndx] );
314 appIdElem.appendChild( t );
318 // Words.
319 for ( int row = 0; row < substLView->rowCount(); ++row )
321 QDomElement wordTag = doc.createElement( "word" );
322 root.appendChild( wordTag );
323 QDomElement propTag = doc.createElement( "type" );
324 wordTag.appendChild( propTag);
325 QDomText t = doc.createTextNode( substLView->item(row, 0)->text() );
326 propTag.appendChild( t );
328 propTag = doc.createElement( "match" );
329 wordTag.appendChild( propTag);
330 t = doc.createCDATASection( substLView->item(row, 1)->text() );
331 propTag.appendChild( t );
333 propTag = doc.createElement( "subst" );
334 wordTag.appendChild( propTag);
335 t = doc.createCDATASection( substLView->item(row, 2)->text() );
336 propTag.appendChild( t );
339 // Write it all out.
340 QTextStream ts( &file );
341 ts.setCodec( "UTF-8" );
342 ts << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
343 ts << doc.toString();
344 // kDebug() << "StringReplacerConf::saveToFile: writing out " << doc.toString() << endl;
345 file.close();
347 return QString();
350 /**
351 * This function is called to set the settings in the module to sensible
352 * default values. It gets called when hitting the "Default" button. The
353 * default values should probably be the same as the ones the application
354 * uses when started without a config file. Note that defaults should
355 * be applied to the on-screen widgets; not to the config file.
357 void StringReplacerConf::defaults(){
358 // kDebug() << "StringReplacerConf::defaults: Running" << endl;
359 // Default language is none.
360 m_languageCodeList.clear();
361 languageLineEdit->setText( "" );
362 // Default name.
363 nameLineEdit->setText( i18n("String Replacer") );
364 substLView->setRowCount(0);
365 // Default App ID is blank.
366 appIdLineEdit->setText( "" );
367 enableDisableButtons();
368 // kDebug() << "StringReplacerConf::defaults: Exiting" << endl;
372 * Indicates whether the plugin supports multiple instances. Return
373 * False if only one instance of the plugin can be configured.
374 * @return True if multiple instances are possible.
376 bool StringReplacerConf::supportsMultiInstance() { return true; }
379 * Returns the name of the plugin. Displayed in Filters tab of KTTSMgr.
380 * If there can be more than one instance of a filter, it should return
381 * a unique name for each instance. The name should be translated for
382 * the user if possible. If the plugin is not correctly configured,
383 * return an empty string.
384 * @return Filter instance name.
386 QString StringReplacerConf::userPlugInName()
388 if ( substLView->rowCount() == 0 ) return QString();
389 QString instName = nameLineEdit->text();
390 if ( instName.isEmpty() )
392 QString language;
393 if (m_languageCodeList.count() == 1)
394 language = KGlobal::locale()->twoAlphaToLanguageName(m_languageCodeList[0]);
395 if (m_languageCodeList.count() > 1)
396 language = i18n("Multiple Languages");
397 if (!language.isEmpty())
398 instName = i18n("String Replacer") + " (" + language + ")";
400 return instName;
403 // Converts a Substitution Type to displayable string.
404 QString StringReplacerConf::substitutionTypeToString(const int substitutionType)
406 switch (substitutionType)
408 case stWord: return i18n("Word");
409 case stRegExp: return "RegExp";
411 return i18n("Error");
414 void StringReplacerConf::slotLanguageBrowseButton_clicked()
416 // Create a QHBox to host QTableWidget.
417 KHBox* hBox = new KHBox(this);
418 // Create a QTableWidget and fill with all known languages.
419 QTableWidget* langLView = new QTableWidget(hBox);
420 langLView->verticalHeader()->hide();
421 langLView->setColumnCount(2);
422 langLView->setHorizontalHeaderItem(0, new QTableWidgetItem(i18n("Language")));
423 langLView->setHorizontalHeaderItem(1, new QTableWidgetItem(i18n("Code")));
424 langLView->setSelectionMode(QAbstractItemView::ExtendedSelection);
425 langLView->setSelectionBehavior(QAbstractItemView::SelectRows);
426 QStringList allLocales = KGlobal::locale()->allLanguagesTwoAlpha();
427 QString locale;
428 QString languageCode;
429 QString countryCode;
430 QString charSet;
431 QString language;
432 // Blank line so user can select no language.
433 langLView->setRowCount(1);
434 langLView->setItem(1, 0, new QTableWidgetItem(""));
435 langLView->setItem(1, 1, new QTableWidgetItem(""));
436 if (m_languageCodeList.isEmpty()) langLView->selectRow(1);
437 const int allLocalesCount = allLocales.count();
438 for (int ndx=0; ndx < allLocalesCount; ++ndx)
440 locale = allLocales[ndx];
441 KGlobal::locale()->splitLocale(locale, languageCode, countryCode, charSet);
442 language = KGlobal::locale()->twoAlphaToLanguageName(languageCode);
443 if (!countryCode.isEmpty()) language +=
444 " (" + KGlobal::locale()->twoAlphaToCountryName(countryCode)+")";
445 int row = langLView->rowCount();
446 langLView->setRowCount(row + 1);
447 langLView->setItem(row, 0, new QTableWidgetItem(language));
448 langLView->setItem(row, 1, new QTableWidgetItem(locale));
449 if (m_languageCodeList.contains(locale)) langLView->selectRow(row);
451 // Sort by language.
452 langLView->sortItems(0);
453 // Display the box in a dialog.
454 KDialog* dlg = new KDialog(
455 this,
456 i18n("Select Languages"),
457 KDialog::Help|KDialog::Ok|KDialog::Cancel);
458 dlg->setMainWidget(hBox);
459 dlg->setHelp("", "kttsd");
460 dlg->setInitialSize(QSize(300, 500));
461 int dlgResult = dlg->exec();
462 languageCode.clear();
463 if (dlgResult == QDialog::Accepted)
465 m_languageCodeList.clear();
466 for (int row = 1; row < langLView->rowCount(); ++row)
468 if (langLView->isItemSelected(langLView->item(row, 1)))
469 m_languageCodeList += langLView->item(row, 1)->text();
472 delete dlg;
473 // TODO: Also delete QTableWidget and QHBox?
474 if (dlgResult != QDialog::Accepted) return;
475 language = "";
476 for ( int ndx=0; ndx < m_languageCodeList.count(); ++ndx)
478 if (!language.isEmpty()) language += ",";
479 language += KGlobal::locale()->twoAlphaToLanguageName(m_languageCodeList[ndx]);
481 QString s1 = languageLineEdit->text();
482 languageLineEdit->setText(language);
483 // Replace language in the user's filter name.
484 QString s2 = nameLineEdit->text();
485 if (m_languageCodeList.count() > 1) language = i18n("Multiple Languages");
486 if ( !s1.isEmpty() )
488 s2.replace( s1, language );
489 s2.replace( i18n("Multiple Languages"), language );
491 s2.replace(" ()", "");
492 if ( !s2.contains("(") && !language.isEmpty() ) s2 += " (" + language + ")";
493 nameLineEdit->setText(s2);
494 configChanged();
497 void StringReplacerConf::enableDisableButtons()
499 int row = substLView->currentRow();
500 bool enableBtn = (row >= 0 && row < substLView->rowCount());
501 if (enableBtn)
503 upButton->setEnabled(row > 0);
504 downButton->setEnabled(row < (substLView->rowCount() - 1));
505 } else {
506 upButton->setEnabled(false);
507 downButton->setEnabled(false);
509 editButton->setEnabled(enableBtn);
510 removeButton->setEnabled(enableBtn);
511 clearButton->setEnabled(substLView->rowCount() > 0);
512 saveButton->setEnabled(substLView->rowCount() > 0);
515 void StringReplacerConf::slotUpButton_clicked()
517 int row = substLView->currentRow();
518 if (row < 1 || row >= substLView->rowCount()) return;
520 QTableWidgetItem *itemAbove = substLView->item(row - 1, 0);
521 QTableWidgetItem *item = substLView->item(row, 0);
522 QString t = itemAbove->text();
523 itemAbove->setText(item->text());
524 item->setText(t);
526 itemAbove = substLView->item(row - 1, 1);
527 item = substLView->item(row, 1);
528 t = itemAbove->text();
529 itemAbove->setText(item->text());
530 item->setText(t);
532 itemAbove = substLView->item(row - 1, 2);
533 item = substLView->item(row, 2);
534 t = itemAbove->text();
535 itemAbove->setText(item->text());
536 item->setText(t);
538 substLView->setCurrentItem(substLView->item(row - 1, substLView->currentColumn()));
539 // TODO: Is this needed? substLView->scrollTo(substLView->indexFromItem(itemAbove));
540 enableDisableButtons();
541 configChanged();
544 void StringReplacerConf::slotDownButton_clicked()
546 int row = substLView->currentRow();
547 if (row < 0 || row >= substLView->rowCount() - 1) return;
549 QTableWidgetItem *itemBelow = substLView->item(row + 1, 0);
550 QTableWidgetItem *item = substLView->item(row, 0);
551 QString t = itemBelow->text();
552 itemBelow->setText(item->text());
553 item->setText(t);
555 itemBelow = substLView->item(row + 1, 1);
556 item = substLView->item(row, 1);
557 t = itemBelow->text();
558 itemBelow->setText(item->text());
559 item->setText(t);
561 itemBelow = substLView->item(row + 1, 2);
562 item = substLView->item(row, 2);
563 t = itemBelow->text();
564 itemBelow->setText(item->text());
565 item->setText(t);
567 substLView->setCurrentItem(substLView->item(row + 1, substLView->currentColumn()));
568 // TODO: Is this needed? substLView->scrollTo(substLView->indexFromItem(itemBelow));
569 enableDisableButtons();
570 configChanged();
573 void StringReplacerConf::slotAddButton_clicked()
575 addOrEditSubstitution( true );
578 void StringReplacerConf::slotEditButton_clicked()
580 addOrEditSubstitution( false );
583 // Displays the add/edit string replacement dialog.
584 void StringReplacerConf::addOrEditSubstitution(bool isAdd)
586 int row;
587 if (isAdd)
588 row = substLView->rowCount() - 1;
589 else
590 row = substLView->currentRow();
591 // Create widget.
592 QWidget *w = new QWidget();
593 m_editWidget = new Ui::EditReplacementWidget();
594 m_editWidget->setupUi( w );
595 // Set controls if editing existing.
596 m_editWidget->matchButton->setEnabled( false );
597 if (!isAdd)
599 if ( substLView->item(row, 0)->text() == "RegExp" )
601 m_editWidget->regexpRadioButton->setChecked( true );
602 m_editWidget->matchButton->setEnabled( m_reEditorInstalled );
604 m_editWidget->matchLineEdit->setText( substLView->item(row, 1)->text() );
605 m_editWidget->substLineEdit->setText( substLView->item(row, 2)->text() );
607 // The match box may not be blank.
608 connect( m_editWidget->matchLineEdit, SIGNAL(textChanged(const QString&)),
609 this, SLOT(slotMatchLineEdit_textChanged(const QString&)) );
610 connect( m_editWidget->regexpRadioButton, SIGNAL(clicked()),
611 this, SLOT(slotTypeButtonGroup_clicked()) );
612 connect( m_editWidget->wordRadioButton, SIGNAL(clicked()),
613 this, SLOT(slotTypeButtonGroup_clicked()) );
614 connect( m_editWidget->matchButton, SIGNAL(clicked()),
615 this, SLOT(slotMatchButton_clicked()) );
616 // Display the box in a dialog.
617 m_editDlg = new KDialog(
618 this,
619 i18n("Edit String Replacement"),
620 KDialog::Help|KDialog::Ok|KDialog::Cancel);
621 // Disable OK button if match field blank.
622 m_editDlg->setMainWidget( w );
623 m_editDlg->setHelp( "", "kttsd" );
624 m_editDlg->enableButton( KDialog::Ok, !m_editWidget->matchLineEdit->text().isEmpty() );
625 int dlgResult = m_editDlg->exec();
626 QString substType = i18n( "Word" );
627 if ( m_editWidget->regexpRadioButton->isChecked() ) substType = "RegExp";
628 QString match = m_editWidget->matchLineEdit->text();
629 QString subst = m_editWidget->substLineEdit->text();
630 delete m_editDlg;
631 m_editDlg = 0;
632 m_editWidget = 0;
633 if (dlgResult != QDialog::Accepted) return;
634 // TODO: Also delete QTableWidget and w?
635 if ( match.isEmpty() ) return;
636 if ( isAdd )
638 row = substLView->rowCount();
639 substLView->setRowCount(row + 1);
640 substLView->setCurrentItem(substLView->item(row, 0));
642 substLView->item(row, 0)->setText(substType);
643 substLView->item(row, 1)->setText(match);
644 substLView->item(row, 2)->setText(subst);
645 // TODO: Is this needed? substLView->scrollTo(substLView->indexFromItem(substLView->item(row,0)));
646 enableDisableButtons();
647 configChanged();
650 void StringReplacerConf::slotMatchLineEdit_textChanged(const QString& text)
652 // Disable OK button if match field blank.
653 if ( !m_editDlg ) return;
654 m_editDlg->enableButton( KDialog::Ok, !text.isEmpty() );
657 void StringReplacerConf::slotRemoveButton_clicked()
659 int row = substLView->currentRow();
660 if (row <= 0 || row >= substLView->rowCount()) return;
661 delete substLView->takeItem(row, 0);
662 delete substLView->takeItem(row, 1);
663 delete substLView->takeItem(row, 2);
664 substLView->removeRow(row);
665 enableDisableButtons();
666 configChanged();
669 void StringReplacerConf::slotTypeButtonGroup_clicked()
671 // Enable Regular Expression Editor button if editor is installed (requires kdeutils).
672 if ( !m_editWidget ) return;
673 m_editWidget->matchButton->setEnabled( m_editWidget->regexpRadioButton->isChecked() && m_reEditorInstalled );
676 void StringReplacerConf::slotMatchButton_clicked()
678 // Show Regular Expression Editor dialog if it is installed.
679 if ( !m_editWidget ) return;
680 if ( !m_editDlg ) return;
681 if ( !m_reEditorInstalled ) return;
682 QDialog *editorDialog =
683 KParts::ComponentFactory::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor" );
684 if ( editorDialog )
686 // kdeutils was installed, so the dialog was found. Fetch the editor interface.
688 KRegExpEditorInterface *reEditor = dynamic_cast<KRegExpEditorInterface*>( editorDialog );
689 Q_ASSERT( reEditor ); // This should not fail!// now use the editor.
690 reEditor->setRegExp( m_editWidget->matchLineEdit->text() );
691 int dlgResult = editorDialog->exec();
692 if ( dlgResult == QDialog::Accepted )
694 QString re = reEditor->regExp();
695 m_editWidget->matchLineEdit->setText( re );
696 m_editDlg->enableButton( KDialog::Ok, !re.isEmpty() );
698 delete editorDialog;
699 } else return;
702 void StringReplacerConf::slotLoadButton_clicked()
704 QStringList dataDirs = KGlobal::dirs()->findAllResources("data", "kttsd/stringreplacer/");
705 QString dataDir;
706 if (!dataDirs.isEmpty()) dataDir = dataDirs.last();
707 QString filename = KFileDialog::getOpenFileName(
708 dataDir,
709 "*.xml|String Replacer Word List (*.xml)",
710 this,
711 "stringreplacer_loadfile");
712 if ( filename.isEmpty() ) return;
713 QString errMsg = loadFromFile( filename, false );
714 enableDisableButtons();
715 if ( !errMsg.isEmpty() )
716 KMessageBox::sorry( this, errMsg, i18n("Error Opening File") );
717 else
718 configChanged();
721 void StringReplacerConf::slotSaveButton_clicked()
723 QString filename = KFileDialog::getSaveFileName(
724 KGlobal::dirs()->saveLocation( "data" ,"kttsd/stringreplacer/", false ),
725 "*.xml|String Replacer Word List (*.xml)",
726 this,
727 "stringreplacer_savefile");
728 if ( filename.isEmpty() ) return;
729 QString errMsg = saveToFile( filename );
730 enableDisableButtons();
731 if ( !errMsg.isEmpty() )
732 KMessageBox::sorry( this, errMsg, i18n("Error Opening File") );
735 void StringReplacerConf::slotClearButton_clicked()
737 substLView->setRowCount(0);
738 enableDisableButtons();