SVN_SILENT made messages (.desktop file)
[kdeaccessibility.git] / kttsd / filters / stringreplacer / stringreplacerproc.cpp
blobf7fa2cb69d150b405c5bedb6870cd0156694027e
1 /***************************************************** vim:set ts=4 sw=4 sts=4:
2 Generic String Replacement Filter Processing 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 // StringReplacer includes.
25 #include "stringreplacerproc.h"
26 #include "stringreplacerproc.moc"
28 // Qt includes.
29 #include <QtXml/QDomDocument>
30 #include <QtCore/QFile>
32 // KDE includes.
33 #include <kdebug.h>
34 #include <klocale.h>
35 #include <kconfig.h>
36 #include <kconfiggroup.h>
37 #include <kglobal.h>
38 #include <kstandarddirs.h>
40 // KTTS includes.
41 #include "filterproc.h"
42 #include "talkercode.h"
44 /**
45 * Constructor.
47 StringReplacerProc::StringReplacerProc( QObject *parent, QVariantList list) :
48 KttsFilterProc(parent, list)
52 /**
53 * Destructor.
55 /*virtual*/ StringReplacerProc::~StringReplacerProc()
57 m_matchList.clear();
58 m_substList.clear();
61 /**
62 * Initialize the filter.
63 * @param config Settings object.
64 * @param configGroup Settings Group.
65 * @return False if filter is not ready to filter.
67 * Note: The parameters are for reading from kttsdrc file. Plugins may wish to maintain
68 * separate configuration files of their own.
70 bool StringReplacerProc::init(KConfig* c, const QString& configGroup){
71 //kDebug() << "StringReplacerProc::init: Running";
72 QString wordsFilename =
73 KGlobal::dirs()->saveLocation( "data" ,"kttsd/stringreplacer/", false );
74 if ( wordsFilename.isEmpty() ) return false;
75 wordsFilename += configGroup;
76 KConfigGroup config( c, configGroup );
77 wordsFilename = config.readEntry( "WordListFile", wordsFilename );
79 // Open existing word list.
80 QFile file( wordsFilename );
81 if ( !file.open( QIODevice::ReadOnly ) )
83 //kDebug() << "StringReplacerProc::init: couldn't open file " << wordsFilename;
84 return false;
86 QDomDocument doc( "" );
87 if ( !doc.setContent( &file ) ) {
88 //kDebug() << "StringReplacerProc::init: couldn't get xml from file " << wordsFilename;
89 file.close();
90 return false;
92 file.close();
94 // Clear list.
95 m_matchList.clear();
96 m_substList.clear();
98 // Name setting.
99 // QDomNodeList nameList = doc.elementsByTagName( "name" );
100 // QDomNode nameNode = nameList.item( 0 );
101 // m_widget->nameLineEdit->setText( nameNode.toElement().text() );
103 // Language Codes setting. List may be single element of comma-separated values,
104 // or multiple elements.
105 m_languageCodeList.clear();
106 QDomNodeList languageList = doc.elementsByTagName( "language-code" );
107 for ( int ndx=0; ndx < languageList.count(); ++ndx )
109 QDomNode languageNode = languageList.item( ndx );
110 m_languageCodeList += languageNode.toElement().text().split( ',', QString::SkipEmptyParts);
113 // AppId. Apply this filter only if DCOP appId of application that queued
114 // the text contains this string. List may be single element of comma-separated values,
115 // or multiple elements.
116 m_appIdList.clear();
117 QDomNodeList appIdList = doc.elementsByTagName( "appid" );
118 for ( int ndx=0; ndx < appIdList.count(); ++ndx )
120 QDomNode appIdNode = appIdList.item( ndx );
121 m_appIdList += appIdNode.toElement().text().split( ',', QString::SkipEmptyParts);
124 // Word list.
125 QDomNodeList wordList = doc.elementsByTagName("word");
126 const int wordListCount = wordList.count();
127 for (int wordIndex = 0; wordIndex < wordListCount; ++wordIndex)
129 QDomNode wordNode = wordList.item(wordIndex);
130 QDomNodeList propList = wordNode.childNodes();
131 QString wordType;
132 QString matchCase = "No"; // Default for old (v<=3.5.3) config files with no <case/>.
133 QString match;
134 QString subst;
135 const int propListCount = propList.count();
136 for (int propIndex = 0; propIndex < propListCount; ++propIndex)
138 QDomNode propNode = propList.item(propIndex);
139 QDomElement prop = propNode.toElement();
140 if (prop.tagName() == "type") wordType = prop.text();
141 if (prop.tagName() == "case") matchCase = prop.text();
142 if (prop.tagName() == "match") match = prop.text();
143 if (prop.tagName() == "subst") subst = prop.text();
145 // Build Regular Expression for each word's match string.
146 QRegExp rx;
147 rx.setCaseSensitivity(matchCase == "Yes"?Qt::CaseInsensitive:Qt::CaseSensitive);
148 if ( wordType == "Word" )
150 // TODO: Does \b honor strange non-Latin1 encodings?
151 rx.setPattern( "\\b" + match + "\\b" );
153 else
155 rx.setPattern( match );
157 // Add Regular Expression to list (if valid).
158 if ( rx.isValid() )
160 m_matchList.append( rx );
161 m_substList.append( subst );
164 return true;
168 * Convert input, returning output.
169 * @param inputText Input text.
170 * @param talkerCode TalkerCode structure for the talker that KTTSD intends to
171 * use for synthing the text. Useful for extracting hints about
172 * how to filter the text. For example, languageCode.
173 * @param appId The DCOP appId of the application that queued the text.
174 * Also useful for hints about how to do the filtering.
176 /*virtual*/ QString StringReplacerProc::convert(const QString& inputText, TalkerCode* talkerCode,
177 const QString& appId)
179 m_wasModified = false;
180 // If language doesn't match, return input unmolested.
181 if ( !m_languageCodeList.isEmpty() )
183 QString languageCode = talkerCode->languageCode();
184 //kDebug() << "StringReplacerProc::convert: converting " << inputText <<
185 // " if language code " << languageCode << " matches " << m_languageCodeList << endl;
186 if ( !m_languageCodeList.contains( languageCode ) )
188 if ( !talkerCode->countryCode().isEmpty() )
190 languageCode += '_' + talkerCode->countryCode();
191 //kDebug() << "StringReplacerProc::convert: converting " << inputText <<
192 // " if language code " << languageCode << " matches " << m_languageCodeList << endl;
193 if ( !m_languageCodeList.contains( languageCode ) ) return inputText;
194 } else return inputText;
197 // If appId doesn't match, return input unmolested.
198 if ( !m_appIdList.isEmpty() )
200 //kDebug() << "StringReplacerProc::convert: converting " << inputText << " if appId "
201 // << appId << " matches " << m_appIdList << endl;
202 bool found = false;
203 QString appIdStr = appId;
204 for ( int ndx=0; ndx < m_appIdList.count(); ++ndx )
206 if ( appIdStr.contains(m_appIdList[ndx]) )
208 found = true;
209 break;
212 if ( !found )
214 //kDebug() << "StringReplacerProc::convert: appId not found";
215 return inputText;
218 QString newText = inputText;
219 const int listCount = m_matchList.count();
220 for ( int index = 0; index < listCount; ++index )
222 //kDebug() << "newtext = " << newText << " matching " << m_matchList[index].pattern() << " replacing with " << m_substList[index];
223 newText.replace( m_matchList[index], m_substList[index] );
225 m_wasModified = true;
226 return newText;
230 * Did this filter do anything? If the filter returns the input as output
231 * unmolested, it should return False when this method is called.
233 /*virtual*/ bool StringReplacerProc::wasModified() { return m_wasModified; }