diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | bd9e6617827818fd043452c08c606f07b78014a0 (patch) | |
tree | 425bb4c3168f9c02f10150f235d2cb998dcc6108 /kbabel/kbabeldict/modules/pocompendium | |
download | tdesdk-bd9e6617827818fd043452c08c606f07b78014a0.tar.gz tdesdk-bd9e6617827818fd043452c08c606f07b78014a0.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdesdk@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kbabel/kbabeldict/modules/pocompendium')
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/Makefile.am | 39 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/compendiumdata.cpp | 261 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/compendiumdata.h | 105 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/pc_factory.cpp | 110 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/pc_factory.h | 60 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/pocompendium.cpp | 1246 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/pocompendium.desktop | 50 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/pocompendium.h | 147 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/preferenceswidget.cpp | 352 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/preferenceswidget.h | 97 | ||||
-rw-r--r-- | kbabel/kbabeldict/modules/pocompendium/pwidget.ui | 280 |
11 files changed, 2747 insertions, 0 deletions
diff --git a/kbabel/kbabeldict/modules/pocompendium/Makefile.am b/kbabel/kbabeldict/modules/pocompendium/Makefile.am new file mode 100644 index 00000000..b4fe4974 --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/Makefile.am @@ -0,0 +1,39 @@ +## Makefile.am for pocompendium + +# this has all of the subdirectories that make will recurse into. if +# there are none, comment this out +#SUBDIRS = + + +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +kde_module_LTLIBRARIES = kbabeldict_pocompendium.la + +# set the include path for X, qt and KDE +INCLUDES = -I$(srcdir)/../.. -I../../../common -I$(srcdir)/../../../common $(all_includes) + + +# which sources should be compiled for kbabel +kbabeldict_pocompendium_la_SOURCES = pocompendium.cpp preferenceswidget.cpp \ + pc_factory.cpp pwidget.ui compendiumdata.cpp + +kbabeldict_pocompendium_la_LIBADD = ../../libkbabeldictplugin.la ../../../common/libkbabelcommon.la $(LIB_KDEUI) $(LIB_KIO) +kbabeldict_pocompendium_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined + + + +# these are the headers for your project +noinst_HEADERS = pocompendium.h preferenceswidget.h pc_factory.h \ + compendiumdata.h + + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + + +# this is where the kdelnk file will go +#datadir = $(kde_datadir)/kbabeldict/modules +#data_DATA = pocompendium.rc + +kde_services_DATA = pocompendium.desktop +EXTRA_DIST = $(kde_services_DATA) diff --git a/kbabel/kbabeldict/modules/pocompendium/compendiumdata.cpp b/kbabel/kbabeldict/modules/pocompendium/compendiumdata.cpp new file mode 100644 index 00000000..d862b236 --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/compendiumdata.cpp @@ -0,0 +1,261 @@ +/* **************************************************************************** + This file is part of KBabel + + Copyright (C) 2001 by Matthias Kiefer + <matthias.kiefer@gmx.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + +**************************************************************************** */ +#include "compendiumdata.h" + +#include <resources.h> +#include <catalog.h> +#include <tagextractor.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> + +using namespace KBabel; + +CompendiumData::CompendiumData(QObject *parent) + : QObject(parent) + , _active(false) + , _error(false) + , _initialized(false) + , _catalog(0) + , _exactDict(9887) + , _allDict(9887) + , _wordDict(9887) + , _textonlyDict(9887) +{ + _catalog = new Catalog(this, "CompendiumData::catalog", QString::null); + _exactDict.setAutoDelete(true); + _allDict.setAutoDelete(true); + _wordDict.setAutoDelete(true); + _textonlyDict.setAutoDelete(true); +} + + +bool CompendiumData::load(KURL url) +{ + if(_active) + return false; + + + _error = false; + _active = true; + + _exactDict.clear(); + _allDict.clear(); + _wordDict.clear(); + _textonlyDict.clear(); + + + emit progressStarts(i18n("Loading PO compendium")); + connect(_catalog, SIGNAL(signalProgress(int)), this, SIGNAL(progress(int))); + + ConversionStatus stat=_catalog->openURL(url); + + disconnect(_catalog, SIGNAL(signalProgress(int)) + , this, SIGNAL(progress(int))); + + + if( stat!= OK && stat != RECOVERED_PARSE_ERROR) + { + kdDebug(KBABEL_SEARCH) << "error while opening file " << url.prettyURL() << endl; + + _error = true; + _errorMsg = i18n("Error while trying to read file for PO Compendium module:\n%1") + .arg(url.prettyURL()); + + emit progressEnds(); + + _active = false; + _initialized=true; + + return false; + } + + emit progressStarts(i18n("Building indices")); + + int total = _catalog->numberOfEntries(); + for(int i=0; i < total; i++) + { + if( (100*(i+1))%total < 100 ) + { + emit progress((100*(i+1))/total); + kapp->processEvents(100); + } + + // FIXME: shoudl care about plural forms + QString temp = _catalog->msgid(i,true).first(); + + int *index = new int(i); + _exactDict.insert(temp,index); + + + temp = simplify(temp); + temp = temp.lower(); + + if(!temp.isEmpty() && temp.length() > 1) + { + // add to allDict + QValueList<int> *indexList=_allDict[temp]; + + if(!indexList) + { + indexList = new QValueList<int>; + _allDict.insert(temp,indexList); + } + + indexList->append(i); + + // add to textonlyDict + QString temp1 = temp; + temp1.remove( ' ' ); + + indexList=_textonlyDict[temp1]; + + if(!indexList) + { + indexList = new QValueList<int>; + _textonlyDict.insert(temp1,indexList); + kdDebug() << "Adding " << temp1 << endl; + } + + indexList->append(i); + + // add to wordDict + QStringList wList = wordList(temp); + for ( QStringList::Iterator it = wList.begin() + ; it != wList.end(); ++it ) + { + if( (*it).length() > 1) + { + indexList=_wordDict[*it]; + + if(!indexList) + { + indexList = new QValueList<int>; + _wordDict.insert(*it,indexList); + } + + indexList->append(i); + } + } + } + } + + // remove words, that are too frequent + uint max=_allDict.count()/10; + QDictIterator< QValueList<int> > it(_wordDict); + while ( it.current() ) + { + if(it.current()->count() > max) + { + _wordDict.remove(it.currentKey()); + } + else + { + ++it; + } + } + + + _initialized=true; + + emit progressEnds(); + + + + _active = false; + + return true; +} + +const int* CompendiumData::exactDict(const QString text) const +{ + return _exactDict[text]; +} + +const QValueList<int>* CompendiumData::allDict(const QString text) const +{ + return _allDict[text]; +} + +const QValueList<int>* CompendiumData::wordDict(const QString text) const +{ + return _wordDict[text]; +} + +const QValueList<int>* CompendiumData::textonlyDict(const QString text) const +{ + return _textonlyDict[text]; +} + + +void CompendiumData::registerObject(QObject *obj) +{ + if(!_registered.containsRef(obj)) + _registered.append(obj); +} + +bool CompendiumData::unregisterObject(QObject *obj) +{ + _registered.removeRef(obj); + + return _registered.count()==0; +} + +bool CompendiumData::hasObjects() const +{ + return _registered.count()==0; +} + +QString CompendiumData::simplify(const QString string) +{ + QString result; + + TagExtractor te; + te.setString(string); + result=te.plainString(); + + result=result.simplifyWhiteSpace(); + result=result.stripWhiteSpace(); + + return result; +} + +QStringList CompendiumData::wordList(const QString string) +{ + QString result=CompendiumData::simplify(string); + + return QStringList::split(' ',result); +} + +#include "compendiumdata.moc" diff --git a/kbabel/kbabeldict/modules/pocompendium/compendiumdata.h b/kbabel/kbabeldict/modules/pocompendium/compendiumdata.h new file mode 100644 index 00000000..2fec45cb --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/compendiumdata.h @@ -0,0 +1,105 @@ +/* **************************************************************************** + This file is part of KBabel + + Copyright (C) 2001 by Matthias Kiefer + <matthias.kiefer@gmx.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + +**************************************************************************** */ +#ifndef COMPENDIUMDATA_H +#define COMPENDIUMDATA_H + + +#include <kurl.h> +#include <qdict.h> +#include <qobject.h> +#include <qstringlist.h> +#include <qvaluelist.h> +#include <qptrlist.h> + +namespace KBabel +{ +class Catalog; +} + +class CompendiumData : public QObject +{ + Q_OBJECT + +public: + CompendiumData(QObject *parent=0); + + bool load(KURL url); + + const KBabel::Catalog *catalog() const { return _catalog; } + const int *exactDict(const QString text) const; + const QValueList<int> *allDict(const QString text) const; + const QValueList<int> *wordDict(const QString text) const; + const QValueList<int> *textonlyDict(const QString text) const; + + bool active() const { return _active; } + bool initialized() const { return _initialized; } + bool hasErrors() const { return _error; } + QString errorMsg() const { return _errorMsg; } + + /** registers an object, that uses this data */ + void registerObject(QObject *); + /** + * unregisters an object, that uses this data + * + * @return true, if this was the last object + */ + bool unregisterObject(QObject *); + + bool hasObjects() const; + + + static QString simplify(const QString text); + static QStringList wordList(const QString text); + +signals: + void progressStarts(const QString); + void progressEnds(); + void progress(int); + + +private: + bool _active; + bool _error; + bool _initialized; + QString _errorMsg; + + KBabel::Catalog *_catalog; + QDict<int> _exactDict; + QDict< QValueList<int> > _allDict; + QDict< QValueList<int> > _wordDict; + QDict< QValueList<int> > _textonlyDict; + + QPtrList<QObject> _registered; +}; + +#endif diff --git a/kbabel/kbabeldict/modules/pocompendium/pc_factory.cpp b/kbabel/kbabeldict/modules/pocompendium/pc_factory.cpp new file mode 100644 index 00000000..882cc064 --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/pc_factory.cpp @@ -0,0 +1,110 @@ +/* **************************************************************************** + This file is part of KBabel + + Copyright (C) 2000 by Matthias Kiefer + <matthias.kiefer@gmx.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + +**************************************************************************** */ + + +#include <klocale.h> +#include <kinstance.h> +#include <kaboutdata.h> +#include <kdebug.h> + +#include "pc_factory.h" +#include "pocompendium.h" + + +extern "C" +{ + KDE_EXPORT void *init_kbabeldict_pocompendium() + { + return new PcFactory; + } +} + + +KInstance *PcFactory::s_instance = 0; +KAboutData *PcFactory::s_about = 0; + + +PcFactory::PcFactory( QObject *parent, const char *name) + : KLibFactory(parent,name) +{ +} + +PcFactory::~PcFactory() +{ + if(s_instance) + { + delete s_instance; + s_instance=0; + } + + if(s_about) + { + delete s_about; + s_about=0; + } +} + + +QObject *PcFactory::createObject( QObject *parent, const char *name + , const char *classname, const QStringList &) +{ + if(QCString(classname) != "SearchEngine") + { + kdError() << "not a SearchEngine requested" << endl; + return 0; + } + + return new PoCompendium(parent,name); +} + + +KInstance *PcFactory::instance() +{ + if(!s_instance) + { + s_about = new KAboutData( "pocompendium", I18N_NOOP("PO Compendium") + , "1.0" + , I18N_NOOP("A module for searching in a PO file") + , KAboutData::License_GPL + , "Copyright 2000-2001, Matthias Kiefer" + ,0,0, "kiefer@kde.org"); + + s_about->addAuthor("Matthias Kiefer",0,"kiefer@kde.org"); + + s_instance = new KInstance(s_about); + } + + return s_instance; +} + +#include "pc_factory.moc" diff --git a/kbabel/kbabeldict/modules/pocompendium/pc_factory.h b/kbabel/kbabeldict/modules/pocompendium/pc_factory.h new file mode 100644 index 00000000..d52fadfe --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/pc_factory.h @@ -0,0 +1,60 @@ +/* **************************************************************************** + This file is part of KBabel + + Copyright (C) 2000 by Matthias Kiefer + <matthias.kiefer@gmx.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + +**************************************************************************** */ + + +#ifndef PC_FACTORY_H +#define PC_FACTORY_H + +#include <klibloader.h> +class KInstance; +class KAboutData; + +class PcFactory : public KLibFactory +{ + Q_OBJECT +public: + PcFactory( QObject *parent=0, const char *name=0); + ~PcFactory(); + + virtual QObject *createObject( QObject *parent=0, const char *name=0 + , const char *classname="QObject" + , const QStringList &args = QStringList()); + + static KInstance *instance(); + +private: + static KInstance *s_instance; + static KAboutData *s_about; +}; + +#endif diff --git a/kbabel/kbabeldict/modules/pocompendium/pocompendium.cpp b/kbabel/kbabeldict/modules/pocompendium/pocompendium.cpp new file mode 100644 index 00000000..0cd79fb3 --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/pocompendium.cpp @@ -0,0 +1,1246 @@ +/* **************************************************************************** + This file is part of KBabel + + Copyright (C) 2000 by Matthias Kiefer + <matthias.kiefer@gmx.de> + 2003 by Stanislav Visnovsky + <visnovsky@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + +**************************************************************************** */ +#include <klocale.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kstaticdeleter.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kinstance.h> +#include <kio/netaccess.h> + +#include <qregexp.h> +#include <qtextstream.h> +#include <qtimer.h> + +#include "resources.h" +#include "compendiumdata.h" +#include "pocompendium.h" +#include "preferenceswidget.h" +#include "pc_factory.h" + +#include <catalog.h> +#include <catalogitem.h> + +// ngram length and minimal matching for fuzzy search +#define NGRAM_LEN 3 +#define LIM_NGRAM 50 + +using namespace KBabel; + +static KStaticDeleter< QDict<CompendiumData> > compDataDeleter; +QDict<CompendiumData> *PoCompendium::_compDict = 0; + +PoCompendium::PoCompendium(QObject *parent, const char *name) + : SearchEngine(parent, name) +{ + prefWidget=0; + data=0; + error=false; + stop=false; + active=false; + initialized=false; + loading=false; + + langCode = KGlobal::locale()->language(); + + caseSensitive = false; + ignoreFuzzy=true; + wholeWords=true; + + matchEqual = true; + matchNGram = true; + matchIsContained = false; + matchContains = true; + matchWords=true; + + + loadTimer = new QTimer(this); + connect(loadTimer,SIGNAL(timeout()),this,SLOT(slotLoadCompendium())); +} + +PoCompendium::~PoCompendium() +{ + if(isSearching()) + { + stopSearch(); + } + + unregisterData(); +} + +bool PoCompendium::isReady() const +{ + return (isSearching() || !error); +} + + +bool PoCompendium::isSearching() const +{ + return (active || loading); +} + + +void PoCompendium::saveSettings(KConfigBase *config ) +{ + if(autoUpdate && prefWidget && prefWidget->settingsChanged()) + { + applySettings(); + } + + config->writeEntry("CaseSensitive",caseSensitive); + config->writeEntry("IgnoreFuzzy", ignoreFuzzy); + config->writeEntry("WholeWords", wholeWords); + + config->writeEntry("MatchEqual", matchEqual); + config->writeEntry("MatchIsContained",matchIsContained); + config->writeEntry("MatchContains", matchContains); + config->writeEntry("MatchWords", matchWords); + config->writeEntry("MatchNGram", matchNGram); + + config->writeEntry("Compendium", url); +} + +void PoCompendium::readSettings(KConfigBase *config) +{ + caseSensitive = config->readBoolEntry("CaseSensitive", false); + ignoreFuzzy = config->readBoolEntry("IgnoreFuzzy",true); + wholeWords = config->readBoolEntry("WholeWords",true); + + matchEqual = config->readBoolEntry("MatchEqual", true); + matchIsContained = config->readBoolEntry("MatchIsContained", false); + matchContains = config->readBoolEntry("MatchContains",true); + matchWords = config->readBoolEntry("MatchWords",true); + matchNGram = config->readBoolEntry("MatchNGram",true); + + QString newPath = config->readEntry("Compendium","http://i18n.kde.org/po_overview/@LANG@.messages"); + if(!initialized) + { + url = newPath; + } + else if(newPath != url) + { + url = newPath; + loadCompendium(); + } + + + restoreSettings(); +} + +PrefWidget *PoCompendium::preferencesWidget(QWidget *parent) +{ + prefWidget = new CompendiumPreferencesWidget(parent,"pocompendium_prefwidget"); + kdDebug(KBABEL_SEARCH) << "PreferencesWidget is " << prefWidget << endl; + connect(prefWidget, SIGNAL(applySettings()), this, SLOT(applySettings())); + connect(prefWidget, SIGNAL(restoreSettings()) + , this, SLOT(restoreSettings())); + + restoreSettings(); + + return prefWidget; +} + +const KAboutData *PoCompendium::about() const +{ + return PcFactory::instance()->aboutData(); +} + + +QString PoCompendium::name() const +{ + return i18n("PO Compendium"); +} + +QString PoCompendium::id() const +{ + return "pocompendium"; +} + +QString PoCompendium::lastError() +{ + return errorMsg; +} + +bool PoCompendium::searchExact(const QString& text, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& ) +{ + const int *index = data->exactDict(text); + if(index) + { + foundIndices.append(*index); + + SearchResult *result = new SearchResult; + result->requested = text; + result->found = data->catalog()->msgid(*index); +#warning kdWarning() << "PoCompendium can't return plural form translation" << endl; + result->translation = data->catalog()->msgstr(*index).first(); + result->score = 100; + + TranslationInfo *info = new TranslationInfo; + info->location = directory(realURL,0); + info->translator = catalogInfo.lastTranslator; + info->description = data->catalog()->comment(*index); + result->descriptions.append(info); + + addResult(result, results); + return true; + } + + return false; + +} + +bool PoCompendium::searchCaseInsensitive(const QString& text, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& ) +{ + QString searchStr = text.lower(); + + const QValueList<int> *indexList = data->allDict(text.lower()); + if(indexList) + { + QValueList<int>::ConstIterator it; + for( it = indexList->begin(); it != indexList->end(); ++it ) + { + if(foundIndices.contains(*it)) + { + continue; + } + + if(ignoreFuzzy && data->catalog()->isFuzzy(*it)) + { + continue; + } + + + QString origStr = data->catalog()->msgid(*it).first(); + origStr = CompendiumData::simplify(origStr); + + + if(!caseSensitive) + { + origStr = origStr.lower(); + } + + if(origStr==searchStr) + { + foundIndices.append(*it); + + SearchResult *result = new SearchResult; + result->requested = text; + result->found = data->catalog()->msgid(*it); + result->translation = *(data->catalog()->msgstr(*it).at(pluralForm)); + result->score = score(result->requested,*(result->found.at(pluralForm))); + + TranslationInfo *info = new TranslationInfo; + info->location = directory(realURL,0); + info->translator = catalogInfo.lastTranslator; + info->description = data->catalog()->comment(*it); + result->descriptions.append(info); + + addResult(result, results); + return true; + } + } + } + return false; +} + +bool PoCompendium::searchTextOnly(const QString& text, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& ) +{ + QString searchStr = text.lower(); + QString t = text; + t.remove( " " ); + + const QValueList<int> *indexList = data->textonlyDict(t.lower()); + if(indexList) + { + QValueList<int>::ConstIterator it; + for( it = indexList->begin(); it != indexList->end(); ++it ) + { + if(foundIndices.contains(*it)) + { + continue; + } + + if(ignoreFuzzy && data->catalog()->isFuzzy(*it)) + { + continue; + } + + + QString origStr = data->catalog()->msgid(*it).first(); + origStr = CompendiumData::simplify(origStr); + + + foundIndices.append(*it); + + SearchResult *result = new SearchResult; + result->requested = text; + result->found = data->catalog()->msgid(*it).first(); +#warning kdWarning() << "PoCompendium can't return plural form translation" << endl; + result->translation = data->catalog()->msgstr(*it).first(); + result->score = score(result->requested,*(result->found.at(pluralForm))); + + TranslationInfo *info = new TranslationInfo; + info->location = directory(realURL,0); + info->translator = catalogInfo.lastTranslator; + info->description = data->catalog()->comment(*it); + result->descriptions.append(info); + + addResult(result, results); + return true; + } + } + return false; +} + +bool PoCompendium::searchWords(const QString& searchStr, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& checkedIndices ) +{ + uint checkCounter = 0; + bool foundResults = false; + + QStringList wList = CompendiumData::wordList(searchStr); + for ( QStringList::Iterator wit = wList.begin() + ; wit != wList.end(); ++wit ) + { + if(stop) + break; + + const QValueList<int> *indexList = data->wordDict((*wit).lower()); + if(indexList) + { + QValueList<int>::ConstIterator it; + for( it = indexList->begin(); it != indexList->end(); ++it ) + { + if(stop) + break; + + if(foundIndices.contains(*it)) + { + continue; + } + + if(checkedIndices.contains(*it)) + { + continue; + } + + checkedIndices.append(*it); + checkCounter++; + + if(ignoreFuzzy && data->catalog()->isFuzzy(*it)) + { + continue; + } + + if( (100*(checkCounter+1))%catalogInfo.total < 100) + { + emit progress( (50*checkCounter+1)/catalogInfo.total); + } + + kapp->processEvents(100); + + QString origStr = data->catalog()->msgid(*it).first(); + origStr = CompendiumData::simplify(origStr); + + + if(!caseSensitive) + { + origStr = origStr.lower(); + } + + bool found = false; + if(matchWords) + { + if(!caseSensitive) + { + found=true; + } + else + { + QString s=*wit; + QString o=origStr; + + if(wholeWords) + { + s=" "+*wit+" "; + o=" "+origStr+" "; + } + if(o.contains(s)) + { + found=true; + } + } + } + + + if(!found && origStr==searchStr) + { + found =true; + } + + // if there is an string which just contains ignored characters, + // continue + if(!found && origStr.isEmpty() || + (origStr.length() == 1 && searchStr.length() > 1)) + { + continue; + } + + + if(!found && matchContains && !wholeWords) + { + QString s=maskString(searchStr); + QRegExp searchReg(s); + + if(searchReg.search(origStr) >= 0) + found=true; + } + + if(!found && matchIsContained && !wholeWords) + { + QString s=maskString(origStr); + QRegExp reg(s); + + if(reg.search(searchStr) >= 0) + { + found = true; + } + } + if(!found && matchWords && !wholeWords) + { + QStringList list = CompendiumData::wordList(searchStr); + + for ( QStringList::Iterator wit2 = list.begin() + ; wit2 != list.end(); ++wit2 ) + { + QString s=maskString(*wit2); + QRegExp reg(s); + + if(reg.search(origStr) >= 0) + { + found = true; + } + } + } + + if(found) + { + foundIndices.append(*it); + + SearchResult *result = new SearchResult; + result->requested = searchStr; // FIXME:here should be the original text + result->found = data->catalog()->msgid(*it).first(); +#warning kdWarning() << "PoCompendium can't return plural form translation" << endl; + result->translation = data->catalog()->msgstr(*it).first(); + result->score = score(result->requested,*(result->found.at(pluralForm))); + + TranslationInfo *info = new TranslationInfo; + info->location = directory(realURL,0); + info->translator = catalogInfo.lastTranslator; + info->description = data->catalog()->comment(*it); + result->descriptions.append(info); + + addResult(result, results); + + foundResults = true; + } + } + } + } + + return foundResults; +} + +bool PoCompendium::searchNGram(const QString& searchStr, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& checkedIndices ) +{ + uint checkCounter = 0; + bool foundResults = false; + + QRegExp searchReg; + if(matchContains) + { + QString s=maskString(searchStr); + searchReg.setPattern(s); + } + + + bool breakLoop=false; + int i=-1; + while(!breakLoop) + { + if(stop) + { + breakLoop=true; + break; + } + + i++; + + if(i >= catalogInfo.total) + { + breakLoop = true; + break; + } + + if( (100*(checkCounter+1))%catalogInfo.total < 100) + { + emit progress( 50+(50*(checkCounter+1))/catalogInfo.total); + } + + if(checkedIndices.contains(i)) + { + continue; + } + + checkedIndices.append(i); + checkCounter++; + + if(ignoreFuzzy && data->catalog()->isFuzzy(i)) + { + continue; + } + + if(foundIndices.contains(i)) + { + continue; + } + + kapp->processEvents(100); + + QString origStr = data->catalog()->msgid(i).first(); + origStr = CompendiumData::simplify(origStr); + + if(!caseSensitive) + { + origStr = origStr.lower(); + } + + + // if there is an string which just contains ignored characters, + // continue + if(origStr.isEmpty() || + (origStr.length() == 1 && searchStr.length() > 1)) + { + continue; + } + + bool found = false; + if(matchContains && searchReg.search(origStr) >= 0) + { + found=true; + } + + if(!found && matchIsContained) + { + QString s=maskString(origStr); + QRegExp reg(s); + + if(reg.search(searchStr) >= 0) + { + found = true; + } + } + + if(!found && matchWords) + { + QStringList list = CompendiumData::wordList(searchStr); + + for ( QStringList::Iterator wit2 = list.begin() + ; wit2 != list.end(); ++wit2 ) + { + QString s=maskString(*wit2); + + if(wholeWords) + { + origStr = " "+origStr+" "; + s=" "+s+" "; + } + QRegExp reg(s); + + if(reg.search(origStr) >= 0) + { + found = true; + } + } + } + + if(!found && matchNGram) + { + // to get more results one could + // interchange searchStr and origStr when + // the latter is shorter + + found = ( ngramMatch(searchStr,origStr,NGRAM_LEN) + > LIM_NGRAM ); + } + + if(found) + { + foundIndices.append(i); + + SearchResult *result = new SearchResult; + result->requested = searchStr; + result->found = data->catalog()->msgid(i).first(); + result->translation = data->catalog()->msgstr(i).first(); +#warning kdWarning() << "PoCompendium can't return plural form translation" << endl; + result->score = score(result->requested,*(result->found.at(pluralForm))); + + TranslationInfo *info = new TranslationInfo; + info->location = directory(realURL,0); + info->translator = catalogInfo.lastTranslator; + info->description = data->catalog()->comment(i); + result->descriptions.append(info); + + addResult(result, results); + + foundResults = true; + } + } + + return foundResults; +} + +bool PoCompendium::startSearch(const QString& text, uint pluralForm, const SearchFilter* filter) +{ + if(autoUpdate && prefWidget && prefWidget->settingsChanged()) + { + applySettings(); + } + + if(isSearching()) + return false; + + clearResults(); + stop = false; + active = true; + + if(!initialized) + { + if(loadTimer->isActive()) + loadTimer->stop(); + + slotLoadCompendium(); + } + + if(error || !data) + { + active = false; + return false; + } + + if(data->active()) + { + active = false; + return true; + } + + emit started(); + + + QValueList<int> foundIndices; + QValueList<int> checkedIndices; + + // first, exact search + searchExact(text, pluralForm, results, foundIndices, checkedIndices); + + QString searchStr=CompendiumData::simplify(text); + + + if(!caseSensitive) + { + searchStr = searchStr.lower(); + + // do case insensite search if necessary + searchCaseInsensitive(searchStr, pluralForm, results, foundIndices, checkedIndices); + } + + // search without whitespace + searchTextOnly(searchStr, pluralForm, results, foundIndices, checkedIndices); + + // now, search based on words (contains, is contained, etc) + searchWords(searchStr, pluralForm, results, foundIndices, checkedIndices); + + + if( matchNGram || + (!wholeWords && (matchContains || matchIsContained || matchWords)) + ) + { + // search based on ngrams + searchNGram(searchStr, pluralForm, results, foundIndices, checkedIndices); + } + + emit progress(100); + + active = false; + stop = false; + emit finished(); + + return true; +} + +void PoCompendium::stopSearch() +{ + stop=true; +} + + +void PoCompendium::applySettings() +{ + if(!prefWidget) + return; + + if(isSearching()) + stopSearch(); + + caseSensitive = prefWidget->caseSensitive(); + ignoreFuzzy = prefWidget->ignoreFuzzy(); + wholeWords = prefWidget->wholeWords(); + + matchEqual = prefWidget->matchEqual(); + matchNGram = prefWidget->matchNGram(); + matchIsContained = prefWidget->matchIsContained(); + matchContains = prefWidget->matchContains(); + matchWords = prefWidget->matchWords(); + + + bool needLoading=false; + + + QString newPath = prefWidget->url(); + if(!initialized) + { + url = newPath; + } + else if(newPath != url) + { + url = newPath; + needLoading = true; + } + + if(needLoading) + { + loadCompendium(); + initialized=false; + } +} + +void PoCompendium::restoreSettings() +{ + if(!prefWidget) + return; + + prefWidget->setCaseSensitive(caseSensitive); + prefWidget->setIgnoreFuzzy(ignoreFuzzy); + prefWidget->setWholeWords(wholeWords); + prefWidget->setURL(url); + + prefWidget->setMatchEqual(matchEqual); + prefWidget->setMatchNGram(matchNGram); + prefWidget->setMatchIsContained(matchIsContained); + prefWidget->setMatchContains(matchContains); + prefWidget->setMatchWords(matchWords); +} + +void PoCompendium::loadCompendium() +{ + if(!loading && !loadTimer->isActive()) + loadTimer->start(100,true); +} + +void PoCompendium::slotLoadCompendium() +{ + if(loading) + return; + + if(loadTimer->isActive()) + loadTimer->stop(); + + loading = true; + + if(data) + { + unregisterData(); + } + + + QString path=url; + + if(path.contains("@LANG@")) + { + path.replace("@LANG@",langCode); + } + KURL u=KCmdLineArgs::makeURL(path.local8Bit()); + realURL = u.url(); + + registerData(); + + + if(!data) + { + kdError() << "no data object in pocompendium?" << endl; + + loading=false; + return; + } + + if(!data->initialized()) + { + if(!data->active()) + { + data->load(u); + recheckData(); + if(error) + { + emit hasError(errorMsg); + } + } + else + { + connect(data, SIGNAL(progressEnds()), this, SLOT(recheckData())); + } + } + else + { + recheckData(); + if(error) + { + emit hasError(errorMsg); + } + } + + initialized=true; +} + +void PoCompendium::recheckData() +{ + if(data) + { + disconnect(data, SIGNAL(progressEnds()), this, SLOT(recheckData())); + + error = data->hasErrors(); + errorMsg = data->errorMsg(); + + if(!error) + { + catalogInfo = Catalog::headerInfo(data->catalog()->header()); + catalogInfo.total = data->catalog()->numberOfEntries(); + catalogInfo.fuzzy = data->catalog()->numberOfFuzzies(); + catalogInfo.untranslated = data->catalog()->numberOfUntranslated(); + } + } + + loading=false; +} + +QString PoCompendium::maskString(QString s) +{ + s.replace("\\","\\\\"); + s.replace("\?","\\?"); + s.replace("[","\\["); + s.replace(".","\\."); + s.replace("*","\\*"); + s.replace("+","\\+"); + s.replace("^","\\^"); + s.replace("$","\\$"); + s.replace("(","\\("); + s.replace(")","\\)"); + s.replace("{","\\{"); + s.replace("}","\\}"); + s.replace("|","\\|"); + + return s; +} + +void PoCompendium::addResult(SearchResult *result, QPtrList<SearchResult>& res) +{ + if(res.last() && res.last()->score >= result->score) + { + res.append(result); + } + else + { + SearchResult *sr; + for(sr = res.first(); sr != 0; sr=res.next()) + { + if(sr->score < result->score) + { + int pos = res.at(); + if( pos < 0 ) pos = 0; + res.insert( pos,result); + emit resultsReordered(); + break; + } + } + + if(!sr) + { + res.append(result); + } + } + + emit numberOfResultsChanged(res.count()); + emit resultFound(result); +} + + +void PoCompendium::setLanguageCode(const QString& lang) +{ + if(initialized && url.contains("@LANG@") && lang!=langCode + && !loadTimer->isActive() ) + { + initialized=false; + } + + langCode=lang; +} + +QString PoCompendium::translate(const QString& text, uint pluralForm) +{ + if(!initialized) + { + if(loadTimer->isActive()) + loadTimer->stop(); + + slotLoadCompendium(); + } + + if(error || !data || data->active()) + { + return QString::null; + } + + + const int *index = data->exactDict(text); + + if(index) + { +#warning kdWarning() << "PoCompendium can't return plural form translation" << endl; + return data->catalog()->msgstr(*index).first(); + } + + return QString::null; +} + +QString PoCompendium::fuzzyTranslation(const QString& text, int &score, const uint pluralForm) +{ + if(!initialized) + { + if(loadTimer->isActive()) + loadTimer->stop(); + + slotLoadCompendium(); + } + + if(error || !data || data->active()) + { + return QString::null; + } + + // try to find fuzzy string + bool breakLoop = false; + stop = false; + int i=-1; + int best_matching = -1; + int best_match = 0; + int total = data->catalog()->numberOfEntries(); + + QString searchStr = CompendiumData::simplify(text); + + //kdDebug(750) << "find best match for " << searchStr << endl; + + while(!breakLoop) + { + + // progress and loop control + if(stop) + { + breakLoop=true; + break; + } + + i++; + + if(i >= total) + { + breakLoop = true; + break; + } + + if( (100*(i+1))%total < 100) + { + emit progress( (100*(i+1))/total); + } + + // get a message from the catalog FIXME: plurals + QString origStr = data->catalog()->msgid(i).first(); + origStr = CompendiumData::simplify(origStr); + + // don't match too long strings for short search string + if (origStr.length() > 2*searchStr.length()) + continue; + // kdDebug(750) << i << ": matching " << origStr << endl; + + int ngram_result = ngramMatch(searchStr,origStr); + + if (ngram_result > best_match) { + best_match = ngram_result; + best_matching = i; + + // kdDebug(750) << "[" << ngram_result << "] " << text << "-" + // << origStr << endl; + } + } + + if (best_match > LIM_NGRAM) { + score = best_match; +#warning kdWarning() << "PoCompendium can't return plural form translation" << endl; + return data->catalog()->msgstr(best_matching).first(); + } + + return QString::null; +} + + +QString PoCompendium::searchTranslation(const QString& text, int &sc, const uint pluralForm) +{ + if(autoUpdate && prefWidget && prefWidget->settingsChanged()) + { + applySettings(); + } + + if(isSearching()) + return QString::null; + + clearResults(); + stop = false; + active = true; + + if(!initialized) + { + if(loadTimer->isActive()) + loadTimer->stop(); + + slotLoadCompendium(); + } + + if(error || !data) + { + active = false; + return QString::null; + } + + if(data->active()) + { + active = false; + return QString::null; + } + + emit started(); + + QPtrList<SearchResult> res; + + QValueList<int> foundIndices; + QValueList<int> checkedIndices; + + // first, exact search + if( searchExact(text, pluralForm, res, foundIndices, checkedIndices) ) + { + active = false; + stop = false; + emit finished(); + + // found, this is the best + sc = res.first()->score; + return res.first()->translation; + } + + QString searchStr=CompendiumData::simplify(text); + + + if(!caseSensitive) + { + searchStr = searchStr.lower(); + + // do case insensite search if necessary + if( searchCaseInsensitive(searchStr, pluralForm, res, foundIndices, checkedIndices) ) + { + active = false; + stop = false; + emit finished(); + + // found, return this one + sc = res.first()->score; + return res.first()->translation; + } + } + + // search without whitespace + QString s = searchStr; + s.remove( ' ' ); + if( searchTextOnly(s, pluralForm, res, foundIndices, checkedIndices) ) + { + active = false; + stop = false; + emit finished(); + + // found, return this one + sc = res.first()->score; + return res.first()->translation; + } + + // now, search based on words (contains, is contained, etc) + searchWords(searchStr, pluralForm, res, foundIndices, checkedIndices); + + if( matchNGram || + (!wholeWords && (matchContains || matchIsContained || matchWords)) + ) + { + // search based on ngrams + searchNGram(searchStr, pluralForm, res, foundIndices, checkedIndices); + } + + active = false; + stop = false; + + // now, pick up the best one from not exact translations + if( res.count() > 0 ) { + + emit finished(); + + sc = res.first()->score; + return res.first()->translation; + } + + sc = 0; + + return QString::null; +} + + +void PoCompendium::unregisterData() +{ + if(data) + { + disconnect(data, SIGNAL(progressStarts(const QString&)), this + , SIGNAL(progressStarts(const QString&))); + disconnect(data, SIGNAL(progressEnds()), this , SIGNAL(progressEnds())); + disconnect(data, SIGNAL(progress(int)), this , SIGNAL(progress(int))); + + if(data->active()) + { + disconnect(data,SIGNAL(progressEnds()),this,SLOT(recheckData())); + } + + if(data->unregisterObject(this)) + { + if(!data->active()) + { + compendiumDict()->remove(realURL); + } + else + { + connect(data,SIGNAL(progressEnds()),this,SLOT(removeData())); + } + } + + data=0; + } +} + +void PoCompendium::registerData() +{ + data = compendiumDict()->find(realURL); + if(!data) + { + data = new CompendiumData; + compendiumDict()->insert(realURL,data); + } + + data->registerObject(this); + + if(data->active()) + { + emit progressStarts(i18n("Loading PO compendium")); + } + + connect(data, SIGNAL( + progressStarts(const QString&)), this + , SIGNAL(progressStarts(const QString&))); + connect(data, SIGNAL(progressEnds()), this , SIGNAL(progressEnds())); + connect(data, SIGNAL(progress(int)), this , SIGNAL(progress(int))); +} + +void PoCompendium::removeData() +{ + const QObject *s=sender(); + if(s && s->inherits("CompendiumData")) + { + const CompendiumData *d=static_cast<const CompendiumData*>(s); + if(d) + { + QDictIterator<CompendiumData> it(*compendiumDict()); + while(it.current()) + { + if(it.current() == d) + { + if(!d->hasObjects()) + { + compendiumDict()->remove(it.currentKey()); + } + + break; + } + + ++it; + } + } + + } +} + +QDict<CompendiumData> *PoCompendium::compendiumDict() +{ + if(!_compDict) + { + _compDict=compDataDeleter.setObject( new QDict<CompendiumData> ); + _compDict->setAutoDelete(true); + } + + return _compDict; +} + + + +#include "pocompendium.moc" diff --git a/kbabel/kbabeldict/modules/pocompendium/pocompendium.desktop b/kbabel/kbabeldict/modules/pocompendium/pocompendium.desktop new file mode 100644 index 00000000..ac9ee368 --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/pocompendium.desktop @@ -0,0 +1,50 @@ +[Desktop Entry] +Type=Service +Name=PO Compendium Module for KBabelDict +Name[bg]=PO компендиум за KBabelDict +Name[bs]=Modul PO kompendijuma za KBabelDict +Name[ca]=Mòdul del Compendi PO per a KBabelDict +Name[cs]=Modul s PO kompendiem pro KBabelDict +Name[cy]=Modiwl Compendiwm PO i KBabelDict +Name[da]=PO-kompendium-module for KBabelDict +Name[de]=PO-Kompendium-Modul für KBabelDict +Name[el]=Άρθρωμα επιτομής PO για το KBabelDict +Name[es]=Módulo de compendio de PO para KBabelDict +Name[et]=KBabelDicti PO kompendiumi moodul +Name[eu]=PO laburpen modulua KBabelDict-entzat +Name[fa]=پیمانۀ مختصر PO برای KBabelDict +Name[fi]=KBabelDict-ohjelman PO-kokoelmatiedostomoduuli +Name[fr]=Module de fichier de référence PO pour KBabelDict +Name[gl]=Módulo de compendio PO para KBabelDict +Name[hi]=के-बेबल-डिक्श के लिए पीओ कम्पेंडियम मॉड्यूल +Name[hu]=PO összefoglaló modul a KBabelDicthez +Name[is]=PO ágrips eining fyrir KBabel orðabókina +Name[it]=Modulo PO Compendium per KBabelDict +Name[ja]=KBabelDict PO 要約モジュール +Name[ka]=PO კონსპექტის მოდული KBabelDict-სთვის +Name[kk]=KBabelDict-тың PO аудармалар жиынтық модулі +Name[lt]=KBabelDict PO tekstyno modulis +Name[ms]=Modul Kompendium PO untuk KBabelDict +Name[nb]=PO-kompendiummodul for KBabelDict +Name[nds]=PO-Kompendiummoduul för KBabelDict +Name[ne]=KBabelDict का लागि संक्षेप पीओ मोड्युल +Name[nl]=PO-samenvattingmodule voor KBabelDict +Name[nn]=PO-kompendiemodul for KBabelDict +Name[pa]=ਕੇਬਬੇਲ-ਸ਼ਬਦਕੋਸ਼ ਲਈ PO ਸੰਖੇਪ ਮੈਡੀਊਲ +Name[pl]=Moduł Kompendium PO dla KBabelDict +Name[pt]=Módulo de Compêndio de PO para o KBabelDict +Name[pt_BR]=Módulo de Compêndio PO para o KBabelDict +Name[ru]=Модуль описания PO для KBabelDict +Name[sk]=Kompendium pre KBabelDict +Name[sl]=Modul zbornika PO za KBabelDict +Name[sr]=Модул PO зборника за KBabelDict +Name[sr@Latn]=Modul PO zbornika za KBabelDict +Name[sv]=PO-kompendiemodul för Kbabeldict +Name[ta]=Kபாபேலுக்கான காம்பென்டியம் PO கூறு +Name[tg]=Модули тасвири PO барои KBabelDict +Name[tr]=KBabelDict için PO Özet Modülü +Name[uk]=Модуль збірки перекладів PO для KBabelDict +Name[zh_CN]=KBabelDict 的 PO 概要词典模块 +Name[zh_TW]=KBabelDict PO 摘要模組 +X-KDE-Library=kbabeldict_pocompendium +ServiceTypes=KBabelDictModule diff --git a/kbabel/kbabeldict/modules/pocompendium/pocompendium.h b/kbabel/kbabeldict/modules/pocompendium/pocompendium.h new file mode 100644 index 00000000..6d92fb58 --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/pocompendium.h @@ -0,0 +1,147 @@ +/* **************************************************************************** + This file is part of KBabel + + Copyright (C) 2000 by Matthias Kiefer + <matthias.kiefer@gmx.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + +**************************************************************************** */ + +#ifndef POCOMPENDIUM_H +#define POCOMPENDIUM_H + +#include <poinfo.h> + +#include "compendiumdata.h" +#include "searchengine.h" + +#include <qdict.h> +#include <qfile.h> +#include <qguardedptr.h> +#include <qptrlist.h> + +class CompendiumPreferencesWidget; +class KConfigBase; +class QTimer; + +class PoCompendium : public SearchEngine +{ + Q_OBJECT + +public: + PoCompendium(QObject *parent=0, const char *name=0); + virtual ~PoCompendium(); + + virtual bool isReady() const; + + virtual QString translate(const QString&text, uint pluralForm); + virtual QString searchTranslation(const QString&, int &score, const uint pluralForm); + virtual QString fuzzyTranslation(const QString&, int &score, const uint pluralForm); + + virtual bool isSearching() const; + + virtual void saveSettings(KConfigBase *config); + virtual void readSettings(KConfigBase *config); + + virtual PrefWidget *preferencesWidget(QWidget *parent); + + virtual const KAboutData *about() const; + + virtual QString name() const; + + virtual QString id() const; + + virtual QString lastError(); + + +public slots: + virtual bool startSearch(const QString& s, uint pluralForm = 0, const SearchFilter* filter = 0); + virtual void stopSearch(); + virtual void setLanguageCode(const QString& lang); + +protected slots: + /** reads the current settings from the preferences dialog */ + void applySettings(); + + /** sets the current settings in the preferences dialog */ + void restoreSettings(); + + void slotLoadCompendium(); + + void recheckData(); + void removeData(); + +protected: + void loadCompendium(); + void addResult(SearchResult *, QPtrList<SearchResult>& allResults); + QString maskString(QString string); + + void registerData(); + void unregisterData(); + + bool searchExact(const QString& searchString, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& checkedIndices ); + bool searchTextOnly(const QString& searchString, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& checkedIndices ); + bool searchCaseInsensitive(const QString& searchString, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& checkedIndices ); + bool searchWords(const QString& searchString, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& checkedIndices ); + bool searchNGram(const QString& searchString, uint pluralForm, QPtrList<SearchResult>& results, QValueList<int>& foundIndices, QValueList<int>& checkedIndices ); + +private: + QGuardedPtr<CompendiumPreferencesWidget> prefWidget; + CompendiumData *data; + KBabel::PoInfo catalogInfo; + QTimer *loadTimer; + + QString url; + QString realURL; + QString langCode; + + bool caseSensitive; + bool ignoreFuzzy; + bool wholeWords; + + bool matchEqual; + bool matchIsContained; + bool matchContains; + bool matchWords; + bool matchNGram; + + bool buildIndex; + uint freeMemDelay; + + bool error; + QString errorMsg; + + bool stop; + bool active; + bool initialized; + bool loading; + + static QDict<CompendiumData> *_compDict; + static QDict<CompendiumData> *compendiumDict(); +}; + +#endif diff --git a/kbabel/kbabeldict/modules/pocompendium/preferenceswidget.cpp b/kbabel/kbabeldict/modules/pocompendium/preferenceswidget.cpp new file mode 100644 index 00000000..c3ce730d --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/preferenceswidget.cpp @@ -0,0 +1,352 @@ +/* **************************************************************************** + This file is part of KBabel + + Copyright (C) 2000 by Matthias Kiefer + <matthias.kiefer@gmx.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + +**************************************************************************** */ +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> + +#include <kfiledialog.h> +#include <qpushbutton.h> +#include <qwhatsthis.h> +#include <klineedit.h> +#include <klocale.h> +#include <kurlrequester.h> + +#include "preferenceswidget.h" +#include "pwidget.h" + +CompendiumPreferencesWidget::CompendiumPreferencesWidget(QWidget *parent, const char* name) + : PrefWidget(parent,name) + , changed(false) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + + prefWidget = new CompendiumPWidget(this); + layout->addWidget(prefWidget); + + connect(prefWidget->caseBtn, SIGNAL(toggled(bool)) + , this, SLOT(setChanged())); + connect(prefWidget->equalBtn, SIGNAL(toggled(bool)) + , this, SLOT(setChanged())); + connect(prefWidget->ngramBtn, SIGNAL(toggled(bool)) + , this, SLOT(setChanged())); + connect(prefWidget->isContainedBtn, SIGNAL(toggled(bool)) + , this, SLOT(setChanged())); + connect(prefWidget->containsBtn, SIGNAL(toggled(bool)) + , this, SLOT(setChanged())); + connect(prefWidget->fuzzyBtn, SIGNAL(toggled(bool)) + , this, SLOT(setChanged())); + connect(prefWidget->hasWordBtn, SIGNAL(toggled(bool)) + , this, SLOT(setChanged())); + connect(prefWidget->wholeBtn, SIGNAL(toggled(bool)) + , this, SLOT(setChanged())); + + connect(prefWidget->urlInput->lineEdit(),SIGNAL(textChanged(const QString&)) + , this, SLOT(setChanged())); + + connect(prefWidget->equalBtn, SIGNAL(toggled(bool)) + , this, SLOT(equalBtnToggled(bool))); + connect(prefWidget->ngramBtn, SIGNAL(toggled(bool)) + , this, SLOT(ngramBtnToggled(bool))); + connect(prefWidget->isContainedBtn, SIGNAL(toggled(bool)) + , this, SLOT(isContainedBtnToggled(bool))); + connect(prefWidget->containsBtn, SIGNAL(toggled(bool)) + , this, SLOT(containsBtnToggled(bool))); + connect(prefWidget->hasWordBtn, SIGNAL(toggled(bool)) + , this, SLOT(hasWordBtnToggled(bool))); + + + QString whatsthis=i18n("<qt><p><b>Parameters</b></p>" + "<p>Here you can fine-tune searching within the PO file. " + "For example if you want to perform a case sensitive search, or if " + "you want fuzzy messages to be ignored.</p></qt>" ); + QWhatsThis::add(prefWidget->caseBtn,whatsthis); + QWhatsThis::add(prefWidget->fuzzyBtn,whatsthis); + QWhatsThis::add(prefWidget->wholeBtn,whatsthis); + + whatsthis = i18n("<qt><p><b>Comparison Options</b></p>" + "<p>Choose here which messages you want to have treated as a matching " + "message.</p></qt>"); + QWhatsThis::add(prefWidget->equalBtn,whatsthis); + QWhatsThis::add(prefWidget->containsBtn,whatsthis); + QWhatsThis::add(prefWidget->isContainedBtn,whatsthis); + QWhatsThis::add(prefWidget->hasWordBtn,whatsthis); + + whatsthis = i18n("<qt><p><b>3-Gram-matching</b></p>" + "<p>A message matches another if most of its 3-letter groups are " + "contained in the other message. e.g. 'abc123' matches 'abcx123c12'.</p></qt>"); + QWhatsThis::add(prefWidget->ngramBtn,whatsthis); + + whatsthis = i18n("<qt><p><b>Location</b></p>" + "<p>Configure here which file is to be used for searching." + "</p></qt>"); + QWhatsThis::add(prefWidget->urlInput,whatsthis); +} + +CompendiumPreferencesWidget::~CompendiumPreferencesWidget() +{ +} + + +void CompendiumPreferencesWidget::apply() +{ + emit applySettings(); +} + +void CompendiumPreferencesWidget::cancel() +{ + emit restoreSettings(); +} + +void CompendiumPreferencesWidget::standard() +{ + prefWidget->urlInput->setURL("http://i18n.kde.org/po_overview/@LANG@.messages"); + prefWidget->caseBtn->setChecked(false); + prefWidget->equalBtn->setChecked(true); + prefWidget->ngramBtn->setChecked(true); + prefWidget->isContainedBtn->setChecked(false); + prefWidget->containsBtn->setChecked(false); + prefWidget->wholeBtn->setChecked(true); + prefWidget->hasWordBtn->setChecked(true); + + prefWidget->fuzzyBtn->setChecked(true); + + changed=true; +} + +void CompendiumPreferencesWidget::setURL(const QString url) +{ + prefWidget->urlInput->setURL(url); + changed=false; +} + +void CompendiumPreferencesWidget::setCaseSensitive(bool on) +{ + prefWidget->caseBtn->setChecked(on); + changed=false; +} + +void CompendiumPreferencesWidget::setMatchEqual(bool on) +{ + prefWidget->equalBtn->setChecked(on); + changed=false; +} + +void CompendiumPreferencesWidget::setMatchNGram(bool on) +{ + prefWidget->ngramBtn->setChecked(on); + changed=false; +} + +void CompendiumPreferencesWidget::setMatchIsContained(bool on) +{ + prefWidget->isContainedBtn->setChecked(on); + changed=false; +} + +void CompendiumPreferencesWidget::setMatchContains(bool on) +{ + prefWidget->containsBtn->setChecked(on); + changed=false; +} + +void CompendiumPreferencesWidget::setIgnoreFuzzy(bool on) +{ + prefWidget->fuzzyBtn->setChecked(on); + changed=false; +} + +void CompendiumPreferencesWidget::setWholeWords(bool on) +{ + prefWidget->wholeBtn->setChecked(on); + changed=false; +} + + +void CompendiumPreferencesWidget::setMatchWords(bool on) +{ + prefWidget->hasWordBtn->setChecked(on); + changed=false; +} + + + +QString CompendiumPreferencesWidget::url() +{ + changed=false; + return prefWidget->urlInput->url(); +} + +bool CompendiumPreferencesWidget::caseSensitive() +{ + changed=false; + + return prefWidget->caseBtn->isChecked(); +} + +bool CompendiumPreferencesWidget::matchEqual() +{ + changed=false; + + return prefWidget->equalBtn->isChecked(); +} + +bool CompendiumPreferencesWidget::matchNGram() +{ + changed=false; + + return prefWidget->ngramBtn->isChecked(); +} + +bool CompendiumPreferencesWidget::matchIsContained() +{ + changed=false; + + return prefWidget->isContainedBtn->isChecked(); +} + +bool CompendiumPreferencesWidget::matchContains() +{ + changed=false; + + return prefWidget->containsBtn->isChecked(); +} + +bool CompendiumPreferencesWidget::ignoreFuzzy() +{ + changed=false; + + return prefWidget->fuzzyBtn->isChecked(); +} + + +bool CompendiumPreferencesWidget::wholeWords() +{ + changed=false; + + return prefWidget->wholeBtn->isChecked(); +} + + +bool CompendiumPreferencesWidget::matchWords() +{ + changed=false; + + return prefWidget->hasWordBtn->isChecked(); +} + + + +bool CompendiumPreferencesWidget::settingsChanged() const +{ + return changed; +} + +void CompendiumPreferencesWidget::setChanged() +{ + changed=true; +} + + +void CompendiumPreferencesWidget::equalBtnToggled(bool on) +{ + if(!on) + { + if(!prefWidget->isContainedBtn->isChecked() + && !prefWidget->ngramBtn->isChecked() + && !prefWidget->containsBtn->isChecked() + && !prefWidget->hasWordBtn->isChecked()) + { + prefWidget->equalBtn->setChecked(true); + } + } +} + +void CompendiumPreferencesWidget::ngramBtnToggled(bool on) +{ + if(!on) + { + if(!prefWidget->isContainedBtn->isChecked() + && !prefWidget->equalBtn->isChecked() + && !prefWidget->containsBtn->isChecked() + && !prefWidget->hasWordBtn->isChecked()) + { + prefWidget->equalBtn->setChecked(true); + } + } +} + +void CompendiumPreferencesWidget::isContainedBtnToggled(bool on) +{ + if(!on) + { + if(!prefWidget->equalBtn->isChecked() + && !prefWidget->ngramBtn->isChecked() + && !prefWidget->containsBtn->isChecked() + && !prefWidget->hasWordBtn->isChecked()) + { + prefWidget->isContainedBtn->setChecked(true); + } + } +} + +void CompendiumPreferencesWidget::containsBtnToggled(bool on) +{ + if(!on) + { + if(!prefWidget->isContainedBtn->isChecked() + && !prefWidget->ngramBtn->isChecked() + && !prefWidget->equalBtn->isChecked() + && !prefWidget->hasWordBtn->isChecked()) + { + prefWidget->containsBtn->setChecked(true); + } + } +} + +void CompendiumPreferencesWidget::hasWordBtnToggled(bool on) +{ + if(!on) + { + if(!prefWidget->isContainedBtn->isChecked() + && !prefWidget->ngramBtn->isChecked() + && !prefWidget->equalBtn->isChecked() + && !prefWidget->containsBtn->isChecked()) + { + prefWidget->hasWordBtn->setChecked(true); + } + } +} + + + +#include "preferenceswidget.moc" diff --git a/kbabel/kbabeldict/modules/pocompendium/preferenceswidget.h b/kbabel/kbabeldict/modules/pocompendium/preferenceswidget.h new file mode 100644 index 00000000..db70df4d --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/preferenceswidget.h @@ -0,0 +1,97 @@ +/* **************************************************************************** + This file is part of KBabel + + Copyright (C) 2000 by Matthias Kiefer + <matthias.kiefer@gmx.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + +**************************************************************************** */ + + +#ifndef PREFERENCESWIDGET_H +#define PREFERENCESWIDGET_H + +#include "searchengine.h" + +class CompendiumPWidget; + +class CompendiumPreferencesWidget : public PrefWidget +{ + Q_OBJECT + +public: + CompendiumPreferencesWidget(QWidget *parent=0, const char* name=0); + virtual ~CompendiumPreferencesWidget(); + + virtual void apply(); + virtual void cancel(); + virtual void standard(); + + void setURL(const QString url); + void setMatchEqual(bool); + void setMatchNGram(bool); + void setMatchIsContained(bool); + void setMatchContains(bool); + void setIgnoreFuzzy(bool); + void setMatchWords(bool); + void setWholeWords(bool); + void setCaseSensitive(bool); + + QString url(); + bool matchEqual(); + bool matchNGram(); + bool matchIsContained(); + bool matchContains(); + bool ignoreFuzzy(); + bool matchWords(); + bool wholeWords(); + bool caseSensitive(); + + + bool settingsChanged() const; + +signals: + void restoreSettings(); + void applySettings(); + +public: + CompendiumPWidget *prefWidget; + +protected slots: + void setChanged(); + void equalBtnToggled(bool); + void ngramBtnToggled(bool); + void isContainedBtnToggled(bool); + void containsBtnToggled(bool); + void hasWordBtnToggled(bool); + +private: + bool changed; + +}; + +#endif diff --git a/kbabel/kbabeldict/modules/pocompendium/pwidget.ui b/kbabel/kbabeldict/modules/pocompendium/pwidget.ui new file mode 100644 index 00000000..8f54b087 --- /dev/null +++ b/kbabel/kbabeldict/modules/pocompendium/pwidget.ui @@ -0,0 +1,280 @@ +<!DOCTYPE UI><UI> +<class>CompendiumPWidget</class> +<include location="global">kseparator.h</include> +<widget> + <class>QWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>PWidget</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>452</width> + <height>291</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string></string> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>11</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget> + <class>QGroupBox</class> + <property stdset="1"> + <name>name</name> + <cstring>GroupBox1</cstring> + </property> + <property stdset="1"> + <name>title</name> + <string>&Path to Compendium File</string> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>11</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget> + <class>KURLRequester</class> + <property stdset="1"> + <name>name</name> + <cstring>urlInput</cstring> + </property> + </widget> + </vbox> + </widget> + <widget> + <class>QButtonGroup</class> + <property stdset="1"> + <name>name</name> + <cstring>ButtonGroup1</cstring> + </property> + <property stdset="1"> + <name>title</name> + <string>Options</string> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>11</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget> + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout4</cstring> + </property> + <grid> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget row="1" column="0" > + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>fuzzyBtn</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Ignore &fuzzy strings</string> + </property> + </widget> + <widget row="0" column="1" > + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>wholeBtn</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Onl&y whole words</string> + </property> + </widget> + <widget row="0" column="0" > + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>caseBtn</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Case sensiti&ve</string> + </property> + </widget> + </grid> + </widget> + <widget> + <class>KSeparator</class> + <property stdset="1"> + <name>name</name> + <cstring>Line1</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Horizontal</enum> + </property> + </widget> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>TextLabel3</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>A text matches if:</string> + </property> + </widget> + <widget> + <class>QLayoutWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>Layout3</cstring> + </property> + <grid> + <property stdset="1"> + <name>margin</name> + <number>0</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget row="0" column="0" > + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>equalBtn</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>E&qual to searched text</string> + </property> + </widget> + <widget row="2" column="1" > + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>hasWordBtn</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Contains a &word of searched text</string> + </property> + </widget> + <widget row="1" column="1" > + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>isContainedBtn</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Co&ntained in searched text</string> + </property> + </widget> + <widget row="1" column="0" > + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>ngramBtn</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>&Similar to searched text</string> + </property> + </widget> + <widget row="0" column="1" > + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>containsBtn</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Contains searched te&xt</string> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + <spacer> + <property> + <name>name</name> + <cstring>Spacer1</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Vertical</enum> + </property> + <property stdset="1"> + <name>sizeType</name> + <enum>Expanding</enum> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KURLRequester</class> + <header location="global">kurlrequester.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image> + <name>image0</name> + <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data> + </image> +</images> +<tabstops> + <tabstop>caseBtn</tabstop> +</tabstops> +</UI> |