summaryrefslogtreecommitdiffstats
path: root/kbabel/kbabeldict
diff options
context:
space:
mode:
Diffstat (limited to 'kbabel/kbabeldict')
-rw-r--r--kbabel/kbabeldict/Makefile.am66
-rw-r--r--kbabel/kbabeldict/README5
-rw-r--r--kbabel/kbabeldict/README.modules34
-rw-r--r--kbabel/kbabeldict/aboutmoduledlg.cpp54
-rw-r--r--kbabel/kbabeldict/aboutmoduledlg.h55
-rw-r--r--kbabel/kbabeldict/dictchooser.cpp335
-rw-r--r--kbabel/kbabeldict/dictchooser.h94
-rw-r--r--kbabel/kbabeldict/dictionarymenu.cpp154
-rw-r--r--kbabel/kbabeldict/dictionarymenu.h81
-rw-r--r--kbabel/kbabeldict/hi16-app-kbabeldict.pngbin0 -> 829 bytes
-rw-r--r--kbabel/kbabeldict/hi32-app-kbabeldict.pngbin0 -> 2278 bytes
-rw-r--r--kbabel/kbabeldict/hi48-app-kbabeldict.pngbin0 -> 4127 bytes
-rw-r--r--kbabel/kbabeldict/kbabeldict.cpp113
-rw-r--r--kbabel/kbabeldict/kbabeldict.desktop96
-rw-r--r--kbabel/kbabeldict/kbabeldict.h62
-rw-r--r--kbabel/kbabeldict/kbabeldict_module.desktop54
-rw-r--r--kbabel/kbabeldict/kbabeldictbox.cpp1767
-rw-r--r--kbabel/kbabeldict/kbabeldictbox.h282
-rw-r--r--kbabel/kbabeldict/kbabeldictiface.h56
-rw-r--r--kbabel/kbabeldict/kbabeldictview.cpp294
-rw-r--r--kbabel/kbabeldict/kbabeldictview.h92
-rw-r--r--kbabel/kbabeldict/kbabelsplash.cpp73
-rw-r--r--kbabel/kbabeldict/kbabelsplash.h55
-rw-r--r--kbabel/kbabeldict/lo16-app-kbabeldict.pngbin0 -> 293 bytes
-rw-r--r--kbabel/kbabeldict/lo32-app-kbabeldict.pngbin0 -> 497 bytes
-rw-r--r--kbabel/kbabeldict/main.cpp136
-rw-r--r--kbabel/kbabeldict/modules/Makefile.am7
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/AUTHOR1
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.cpp1899
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.h333
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/Makefile.am34
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/STRUCTURE25
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/TODO27
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/configure.in.bot5
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/configure.in.in143
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/database.cpp1533
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/database.h329
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/dbscan.cpp197
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/dbscan.h86
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/dbse_factory.cpp82
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/dbse_factory.h26
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/dbsearchengine.desktop52
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/dbseprefwidget.ui1036
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/makemsgdb.C327
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/preferenceswidget.cpp111
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/preferenceswidget.h28
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/AUTHOR1
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/KDBSearchEngine2.cpp686
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/KDBSearchEngine2.h202
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/Makefile.am34
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/README21
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/algorithms.cpp425
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/algorithms.h157
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/chunk.cpp203
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/chunk.h151
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/database.cpp752
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/database.h237
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbentries.cpp171
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbentries.h170
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbscan.cpp280
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbscan.h120
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbse2.ui732
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbse2_factory.cpp83
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbse2_factory.h26
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbsearchengine2.desktop52
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/dbseprefwidget.ui1039
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/preferenceswidget.cpp98
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/preferenceswidget.h26
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine2/sourcedialog.ui266
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/Makefile.am36
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/pa_factory.cpp110
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/pa_factory.h60
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/poauxiliary.cpp554
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/poauxiliary.desktop51
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/poauxiliary.h136
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/preferenceswidget.cpp115
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/preferenceswidget.h77
-rw-r--r--kbabel/kbabeldict/modules/poauxiliary/pwidget.ui133
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/Makefile.am39
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/compendiumdata.cpp261
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/compendiumdata.h105
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/pc_factory.cpp110
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/pc_factory.h60
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/pocompendium.cpp1246
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/pocompendium.desktop50
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/pocompendium.h147
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/preferenceswidget.cpp352
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/preferenceswidget.h97
-rw-r--r--kbabel/kbabeldict/modules/pocompendium/pwidget.ui280
-rw-r--r--kbabel/kbabeldict/modules/tmx/Makefile.am34
-rw-r--r--kbabel/kbabeldict/modules/tmx/pc_factory.cpp111
-rw-r--r--kbabel/kbabeldict/modules/tmx/pc_factory.h62
-rw-r--r--kbabel/kbabeldict/modules/tmx/preferenceswidget.cpp334
-rw-r--r--kbabel/kbabeldict/modules/tmx/preferenceswidget.h97
-rw-r--r--kbabel/kbabeldict/modules/tmx/pwidget.ui216
-rw-r--r--kbabel/kbabeldict/modules/tmx/tmxcompendium.cpp1007
-rw-r--r--kbabel/kbabeldict/modules/tmx/tmxcompendium.desktop50
-rw-r--r--kbabel/kbabeldict/modules/tmx/tmxcompendium.h137
-rw-r--r--kbabel/kbabeldict/modules/tmx/tmxcompendiumdata.cpp308
-rw-r--r--kbabel/kbabeldict/modules/tmx/tmxcompendiumdata.h106
-rw-r--r--kbabel/kbabeldict/searchengine.cpp283
-rw-r--r--kbabel/kbabeldict/searchengine.h534
102 files changed, 23469 insertions, 0 deletions
diff --git a/kbabel/kbabeldict/Makefile.am b/kbabel/kbabeldict/Makefile.am
new file mode 100644
index 00000000..3720988f
--- /dev/null
+++ b/kbabel/kbabeldict/Makefile.am
@@ -0,0 +1,66 @@
+## Makefile.am for kbabeldict
+
+# this has all of the subdirectories that make will recurse into. if
+# there are none, comment this out
+SUBDIRS = . modules
+
+pkgincludedir = $(includedir)/kbabel
+
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+noinst_LTLIBRARIES = libkbabeldict.la
+bin_PROGRAMS = kbabeldict
+
+# set the include path for X, qt and KDE
+INCLUDES = -I$(srcdir)/../common -I$(top_builddir)/kbabel/common $(all_includes)
+
+
+# library for babeldict plugins
+lib_LTLIBRARIES = libkbabeldictplugin.la
+libkbabeldictplugin_la_SOURCES = searchengine.cpp
+libkbabeldictplugin_la_LIBADD = $(LIB_KDECORE)
+libkbabeldictplugin_la_LDFLAGS = -version-info 3:0:2 $(all_libraries)
+
+libkbabeldict_la_SOURCES = kbabeldictbox.cpp \
+ kbabeldictiface.skel dictionarymenu.cpp dictchooser.cpp \
+ aboutmoduledlg.cpp
+libkbabeldict_la_LIBADD = ../common/libkbabelcommon.la libkbabeldictplugin.la $(LIB_KDEUI)
+libkbabeldict_la_LDFLAGS = $(all_libraries) -no-undefined
+
+
+kbabeldict_SOURCES = main.cpp kbabeldictview.cpp kbabeldict.cpp kbabelsplash.cpp
+
+# the libraries to link against.
+kbabeldict_LDADD = libkbabeldict.la
+kbabeldict_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+# these are the headers for your project
+noinst_HEADERS = kbabeldict.h kbabeldictview.h kbabelsplash.h aboutmoduledlg.h
+pkginclude_HEADERS = searchengine.h kbabeldictbox.h kbabeldictiface.h \
+dictionarymenu.h dictchooser.h
+
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+#rcdir = $(kde_datadir)/kbabel
+#rc_DATA = kbabelui.rc
+
+api:
+ mkdir -p API && kdoc -d API -u $$PWD/API -p -lkdeui -lkdecore -lqt -ldcop *.h
+
+distclean-local:
+ rm -r -f API
+
+KDE_ICON = kbabeldict
+
+ # this is where the kdelnk file will go
+xdg_apps_DATA = kbabeldict.desktop
+
+kde_servicetypes_DATA = kbabeldict_module.desktop
+EXTRA_DIST = $(kde_servicetypes_DATA)
+
+kbabeldictbox.lo: ../common/version.h
+main.o: ../common/version.h
+
diff --git a/kbabel/kbabeldict/README b/kbabel/kbabeldict/README
new file mode 100644
index 00000000..9a4eb950
--- /dev/null
+++ b/kbabel/kbabeldict/README
@@ -0,0 +1,5 @@
+This directory contains a standalone application to search for translations
+as you can do in KBabel and the framework for loading plugins for
+searching in different types of translation sources. This way
+KBabel can be easily extended. For more information about
+developing a search module for KBabel see file README.modules
diff --git a/kbabel/kbabeldict/README.modules b/kbabel/kbabeldict/README.modules
new file mode 100644
index 00000000..a672743b
--- /dev/null
+++ b/kbabel/kbabeldict/README.modules
@@ -0,0 +1,34 @@
+This directory contains the framework for KBabel to be easily extensible with
+plugins for searching translations.
+
+For an examples of modules see subdirectory "modules".
+
+
+Here is a short description, how to write an module:
+
+First off all, the module must inherit the interface class SearchEngine and
+has to implement all the virtual functions in there. Also a preferences
+widget must be available, that has to inherit from PrefWidget.
+Just include searchengine.h to have everything necessary available.
+
+Then you module has to be compiled as shared library and there must be a
+factory available, so that it can be loaded with KLibLoader. See
+documentation of KLibLoader for more details. The library should be prefixed
+by "kbabeldict_" instead of more common "lib". This is to indicate that it is
+a module for KBabelDict.
+
+The method of dictionary loading has changed in KBabel 1.2, but the
+modules for previous versions should work. Here is how to install
+the dictionary: You should define a standard KDE service desktop file.
+The most important entry is
+
+X-KDE-Library=<libname>
+
+where <libname> is the name of the shared library, that contains your
+SearchEngine, for example "kbabeldict_pocompendium".
+Additionally you can add a list of applications, to them your module is
+restricted to with "Applications=<list>". For example with "Applications=kbabel",
+your module will only be used in KBabel. If you omit the entry, the
+module can be used in any application.
+
+
diff --git a/kbabel/kbabeldict/aboutmoduledlg.cpp b/kbabel/kbabeldict/aboutmoduledlg.cpp
new file mode 100644
index 00000000..eaab8b3b
--- /dev/null
+++ b/kbabel/kbabeldict/aboutmoduledlg.cpp
@@ -0,0 +1,54 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-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 "aboutmoduledlg.h"
+
+#include <kbugreport.h>
+#include <klocale.h>
+
+AboutModuleDlg::AboutModuleDlg(const KAboutData *aboutData, QWidget *parent)
+ : KAboutApplication(aboutData, parent)
+ , _aboutData(aboutData)
+{
+ setHelpLinkText(i18n("Report Bug..."));
+ enableLinkedHelp(true);
+}
+
+void AboutModuleDlg::helpClickedSlot(const QString&)
+{
+ KBugReport *bugReport = new KBugReport(0,true,_aboutData);
+
+ bugReport->exec();
+
+ delete bugReport;
+}
+#include "aboutmoduledlg.moc"
diff --git a/kbabel/kbabeldict/aboutmoduledlg.h b/kbabel/kbabeldict/aboutmoduledlg.h
new file mode 100644
index 00000000..f79d77ec
--- /dev/null
+++ b/kbabel/kbabeldict/aboutmoduledlg.h
@@ -0,0 +1,55 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-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 ABOUTMODULEDLG_H
+#define ABOUTMODULEDLG_H
+
+#include <kaboutapplication.h>
+
+
+class AboutModuleDlg : public KAboutApplication
+{
+ Q_OBJECT
+
+public:
+ AboutModuleDlg(const KAboutData *aboutData, QWidget* parent=0);
+
+public slots:
+ virtual void helpClickedSlot(const QString&);
+
+private:
+ const KAboutData *_aboutData;
+};
+
+#endif
diff --git a/kbabel/kbabeldict/dictchooser.cpp b/kbabel/kbabeldict/dictchooser.cpp
new file mode 100644
index 00000000..f9360b61
--- /dev/null
+++ b/kbabel/kbabeldict/dictchooser.cpp
@@ -0,0 +1,335 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2001 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 "dictchooser.h"
+#include "resources.h"
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <kconfig.h>
+#include <klistbox.h>
+#include <klocale.h>
+#include <kdialog.h>
+#include <ktempfile.h>
+
+DictChooser::DictChooser(KBabelDictBox*b, QStringList selected
+ , QWidget *parent, const char *name)
+ : QWidget(parent,name), box(b)
+{
+ tempConfig.clear();
+ tempConfig.setAutoDelete(true);
+
+ dictList = box->moduleInfos();
+ QGridLayout *layout = new QGridLayout(this);
+ layout->setSpacing(KDialog::spacingHint());
+
+
+ QLabel *label = new QLabel(i18n("dictionary to not use","Do not use:"),this);
+ layout->addWidget(label,0,0);
+
+ label = new QLabel(i18n("dictionary to use","Use:"),this);
+ layout->addWidget(label,0,2);
+
+ unselectedBox = new KListBox(this,"unselectedBox");
+ layout->addWidget(unselectedBox,1,0);
+
+
+ QVBoxLayout *bLayout = new QVBoxLayout();
+ selectBtn = new QPushButton(" &>> ", this);
+ selectBtn->setEnabled(false);
+ bLayout->addWidget(selectBtn);
+ unselectBtn = new QPushButton(" &<< ", this);
+ unselectBtn->setEnabled(false);
+ bLayout->addWidget(unselectBtn);
+ bLayout->addStretch();
+ layout->addLayout(bLayout,1,1);
+
+ selectedBox = new KListBox(this,"selectedBox");
+ layout->addWidget(selectedBox,1,2);
+
+
+ bLayout = new QVBoxLayout();
+ upBtn = new QPushButton(i18n("Move &Up"), this);
+ upBtn->setEnabled(false);
+ bLayout->addWidget(upBtn);
+ downBtn = new QPushButton(i18n("Move &Down"), this);
+ downBtn->setEnabled(false);
+ bLayout->addWidget(downBtn);
+ configureBtn = new QPushButton(i18n("Con&figure..."), this);
+ bLayout->addWidget(configureBtn);
+ bLayout->addStretch();
+ layout->addLayout(bLayout,1,3);
+
+
+ dictList.setAutoDelete(true);
+ ModuleInfo *mi;
+ for(QStringList::Iterator it=selected.begin(); it!=selected.end();
+ ++it)
+ {
+ for(mi = dictList.first(); mi != 0; mi = dictList.next())
+ {
+ if(mi->id==*it)
+ {
+ selectedBox->insertItem(mi->name);
+ }
+ }
+ }
+
+ for(mi = dictList.first(); mi != 0; mi = dictList.next())
+ {
+ if(!selected.contains(mi->id))
+ {
+ unselectedBox->insertItem(mi->name);
+ }
+ }
+
+ if(selectedBox->count() == 0 && unselectedBox->count() > 0)
+ {
+ selectedBox->insertItem(unselectedBox->text(0));
+ unselectedBox->removeItem(0);
+ }
+
+
+ connect(selectedBox,SIGNAL(highlighted(int)), this
+ , SLOT(selectedMarked(int)));
+ connect(unselectedBox,SIGNAL(highlighted(int)), this
+ , SLOT(unselectedMarked(int)));
+
+ connect(selectBtn, SIGNAL(clicked()), this, SLOT(select()));
+ connect(unselectBtn, SIGNAL(clicked()), this, SLOT(unselect()));
+ connect(upBtn, SIGNAL(clicked()), this, SLOT(up()));
+ connect(downBtn, SIGNAL(clicked()), this, SLOT(down()));
+ connect(configureBtn,SIGNAL(clicked()), this
+ , SLOT(configureSelected()));
+
+
+ selectedBox->installEventFilter(this);
+ unselectedBox->installEventFilter(this);
+
+ int min = minimumHeight();
+ if(min < 100)
+ setMinimumHeight(100);
+}
+
+
+QStringList DictChooser::selectedDicts()
+{
+ QStringList selected;
+
+ for(int i = 0; i < (int)selectedBox->count(); i++)
+ {
+ QString text = selectedBox->text(i);
+
+ ModuleInfo *mi;
+ for(mi = dictList.first(); mi!=0; mi = dictList.next())
+ {
+ if(mi->name == text)
+ {
+ selected.append(mi->id);
+ }
+ }
+ }
+
+ return selected;
+}
+
+
+void DictChooser::selectedMarked(int index)
+{
+ unselectedBox->selectAll(false);
+
+ unselectBtn->setEnabled(selectedBox->count() > 1);
+ selectBtn->setEnabled(false);
+ downBtn->setEnabled((int)selectedBox->count()-1 > index);
+ upBtn->setEnabled(index > (int)0);
+}
+
+void DictChooser::unselectedMarked(int)
+{
+ selectedBox->selectAll(false);
+
+ selectBtn->setEnabled(true);
+ unselectBtn->setEnabled(false);
+ downBtn->setEnabled(false);
+ upBtn->setEnabled(false);
+}
+
+
+void DictChooser::select()
+{
+ int i = unselectedBox->currentItem();
+ if(i >= 0)
+ {
+ QString text = unselectedBox->text(i);
+ selectedBox->insertItem(text);
+
+ unselectedBox->removeItem(i);
+
+ if(unselectedBox->count() == 0)
+ {
+ selectBtn->setEnabled(false);
+ }
+ else
+ {
+ unselectedBox->setSelected(i,true);
+ }
+ }
+}
+
+
+void DictChooser::unselect()
+{
+ int i = selectedBox->currentItem();
+ if(i >= 0 && selectedBox->count() > 1)
+ {
+ QString text = selectedBox->text(i);
+ unselectedBox->insertItem(text);
+
+ selectedBox->removeItem(i);
+
+ if(i < (int)selectedBox->count()-1)
+ {
+ selectedBox->setSelected(i,true);
+ }
+ else
+ {
+ selectedBox->setSelected(i-1,true);
+ }
+ }
+}
+
+
+void DictChooser::up()
+{
+ int i = selectedBox->currentItem();
+ if(i > 0)
+ {
+ QString text = selectedBox->text(i);
+ selectedBox->changeItem(selectedBox->text(i-1),i);
+ selectedBox->changeItem(text,i-1);
+ selectedBox->setSelected(i-1,true);
+ }
+}
+
+
+void DictChooser::down()
+{
+ int i = selectedBox->currentItem();
+ if(i < (int)selectedBox->count()-1)
+ {
+ QString text = selectedBox->text(i);
+ selectedBox->changeItem(selectedBox->text(i+1),i);
+ selectedBox->changeItem(text,i+1);
+ selectedBox->setSelected(i+1,true);
+ }
+}
+
+
+bool DictChooser::eventFilter(QObject *object, QEvent *event)
+{
+ if(event->type() == QEvent::FocusIn)
+ {
+ if(object==selectedBox)
+ {
+ int i = selectedBox->currentItem();
+ selectedBox->setSelected(i,true);
+ selectedMarked(i);
+ unselectedBox->clearSelection();
+ }
+ else
+ {
+ int i = unselectedBox->currentItem();
+ if(i >= 0)
+ {
+ unselectedBox->setSelected(i,true);
+ unselectedMarked(i);
+ selectedBox->clearSelection();
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void DictChooser::configureSelected()
+{
+ int ci = selectedBox->currentItem();
+ if( ci == -1 ) ci = 0; // there is always at least one item
+ QString module = selectedBox->text(ci);
+
+ ModuleInfo *mi;
+ for(mi = dictList.first(); mi!=0; mi = dictList.next())
+ {
+ if(mi->name == module)
+ {
+ // do backup first
+ if( !tempConfig[mi->id])
+ {
+ KTempFile* tmp=new KTempFile();
+ tmp->setAutoDelete(true);
+ tempConfig.insert(mi->id ,tmp);
+
+ kdDebug(KBABEL_SEARCH) << "Temp file: " << tmp->name() << endl;
+ KConfig config(tmp->name());
+ config.setGroup(mi->id);
+ box->saveSettings(mi->id, &config);
+ }
+
+ // now let user change configuration
+ box->configure(mi->id,true);
+ break;
+ }
+ }
+}
+
+void DictChooser::restoreConfig()
+{
+ kdDebug( KBABEL_SEARCH ) << "Cleanup" << endl;
+ // cleanup
+ QDictIterator<KTempFile> it( tempConfig ); // See QDictIterator
+ for( ; it.current(); ++it )
+ {
+ KConfig config( it.current()->name() );
+ config.setGroup( it.currentKey() );
+ box->readSettings( it.currentKey(), &config);
+ }
+
+ // there is no temporary configs
+ tempConfig.clear();
+}
+
+#include "dictchooser.moc"
diff --git a/kbabel/kbabeldict/dictchooser.h b/kbabel/kbabeldict/dictchooser.h
new file mode 100644
index 00000000..2b757455
--- /dev/null
+++ b/kbabel/kbabeldict/dictchooser.h
@@ -0,0 +1,94 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-2001 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.
+
+**************************************************************************** */
+#ifndef DICTCHOOSER_H
+#define DICTCHOOSER_H
+
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qwidget.h>
+#include <kbabeldictbox.h>
+
+class KListBox;
+class KTempFile;
+
+class QPushButton;
+class QListBoxItem;
+
+
+class KDE_EXPORT DictChooser : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DictChooser(KBabelDictBox* box, QStringList selected,
+ QWidget *parent , const char *name=0);
+
+ QStringList selectedDicts();
+
+ /** If the user configured some of the modules, this
+ * restores the original configuration of all these modules
+ */
+ void restoreConfig();
+
+ virtual bool eventFilter(QObject *, QEvent *);
+
+private slots:
+ void select();
+ void unselect();
+ void up();
+ void down();
+
+ void selectedMarked(int);
+ void unselectedMarked(int);
+
+ void configureSelected();
+
+private:
+ KBabelDictBox* box;
+ QPtrList<ModuleInfo> dictList;
+
+ KListBox *selectedBox;
+ KListBox *unselectedBox;
+
+ QPushButton *selectBtn;
+ QPushButton *unselectBtn;
+ QPushButton *upBtn;
+ QPushButton *downBtn;
+ QPushButton *configureBtn;
+
+ QDict<KTempFile> tempConfig;
+};
+
+#endif // DICTCHOOSER_H
diff --git a/kbabel/kbabeldict/dictionarymenu.cpp b/kbabel/kbabeldict/dictionarymenu.cpp
new file mode 100644
index 00000000..2ed57d5f
--- /dev/null
+++ b/kbabel/kbabeldict/dictionarymenu.cpp
@@ -0,0 +1,154 @@
+/* ****************************************************************************
+ 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 "dictionarymenu.h"
+#include <kpopupmenu.h>
+#include <kaction.h>
+#include <kdebug.h>
+#include <kshortcut.h>
+
+#include <qsignalmapper.h>
+
+DictionaryMenu::DictionaryMenu(KPopupMenu *popupMenu, KActionCollection *collection
+ , QObject *parent)
+ : QObject(parent, "dictionarymenu")
+ , popup(popupMenu)
+ , actionCollection(collection)
+ , maxId(10)
+{
+ num2id.setAutoDelete(true);
+ accel2id.setAutoDelete(true);
+
+ if(popup)
+ {
+ connect(popup,SIGNAL(activated(int)),this,SLOT(activated(int)));
+ }
+
+ dictionaryMapper = new QSignalMapper( this );
+ connect( dictionaryMapper, SIGNAL( mapped( int ) ),
+ this, SLOT( activated( int ) ) );
+
+}
+
+DictionaryMenu::~DictionaryMenu()
+{
+ clear();
+}
+
+void DictionaryMenu::clear()
+{
+ if(popup)
+ {
+ QIntDictIterator<QString> it( num2id ); // iterator for dict
+ while ( it.current() )
+ {
+ popup->removeItem(it.currentKey());
+ ++it;
+ }
+ }
+
+ num2id.clear();
+
+ // create new mapper
+ delete dictionaryMapper;
+ dictionaryMapper = new QSignalMapper( this );
+ connect( dictionaryMapper, SIGNAL( mapped( int ) ),
+ this, SLOT( activated( int ) ) );
+}
+
+void DictionaryMenu::add(const QString& name, const QString& moduleId)
+{
+ if(popup)
+ {
+ KAction* dictionaryAction = new KAction( name, 0, dictionaryMapper, SLOT(map()), actionCollection, moduleId.utf8() );
+
+ uint id = maxId++;
+ dictionaryAction->plug(popup, id);
+
+ dictionaryMapper->setMapping( dictionaryAction, id );
+
+ QString *idString = new QString(moduleId);
+ num2id.insert(id,idString);
+ }
+
+}
+
+void DictionaryMenu::add(const QString& n, const QString& moduleId
+ , const QString& key)
+{
+ if(popup)
+ {
+ QString name=n;
+
+ QString keyString=key;
+ if(keyString.contains("%1"))
+ {
+ keyString=key.arg(accel2id.count()+1);
+ }
+ KShortcut k(keyString);
+
+ KAction* dictionaryAction = new KAction( name, k, dictionaryMapper, SLOT(map()), actionCollection, key.arg(moduleId).utf8() );
+ uint id = maxId++;
+ dictionaryAction->plug(popup,id);
+
+ if(!k.isNull())
+ {
+ QString *idString = new QString(moduleId);
+ accel2id.insert(id,idString);
+
+ dictionaryMapper->setMapping( dictionaryAction, id );
+
+ name+='\t';
+ name+=k.toString();
+ }
+ else
+ {
+ kdWarning() << "key not valid" << endl;
+ }
+
+ QString *idString = new QString(moduleId);
+ num2id.insert(id,idString);
+ }
+}
+
+
+void DictionaryMenu::activated(int id)
+{
+ QString *idString = num2id[id];
+
+ if(idString)
+ {
+ emit activated(*idString);
+ }
+}
+
+#include "dictionarymenu.moc"
diff --git a/kbabel/kbabeldict/dictionarymenu.h b/kbabel/kbabeldict/dictionarymenu.h
new file mode 100644
index 00000000..c688508e
--- /dev/null
+++ b/kbabel/kbabeldict/dictionarymenu.h
@@ -0,0 +1,81 @@
+/* ****************************************************************************
+ 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 DICTIONARYMENU_H
+#define DICTIONARYMENU_H
+
+#include <qintdict.h>
+#include <qobject.h>
+#include <qstringlist.h>
+#include <qguardedptr.h>
+#include <kdemacros.h>
+
+class QSignalMapper;
+class KPopupMenu;
+class KActionCollection;
+
+class KDE_EXPORT DictionaryMenu : public QObject
+{
+ Q_OBJECT
+
+public:
+ DictionaryMenu(KPopupMenu *menu, KActionCollection *collection, QObject *parent=0);
+ ~DictionaryMenu();
+
+ void add(const QString& name,const QString& id);
+
+ /**
+ * Adds an item to this menu and to the keyboard accelerator.
+ * If key contains %1 it is replaced with a number 1-9
+ */
+ void add(const QString& name,const QString& id, const QString& key);
+
+ void clear();
+
+signals:
+ void activated(const QString moduleId);
+
+private slots:
+ void activated(int);
+
+private:
+ QGuardedPtr<KPopupMenu> popup;
+ QGuardedPtr<KActionCollection> actionCollection;
+ QIntDict<QString> num2id;
+ QIntDict<QString> accel2id;
+ QSignalMapper* dictionaryMapper;
+
+ uint maxId;
+};
+
+#endif
+
diff --git a/kbabel/kbabeldict/hi16-app-kbabeldict.png b/kbabel/kbabeldict/hi16-app-kbabeldict.png
new file mode 100644
index 00000000..eedcb0c1
--- /dev/null
+++ b/kbabel/kbabeldict/hi16-app-kbabeldict.png
Binary files differ
diff --git a/kbabel/kbabeldict/hi32-app-kbabeldict.png b/kbabel/kbabeldict/hi32-app-kbabeldict.png
new file mode 100644
index 00000000..d6d23a0a
--- /dev/null
+++ b/kbabel/kbabeldict/hi32-app-kbabeldict.png
Binary files differ
diff --git a/kbabel/kbabeldict/hi48-app-kbabeldict.png b/kbabel/kbabeldict/hi48-app-kbabeldict.png
new file mode 100644
index 00000000..75eb285b
--- /dev/null
+++ b/kbabel/kbabeldict/hi48-app-kbabeldict.png
Binary files differ
diff --git a/kbabel/kbabeldict/kbabeldict.cpp b/kbabel/kbabeldict/kbabeldict.cpp
new file mode 100644
index 00000000..ebb68227
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldict.cpp
@@ -0,0 +1,113 @@
+/* ****************************************************************************
+ 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 <kapplication.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include "kbabeldict.h"
+#include "kbabeldictview.h"
+
+#include <kdebug.h>
+
+KBabelDict::KBabelDict()
+ : KDialogBase(0,"kbabeldictmain",false,i18n("KBabelDict")
+ , Close|Help|User1|User2|User3|Ok, Ok, true
+ , i18n("About"), i18n("About Module")
+ , i18n("Hide Sett&ings"))
+{
+ connect(this, SIGNAL(closeClicked()),this,SLOT(saveConfig()));
+ connect(this, SIGNAL(closeClicked()),this,SLOT(quit()));
+
+ view = new KBabelDictView(this);
+ connect(this, SIGNAL(user1Clicked()), view, SLOT(about()));
+ connect(this, SIGNAL(user2Clicked()), view, SLOT(aboutModule()));
+ connect(this, SIGNAL(user3Clicked()), this, SLOT(togglePref()));
+
+ // HACK: hide default button, otherwise it would be Help button
+ showButtonOK(false);
+
+ // KBabelDict has not a separate help file, so point to the correct part of the KBabel documentation
+ setHelp( "using-kbabeldict", "kbabel" );
+
+ setMainWidget(view);
+
+ readConfig();
+}
+
+KBabelDict::~KBabelDict()
+{
+ delete(view);
+}
+
+void KBabelDict::saveConfig()
+{
+ KConfig *config=KGlobal::config();
+ KConfigGroupSaver gs(config,"KBabelDict");
+ config->writeEntry("Preferences",view->prefVisible());
+}
+
+void KBabelDict::readConfig()
+{
+ KConfig *config=KGlobal::config();
+ KConfigGroupSaver gs(config,"KBabelDict");
+ bool pref=config->readBoolEntry("Preferences",true);
+
+ if(view->prefVisible() != pref)
+ {
+ togglePref();
+ }
+}
+
+void KBabelDict::quit()
+{
+ kapp->quit();
+}
+
+void KBabelDict::togglePref()
+{
+ view->togglePref();
+
+ if(view->prefVisible())
+ {
+ setButtonText(User3,i18n("Hide Sett&ings"));
+ }
+ else
+ {
+ setButtonText(User3,i18n("Show Sett&ings"));
+ }
+}
+
+
+#include "kbabeldict.moc"
diff --git a/kbabel/kbabeldict/kbabeldict.desktop b/kbabel/kbabeldict/kbabeldict.desktop
new file mode 100644
index 00000000..21b60a04
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldict.desktop
@@ -0,0 +1,96 @@
+[Desktop Entry]
+Name=KBabel Dictionary
+Name[bg]=Речник - KBabel
+Name[br]=Geriadur KBabel
+Name[ca]=Diccionari de KBabel
+Name[cs]=Slovník (KBabel)
+Name[da]=KBabel ordbog
+Name[de]=KBabel-Wörterbuch
+Name[el]=Λεξικό του KBabel
+Name[eo]=Babelo-vortaro
+Name[es]=Diccionario de KBabel
+Name[et]=Sõnaraamat
+Name[eu]=KBabel hiztegia
+Name[fa]=واژه‌نامۀKBabel
+Name[fi]=KBabel-sanakirja
+Name[fr]=Dictionnaire de KBabel
+Name[ga]=Foclóir KBabel
+Name[gl]=Dicionario de KBabel
+Name[he]=KBabel - מילון
+Name[hu]=KBabel szótár
+Name[is]=KBabel orðabók
+Name[it]=Dizionario di KBabel
+Name[ja]=KBabel 辞書
+Name[ka]=KBabel ლექსიკონი
+Name[kk]=KBabel сөздігі
+Name[lt]=KBabel žodynas
+Name[nb]=KBabel-ordbok
+Name[nds]=KBabel-Wöörbook
+Name[ne]=केब्याबल शब्दकोश
+Name[nl]=KBabel woordenboek
+Name[nn]=KBabel-ordbok
+Name[pa]=ਕੇਬਬੇਲ ਸ਼ਬਦ-ਕੋਸ਼
+Name[pl]=Słownik programu KBabel
+Name[pt]=Dicionário do KBabel
+Name[pt_BR]=Dicionário do KBabel
+Name[ru]=KBabel - Словарь
+Name[sk]=KBabel slovník
+Name[sl]=Slovar za KBabel
+Name[sr]=KBabel-ов Речник
+Name[sr@Latn]=KBabel-ov Rečnik
+Name[sv]=Kbabel ordlista
+Name[tr]=KBabel Sözlüğü
+Name[uk]=Словник KBabel
+Name[zh_CN]=KBabel 词典
+Name[zh_TW]=KBabel 字典
+GenericName=Translation Tool Dictionary
+GenericName[bg]=Речник за инструмента за превод
+GenericName[br]=Geriaoueg an ostilh troidigezh
+GenericName[ca]=Diccionari de l'eina de traducció
+GenericName[cs]=Překladový slovník
+GenericName[da]=Ordbog til oversættelsesværktøj
+GenericName[de]=Wörterbuch für Übersetzungsprogramm
+GenericName[el]=Λεξικό εργαλείου μετάφρασης
+GenericName[eo]=Tradukila Vortaro
+GenericName[es]=Diccionario de la herramienta de traducción
+GenericName[et]=KBabel'i sõnaraamat
+GenericName[eu]=Itzulpen tresnen hiztegia
+GenericName[fa]=واژه‌نامۀ ابزار ترجمه
+GenericName[fi]=Käännöstyökalun sanakirja
+GenericName[fr]=Dictionnaire d'un outil de traduction
+GenericName[ga]=Uirlis Aistriúcháin - Foclóir
+GenericName[gl]=Dicionario da ferramenta de tradución
+GenericName[he]=מילון של כלי תרגום
+GenericName[hu]=Fordítássegítő szótár
+GenericName[is]=Þýðingaforrit orðabók
+GenericName[it]=Dizionario di uno strumento di traduzione
+GenericName[ja]=翻訳ツール辞書
+GenericName[ka]=თარგმნის ხელსაწყოს ლექსიკონი
+GenericName[kk]=Аудару құралының сөздігі
+GenericName[lt]=Vertimo įrankio žodynas
+GenericName[nb]=Ordbok for oversettingsverktøy
+GenericName[nds]=Översettenwarktüüch-Wöörbook
+GenericName[ne]=अनुबाद उपकरण शब्दकोश
+GenericName[nl]=Vertaalhulpmiddel woordenboek
+GenericName[nn]=Ordbok for omsetjingsverktøy
+GenericName[pa]=ਅਨੁਵਾਦ ਸੰਦ ਲਈ ਸ਼ਬਦ-ਕੋਸ਼
+GenericName[pl]=Słownik do narzędzia tłumaczy
+GenericName[pt]=Dicionário da Ferramenta de Tradução
+GenericName[pt_BR]=Dicionário da Ferramenta de Tradução
+GenericName[ru]=Поиск в готовых переводах
+GenericName[sk]=Slovník pre prekladací nástroj
+GenericName[sl]=Slovar orodja za prevajanje
+GenericName[sr]=Речник преводилачких алата
+GenericName[sr@Latn]=Rečnik prevodilačkih alata
+GenericName[sv]=Översättningsverktyg ordlista
+GenericName[tr]=Çeviri Aracı Sözlüğü
+GenericName[uk]=Словник засобу для перекладів
+GenericName[zh_CN]=翻译工具词典
+GenericName[zh_TW]=翻譯工具字典
+Exec=kbabeldict %i %m -caption "%c"
+Icon=kbabeldict
+Type=Application
+Terminal=false
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Unique
+Categories=Qt;KDE;Development;Translation;
diff --git a/kbabel/kbabeldict/kbabeldict.h b/kbabel/kbabeldict/kbabeldict.h
new file mode 100644
index 00000000..3bfca817
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldict.h
@@ -0,0 +1,62 @@
+/* ****************************************************************************
+ 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 KBABELDICT_H
+#define KBABELDICT_H
+
+#include <kdialogbase.h>
+
+class KBabelDictView;
+
+class KBabelDict : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ KBabelDict();
+ ~KBabelDict();
+
+protected slots:
+ void saveConfig();
+ void quit();
+ void togglePref();
+
+protected:
+ void readConfig();
+
+private:
+ KBabelDictView *view;
+};
+
+#endif
diff --git a/kbabel/kbabeldict/kbabeldict_module.desktop b/kbabel/kbabeldict/kbabeldict_module.desktop
new file mode 100644
index 00000000..c5a019d1
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldict_module.desktop
@@ -0,0 +1,54 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=KBabelDictModule
+Comment=Dictionary module for KBabelDict
+Comment[bg]=Речников модул за KBabelDict
+Comment[br]=Mollad geriaoueg evit KBabelDict
+Comment[bs]=Rječnički modul za KBabelDict
+Comment[ca]=Mòdul de diccionari per a KBabelDict
+Comment[cs]=Modul se slovníkem pro KBabelDict
+Comment[cy]=Modiwl geiriadur i KBabelDict
+Comment[da]=Ordbogsmodul for KBabelDict
+Comment[de]=Wörterbuch-Modul für KBabelDict
+Comment[el]=Άρθρωμα λεξικού για το KBabelDict
+Comment[es]=Módulo de diccionario para KBabelDict
+Comment[et]=KBabelDicti sõnaraamatumoodul
+Comment[eu]=Hiztegi modulua KBabelDict-entzat
+Comment[fa]=پیمانۀ واژه‌نامه برایKBabelDict
+Comment[fi]=KBabelDict-ohjelman sanakirjamoduuli
+Comment[fr]=Module de dictionnaire pour KBabelDict
+Comment[ga]=Modúl foclóra le haghaidh KBabelDict
+Comment[gl]=Módulo de dicionario para KBabelDict
+Comment[hi]=के-बेबल-डिक्श के लिए शब्दकोश मॉड्यूल
+Comment[hu]=Szótármodul a KBabelDicthez
+Comment[is]=Orðabókareining fyrir KBabel
+Comment[it]=Modulo dizionario per KBabelDict
+Comment[ja]=KBabelDict 辞書モジュール
+Comment[ka]=ლექსიკონის მოდული KBabelDict-სთვის
+Comment[kk]=KBabelDict-тің сөздік модулі
+Comment[lt]=KBabelDict žodyno modulis
+Comment[ms]=Modul kamus untuk KBabelDict
+Comment[nb]=Ordboksmodul for KBabelDict
+Comment[nds]=Wöörbookmoduul för KBabelDict
+Comment[ne]=KBabelDict का लागि शब्दकोश मोड्युल
+Comment[nl]=Woordenboekmodule voor KBabelDict
+Comment[nn]=Ordboksmodul for KBabelDict
+Comment[pa]=ਕੇਬਬੇਲ-ਸ਼ਬਦਕੋਸ਼ ਲਈ ਸ਼ਬਦ-ਕੋਸ਼ ਮੈਡੀਊਲ
+Comment[pl]=Moduł słownika dla KBabelDict
+Comment[pt]=Módulo de dicionário para o KBabelDict
+Comment[pt_BR]=Módulo de dicionário para o KBabekDict
+Comment[ru]=Модуль словаря для KBabelDict
+Comment[sk]=Modul slovníka pre KBabelDict
+Comment[sl]=Slovarski modul za KBabelDict
+Comment[sr]=Модул речника за KBabelDict
+Comment[sr@Latn]=Modul rečnika za KBabelDict
+Comment[sv]=Ordlistemodul för Kbabeldict
+Comment[ta]= Kபாபேலுக்கான அகராதி கூறு
+Comment[tg]=Модули луғат барои KBabelDict
+Comment[tr]=KBabelDict için Sözlük Modülü
+Comment[uk]=Модуль словника для KBabelDict
+Comment[zh_CN]=KBabelDict 的词典模块
+Comment[zh_TW]=KBabelDict 字典模組
+
+[PropertyDef::Applications]
+Type=QStringList
diff --git a/kbabel/kbabeldict/kbabeldictbox.cpp b/kbabel/kbabeldict/kbabeldictbox.cpp
new file mode 100644
index 00000000..2beed684
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldictbox.cpp
@@ -0,0 +1,1767 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2003-2005 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 <dcopclient.h>
+#include <kaboutapplication.h>
+
+#include "aboutmoduledlg.h"
+#include "kbabeldictbox.h"
+#include <version.h>
+#include <resources.h>
+
+#include <kaboutdata.h>
+#include <kaboutdialog.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcmenumngr.h>
+#include <kdialogbase.h>
+#include <klibloader.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kglobal.h>
+#include <kdebug.h>
+#include <ktrader.h>
+#include <kwin.h>
+
+#include <qclipboard.h>
+#include <qdir.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpopupmenu.h>
+#include <qpushbutton.h>
+#include <qtextview.h>
+#include <qstylesheet.h>
+#include <qtoolbutton.h>
+#include <qwhatsthis.h>
+#include <qtimer.h>
+
+#define KBABELDICT 5321
+
+using namespace KBabel;
+
+class ResultListItem : public QListViewItem
+{
+public:
+ ResultListItem(QListView *parent, const SearchResult& result,bool richText);
+
+ virtual QString key(int column, bool ascending) const;
+ const SearchResult* result() const;
+ bool richText() const { return _richText; }
+
+private:
+ SearchResult _result;
+ bool _richText;
+};
+
+ResultListItem::ResultListItem(QListView *parent, const SearchResult& result
+ , bool richText)
+ : QListViewItem(parent)
+ , _result(result)
+ , _richText(richText)
+{
+ int score=_result.score;
+ if(score<0)
+ score=0;
+ else if(score>100)
+ score=100;
+ setText(0,QString::number(score));
+
+ QString tmp;
+ if(richText)
+ tmp=_result.plainFound;
+ else
+ // FIXME: what about plural forms?
+ tmp=result.found.first();
+
+ bool cutted=false;
+ int index=tmp.find('\n');
+ if(index > 0)
+ {
+ tmp=tmp.left(index);
+ cutted=true;
+ }
+ if(tmp.length() > 30)
+ {
+ tmp=tmp.left(30);
+ cutted=true;
+ }
+ tmp=tmp.stripWhiteSpace();
+ if(cutted)
+ tmp+="...";
+
+ setText(1,tmp);
+
+ if(richText)
+ tmp=_result.plainTranslation;
+ else
+ tmp=result.translation;
+
+ cutted=false;
+ index=tmp.find('\n');
+ if(index > 0)
+ {
+ tmp=tmp.left(index);
+ cutted=true;
+ }
+ if(tmp.length() > 30)
+ {
+ tmp=tmp.left(30);
+ cutted=true;
+ }
+ tmp=tmp.stripWhiteSpace();
+ if(cutted)
+ tmp+="...";
+ setText(2,tmp);
+
+
+ if(!_result.descriptions.isEmpty())
+ {
+ TranslationInfo *ti = _result.descriptions.first();
+ if(ti)
+ {
+ setText(3,ti->location);
+ }
+ }
+
+}
+
+QString ResultListItem::key(int column, bool ascending) const
+{
+ if(column==0)
+ {
+ QString result=QString::number(_result.score);
+ result=result.rightJustify(10,'0');
+
+ return result;
+ }
+
+ return QListViewItem::key(column,ascending);
+}
+
+const SearchResult *ResultListItem::result() const
+{
+ return &_result;
+}
+
+/*
+ * Constructs a KBabelDictBox which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+KBabelDictBox::KBabelDictBox( QWidget* parent, const char* name, WFlags fl )
+ : DCOPObject("KBabelDict"), QWidget( parent, name, fl )
+{
+ active=-1;
+ currentResult=0;
+ currentInfo=0;
+ moduleList.setAutoDelete(false);
+
+
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ mainLayout->setMargin(KDialog::marginHint());
+ mainLayout->setSpacing(KDialog::spacingHint());
+
+ QGridLayout *grid = new QGridLayout(mainLayout);
+
+ QHBoxLayout *hbox = new QHBoxLayout;
+ QLabel *label = new QLabel(i18n("Total:"),this);
+ hbox->addWidget(label);
+ totalResultsLabel = new QLabel("0",this);
+ hbox->addWidget(totalResultsLabel);
+ grid->addLayout(hbox,0,0);
+
+ hbox = new QHBoxLayout;
+ label = new QLabel(i18n("Current:"), this);
+ hbox->addWidget(label);
+ currentLabel = new QLabel("0",this);
+ hbox->addWidget(currentLabel);
+ grid->addLayout(hbox,1,0);
+
+
+ hbox = new QHBoxLayout;
+ label = new QLabel(i18n("Found in:"), this);
+ hbox->addWidget(label);
+ locationLabel = new QLabel(this);
+ hbox->addWidget(locationLabel);
+ hbox->setStretchFactor(locationLabel,2);
+ grid->addLayout(hbox,0,1);
+
+ hbox = new QHBoxLayout;
+ label = new QLabel(i18n("Translator:"), this);
+ hbox->addWidget(label);
+ translatorLabel = new QLabel(this);
+ translatorLabel->setMinimumSize(50,0);
+ hbox->addWidget(translatorLabel);
+ hbox->setStretchFactor(translatorLabel,2);
+ grid->addLayout(hbox,1,1);
+
+ grid->setColStretch(1,2);
+
+
+ hbox = new QHBoxLayout;
+ label = new QLabel(i18n("Date:"),this);
+ hbox->addWidget(label);
+ dateLabel = new QLabel(this);
+ dateLabel->setMinimumSize(50,0);
+ hbox->addWidget(dateLabel);
+ hbox->setStretchFactor(dateLabel,2);
+
+ moreButton = new QPushButton(this,"moreButton");
+ moreButton->setText(i18n("&More"));
+ moreButton->setEnabled(false);
+ moreButton->setAutoRepeat(true);
+ hbox->addWidget(moreButton);
+
+ mainLayout->addLayout(hbox);
+
+
+ hbox = new QHBoxLayout;
+ hbox->addStretch(1);
+ listButton = new QToolButton(Qt::UpArrow,this);
+ listButton->setFixedSize(20,15);
+ listButton->setAutoRepeat(false);
+ connect(listButton,SIGNAL(clicked()),this,SLOT(showListOnly()));
+ hbox->addWidget(listButton);
+ detailButton = new QToolButton(Qt::DownArrow,this);
+ detailButton->setFixedSize(20,15);
+ detailButton->setAutoRepeat(false);
+ connect(detailButton,SIGNAL(clicked()),this,SLOT(showDetailsOnly()));
+ hbox->addWidget(detailButton);
+
+ mainLayout->addLayout(hbox);
+
+
+ resultSplitter = new QSplitter(Qt::Vertical,this
+ ,"resultsplitter");
+ mainLayout->addWidget(resultSplitter);
+
+ viewContainer = new QSplitter(Qt::Vertical,resultSplitter, "singleEntrySplitter");
+ QVBoxLayout *vbox = new QVBoxLayout(viewContainer);
+ vbox->setResizeMode(QLayout::FreeResize);
+ origView = new QTextView(viewContainer,"origView");
+ origView->setWordWrap( QTextEdit::WidgetWidth );
+ origView->setMinimumSize(1,1);
+ vbox->addWidget(origView);
+ translationView = new QTextView(viewContainer,"translationView");
+ origView->setWordWrap( QTextEdit::WidgetWidth );
+ translationView->setMinimumSize(1,1);
+ vbox->addWidget(translationView);
+ viewContainer->setMinimumSize(1,1);
+
+ resultListView = new KListView( resultSplitter, "resultListView" );
+ resultListView->setMinimumSize(1,1);
+ resultListView->addColumn( i18n( "Score" ) );
+ resultListView->addColumn( i18n( "Original" ) );
+ resultListView->addColumn( i18n( "Translation" ) );
+ resultListView->addColumn( i18n( "Location" ) );
+
+ resultListView->installEventFilter(this);
+ connect(resultListView
+ , SIGNAL(doubleClicked(QListViewItem *,const QPoint&,int))
+ , this, SLOT(editFile()));
+ connect(resultListView, SIGNAL(returnPressed(QListViewItem *))
+ , this, SLOT(editFile()));
+ connect(resultListView
+ , SIGNAL(contextMenu(KListView *,QListViewItem *,const QPoint&))
+ , this
+ , SLOT(showContextMenu(KListView *,QListViewItem *,const QPoint&)));
+
+ resultSplitter->setResizeMode(viewContainer,QSplitter::KeepSize);
+ QValueList<int> sizes;
+ sizes.append(50);
+ sizes.append(50);
+ resultSplitter->setSizes(sizes);
+
+
+ hbox = new QHBoxLayout;
+ hbox->addStretch(1);
+
+ prevButton = new QPushButton(i18n("< &Previous"),this);
+ prevButton->setEnabled(false);
+ prevButton->setAutoRepeat(true);
+ hbox->addWidget(prevButton);
+
+ nextButton = new QPushButton(i18n("&Next >"),this);
+ nextButton->setEnabled(false);
+ nextButton->setAutoRepeat(true);
+ hbox->addWidget(nextButton);
+
+ hbox->addStretch(1);
+ mainLayout->addLayout(hbox);
+
+ totalResultsLabel->setNum(100000);
+ totalResultsLabel->setFixedSize(totalResultsLabel->sizeHint());
+ totalResultsLabel->setNum(0);
+ currentLabel->setNum(100000);
+ currentLabel->setFixedSize(currentLabel->sizeHint());
+ currentLabel->setNum(0);
+
+ setRMBMenu(new QPopupMenu(this));
+ QStringList fileList;
+#if 0
+ // try to find installed modules by looking into directories
+ // kbabeldict/modules and getting all files *.rc
+ QStringList dirList = KGlobal::dirs()->findDirs("data"
+ ,"kbabeldict/modules");
+
+ for ( QStringList::Iterator it = dirList.begin(); it != dirList.end()
+ ; ++it )
+ {
+ QDir dir((*it),"*.rc");
+ QStringList list = dir.entryList(QDir::Files|QDir::Readable);
+
+ for ( QStringList::Iterator fit = list.begin(); fit != list.end()
+ ; ++fit )
+ {
+ if(!fileList.contains((*fit)))
+ {
+ fileList.append((*fit));
+ }
+ }
+ }
+#endif
+
+ // use locate to locate the actual file, because rcfiles in the users
+ // directory is prefered for systemwide rc files
+ QStringList rcList;
+ for( QStringList::Iterator fit = fileList.begin(); fit != fileList.end();
+ ++fit)
+ {
+ rcList.append(locate("data","kbabeldict/modules/"+(*fit)));
+ }
+
+ for( QStringList::Iterator rit = rcList.begin(); rit != rcList.end();
+ ++rit)
+ {
+ KConfig rcConfig((*rit),true,false);
+
+ rcConfig.setGroup("SearchEngine");
+
+ QStringList appList = rcConfig.readListEntry("Applications");
+ KInstance *inst = KGlobal::instance();
+ if(inst && !appList.isEmpty() && !appList.contains(inst->instanceName()))
+ {
+ continue;
+ }
+
+ QString libName = rcConfig.readEntry("Lib");
+
+ if(!libName.isNull())
+ {
+ kdDebug(KBABELDICT) << "loading library " << libName << endl;
+
+ KLibFactory *factory=KLibLoader::self()->factory(libName.latin1());
+
+ if(factory)
+ {
+ SearchEngine *e = (SearchEngine *)factory->create(this
+ , "searchengine", "SearchEngine");
+ if(!e)
+ {
+ kdError() << "searchengine not initialized" << endl;
+ }
+ else
+ {
+ registerModule(e);
+ }
+ }
+ else
+ {
+ kdError() << "wasn't able to load library" << endl;
+ }
+
+ }
+ }
+
+ kdDebug(KBABEL_SEARCH) << "Now using trader for " << KGlobal::instance()->instanceName() << endl;
+
+ // try to find installed modules by KTrader
+ KTrader::OfferList offers = KTrader::self()->query("KBabelDictModule",
+ "('"+KGlobal::instance()->instanceName()+"' in [Applications])");
+
+ for(KTrader::OfferList::ConstIterator it = offers.begin(); it != offers.end(); ++it )
+ {
+ KLibFactory *factory = KLibLoader::self()->factory( (*it)->library().local8Bit() );
+
+ if(factory)
+ {
+ SearchEngine *e = (SearchEngine *)factory->create(this
+ , "searchengine", "SearchEngine");
+ if(!e)
+ {
+ kdError() << "searchengine not initialized" << endl;
+ }
+ else
+ {
+ registerModule(e);
+ }
+ }
+ else
+ {
+ kdError() << "wasn't able to load library" << endl;
+ }
+ }
+
+ kdDebug(KBABEL_SEARCH) << "Now for any application" << endl;
+
+ offers = KTrader::self()->query("KBabelDictModule",
+ "not ( exist Applications)");
+
+ for(KTrader::OfferList::ConstIterator it = offers.begin(); it != offers.end(); ++it )
+ {
+ KLibFactory *factory = KLibLoader::self()->factory( (*it)->library().local8Bit() );
+
+ if(factory)
+ {
+ SearchEngine *e = (SearchEngine *)factory->create(this
+ , "searchengine", "SearchEngine");
+ if(!e)
+ {
+ kdError() << "searchengine not initialized" << endl;
+ }
+ else
+ {
+ registerModule(e);
+ }
+ }
+ else
+ {
+ kdError() << "wasn't able to load library" << endl;
+ }
+ }
+
+ connect(nextButton,SIGNAL(clicked()),this,SLOT(slotNextResult()));
+ connect(prevButton,SIGNAL(clicked()),this,SLOT(slotPrevResult()));
+ connect(moreButton,SIGNAL(clicked()),this,SLOT(nextInfo()));
+
+
+ origView->installEventFilter(this);
+ translationView->installEventFilter(this);
+
+ resultListView->setSorting(0,false);
+ resultListView->setAllColumnsShowFocus(true);
+
+ connect(resultListView,SIGNAL(selectionChanged(QListViewItem*))
+ , this, SLOT(showResult(QListViewItem*)));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+KBabelDictBox::~KBabelDictBox()
+{
+}
+
+void KBabelDictBox::registerModule( SearchEngine* e )
+{
+ active = 0;
+ moduleList.append(e);
+ connect(e, SIGNAL(started()),this,SIGNAL(searchStarted()));
+ connect(e, SIGNAL(finished()),this,SIGNAL(searchStopped()));
+ connect(e, SIGNAL(finished()),this
+ ,SLOT(clearModuleResults()));
+ connect(e, SIGNAL(progress(int)),this,SIGNAL(progressed(int)));
+ connect(e, SIGNAL(progressStarts(const QString&)),this
+ , SIGNAL(progressStarts(const QString&)));
+ connect(e, SIGNAL(progressEnds()),this,SIGNAL(progressEnds()));
+ connect(e, SIGNAL(resultFound(const SearchResult*)), this
+ , SLOT(addResult(const SearchResult*)));
+ connect(e, SIGNAL(hasError(const QString&)), this
+ , SIGNAL(errorInModule(const QString&)));
+}
+
+void KBabelDictBox::saveSettings(KConfigBase *config)
+{
+ KConfigGroupSaver cs(config,"KBabelDict");
+
+ config->writeEntry("ResultSplitter",resultSplitter->sizes());
+
+ SearchEngine *e;
+
+ e = moduleList.at(active);
+ if(e)
+ {
+ config->writeEntry("ActiveModule",e->id());
+ }
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ config->setGroup(e->id());
+ e->saveSettings(config);
+ }
+
+
+}
+
+void KBabelDictBox::saveSettings(const QString& moduleId, KConfigBase *config)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ if(e->id() == moduleId)
+ {
+ e->saveSettings(config);
+ break;
+ }
+ }
+}
+
+void KBabelDictBox::readSettings(KConfigBase *config)
+{
+ SearchEngine *e;
+ KConfigGroupSaver cs(config,"KBabelDict");
+ QValueList<int> sizes=config->readIntListEntry("ResultSplitter");
+ if(!sizes.isEmpty())
+ resultSplitter->setSizes(sizes);
+
+ QString m = config->readEntry("ActiveModule");
+ if(!m.isEmpty())
+ {
+ setActiveModule(m);
+ }
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ config->setGroup(e->id());
+ e->readSettings(config);
+ }
+}
+
+void KBabelDictBox::readSettings(const QString& moduleId, KConfigBase *config)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ if(e->id() == moduleId)
+ {
+ e->readSettings(config);
+ break;
+ }
+ }
+}
+
+void KBabelDictBox::setAutoUpdateOptions(bool on)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ e->setAutoUpdateOptions(on);
+ }
+}
+
+
+int KBabelDictBox::activeModule()
+{
+ return active;
+}
+
+/*
+ * public slot
+ */
+void KBabelDictBox::setActiveModule(int a)
+{
+ if( a == active)
+ return;
+
+ if( a < (int)moduleList.count())
+ {
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ }
+ else if(engine->isSearching())
+ {
+ engine->stopSearch();
+ engine->clearResults();
+ }
+
+ engine = moduleList.at(a);
+ if(engine)
+ {
+ active = a;
+ emit activeModuleChanged(active);
+ emit activeModuleChanged(engine->isEditable());
+ }
+
+
+ }
+}
+
+void KBabelDictBox::setActiveModule(QString id)
+{
+ SearchEngine *e;
+
+ int i=0;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ if(e->id() == id)
+ {
+ setActiveModule(i);
+ break;
+ }
+
+ i++;
+ }
+}
+
+/*
+ * public slot
+ */
+void KBabelDictBox::startSearch(const QString text)
+{
+ clear();
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ }
+ else
+ {
+ if(engine->isSearching())
+ {
+ engine->stopSearch();
+ connect(this, SIGNAL(searchStopped()), this
+ , SLOT(startDelayedSearch()));
+
+ searchText=text;
+ }
+ else engine->startSearch(text);
+ }
+}
+
+/*
+ * public slot
+ */
+void KBabelDictBox::startTranslationSearch(const QString text)
+{
+ clear();
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ }
+ else
+ {
+ if(engine->isSearching())
+ {
+ engine->stopSearch();
+ connect(this, SIGNAL(searchStopped()), this
+ , SLOT(startDelayedTranslationSearch()));
+
+ searchText=text;
+ }
+ else engine->startSearchInTranslation(text);
+ }
+}
+
+void KBabelDictBox::startDelayedSearch(const QString text)
+{
+ clear();
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ }
+ else
+ {
+ searchText=text;
+
+ if(engine->isSearching())
+ {
+ engine->stopSearch();
+
+ connect(this, SIGNAL(searchStopped()), this
+ , SLOT(startDelayedSearch()));
+
+ }
+ else
+ {
+ QTimer::singleShot(5,this,SLOT(startDelayedSearch()));
+ }
+ }
+}
+
+void KBabelDictBox::startDelayedTranslationSearch(const QString text)
+{
+ clear();
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ }
+ else
+ {
+ searchText=text;
+
+ if(engine->isSearching())
+ {
+ engine->stopSearch();
+
+ connect(this, SIGNAL(searchStopped()), this
+ , SLOT(startDelayedTranslationSearch()));
+
+ }
+ else
+ {
+ QTimer::singleShot(5,this,SLOT(startDelayedTranslationSearch()));
+ }
+ }
+}
+
+QString KBabelDictBox::translate(const QString text)
+{
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ return QString::null;
+ }
+ else
+ {
+ if(engine->isSearching())
+ {
+ engine->stopSearch();
+ }
+
+ return engine->translate(text);
+ }
+}
+
+QString KBabelDictBox::fuzzyTranslation(const QString text, int &score)
+{
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ return QString::null;
+ }
+ else
+ {
+ if(engine->isSearching())
+ {
+ engine->stopSearch();
+ }
+
+ return engine->fuzzyTranslation(text, score);
+ }
+}
+
+QString KBabelDictBox::searchTranslation(const QString text, int &score)
+{
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ return QString::null;
+ }
+ else
+ {
+ if(engine->isSearching())
+ {
+ engine->stopSearch();
+ }
+
+ return engine->searchTranslation(text, score);
+ }
+}
+
+void KBabelDictBox::startDelayedSearch()
+{
+ clear();
+
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ }
+ else
+ {
+ disconnect(this, SIGNAL(searchStopped()), this
+ , SLOT(startDelayedSearch()));
+
+
+ engine->startSearch(searchText);
+ }
+}
+
+void KBabelDictBox::startDelayedTranslationSearch()
+{
+ clear();
+
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ }
+ else
+ {
+ disconnect(this, SIGNAL(searchStopped()), this
+ , SLOT(startDelayedTranslationSearch()));
+
+
+ engine->startSearchInTranslation(searchText);
+ }
+}
+
+/*
+ * public slot
+ */
+void KBabelDictBox::stopSearch()
+{
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ }
+ else
+ {
+ engine->stopSearch();
+ }
+
+}
+
+bool KBabelDictBox::isSearching()
+{
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ kdDebug(KBABELDICT) << "no module available" << endl;
+ return false;
+ }
+
+ return engine->isSearching();
+}
+
+
+QStringList KBabelDictBox::moduleNames()
+{
+ QStringList list;
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ list.append(e->name());
+ }
+
+ return list;
+}
+
+QStringList KBabelDictBox::modules()
+{
+ QStringList list;
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ list.append(e->id());
+ }
+
+ return list;
+}
+
+QPtrList<ModuleInfo> KBabelDictBox::moduleInfos()
+{
+ QPtrList<ModuleInfo> list;
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ ModuleInfo *info = new ModuleInfo;
+ info->id=e->id();
+ info->name=e->name();
+ info->editable=e->isEditable();
+
+ list.append(info);
+ }
+
+ return list;
+}
+
+
+QPtrList<PrefWidget> KBabelDictBox::modPrefWidgets(QWidget *parent)
+{
+ QPtrList<PrefWidget> list;
+ list.setAutoDelete(false);
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ list.append(e->preferencesWidget(parent));
+ }
+
+ return list;
+
+}
+
+
+void KBabelDictBox::showResult(QListViewItem *item)
+{
+ ResultListItem *resultItem = static_cast<ResultListItem*>(item);
+
+ if(!item)
+ {
+ kdError(KBABELDICT) << "no item" << endl;
+ if(rmbPopup)
+ {
+ rmbPopup->changeItem(editFileIndex, i18n("Edit File"));
+ rmbPopup->setItemEnabled(editFileIndex,false);
+ }
+ }
+ else
+ {
+ const SearchResult *result= resultItem->result();
+ if(!result)
+ return;
+
+ resultListView->ensureItemVisible(item);
+
+ currentResult = resultListView->itemIndex(item);
+ currentInfo = 0;
+
+ bool richText=resultItem->richText();
+ if(richText)
+ {
+ // FIXME: what about plural forms?
+ origView->setText(result->found.first());
+ translationView->setText(result->translation);
+ }
+ else
+ {
+ // FIXME: what about plural forms?
+ origView->setText(QStyleSheet::convertFromPlainText(result->found.first()));
+ translationView->setText(
+ QStyleSheet::convertFromPlainText(result->translation));
+ }
+
+ if(result->descriptions.count() > 0)
+ {
+ QPtrListIterator<TranslationInfo> it(result->descriptions);
+ TranslationInfo *info=it.current();
+ if(info)
+ {
+ if(info->lastChange.isValid())
+ {
+ dateLabel->setText(KGlobal::locale()->formatDate(
+ info->lastChange.date(),true));
+ }
+ else
+ {
+ dateLabel->setText("");
+ }
+ locationLabel->setText(info->location);
+ translatorLabel->setText(info->translator);
+
+ if(rmbPopup)
+ {
+ if(!info->filePath.isEmpty())
+ {
+ rmbPopup->changeItem(editFileIndex
+ ,i18n("Edit File %1").arg(info->location));
+ rmbPopup->setItemEnabled(editFileIndex,true);
+ }
+ else
+ {
+ rmbPopup->changeItem(editFileIndex, i18n("Edit File"));
+ rmbPopup->setItemEnabled(editFileIndex,false);
+ }
+ }
+ }
+ }
+ else
+ {
+ dateLabel->setText("");
+ locationLabel->setText("");
+ translatorLabel->setText("");
+
+ rmbPopup->changeItem(editFileIndex, i18n("Edit File"));
+ rmbPopup->setItemEnabled(editFileIndex,false);
+ }
+
+ moreButton->setEnabled((result->descriptions.count() > 1));
+
+ currentLabel->setText(QString::number(currentResult+1));
+
+ prevButton->setEnabled(currentResult > 0);
+ nextButton->setEnabled(currentResult+1 < total);
+ }
+
+}
+
+void KBabelDictBox::nextResult()
+{
+ QListViewItem *item=resultListView->selectedItem();
+ if(item)
+ {
+ item=item->itemBelow();
+ if(item)
+ {
+ resultListView->setSelected(item,true);
+ }
+ }
+}
+
+
+void KBabelDictBox::prevResult()
+{
+ QListViewItem *item=resultListView->selectedItem();
+ if(item)
+ {
+ item=item->itemAbove();
+ if(item)
+ {
+ resultListView->setSelected(item,true);
+ }
+ }
+
+}
+
+void KBabelDictBox::addResult(const SearchResult* result)
+{
+ SearchEngine *e;
+
+ e = moduleList.at(active);
+ if(!e)
+ {
+ kdError(KBABELDICT) << "no module available" << endl;
+ return;
+ }
+
+ QListViewItem *item=resultListView->selectedItem();
+ int index=0;
+ if(item)
+ {
+ index=resultListView->itemIndex(item);
+ }
+
+ new ResultListItem(resultListView, *result,e->usesRichTextResults());
+ total++;
+ totalResultsLabel->setText(QString::number(total));
+
+ if(total==1)
+ {
+ resultListView->setSelected(resultListView->firstChild(),true);
+ }
+ else
+ {
+ nextButton->setEnabled((currentResult+1) < total);
+ item=resultListView->itemAtIndex(index);
+ if(item)
+ {
+ resultListView->setSelected(item,true);
+ }
+ }
+}
+
+void KBabelDictBox::clear()
+{
+ dateLabel->setText("");
+ locationLabel->setText("");
+ translatorLabel->setText("");
+ currentLabel->setText(QString::number(0));
+ totalResultsLabel->setText(QString::number(0));
+ origView->setText("");
+ translationView->setText("");
+ currentResult=0;
+ currentInfo=0;
+ total=0;
+
+ resultListView->clear();
+ clearModuleResults();
+
+ moreButton->setEnabled(false);
+ prevButton->setEnabled(false);
+ nextButton->setEnabled(false);
+
+ if(rmbPopup)
+ {
+ rmbPopup->changeItem(editFileIndex,i18n("Edit File"));
+ rmbPopup->setItemEnabled(editFileIndex,false);
+ }
+}
+
+void KBabelDictBox::nextInfo()
+{
+ ResultListItem *item = static_cast<ResultListItem*>(resultListView->selectedItem());
+
+ if(!item)
+ {
+ kdDebug(KBABELDICT) << "no item available" << endl;
+ }
+ else
+ {
+ const SearchResult *result = item->result();
+ if(!result)
+ return;
+
+ if(result->descriptions.count() > 0)
+ {
+ currentInfo++;
+ TranslationInfo *info;
+ if(currentInfo == (int)result->descriptions.count())
+ {
+ QPtrListIterator<TranslationInfo> it(result->descriptions);
+ info = it.current();
+ currentInfo = 0;
+ }
+ else
+ {
+ QPtrListIterator<TranslationInfo> it(result->descriptions);
+ for(int i=0; i < currentInfo; i++)
+ {
+ ++it;
+ }
+ info=*it;
+ }
+
+ if(info->lastChange.isValid())
+ {
+ dateLabel->setText(KGlobal::locale()->formatDate(
+ info->lastChange.date(),true));
+ }
+ else
+ {
+ dateLabel->setText("");
+ }
+
+ locationLabel->setText(info->location);
+ translatorLabel->setText(info->translator);
+
+ if(rmbPopup)
+ {
+ if(!info->filePath.isEmpty())
+ {
+ rmbPopup->changeItem(editFileIndex
+ ,i18n("Edit File %1").arg(info->location));
+ rmbPopup->setItemEnabled(editFileIndex,true);
+ }
+ else
+ {
+ rmbPopup->changeItem(editFileIndex, i18n("Edit File"));
+ rmbPopup->setItemEnabled(editFileIndex,false);
+ }
+ }
+ }
+ }
+
+}
+
+void KBabelDictBox::showListOnly()
+{
+ int h=resultSplitter->height();
+ QValueList<int> sizes;
+ sizes.append(1);
+ sizes.append(h-1);
+ resultSplitter->setSizes(sizes);
+}
+
+void KBabelDictBox::showDetailsOnly()
+{
+ int h=resultSplitter->height();
+ QValueList<int> sizes;
+ sizes.append(h-1);
+ sizes.append(h);
+ resultSplitter->setSizes(sizes);
+}
+
+void KBabelDictBox::clearModuleResults()
+{
+ SearchEngine *engine = moduleList.at(active);
+ if(engine)
+ engine->clearResults();
+}
+
+void KBabelDictBox::about()
+{
+ KAboutApplication *aboutDlg = new KAboutApplication(this);
+
+ SearchEngine *e;
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ KAboutContainer *page = aboutDlg->addScrolledContainerPage(e->name());
+
+ const KAboutData *aboutData = e->about();
+ if(aboutData)
+ {
+
+ QString text = aboutData->programName() + " " +
+ aboutData->version() + "\n";
+
+ text += "\n"+aboutData->shortDescription()+"\n";
+
+ if(!aboutData->homepage().isEmpty())
+ {
+ text += "\n" + aboutData->homepage() + "\n";
+ }
+ if(!aboutData->otherText().isEmpty())
+ {
+ text += "\n" + aboutData->otherText() + "\n";
+ }
+ if(!aboutData->copyrightStatement().isEmpty())
+ {
+ text += "\n" + aboutData->copyrightStatement() + "\n";
+ }
+
+ if(aboutData->bugAddress() != "submit@bugs.kde.org")
+ {
+ text += "\n" + i18n("Send bugs to %1")
+ .arg(aboutData->bugAddress()) +"\n";
+ }
+
+ QLabel *label = new QLabel(text,0);
+ page->addWidget(label);
+
+ int authorCount = aboutData->authors().count();
+ if(authorCount)
+ {
+ if(authorCount==1)
+ text=i18n("Author:");
+ else
+ text=i18n("Authors:");
+
+ label = new QLabel(text,0);
+ page->addWidget(label);
+
+ QValueList<KAboutPerson>::ConstIterator it;
+ for(it = aboutData->authors().begin();
+ it != aboutData->authors().end(); ++it)
+ {
+ page->addPerson( (*it).name(), (*it).emailAddress(),
+ (*it).webAddress(), (*it).task() );
+ }
+ }
+ int creditsCount = aboutData->credits().count();
+ if(creditsCount)
+ {
+ text = i18n("Thanks to:");
+ label = new QLabel(text,0);
+ page->addWidget(label);
+
+ QValueList<KAboutPerson>::ConstIterator it;
+ for(it = aboutData->credits().begin();
+ it != aboutData->credits().end(); ++it)
+ {
+ page->addPerson( (*it).name(), (*it).emailAddress(),
+ (*it).webAddress(), (*it).task() );
+ }
+
+ }
+ }
+ else
+ {
+ QString text = i18n("No information available.");
+ QLabel *label = new QLabel(text,0);
+ page->addWidget(label);
+ }
+
+ }
+
+ aboutDlg->setInitialSize(QSize(400,1));
+ aboutDlg->exec();
+
+ delete aboutDlg;
+}
+
+void KBabelDictBox::aboutActiveModule()
+{
+ SearchEngine *engine = moduleList.at(active);
+ if(!engine)
+ return;
+
+ aboutModule(engine->id());
+}
+
+void KBabelDictBox::aboutModule(const QString& id)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ if(e->id() == id)
+ {
+ break;
+ }
+ }
+
+ if(!e)
+ return;
+
+ AboutModuleDlg *aboutDlg = new AboutModuleDlg(e->about(),this);
+ aboutDlg->exec();
+
+ delete aboutDlg;
+
+}
+
+
+void KBabelDictBox::slotNextResult()
+{
+ nextResult();
+}
+
+void KBabelDictBox::slotPrevResult()
+{
+ prevResult();
+}
+
+
+void KBabelDictBox::slotStopSearch()
+{
+ stopSearch();
+}
+
+void KBabelDictBox::slotStartSearch(const QString& text)
+{
+ startSearch(text);
+}
+
+void KBabelDictBox::setEditedPackage(const QString& name)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ e->setEditedPackage(name);
+ }
+}
+
+
+void KBabelDictBox::setEditedFile(const QString& path)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ e->setEditedFile(path);
+ }
+}
+
+void KBabelDictBox::setLanguage(const QString& languageCode,
+ const QString& languageName)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ e->setLanguage(languageCode,languageName);
+ e->setLanguageCode(languageCode);
+ }
+}
+
+void KBabelDictBox::copy()
+{
+ if(origView->hasSelectedText())
+ {
+ origView->copy();
+ }
+ else if(translationView->hasSelectedText())
+ {
+ translationView->copy();
+ }
+ else
+ {
+ QClipboard *cb = KApplication::clipboard();
+ cb->setText(translation());
+ }
+}
+
+QString KBabelDictBox::translation()
+{
+ QString trans;
+
+ QListViewItem *item=resultListView->selectedItem();
+ if(item)
+ {
+ ResultListItem *r=static_cast<ResultListItem*>(item);
+ if(r)
+ {
+ const SearchResult *sr=r->result();
+ if(sr)
+ {
+ if(r->richText())
+ trans=sr->plainTranslation;
+ else
+ trans=sr->translation;
+ }
+ }
+ }
+
+ return trans;
+}
+
+void KBabelDictBox::setRMBMenu(QPopupMenu *popup)
+{
+ if(popup)
+ {
+ if(popup->count() > 0)
+ popup->insertSeparator();
+
+ editFileIndex = popup->insertItem(i18n("Edit File")
+ , this, SLOT(editFile()));
+ popup->setItemEnabled(editFileIndex,false);
+
+ KContextMenuManager::insert(origView,popup);
+ KContextMenuManager::insert(origView->viewport(),popup);
+ KContextMenuManager::insert(translationView,popup);
+ KContextMenuManager::insert(translationView->viewport(),popup);
+ KContextMenuManager::insert(this,popup);
+ //KContextMenuManager::insert(resultListView->viewport(),popup);
+
+ rmbPopup = popup;
+ }
+}
+
+bool KBabelDictBox::hasSelectedText() const
+{
+ bool have=false;
+ if(origView->hasSelectedText())
+ have=true;
+ else if(translationView->hasSelectedText())
+ have=true;
+ else if(resultListView->selectedItem() )
+ have=true;
+
+ return have;
+}
+
+QString KBabelDictBox::selectedText() const
+{
+ QString text;
+ if(origView->hasSelectedText())
+ text=origView->selectedText();
+ else if(translationView->hasSelectedText())
+ translationView->selectedText();
+
+ return text;
+}
+
+
+
+void KBabelDictBox::configure(const QString& id, bool modal)
+{
+
+ QWidget* w = prefDialogs[id];
+ if(w)
+ {
+ KWin::setActiveWindow(w->winId());
+ return;
+ }
+
+ SearchEngine *e;
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ if(e->id() == id)
+ {
+ QString caption = i18n("Configure Dictionary %1").arg(e->name());
+ KDialogBase *dialog = new KDialogBase(this,"prefDialog"
+ , modal, caption
+ , KDialogBase::Ok|KDialogBase::Apply|KDialogBase::Cancel|
+ KDialogBase::Default);
+
+ QWhatsThis::add(dialog,"");
+
+ PrefWidget *prefWidget = e->preferencesWidget(dialog);
+ dialog->setMainWidget(prefWidget);
+
+ connect(dialog, SIGNAL(okClicked()),prefWidget,SLOT(apply()));
+ connect(dialog, SIGNAL(applyClicked()),prefWidget,SLOT(apply()));
+ connect(dialog, SIGNAL(defaultClicked()),prefWidget,SLOT(standard()));
+ connect(dialog, SIGNAL(cancelClicked()),prefWidget,SLOT(cancel()));
+
+ connect(dialog, SIGNAL(finished()),this,SLOT(destroyConfigDialog()));
+
+ prefDialogs.insert(id,dialog);
+
+ if( modal ) dialog->exec();
+ else dialog->show();
+
+ break;
+ }
+ }
+
+}
+
+
+void KBabelDictBox::destroyConfigDialog()
+{
+ const QObject *obj = sender();
+ if(obj && obj->inherits("KDialogBase"))
+ {
+ KDialogBase *dialog = (KDialogBase*)obj;
+ if(dialog)
+ {
+ dialog->delayedDestruct();
+
+ QDictIterator<QWidget> it(prefDialogs);
+ while(it.current() != dialog)
+ {
+ ++it;
+ }
+
+ prefDialogs.remove(it.currentKey());
+ }
+ }
+}
+
+void KBabelDictBox::edit(const QString& id)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ if(e->id() == id)
+ {
+ if(e->isEditable())
+ e->edit();
+
+ break;
+ }
+ }
+}
+
+void KBabelDictBox::edit()
+{
+ SearchEngine *engine = moduleList.at(active);
+ if(!engine)
+ return;
+
+ if(engine->isEditable())
+ engine->edit();
+}
+
+void KBabelDictBox::setTextChanged(const QStringList& orig,
+ const QString& translation, uint pluralForm, const QString& description)
+{
+ SearchEngine *e;
+
+ for(e = moduleList.first(); e != 0; e = moduleList.next())
+ {
+ e->stringChanged(orig,translation,pluralForm,description);
+ }
+}
+
+
+void KBabelDictBox::wheelEvent(QWheelEvent *we)
+{
+ if(we->delta() > 0)
+ {
+ prevResult();
+ }
+ else
+ {
+ nextResult();
+ }
+
+ we->accept();
+}
+
+bool KBabelDictBox::eventFilter(QObject *o, QEvent *e)
+{
+ if(e->type() == QEvent::Wheel)
+ {
+ QWheelEvent *we = static_cast<QWheelEvent*>(e);
+ if(we)
+ {
+ wheelEvent(we);
+ return true;
+ }
+ }
+ else if(e->type() == QEvent::Resize && o == resultListView)
+ {
+ if(resultListView->height() < 2)
+ {
+ detailButton->setEnabled(false);
+ listButton->setEnabled(true);
+ }
+ else if(resultListView->height() > resultSplitter->height()-10)
+ {
+ detailButton->setEnabled(true);
+ listButton->setEnabled(false);
+ }
+ else
+ {
+ detailButton->setEnabled(true);
+ listButton->setEnabled(true);
+ }
+ }
+
+ return false;
+}
+
+void KBabelDictBox::editFile()
+{
+ ResultListItem *item = static_cast<ResultListItem*>(resultListView->currentItem());
+
+ if(!item)
+ {
+ kdDebug(KBABELDICT) << "no item available" << endl;
+ }
+ else
+ {
+ const SearchResult *result = item->result();
+ if(!result)
+ return;
+
+ if(!result->descriptions.isEmpty())
+ {
+ TranslationInfo *info;
+ QPtrListIterator<TranslationInfo> it(result->descriptions);
+ for(int i=0; i < currentInfo; i++)
+ {
+ ++it;
+ }
+ info=*it;
+
+ if(!info->filePath.isEmpty())
+ {
+ QString url = info->filePath;
+ QString msgid;
+
+ if( item->richText() )
+ {
+ msgid = result->plainFound;
+ }
+ else
+ {
+ msgid = result->found.first();
+ }
+
+ DCOPClient *dcop = kapp->dcopClient();
+
+ QCStringList list = dcop->registeredApplications();
+ int index = list.findIndex("kbabel");
+ if(index < 0)
+// if(!dcop->isApplicationRegistered("kbabel"));
+ {
+ kdDebug(KBABELDICT) << "kbabel is not registered" << endl;
+
+ QString error;
+ QStringList argList;
+ argList.append("--nosplash");
+ argList.append("--gotomsgid");
+ argList.append(msgid.local8Bit());
+ argList.append(url.local8Bit());
+ kapp->kdeinitExec("kbabel",argList,&error);
+ if(!error.isNull())
+ {
+ KMessageBox::sorry(this
+ ,i18n("There was an error starting KBabel:\n%1")
+ .arg(error));
+ return;
+ }
+ }
+ else
+ {
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << url.utf8() << msgid.utf8();
+ if (!dcop->send("kbabel", "KBabelIFace"
+ , "gotoFileEntry(QCString,QCString)",data))
+ {
+ KMessageBox::sorry(this
+ ,i18n("There was an error using DCOP."));
+ }
+ }
+ }
+ }
+ }
+}
+
+void KBabelDictBox::showContextMenu(KListView *,QListViewItem *,const QPoint& p)
+{
+ if(rmbPopup)
+ {
+ rmbPopup->exec(p);
+ }
+}
+
+
+bool KBabelDictBox::messagesForPackage(const QString& package
+ , QValueList<DiffEntry>& resultList, QString& error)
+{
+ setActiveModule("dbsearchengine");
+ SearchEngine *engine = moduleList.at(active);
+
+ if(!engine)
+ {
+ KMessageBox::sorry(this
+ ,i18n("The \"Translation Database\" module\n"
+ "appears not to be installed on your system."));
+ return false;
+ }
+
+ QValueList<SearchResult> rList;
+
+ SearchFilter* filter = new SearchFilter();
+ filter->setLocation(package);
+
+ bool success = engine->messagesForFilter(filter,rList,error);
+
+ if(success)
+ {
+ QValueList<SearchResult>::Iterator it;
+ for(it=rList.begin(); it != rList.end(); ++it)
+ {
+ // FIXME: what about plural forms?
+ DiffEntry e;
+ e.msgid = (*it).found.first();
+ e.msgstr = (*it).translation;
+ resultList.append(e);
+ }
+ }
+
+ return success;
+}
+
+#include "kbabeldictbox.moc"
+
diff --git a/kbabel/kbabeldict/kbabeldictbox.h b/kbabel/kbabeldict/kbabeldictbox.h
new file mode 100644
index 00000000..8168786e
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldictbox.h
@@ -0,0 +1,282 @@
+/* ****************************************************************************
+ 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 KBABELDICTBOX_H
+#define KBABELDICTBOX_H
+
+#include "kbabeldictiface.h"
+#include "searchengine.h"
+#include "catalog.h"
+
+#include <qdict.h>
+#include <qguardedptr.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+
+class KListView;
+class QLabel;
+class QListViewItem;
+class QPopupMenu;
+class QPushButton;
+class QSplitter;
+class QTextView;
+class QToolButton;
+
+struct ModuleInfo
+{
+ QString id;
+ QString name;
+
+ bool editable;
+};
+
+
+class KDE_EXPORT KBabelDictBox : public QWidget, virtual public KBabelDictIFace
+{
+ Q_OBJECT
+
+public:
+ KBabelDictBox( QWidget* parent = 0, const char* name = 0
+ , WFlags fl = 0 );
+ ~KBabelDictBox();
+
+ /** @returns ids of available modules */
+ virtual QStringList modules();
+
+ /** @returns (translated) names of available modules */
+ QStringList moduleNames();
+
+ /**
+ * @returns a list with information about the available modules
+ * Take care about, that you have to delete the items by yourself.
+ */
+ QPtrList<ModuleInfo> moduleInfos();
+
+ /** @returns preferencesWidgets of modules */
+ QPtrList<PrefWidget> modPrefWidgets(QWidget* parent);
+
+ int activeModule();
+ bool activeModuleEditable();
+
+ /**
+ * lets the modules always update their options before
+ * starting a new search
+ */
+ void setAutoUpdateOptions(bool on);
+
+ void nextResult();
+ void prevResult();
+ void startSearch(const QString);
+ void startTranslationSearch(const QString);
+ void startDelayedSearch(const QString);
+ void startDelayedTranslationSearch(const QString);
+ QString translate(const QString);
+ QString searchTranslation(const QString, int& score);
+ QString fuzzyTranslation(const QString, int& score);
+ void stopSearch();
+ void setActiveModule(QString name);
+
+ /**
+ * @returns true, if a search is active at the moment
+ */
+ bool isSearching();
+
+ /**
+ * Saves the settings including the settings of the different modules
+ * in the given config object.
+ */
+ void saveSettings(KConfigBase *config);
+
+ /**
+ * Saves the settings of the given module
+ * in the given config object.
+ */
+ void saveSettings(const QString& moduleId, KConfigBase *config);
+
+ /**
+ * Reads the settings including the settings of the different modules
+ * from the given config object.
+ */
+ void readSettings(KConfigBase *config);
+
+ /**
+ * Reads the settings of the given module
+ * from the given config object.
+ */
+ void readSettings(const QString& moduleId, KConfigBase *config);
+
+
+
+ /** @returns the translation of the current search result */
+ QString translation();
+
+ bool hasSelectedText() const;
+ QString selectedText() const;
+
+ void setRMBMenu(QPopupMenu *popup);
+
+
+ virtual bool eventFilter(QObject *, QEvent*);
+
+
+ /**
+ * A hack for kbabel to get a list of messages for a specific package
+ * from dbsearchengine. When dbsearchengine allows multiple access to
+ * the database this will get removed.
+ */
+ bool messagesForPackage(const QString& package
+ , QValueList<KBabel::DiffEntry>& resultList, QString& error);
+
+public slots:
+ virtual void setActiveModule(int);
+ void slotStartSearch(const QString&);
+ void slotStopSearch();
+ void slotNextResult();
+ void slotPrevResult();
+
+ void about();
+ void aboutModule(const QString& moduleID);
+ void aboutActiveModule();
+
+ /**
+ * sets the name of the package currently edited
+ */
+ void setEditedPackage(const QString& packageName);
+
+ /**
+ * sets the filepath of the package currently edited
+ */
+ void setEditedFile(const QString& path);
+
+ /** sets the language code to use */
+ void setLanguage(const QString& languageCode
+ , const QString& languageName);
+
+
+ void setTextChanged(const QStringList& orig, const QString& translation,
+ uint pluralForm, const QString& description);
+
+ /**
+ * if text is marked, copy this into the clipboard, otherwise
+ * copy the current translation into the clipboard
+ */
+ void copy();
+
+ void configure(const QString& moduleID, bool modal=false);
+ void edit(const QString& moduleID);
+ void edit();
+
+ void clear();
+
+
+signals:
+ void searchStarted();
+ void searchStopped();
+ void progressed(int);
+ void progressStarts(const QString&);
+ void progressEnds();
+ void activeModuleChanged(int);
+ void activeModuleChanged(bool editable);
+ void errorInModule(const QString& error);
+
+ /**
+ * emitted when either the order
+ * or the number of modules was changed
+ */
+ void modulesChanged();
+
+protected slots:
+ void showResult(QListViewItem*);
+ void addResult(const SearchResult*);
+ void nextInfo();
+ void showDetailsOnly();
+ void showListOnly();
+ void clearModuleResults();
+ void editFile();
+ void showContextMenu(KListView *, QListViewItem *, const QPoint&);
+
+ /**
+ * This slots gets connected to a SearchEngine's searchStopped() signal,
+ * when a new search is requested although a search is currently active.
+ */
+ void startDelayedSearch();
+ void startDelayedTranslationSearch();
+
+
+ /**
+ * This slot is connected to the finished signal of @ref KDialogBase
+ * to destroy this dialog after the user has closed it.
+ */
+ void destroyConfigDialog();
+
+protected:
+ virtual void wheelEvent(QWheelEvent*);
+
+private:
+ /**
+ * Register the module and connect the slots
+ */
+ void registerModule( SearchEngine* module);
+
+ QPtrList<SearchEngine> moduleList;
+ int active;
+ int currentResult;
+ int currentInfo;
+ int total;
+
+ /** stores a string to be used with delayed search */
+ QString searchText;
+
+ QDict<QWidget> prefDialogs;
+
+ QLabel *translatorLabel;
+ QLabel *locationLabel;
+ QLabel *totalResultsLabel;
+ QLabel *currentLabel;
+ QLabel *dateLabel;
+ QPushButton *moreButton;
+ QPushButton *nextButton;
+ QPushButton *prevButton;
+ QTextView *origView;
+ QTextView *translationView;
+ QSplitter *viewContainer;
+ KListView *resultListView;
+ QSplitter *resultSplitter;
+
+ QToolButton *listButton;
+ QToolButton *detailButton;
+
+ int editFileIndex;
+ QGuardedPtr<QPopupMenu> rmbPopup;
+};
+
+#endif // KBABELDICTBOX_H
diff --git a/kbabel/kbabeldict/kbabeldictiface.h b/kbabel/kbabeldict/kbabeldictiface.h
new file mode 100644
index 00000000..0b98a565
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldictiface.h
@@ -0,0 +1,56 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 1999-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 KBABELDICTINTERFACE_H
+#define KBABELDICTINTERFACE_H
+
+#include <dcopobject.h>
+#include <qstringlist.h>
+
+class KBabelDictIFace : virtual public DCOPObject
+{
+ K_DCOP
+
+k_dcop:
+ virtual QStringList modules() = 0;
+ virtual ASYNC setActiveModule(QString modulename) = 0;
+
+ virtual ASYNC startSearch(const QString searchstring) = 0;
+ virtual ASYNC stopSearch() = 0;
+
+ virtual ASYNC nextResult()=0;
+ virtual ASYNC prevResult()=0;
+
+};
+
+#endif
diff --git a/kbabel/kbabeldict/kbabeldictview.cpp b/kbabel/kbabeldict/kbabeldictview.cpp
new file mode 100644
index 00000000..26afd981
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldictview.cpp
@@ -0,0 +1,294 @@
+/* ****************************************************************************
+ 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 "kbabeldictview.h"
+#include "kbabeldictbox.h"
+#include "searchengine.h"
+
+
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qptrlist.h>
+#include <qpushbutton.h>
+#include <qstringlist.h>
+#include <qwidgetstack.h>
+#include <qsplitter.h>
+#include <qvbox.h>
+
+#include <kcombobox.h>
+#include <kconfig.h>
+#include <kdialog.h>
+#include <kglobal.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kprogress.h>
+#include <kseparator.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+
+/*
+ * Constructs a KBabelDictView which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+KBabelDictView::KBabelDictView( QWidget* parent, const char* name, WFlags fl )
+ : QWidget( parent, name, fl )
+{
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ mainLayout->setSpacing(KDialog::spacingHint());
+ mainLayout->setMargin(KDialog::marginHint());
+
+ splitter = new QSplitter(this);
+ mainLayout->addWidget(splitter);
+
+ QWidget *w = new QWidget(splitter);
+ QVBoxLayout *wLayout= new QVBoxLayout(w);
+ wLayout->setSpacing(KDialog::spacingHint());
+ wLayout->setMargin(KDialog::marginHint());
+
+ QHBoxLayout *hbox = new QHBoxLayout(wLayout);
+ QLabel *label = new QLabel(i18n("Search in module:"), w);
+ hbox->addWidget(label);
+ moduleCombo = new KComboBox(w);
+ hbox->addWidget(moduleCombo);
+
+ QWidget *temp = new QWidget(w);
+ hbox->addWidget(temp);
+ hbox->setStretchFactor(temp,2);
+ editButton = new QPushButton(i18n("&Edit"),w);
+ editButton->setEnabled(false);
+ hbox->addWidget(editButton);
+
+ // added a button "clear search" here
+ hbox = new QHBoxLayout(wLayout);
+ QPushButton* clearButton = new QPushButton(w);
+ clearButton->setFlat(true);
+ clearButton->setPixmap(SmallIcon("locationbar_erase"));
+ hbox->addWidget(clearButton);
+ textEdit = new KLineEdit(w,"textedit");
+ textEdit->setFocus();
+ hbox->addWidget(textEdit);
+
+ hbox = new QHBoxLayout(wLayout);
+ startButton = new QPushButton(i18n("&Start Search"),w);
+ hbox->addWidget(startButton);
+ inTransButton = new QCheckBox(i18n("Sea&rch in translations"),w);
+ hbox->addWidget(inTransButton);
+ hbox->addStretch(1);
+ stopButton = new QPushButton(i18n("S&top"),w);
+ stopButton->setEnabled(false);
+ hbox->addWidget(stopButton);
+
+ KSeparator *sep = new KSeparator(w);
+ wLayout->addWidget(sep);
+ dictBox = new KBabelDictBox(w,"kbabeldictbox");
+ wLayout->addWidget(dictBox);
+
+ prefWidget = new QWidget(splitter);
+ QVBoxLayout *tempLayout= new QVBoxLayout(prefWidget);
+ tempLayout->setSpacing(KDialog::spacingHint());
+ tempLayout->setMargin(KDialog::marginHint());
+
+ label = new QLabel(i18n("Settings:"),prefWidget);
+ tempLayout->addWidget(label);
+
+ prefStack = new QWidgetStack(prefWidget);
+ tempLayout->addWidget(prefStack);
+ tempLayout->addStretch(1);
+
+ KConfig *config = KGlobal::config();
+ dictBox->readSettings(config);
+ dictBox->setAutoUpdateOptions(true);
+
+ QStringList modules = dictBox->moduleNames();
+ moduleCombo->insertStringList(modules);
+
+ QPtrList<PrefWidget> prefs = dictBox->modPrefWidgets(prefStack);
+ prefs.setAutoDelete(false);
+
+ PrefWidget *p;
+ int i=0;
+ for(p = prefs.first(); p != 0; p=prefs.next())
+ {
+ prefStack->addWidget(p,i);
+ i++;
+ }
+
+ int active=dictBox->activeModule();
+ prefStack->raiseWidget(active);
+ moduleCombo->setCurrentItem(active);
+
+
+ QHBox *h = new QHBox(this);
+ h->setSpacing(KDialog::spacingHint());
+ mainLayout->addWidget(h);
+ progressLabel = new QLabel(h);
+ progressBar = new KProgress(h);
+
+ connect(textEdit,SIGNAL(returnPressed()),startButton,SLOT(animateClick()));
+ connect(startButton,SIGNAL(clicked()),this, SLOT(startSearch()));
+ connect(stopButton, SIGNAL(clicked()), dictBox,SLOT(slotStopSearch()));
+ connect(editButton, SIGNAL(clicked()), dictBox, SLOT(edit()));
+ connect(dictBox, SIGNAL(searchStarted()), this, SLOT(searchStarted()));
+ connect(dictBox, SIGNAL(searchStopped()), this, SLOT(searchStopped()));
+ connect(dictBox, SIGNAL(progressed(int)), progressBar, SLOT(setProgress(int)));
+ connect(dictBox, SIGNAL(activeModuleChanged(bool))
+ , editButton, SLOT(setEnabled(bool)));
+
+ connect(dictBox, SIGNAL(progressStarts(const QString&))
+ , this, SLOT(progressStarted(const QString&)));
+ connect(dictBox, SIGNAL(progressEnds()), this, SLOT(progressStopped()));
+
+ connect(moduleCombo, SIGNAL(activated(int)),
+ dictBox, SLOT(setActiveModule(int)));
+ connect(dictBox, SIGNAL(activeModuleChanged(int))
+ , this, SLOT(switchModule(int)));
+ connect(clearButton, SIGNAL(clicked()), this, SLOT(slotClearSearch()));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+KBabelDictView::~KBabelDictView()
+{
+ // no need to delete child widgets, Qt does it all for us
+ KConfig *config = KGlobal::config();
+ dictBox->saveSettings(config);
+}
+
+/*
+ * public slot
+ */
+void KBabelDictView::startSearch()
+{
+ QString text = textEdit->text();
+
+ if(!text.isEmpty())
+ {
+ if(inTransButton->isChecked())
+ {
+ dictBox->startTranslationSearch(text);
+ }
+ else
+ {
+ dictBox->startSearch(text);
+ }
+ }
+
+
+}
+
+void KBabelDictView::progressStopped()
+{
+ progressBar->setProgress(0);
+ progressLabel->setText("");
+ startButton->setEnabled(true);
+ stopButton->setEnabled(false);
+}
+
+void KBabelDictView::progressStarted(const QString& msg)
+{
+ progressLabel->setText(msg);
+ startButton->setEnabled(false);
+ stopButton->setEnabled(true);
+}
+
+void KBabelDictView::searchStopped()
+{
+ progressLabel->setText("");
+ progressBar->setProgress(0);
+ startButton->setEnabled(true);
+ stopButton->setEnabled(false);
+}
+
+void KBabelDictView::searchStarted()
+{
+ progressLabel->setText(i18n("Searching"));
+ startButton->setEnabled(false);
+ stopButton->setEnabled(true);
+}
+
+void KBabelDictView::switchModule(int m)
+{
+ moduleCombo->blockSignals(true);
+ moduleCombo->setCurrentItem(m);
+ moduleCombo->blockSignals(false);
+
+ prefStack->raiseWidget(m);
+}
+
+
+void KBabelDictView::about()
+{
+ dictBox->about();
+}
+
+
+void KBabelDictView::aboutModule()
+{
+ dictBox->aboutActiveModule();
+}
+
+int KBabelDictView::togglePref()
+{
+ int prefWidth=0;
+ if(prefWidget->isVisibleTo(this))
+ {
+ prefWidget->hide();
+ prefWidth=prefWidget->width();
+ }
+ else
+ {
+ prefWidget->show();
+ prefWidth=prefWidget->width();
+ }
+
+ return prefWidth;
+}
+
+bool KBabelDictView::prefVisible()
+{
+ return prefWidget->isVisibleTo(this);
+}
+
+void KBabelDictView::slotClearSearch()
+{
+ textEdit->clear();
+ textEdit->setFocus();
+}
+
+#include "kbabeldictview.moc"
+
diff --git a/kbabel/kbabeldict/kbabeldictview.h b/kbabel/kbabeldict/kbabeldictview.h
new file mode 100644
index 00000000..510936c4
--- /dev/null
+++ b/kbabel/kbabeldict/kbabeldictview.h
@@ -0,0 +1,92 @@
+/* ****************************************************************************
+ 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 KBABELDICTVIEW_H
+#define KBABELDICTVIEW_H
+
+#include <qwidget.h>
+
+class KComboBox;
+class KLineEdit;
+class KProgress;
+class QCheckBox;
+class QLabel;
+class QPushButton;
+class QSplitter;
+class QWidgetStack;
+
+class KBabelDictBox;
+
+class KBabelDictView : public QWidget
+{
+ Q_OBJECT
+
+public:
+ KBabelDictView( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~KBabelDictView();
+
+ bool prefVisible();
+
+public slots:
+ void startSearch();
+ void about();
+ void aboutModule();
+ int togglePref();
+
+private slots:
+ void searchStopped();
+ void searchStarted();
+ void switchModule(int);
+ void progressStopped();
+ void progressStarted(const QString&);
+ void slotClearSearch();
+
+private:
+ KBabelDictBox *dictBox;
+
+ KComboBox *moduleCombo;
+ KLineEdit *textEdit;
+ QCheckBox *inTransButton;
+ QPushButton *startButton;
+ QPushButton *stopButton;
+ QPushButton *editButton;
+ QWidgetStack *prefStack;
+ KProgress *progressBar;
+ QLabel *progressLabel;
+ QSplitter *splitter;
+
+ QWidget *prefWidget;
+};
+
+#endif // KBABELDICTVIEW_H
diff --git a/kbabel/kbabeldict/kbabelsplash.cpp b/kbabel/kbabeldict/kbabelsplash.cpp
new file mode 100644
index 00000000..16ac2352
--- /dev/null
+++ b/kbabel/kbabeldict/kbabelsplash.cpp
@@ -0,0 +1,73 @@
+/*
+ *
+ * $Id$
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ * 2003 Stanislav Visnovsky <visnovsky@kde.org>
+ *
+ * This file is part of the KBabel project. It's taken from the K3b project,
+ * Copyright (C) 1998-2003 Sebastian Trueg <trueg@k3b.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.
+ * See the file "COPYING" for the exact licensing terms.
+ *
+ * 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 "kbabelsplash.h"
+
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qevent.h>
+#include <qstring.h>
+#include <qfontmetrics.h>
+#include <qpainter.h>
+
+#include <kstandarddirs.h>
+
+KBabelSplash* KBabelSplash::instance = 0;
+
+KBabelSplash::KBabelSplash( QWidget* parent, const char* name )
+ : QVBox( parent, name, WType_Dialog|WShowModal|WStyle_Customize|WStyle_NoBorder|WDestructiveClose )
+{
+ setMargin( 0 );
+ setSpacing( 0 );
+
+ QLabel* picLabel = new QLabel( this );
+ QPixmap pixmap;
+ if( pixmap.load( locate( "data", "kbabel/pics/splash.png" ) ) )
+ picLabel->setPixmap( pixmap );
+
+ picLabel->setFrameStyle(QFrame::WinPanel | QFrame::Raised);
+
+ // Set geometry, with support for Xinerama systems
+ QRect r;
+ r.setSize(sizeHint());
+ int ps = QApplication::desktop()->primaryScreen();
+ r.moveCenter( QApplication::desktop()->screenGeometry(ps).center() );
+ setGeometry(r);
+
+ if( instance ) delete instance;
+ instance = this;
+}
+
+
+void KBabelSplash::mousePressEvent( QMouseEvent* )
+{
+ close();
+}
+
+#include "kbabelsplash.moc"
diff --git a/kbabel/kbabeldict/kbabelsplash.h b/kbabel/kbabeldict/kbabelsplash.h
new file mode 100644
index 00000000..c10b4fec
--- /dev/null
+++ b/kbabel/kbabeldict/kbabelsplash.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * $Id$
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ * 2003 Stanislav Visnovsky <visnovsky@kde.org>
+ *
+ * This file is part of the KBabel project. It's taken from the K3b project,
+ * Copyright (C) 1998-2003 Sebastian Trueg <trueg@k3b.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.
+ * See the file "COPYING" for the exact licensing terms.
+ *
+ * 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 KBABELSPLASH_H
+#define KBABELSPLASH_H
+
+#include <qvbox.h>
+
+class QLabel;
+class QMouseEvent;
+class QPaintEvent;
+class QString;
+
+
+class KBabelSplash : public QVBox
+{
+Q_OBJECT
+
+ public:
+ KBabelSplash( QWidget* parent = 0, const char* name = 0 );
+ ~KBabelSplash() { instance = 0; }
+
+ static KBabelSplash* instance;
+
+ protected:
+ void mousePressEvent( QMouseEvent* );
+};
+
+#endif
diff --git a/kbabel/kbabeldict/lo16-app-kbabeldict.png b/kbabel/kbabeldict/lo16-app-kbabeldict.png
new file mode 100644
index 00000000..a296a94f
--- /dev/null
+++ b/kbabel/kbabeldict/lo16-app-kbabeldict.png
Binary files differ
diff --git a/kbabel/kbabeldict/lo32-app-kbabeldict.png b/kbabel/kbabeldict/lo32-app-kbabeldict.png
new file mode 100644
index 00000000..6cc4e301
--- /dev/null
+++ b/kbabel/kbabeldict/lo32-app-kbabeldict.png
Binary files differ
diff --git a/kbabel/kbabeldict/main.cpp b/kbabel/kbabeldict/main.cpp
new file mode 100644
index 00000000..30d5a6c9
--- /dev/null
+++ b/kbabel/kbabeldict/main.cpp
@@ -0,0 +1,136 @@
+/* ****************************************************************************
+ 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., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, 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 <dcopclient.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kwin.h>
+
+#include <qtimer.h>
+
+#include "kbabeldict.h"
+#include "kbabelsplash.h"
+#include <version.h>
+
+class KBabelDictApplication : public KApplication
+{
+public:
+ KBabelDictApplication();
+ ~KBabelDictApplication();
+
+private:
+ KBabelDict *topLevel;
+};
+
+KBabelDictApplication::KBabelDictApplication()
+ : KApplication()
+ , topLevel(0)
+{
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ QTimer timer;
+ QWidget *splash=0;
+ bool showSplash=args->isSet("splash");
+ if(showSplash)
+ {
+ timer.start(2000,true);
+ KApplication::setOverrideCursor(KCursor::waitCursor());
+ splash = new KBabelSplash();
+ splash->show();
+ }
+
+ topLevel = new KBabelDict();
+
+ while(timer.isActive()) // let the user admire the splash screen ;-)
+ processEvents();
+
+ setTopWidget(topLevel);
+ topLevel->show();
+
+ if(KBabelSplash::instance)
+ {
+ delete KBabelSplash::instance;
+ }
+ if(showSplash)
+ {
+ KApplication::restoreOverrideCursor();
+ }
+
+ QObject::connect( topLevel, SIGNAL( destroyed() ),
+ this, SLOT( quit() ) );
+}
+
+KBabelDictApplication::~KBabelDictApplication()
+{
+ delete(topLevel);
+}
+
+static KCmdLineOptions options[] =
+{
+ {"nosplash",I18N_NOOP("Disable splashscreen at startup"),0},
+ KCmdLineLastOption
+};
+
+
+int main(int argc, char **argv)
+{
+ KLocale::setMainCatalogue("kbabel");
+
+ KAboutData about("kbabeldict",I18N_NOOP("KBabel - Dictionary"),VERSION,
+ I18N_NOOP("A dictionary for translators"),KAboutData::License_GPL,
+ I18N_NOOP("(c) 2000,2001,2002,2003 The KBabeldict developers"),0,"http://kbabel.kde.org");
+
+ about.addAuthor("Matthias Kiefer",I18N_NOOP("Original author"),"kiefer@kde.org");
+ about.addAuthor("Stanislav Visnovsky",I18N_NOOP("Current maintainer"),"visnovsky@kde.org");
+
+ about.setTranslator( I18N_NOOP("_: NAME OF TRANSLATORS\nYour names")
+ , I18N_NOOP("_: EMAIL OF TRANSLATORS\nYour emails"));
+
+ // Initialize command line args
+ KCmdLineArgs::init(argc, argv, &about);
+
+ // Tell which options are supported
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ // Add options from other components
+ KApplication::addCmdLineOptions();
+
+ KBabelDictApplication app;
+
+ return app.exec();
+}
diff --git a/kbabel/kbabeldict/modules/Makefile.am b/kbabel/kbabeldict/modules/Makefile.am
new file mode 100644
index 00000000..1807fb23
--- /dev/null
+++ b/kbabel/kbabeldict/modules/Makefile.am
@@ -0,0 +1,7 @@
+
+if include_DBSEARCHENGINE
+DB_SUBDIR=dbsearchengine
+endif
+
+SUBDIRS = pocompendium poauxiliary $(DB_SUBDIR) tmx
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/AUTHOR b/kbabel/kbabeldict/modules/dbsearchengine/AUTHOR
new file mode 100644
index 00000000..2a79312d
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/AUTHOR
@@ -0,0 +1 @@
+Andrea Rizzi <rizzi@kde.org> \ No newline at end of file
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.cpp b/kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.cpp
new file mode 100644
index 00000000..ac55335d
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.cpp
@@ -0,0 +1,1899 @@
+/***************************************************************************
+ KDBSearchEngine.cpp - description
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000 by Andrea Rizzi
+ (C) 2005 by Stanislav Visnovsky
+ email : rizzi@kde.org
+ ***************************************************************************/
+
+/*
+ Translation search engine
+
+
+ Copyright 2000
+ Andrea Rizzi rizzi@kde.org
+
+ License GPL v 2.0
+ * *
+ * 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 <qtextedit.h>
+#include <qprogressdialog.h>
+
+#include <qinputdialog.h>
+#include <kdeversion.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kio/netaccess.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <kurlrequester.h>
+#include <kstandarddirs.h>
+
+#include "kapplication.h"
+#include "KDBSearchEngine.h"
+
+#include "dbscan.h"
+
+#include "errno.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include <sys/time.h>
+#include "preferenceswidget.h"
+#include "dbse_factory.h"
+#include <qprogressbar.h>
+#include <qpushbutton.h>
+#include <klineedit.h>
+#include <kconfig.h>
+
+#include <qdir.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qspinbox.h>
+#include <qslider.h>
+#include <qmemarray.h>
+
+#include "database.h"
+
+#include "catalogsettings.h"
+
+#define BIGNUMBER 400000000
+
+using namespace KBabel;
+
+KDBSearchEngine::KDBSearchEngine (QObject * parent, const char *name):
+SearchEngine (parent, name)
+{
+ edited = "unknown";
+ dm = 0; //Database Manager
+ pw = 0; //Preference widget
+ lang = "";
+ dbOpened = false;
+ dbname = "";
+ lasterror = i18n ("No error");
+ connect (this, SIGNAL (hasError (const QString &)),
+ SLOT (setLastError (const QString &)));
+
+ IAmReady = true; // I don't know if it is a good idea, no DB loaded!!!
+
+ scanInProgress = false;
+ searching = false;
+ stopNow = false;
+
+ norm = false; // Normalize white space = FALSE
+ comm = true; // Remove Comments = TRUE
+
+}
+
+
+KDBSearchEngine::~KDBSearchEngine ()
+{
+}
+
+
+
+bool
+KDBSearchEngine::loadDatabase (QString database, bool noask = false)
+{
+ bool ret = true;
+ bool asked = false;
+ if (noask)
+ asked = true;
+ if (dm != 0)
+ {
+ delete dm;
+ dm = 0;
+ }
+
+ QDir dir (database);
+ if (!dir.exists ())
+ {
+ if (asked
+ || KMessageBox::questionYesNo (0,
+ i18n
+ ("Database folder does not exist:\n%1\n"
+ "Do you want to create it now?").
+ arg (database), QString::null, i18n("Create Folder"), i18n("Do Not Create")) ==
+ KMessageBox::Yes)
+ {
+ asked = true;
+
+ QStringList dirList;
+ while (!dir.exists () && !dir.dirName ().isEmpty ())
+ {
+ dirList.prepend (dir.dirName ());
+ dir.setPath (dir.path () + "/..");
+ }
+
+ for (QStringList::Iterator it = dirList.begin ();
+ it != dirList.end (); ++it)
+ {
+ if (!dir.mkdir (*it))
+ {
+ KMessageBox::sorry (0,
+ i18n
+ ("It was not possible to create folder %1").
+ arg (dir.path () + "/" +
+ (*it)));
+ ret = false;
+ break;
+ }
+ dir.cd (*it);
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+ }
+
+ if (ret)
+ {
+ // test, if there are both of ,old and standard databases
+ QString transFile = database + "/translations." + lang + ".db";
+
+ bool oldstuff = QFile::exists (transFile + ",old");
+ bool newstuff = QFile::exists (transFile);
+
+ if (oldstuff && newstuff)
+ {
+ // there is an old db2 database, ask user
+
+ if (KMessageBox::
+ questionYesNo (0,
+ i18n
+ ("<p>There are backup database files from previous versions "
+ "of KBabel. However, another version of KBabel (probably from KDE 3.1.1 or 3.1.2) "
+ "created a new database. As a result, your KBabel installation contains two versions "
+ "of database files. Unfortunatelly, the old and new version "
+ "can not be merged. You need to choose one of them.<br/><br/>"
+ "If you choose the old version, the new one will be removed. "
+ "If you choose the new version, the old database files will be left alone "
+ "and you need to remove them manually. Otherwise this message will be displayed "
+ "again (the old files are at $KDEHOME/share/apps/kbabeldict/dbsearchengine/*,old).</p>"),
+ i18n ("Old Database Found"),
+ i18n ("Use &Old Database"),
+ i18n ("Use &New Database")) ==
+ KMessageBox::Yes)
+ {
+ // remove the new files
+ QFile::remove (transFile);
+ QFile::remove (database + "/wordsindex." + lang +
+ ".db");
+ QFile::remove (database + "/keysindex." + lang + ".db");
+ QFile::remove (database + "/catalogsinfo." + lang +
+ ".db");
+
+ // rename the old files
+ KIO::NetAccess::copy (KURL (transFile + ",old"),
+ KURL (transFile), 0);
+ KIO::NetAccess::
+ copy (KURL
+ (database + "/wordsindex." + lang +
+ ".db,old"),
+ KURL (database + "/wordsindex." + lang +
+ ".db"), 0);
+ KIO::NetAccess::
+ copy (KURL
+ (database + "/keysindex." + lang + ".db,old"),
+ KURL (database + "/keysindex." + lang +
+ ".db"), 0);
+ KIO::NetAccess::
+ copy (KURL
+ (database + "/catalogsinfo." + lang +
+ ".db,old"),
+ KURL (database + "/catalogsinfo." + lang +
+ ".db"), 0);
+
+ QFile::remove (transFile + ",old");
+ QFile::remove (database + "/wordsindex." + lang +
+ ".db,old");
+ QFile::remove (database + "/keysindex." + lang +
+ ".db,old");
+ QFile::remove (database + "/catalogsinfo." + lang +
+ ".db,old");
+ }
+ }
+ else if (oldstuff)
+ {
+ // rename the old files
+ KIO::NetAccess::copy (KURL (transFile + ",old"),
+ KURL (transFile), 0);
+ KIO::NetAccess::
+ copy (KURL (database + "/wordsindex." + lang + ".db,old"),
+ KURL (database + "/wordsindex." + lang + ".db"), 0);
+ KIO::NetAccess::
+ copy (KURL (database + "/keysindex." + lang + ".db,old"),
+ KURL (database + "/keysindex." + lang + ".db"), 0);
+ KIO::NetAccess::
+ copy (KURL
+ (database + "/catalogsinfo." + lang + ".db,old"),
+ KURL (database + "/catalogsinfo." + lang + ".db"), 0);
+
+ QFile::remove (transFile + ",old");
+ QFile::remove (database + "/wordsindex." + lang + ".db,old");
+ QFile::remove (database + "/keysindex." + lang + ".db,old");
+ QFile::remove (database + "/catalogsinfo." + lang +
+ ".db,old");
+ }
+
+ dm = new DataBaseManager (database, lang, this, "Database manager");
+
+ if (!dm->isOk ())
+ {
+ if (asked
+ || KMessageBox::questionYesNo (0,
+ i18n
+ ("Database files not found.\nDo you want to create them now?"), QString::null, i18n("Create"), i18n("Do Not Create"))
+ == KMessageBox::Yes)
+ {
+ //fprintf(stderr,"SI\n");
+ ret = dm->createDataBase (database, lang);
+ }
+ else
+ ret = false;
+ }
+ else
+ ret = true;
+ }
+
+//Wrong errore hangdling
+
+ if (ret)
+ totalRecord = dm->count ();
+ else
+ totalRecord = 0;
+
+ return ret;
+}
+
+
+/*
+ Set if the research have to consider multiple spaces as a single one.
+ */
+
+void
+KDBSearchEngine::setNormalizeSpace (bool normalize)
+{
+ norm = normalize;
+}
+
+
+void
+KDBSearchEngine::setRemoveInternalComment (bool internalcomment)
+{
+ comm = internalcomment;
+}
+
+/*
+ Set if the research have to be Case Sensitive or not
+ */
+
+void
+KDBSearchEngine::setCaseSensitive (bool sensitive)
+{
+ sens = sensitive;
+}
+
+/*
+ Set the a string containing all char that must be ignored
+ during the search.
+ */
+
+void
+KDBSearchEngine::setRemoveCharString (QString chartoremove)
+{
+ remchar = chartoremove;
+}
+
+/*
+ Return true if there's a search in progress.
+ */
+bool
+KDBSearchEngine::isSearching () const
+{
+ return searching;
+}
+
+
+
+
+/*
+ Add a search string in the list of the string to search for.
+ Returns the ID of the string in the list.
+ Returns -1 if there is a problem (may be search in progress)
+ */
+
+int
+KDBSearchEngine::addSearchString (QString searchString, int rule)
+{
+ if (searching || scanInProgress)
+ return -1;
+ SearchEntry e;
+ e.string = QString (searchString);
+ e.rules = rule;
+ searchStringList.append (e);
+ return searchStringList.count ();
+}
+
+
+/*
+ Start the research in the database of all the string in the list
+
+ */
+
+bool
+KDBSearchEngine::startSearch (const QString & str, uint pluralForm,
+ const SearchFilter * filter)
+{
+
+ if (autoUpdate)
+ {
+ updateSettings ();
+ }
+
+
+ int l1 = 0, l2 = 0;
+ if (defSub1)
+ l1 = defLimit1;
+ if (defSub2)
+ l2 = defLimit2;
+
+ return startSingleSearch (str, l1, l2);
+
+
+}
+
+bool
+KDBSearchEngine::startSearchInTranslation (QString s)
+{
+
+ if (autoUpdate)
+ {
+ updateSettings ();
+ }
+
+
+ int l1 = 0, l2 = 0;
+ if (defSub1)
+ l1 = defLimit1;
+ if (defSub2)
+ l2 = defLimit2;
+
+
+ return startSingleSearch (s, l1, l2, true);
+
+}
+
+
+bool
+KDBSearchEngine::openDb (bool noask = false)
+{
+ if (!dbOpened)
+ {
+ dbOpened = loadDatabase (dbname, noask); //Try first to open it now
+ if (!dbOpened) // Still not opened!!
+ {
+ hasError (i18n ("Cannot open the database"));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+
+bool
+KDBSearchEngine::messagesForFilter (const SearchFilter * filter,
+ QValueList < SearchResult > &resultList,
+ QString & error)
+{
+
+ int count = 0;
+ stopNow = false; // Remove dirty.
+ SearchResult m;
+
+ if (searching)
+ {
+ error = i18n ("Another search has already been started");
+ return false;
+ }
+
+ if (scanInProgress)
+ {
+ error =
+ i18n ("Unable to search now: a PO file scan is in progress");
+ return false;
+ }
+
+
+ if (!openDb ())
+ {
+ error = i18n ("Unable to open the database");
+ return false;
+ }
+
+ if (totalRecord <= 0)
+ {
+ error = i18n ("Database empty");
+ return false;
+ }
+
+ QString package = filter->location ();
+
+ int step = (totalRecord / 30) + 1;
+ int ntra, nref;
+ int req = dm->searchCatalogInfo (package);
+ if (req == -1)
+ {
+ error = i18n ("No entry for this package in the database.");
+ return false;
+ }
+ DataBaseItem item;
+ int i, h;
+ kdDebug (0) << "looking for catalog " << req << endl;
+
+ progressStarts (i18n ("Searching for %1 in database").arg (package));
+
+ for (item = dm->firstItem (); !item.isNull (); item = dm->nextItem ())
+ {
+ count++;
+ if (count % step == 0)
+ {
+ emit progress (100 * count / totalRecord);
+ kapp->processEvents (100);
+ }
+ if (stopNow)
+ {
+ stopNow = false;
+ searching = false;
+ emit finished ();
+ return true; // No error, stopped!
+ }
+
+ ntra = item.numTra;
+ for (i = 0; i < ntra; i++)
+ {
+ nref = item.translations[i].numRef;
+
+ for (h = 0; h < nref; h++)
+ {
+ if (item.translations[i].infoRef[h] == req)
+ {
+ m.found = item.key;
+ m.translation = item.translations[i].translation;
+ resultList.append (m);
+ }
+ }
+ }
+
+ }
+
+ return true;
+}
+
+void
+KDBSearchEngine::repeat ()
+{
+
+ int count = 0;
+ stopNow = false; // Remove dirty.
+
+ if (searching)
+ {
+ return;
+ }
+
+ if (scanInProgress)
+ {
+ return;
+ }
+
+
+ if (!openDb ())
+ {
+ return;
+ }
+
+ if (totalRecord <= 0)
+ {
+ return;
+ }
+
+ int step = (totalRecord / 30) + 1;
+ int ntra, nref;
+
+ DataBaseItem item;
+ int i, h, tot;
+
+ int req = dm->searchCatalogInfo ("kdelibs.po");
+ if (req == -1)
+ kdDebug (0) << "No kdelibs.po found!" << endl;
+
+
+ QProgressDialog *pd =
+ new QProgressDialog (i18n ("Looking for repetitions"), i18n ("Stop"),
+ 100);
+
+ connect (this, SIGNAL (progress (int)), pd, SLOT (setProgress (int)));
+ connect (this, SIGNAL (finished ()), pd, SLOT (close ()));
+ connect (pd, SIGNAL (cancelled ()), this, SLOT (stopSearch ()));
+
+
+ QString txt = "// %1 repetitions, %2 translation(s)\ni18n(\"%3\");\n";
+ QString id;
+ int min;
+ bool ok = false;
+
+ min =
+ QInputDialog::getInteger (i18n ("Minimum Repetition"),
+ i18n
+ ("Insert the minimum number of repetitions for a string:"),
+ 2, 1, 999999, 1, &ok);
+
+ if (!ok)
+ return;
+
+ pd->show ();
+
+ progressStarts (i18n ("Searching repeated string"));
+
+ static QTextEdit *mle = new QTextEdit ();
+ mle->clear ();
+
+ bool inlibs;
+
+ for (item = dm->firstItem (); !item.isNull (); item = dm->nextItem ())
+ {
+ count++;
+ if (count % step == 0)
+ {
+ emit progress (100 * count / totalRecord);
+ kapp->processEvents (100);
+ }
+ if (stopNow)
+ {
+ stopNow = false;
+ searching = false;
+ emit finished ();
+ return; // No error, stopped!
+ }
+ tot = 0;
+ inlibs = false;
+ ntra = item.numTra;
+ for (i = 0; i < ntra; i++)
+ {
+ nref = item.translations[i].numRef;
+ for (h = 0; h < nref; h++)
+ if (item.translations[i].infoRef[h] == req)
+ inlibs = true;
+
+ tot += nref;
+ }
+
+ if (tot >= min && !inlibs)
+ {
+ id = item.key;
+ id = id.replace ("\n", "\"\n\"");
+ mle->append (txt.arg (tot).arg (ntra).arg (id));
+
+ }
+ }
+
+
+ emit progress (100);
+ emit finished ();
+ mle->resize (400, 400);
+ mle->show ();
+
+ delete pd;
+ return;
+}
+
+
+
+bool
+KDBSearchEngine::startSearchNow (int searchmode)
+{
+ if (searchmode == -1)
+ searchmode = mode;
+ int count = 0;
+ stopNow = false; // Remove dirty.
+ clearResults ();
+
+
+ if (searching)
+ {
+ hasError (i18n ("Another search has already been started"));
+ return false;
+ }
+
+ if (scanInProgress)
+ {
+ hasError (i18n
+ ("Unable to search now: a PO file scan is in progress"));
+ return false;
+ }
+
+
+ if (!openDb ())
+ return false;
+
+
+ if (totalRecord <= 0)
+ {
+ hasError (i18n ("Database empty"));
+ return false;
+ }
+
+
+
+ searching = true;
+
+ emit started ();
+
+ bool allkey = (searchmode == MD_ALL_GOOD_KEYS);
+
+ bool equal, contains, contained, regexp, intra;
+
+ intra = searchmode & MD_IN_TRANSLATION;
+
+ QString msgIdFound;
+ QString msgId;
+ QString msgStr;
+ //QString msgIdRequested;
+ SearchResult *aresult;
+ TranslationInfo *adescription;
+ SearchList searchList;
+ int i, len, files, h;
+ len = remchar.length ();
+
+ int n, m; //,word;
+ QString *id;
+
+ QString mainRequest = searchStringList[0].string;
+
+
+ SearchList::Iterator it, it1;
+ QString *idMod;
+ bool foundSomething = false;
+
+ searchList = searchStringList; //Create a copy and modify it
+ if (!allkey)
+ {
+ for (it = searchList.begin (); it != searchList.end (); ++it)
+ {
+ idMod = &((*it).string);
+ int pos;
+ for (i = 0; i < len; i++)
+ {
+ while ((pos = idMod->find (remchar.at (i))) != -1)
+ idMod->remove (pos, 1);
+ }
+
+ if (comm)
+ idMod->replace (QRegExp ("\\_\\:.*\\\\n"), ""); //Read it from catalog !!! (NOT ONLY HERE)
+
+
+ if (norm)
+ idMod->simplifyWhiteSpace ();
+ if (!sens)
+ *idMod = idMod->upper ();
+ }
+
+ }
+
+ timeval now;
+ gettimeofday (&now, NULL);
+ //fprintf(stderr,"\n%ld.%ld\n",now.tv_sec,now.tv_usec);
+ //double tim=1.0*now.tv_usec/1000000.0+now.tv_sec;
+ int pos;
+
+
+
+ DataBaseItem item;
+
+
+ //Now we can browse the whole db or the "good keys"
+ QValueList < KeyAndScore > goodkeys;
+ int totalprogress;
+
+ bool gk = (searchmode == MD_GOOD_KEYS) || allkey;
+ int k = 0;
+
+ if (gk)
+ {
+ goodkeys = searchWords (mainRequest, thre, threorig, listmax); //FIX IT, mainReq?
+ if (stopNow)
+ {
+ stopNow = false;
+ searching = false;
+ emit finished ();
+ return false;
+ }
+ if (goodkeys.count () == 0)
+ gk = false; // if no good keys, use the whole database
+ }
+
+ // prepare progress values
+ totalprogress = gk ? goodkeys.count () : totalRecord;
+ int step = (totalprogress / 30) + 1;
+ if( step > 100 )
+ step = 100;
+
+ emit progress (0);
+ kapp->processEvents (100);
+ if (stopNow)
+ {
+ stopNow = false;
+ searching = false;
+ emit finished ();
+ return true; // No error, stopped!
+ }
+
+
+ for (item = gk ? (dm->getItem (goodkeys[0])) : (dm->firstItem ());
+ !item.isNull ();
+ item = gk ? (dm->getItem (goodkeys[++k])) : (dm->nextItem ()))
+ {
+
+// Emit progress, process event and check stop now
+ if (count % step == 0)
+ {
+ emit progress (100 * count / /*QMAX( */
+ totalprogress /*,1) */ );
+ kapp->processEvents (100);
+
+ if (stopNow)
+ {
+ stopNow = false;
+ searching = false;
+ emit finished ();
+ return true; // No error, stopped!
+ }
+ }
+
+ // fprintf(stderr,"%s\n",(const char *)item.key.utf8());
+ msgIdFound = item.key; //Check if this is OK with UTF8
+
+// searchmode && MD_IN_TRANSLATION)
+
+ count++;
+
+
+
+ msgId = msgIdFound;
+
+ if (!allkey)
+ {
+
+ //Remove character in list of character to be ignored
+ for (i = 0; i < len; i++)
+ while ((pos = msgId.find (remchar.at (i))) != -1)
+ msgId.remove (pos, 1);
+
+ //Remove context information from id found
+ if (comm)
+ msgId.replace (QRegExp ("\\_\\:.*\\\\n"), "");
+
+
+ if (norm)
+ msgId.simplifyWhiteSpace ();
+ if (!sens)
+ msgId = msgId.upper ();
+ }
+
+
+
+ it = searchList.begin ();
+ idMod = &((*it).string);
+ bool foundExact = false;
+
+ for (it1 = searchStringList.begin ();
+ it1 != searchStringList.end (); it1++)
+ {
+
+ id = &((*it1).string);
+ uint nn = 0;
+ do
+ {
+ if (intra)
+ {
+ msgId = item.translations[nn].translation;
+ if (!allkey)
+ {
+ //Remove character in list of character to be ignored
+ for (i = 0; i < len; i++)
+ while ((pos =
+ msgId.find (remchar.at (i))) !=
+ -1)
+ msgId.remove (pos, 1);
+
+ //Remove context information from id found
+ if (comm)
+ msgId.
+ replace (QRegExp ("\\_\\:.*\\\\n"),
+ "");
+
+
+ if (norm)
+ msgId.simplifyWhiteSpace ();
+ if (!sens)
+ msgId = msgId.upper ();
+ }
+
+
+ }
+
+
+ int rules = (*it).rules;
+
+ if (rules & Equal)
+ equal = (*idMod == msgId);
+ else
+ equal = false;
+
+ if (rules & Contains)
+ contains = idMod->contains (msgId);
+ else
+ contains = false;
+
+ if (rules & Contained)
+ contained = msgId.contains (*idMod);
+ else
+ contained = false;
+
+ if (!foundExact && (rules & RegExp))
+ {
+ QRegExp reg (*idMod);
+ regexp = (reg.search (msgId) != -1);
+ }
+ else
+ regexp = false;
+ nn++;
+ }
+ while (intra && nn < item.numTra);
+
+ if (equal || contains || contained || regexp || allkey)
+ {
+
+ if (equal)
+ foundExact = true;
+
+ m = item.numTra; //Translations found.
+
+ for (n = 0; n < m; n++)
+ {
+
+ foundSomething = true;
+
+
+ msgStr = item.translations[n].translation;
+
+ files = item.translations[n].numRef;
+
+ aresult = new SearchResult ();
+
+ results.setAutoDelete (true);
+ if (!gk)
+ aresult->score =
+ score (mainRequest, msgIdFound);
+ else
+ aresult->score = goodkeys[k].score;
+
+ if (intra)
+ aresult->score =
+ score (mainRequest,
+ item.translations[n].translation);
+
+
+ SearchResult *s = 0;
+ for (s = results.first (); s != 0;
+ s = results.next ())
+ {
+ if (s->score > aresult->score)
+ {
+ results.insert (results.at (),
+ aresult);
+ break;
+ }
+
+ }
+ if (s == 0) //no break or empty list
+ results.append (aresult);
+
+
+/* if(*id==msgIdFound) //Put it first of the list
+ results.prepend(aresult);
+ else
+ results.append(aresult);
+*/
+ aresult->requested = *id;
+ aresult->found = msgIdFound;
+ aresult->translation = msgStr;
+ aresult->descriptions.setAutoDelete (true);
+ for (h = 0; h < files; h++)
+ {
+
+ aresult->descriptions.append (adescription =
+ new
+ TranslationInfo
+ ());
+ int rr = item.translations[n].infoRef[h];
+
+ InfoItem info = dm->getCatalogInfo (rr);
+
+
+ adescription->location = info.catalogName;
+ adescription->translator =
+ info.lastTranslator;
+ adescription->filePath = info.lastFullPath;
+ }
+
+ emit numberOfResultsChanged (results.count ());
+ emit resultFound (aresult);
+
+// if(*id==msgIdFound) //Put it first of the list so th order change
+ emit resultsReordered ();
+
+
+
+ }
+ }
+ // idMod=searchList.next();
+ it++;
+ idMod = &((*it).string);
+ }
+
+
+ }
+ gettimeofday (&now, NULL);
+ //fprintf(stderr,"%ld.%ld\n",now.tv_sec,now.tv_usec);
+
+ //fprintf(stderr,"Finish, %d (of %d) records in %f seconds!!\n",count,totalRecord, 1.0*now.tv_usec/1000000.0+now.tv_sec-tim);
+ emit progress (100);
+ emit finished ();
+
+ searching = false;
+ return true; //foundSomething;
+}
+
+/*
+ Start a search for a single string
+ */
+
+bool
+KDBSearchEngine::startSingleSearch (QString searchString,
+ unsigned int pattern1Limit,
+ unsigned int /*pattern2Limit */ ,
+ bool inTranslation)
+{
+ /*
+ Check Ret
+ value.
+ */
+
+ unsigned int nw = 0;
+ int in = 0, len = 0;
+ clearList ();
+ addSearchString (searchString, defRule);
+
+
+
+ QRegExp reg ("[a-zA-Z0-9_%" /*+remchar */ + regaddchar + "]+");
+ while ((in = reg.search (searchString, in + len)) != -1)
+ {
+ nw++;
+ len = reg.matchedLength ();
+ }
+ in = 0;
+ len = 0;
+ // fprintf(stderr,"asas %d\n",nw);
+
+ if (mode == MD_ALL_GOOD_KEYS && !inTranslation)
+ return startSearchNow ();
+
+
+
+ if ((nw < pattern1Limit) && (nw > 1))
+ for (unsigned int k = 0; k < nw; k++)
+ {
+ in = reg.search (searchString, in + len);
+ len = reg.matchedLength ();
+ QString regToAdd = searchString;
+ regToAdd.replace (in, len, "[a-zA-Z0-9_%" + regaddchar + "]*");
+ regToAdd.append ("$");
+ regToAdd.prepend ("^");
+// fprintf(stderr,"%s",(const char *)regToAdd.local8Bit());
+ addSearchString (regToAdd, RegExp);
+ }
+
+ if (inTranslation)
+ return startSearchNow (MD_IN_TRANSLATION);
+ else
+ return startSearchNow ();
+
+ return false;
+
+}
+
+
+/*
+ Start a search for a list of string
+ */
+
+//bool KDBSearchEngine::startListSearch(QPtrList<QString> searchStrList)
+//{
+ // searchStringList=searchStrList;
+// return startSearchNow();
+//}
+/*
+ Stop the current search
+ */
+
+
+
+void
+KDBSearchEngine::setLanguageCode (const QString & ll)
+{
+ if (ll == lang)
+ return;
+
+ lang = ll;
+ if (dbOpened) //if opened open it again with new code, what about close before open ?
+ dbOpened = loadDatabase (dbname);
+
+}
+
+void
+KDBSearchEngine::setLanguage (const QString & languageCode,
+ const QString & /*languageName */ )
+{
+ setLanguageCode (languageCode);
+}
+
+void
+KDBSearchEngine::stopSearch ()
+{
+ stopNow = true;
+}
+
+
+void
+KDBSearchEngine::clearList ()
+{
+ searchStringList.clear ();
+}
+
+bool
+KDBSearchEngine::isReady () const
+{
+ return IAmReady;
+}
+
+
+void
+KDBSearchEngine::saveSettings (KConfigBase * config)
+{
+// updateSettings(); //maybe with autoupdate
+ KConfigGroupSaver cgs (config, "KDBSearchEngine");
+#if KDE_IS_VERSION(3,1,3)
+ config->writePathEntry ("Filename", dbname);
+#else
+ config->writeEntry ("Filename", dbname);
+#endif
+ config->writeEntry ("Language", lang);
+
+
+ config->writeEntry ("CaseSensitive", sens);
+ config->writeEntry ("Normalize", norm);
+ config->writeEntry ("RemoveContext", comm);
+
+ config->writeEntry ("Rules", defRule);
+ config->writeEntry ("Limit1", defLimit1);
+ config->writeEntry ("Limit2", defLimit2);
+ config->writeEntry ("Substitution1", defSub1);
+ config->writeEntry ("Substitution2", defSub2);
+
+ config->writeEntry ("RegExp", regaddchar);
+ config->writeEntry ("RemoveCharacter", remchar);
+
+ config->writeEntry ("Threshold1", thre);
+ config->writeEntry ("Threshold2", threorig);
+ config->writeEntry ("ListMax", listmax);
+ config->writeEntry ("Mode", mode);
+ config->writeEntry ("CommonThrs", commonthre);
+ config->writeEntry ("ReturnNothing", retnot);
+
+ config->writeEntry ("AutoAuthor", autoauthor);
+ config->writeEntry ("AutoUp", autoup);
+
+}
+
+
+void
+KDBSearchEngine::readSettings (KConfigBase * config)
+{
+ QString newName;
+
+ KConfigGroupSaver cgs (config, "KDBSearchEngine");
+
+ QString defaultLang;
+ QString oldLang = lang;
+ Defaults::Identity def;
+ defaultLang = def.languageCode ();
+ lang = config->readEntry ("Language", defaultLang);
+
+ QString defaultDir;
+ KStandardDirs *dirs = KGlobal::dirs ();
+ if (dirs)
+ {
+ defaultDir = dirs->saveLocation ("data");
+ if (defaultDir.right (1) != "/")
+ defaultDir += "/";
+ defaultDir += "kbabeldict/dbsearchengine";
+ }
+
+ newName = config->readPathEntry ("Filename", defaultDir);
+
+ if (newName != dbname || oldLang != lang)
+ {
+ dbname = newName;
+ if (dbOpened) //Reload only if it is opened
+ dbOpened = loadDatabase (dbname);
+ }
+
+ sens = config->readBoolEntry ("CaseSensitive", false);
+ norm = config->readBoolEntry ("Normalize", true);
+ comm = config->readBoolEntry ("RemoveContext", true);
+
+ defRule = config->readNumEntry ("Rules", 1);
+ defLimit1 = config->readNumEntry ("Limit1", 20);
+ defLimit2 = config->readNumEntry ("Limit2", 8);
+
+ thre = config->readNumEntry ("Threshold1", 50);
+ threorig = config->readNumEntry ("Threshold2", 50);
+ listmax = config->readNumEntry ("ListMax", 500);
+ mode = config->readNumEntry ("Mode", MD_GOOD_KEYS);
+
+ defSub1 = config->readBoolEntry ("Substitution1", true);
+ defSub2 = config->readBoolEntry ("Substitution2", false);
+
+ regaddchar = config->readEntry ("RegExp");
+ remchar = config->readEntry ("RemoveCharacter", "&.:");
+ commonthre = config->readNumEntry ("CommonThrs", 300);
+ retnot = config->readBoolEntry ("ReturnNothing", false);
+ autoauthor = config->readEntry ("AutoAuthor");
+ autoup = config->readBoolEntry ("AutoUp", true);
+
+ setSettings ();
+}
+
+PrefWidget *
+KDBSearchEngine::preferencesWidget (QWidget * parent)
+{
+
+ pw = new PreferencesWidget (parent);
+ setSettings ();
+ connect (pw, SIGNAL (restoreNow ()), this, SLOT (setSettings ()));
+ connect (pw, SIGNAL (applyNow ()), this, SLOT (updateSettings ()));
+ connect (pw, SIGNAL (destroyed ()), this, SLOT (prefDestr ()));
+ connect (pw->dbpw->scanPB_2, SIGNAL (clicked ()), this, SLOT (scan ()));
+ connect (pw->dbpw->scanrecPB, SIGNAL (clicked ()), this,
+ SLOT (scanRecur ()));
+ connect (pw->dbpw->scanFilePB, SIGNAL (clicked ()), this,
+ SLOT (scanFile ()));
+ connect (pw->dbpw->repeatPB, SIGNAL (clicked ()), this, SLOT (repeat ()));
+
+
+ return pw;
+}
+
+void
+KDBSearchEngine::scanRecur ()
+{
+ if (scanInProgress)
+ return;
+ updateSettings ();
+
+ if (!openDb ())
+ return;
+ scanInProgress = true;
+ PoScanner *sca = new PoScanner (dm, this, "Po Scanner");
+ QString cvsdir;
+ cvsdir =
+ KFileDialog::getExistingDirectory ("", 0,
+ i18n
+ ("Select Folder to Scan Recursively"));
+
+ if (cvsdir.isEmpty ())
+ {
+ scanInProgress = false;
+ return;
+ }
+ if (pw)
+ {
+ connect (sca, SIGNAL (patternProgress (int)), pw->dbpw->totalPB,
+ SLOT (setProgress (int)));
+ connect (sca, SIGNAL (fileLoading (int)), pw->dbpw->loadingPB,
+ SLOT (setProgress (int)));
+ connect (sca, SIGNAL (fileProgress (int)), pw->dbpw->processPB,
+ SLOT (setProgress (int)));
+ }
+
+ connect (sca, SIGNAL (patternProgress (int)), SIGNAL (progress (int))); //Kbabel progress bar
+
+ connect (sca, SIGNAL (added (int)), pw, SLOT (setEntries (int)));
+ connect (sca, SIGNAL (filename (QString)), pw, SLOT (setName (QString)));
+
+
+ progressStarts (i18n ("Scanning folder %1").arg (cvsdir));
+ connect (sca, SIGNAL (patternFinished ()), SIGNAL (progressEnds ()));
+
+ sca->scanPattern (cvsdir, "*.po", true);
+ disconnect (this, SIGNAL (progress (int)));
+//disconnect(SIGNAL(patternStarted()),this,SIGNAL(started()) );
+ disconnect (this, SIGNAL (progressEnds ()));
+ if (pw)
+ {
+ disconnect (pw->dbpw->totalPB, SLOT (setProgress (int)));
+ disconnect (pw->dbpw->loadingPB, SLOT (setProgress (int)));
+ disconnect (pw->dbpw->processPB, SLOT (setProgress (int)));
+ }
+ totalRecord = dm->count ();
+
+ scanInProgress = false;
+ dm->sync ();
+ delete sca;
+}
+
+
+void
+KDBSearchEngine::scan ()
+{
+ if (scanInProgress)
+ return;
+ updateSettings ();
+
+ if (!openDb ())
+ return;
+ scanInProgress = true;
+ PoScanner *sca = new PoScanner (dm, this, "Po Scanner");
+ QString cvsdir;
+
+ cvsdir =
+ KFileDialog::getExistingDirectory ("", 0,
+ i18n ("Select Folder to Scan"));
+ if (cvsdir.isEmpty ())
+ {
+ scanInProgress = false;
+ return;
+ }
+ if (pw)
+ {
+ connect (sca, SIGNAL (patternProgress (int)), pw->dbpw->totalPB,
+ SLOT (setProgress (int)));
+ connect (sca, SIGNAL (fileLoading (int)), pw->dbpw->loadingPB,
+ SLOT (setProgress (int)));
+ connect (sca, SIGNAL (fileProgress (int)), pw->dbpw->processPB,
+ SLOT (setProgress (int)));
+ }
+ connect (sca, SIGNAL (patternProgress (int)), SIGNAL (progress (int)));
+ progressStarts (i18n ("Scanning folder %1").arg (cvsdir));
+ connect (sca, SIGNAL (patternFinished ()), SIGNAL (progressEnds ()));
+
+ connect (sca, SIGNAL (added (int)), pw, SLOT (setEntries (int)));
+ connect (sca, SIGNAL (filename (QString)), pw, SLOT (setName (QString)));
+
+
+
+ sca->scanPattern (cvsdir, "*.po", false);
+
+ disconnect (this, SIGNAL (progress (int)));
+//disconnect(SIGNAL(patternStarted()),this,SIGNAL(started()) );
+ disconnect (this, SIGNAL (progressEnds ()));
+ if (pw)
+ {
+ disconnect (pw->dbpw->totalPB, SLOT (setProgress (int)));
+ disconnect (pw->dbpw->loadingPB, SLOT (setProgress (int)));
+ disconnect (pw->dbpw->processPB, SLOT (setProgress (int)));
+ }
+ totalRecord = dm->count ();
+
+ scanInProgress = false;
+
+ dm->sync ();
+ delete sca;
+}
+
+void
+KDBSearchEngine::scanFile ()
+{
+ if (scanInProgress)
+ return;
+ updateSettings ();
+
+ if (!openDb ())
+ return;
+ scanInProgress = true;
+ PoScanner *sca = new PoScanner (dm, this, "Po Scanner");
+ QString cvsdir;
+ pw->dbpw->totalPB->setProgress (0);
+
+ cvsdir =
+ KFileDialog::getOpenFileName ("", "*.po", 0,
+ i18n ("Select PO File to Scan"));
+ if (cvsdir.isEmpty ())
+ {
+ scanInProgress = false;
+ return;
+ }
+ if (pw)
+ {
+ connect (sca, SIGNAL (fileLoading (int)), pw->dbpw->loadingPB,
+ SLOT (setProgress (int)));
+ connect (sca, SIGNAL (fileProgress (int)), pw->dbpw->processPB,
+ SLOT (setProgress (int)));
+ }
+ connect (sca, SIGNAL (fileProgress (int)), SIGNAL (progress (int)));
+ progressStarts (i18n ("Scanning file %1").arg (directory (cvsdir, 0)));
+ connect (sca, SIGNAL (fileFinished ()), SIGNAL (progressEnds ()));
+
+ connect (sca, SIGNAL (added (int)), pw, SLOT (setEntries (int)));
+ connect (sca, SIGNAL (filename (QString)), pw, SLOT (setName (QString)));
+
+
+
+ sca->scanFile (cvsdir);
+
+ sca->disconnect (SIGNAL (fileProgress (int)), this,
+ SIGNAL (progress (int)));
+//disconnect(SIGNAL(patternStarted()),this,SIGNAL(started()) );
+ sca->disconnect (SIGNAL (fileFinished ()), this,
+ SIGNAL (progressEnds ()));
+ if (pw)
+ {
+ disconnect (pw->dbpw->loadingPB, SLOT (setProgress (int)));
+ disconnect (pw->dbpw->processPB, SLOT (setProgress (int)));
+ }
+
+ totalRecord = dm->count ();
+
+ scanInProgress = false;
+
+ dm->sync ();
+ delete sca;
+}
+
+const KAboutData *
+KDBSearchEngine::about () const
+{
+
+ return DbSeFactory::instance ()->aboutData ();
+
+}
+
+QString
+KDBSearchEngine::name () const
+{
+ return i18n ("Translation Database");
+}
+
+QString
+KDBSearchEngine::id () const
+{
+ return QString ("KDBSearchEngine");
+}
+
+QString
+KDBSearchEngine::lastError ()
+{
+ return lasterror;
+}
+
+void
+KDBSearchEngine::prefDestr ()
+{
+ pw = 0;
+}
+
+
+void
+KDBSearchEngine::setSettings ()
+{
+
+ if (pw == 0)
+ return;
+
+ pw->dbpw->dirInput->setURL (dbname);
+ pw->dbpw->caseSensitiveCB->setChecked (sens);
+ pw->dbpw->normalizeCB->setChecked (norm);
+ pw->dbpw->removeContextCB->setChecked (comm);
+
+ pw->dbpw->oneWordSubCB->setChecked (defSub1);
+ pw->dbpw->twoWordSubCB->setChecked (defSub2);
+
+
+ if (defRule == 8)
+ pw->dbpw->RegExpRB->setChecked (true);
+ else
+ {
+ pw->dbpw->normalTextRB->setChecked (true);
+ pw->dbpw->equalCB->setChecked (defRule & Equal);
+ pw->dbpw->containsCB->setChecked (defRule & Contains);
+ pw->dbpw->containedCB->setChecked (defRule & Contained);
+ }
+
+ pw->dbpw->oneWordSubSB->setValue (defLimit1);
+ pw->dbpw->twoWordSubSB->setValue (defLimit2);
+
+ pw->dbpw->maxSB->setValue (listmax);
+ pw->dbpw->thresholdSL->setValue (thre);
+ pw->dbpw->thresholdOrigSL->setValue (threorig);
+
+ pw->dbpw->allRB->setChecked (mode == MD_ALL_DB);
+ pw->dbpw->slistRB->setChecked (mode == MD_GOOD_KEYS);
+ pw->dbpw->rlistRB->setChecked (mode == MD_ALL_GOOD_KEYS);
+
+ pw->dbpw->nothingCB->setChecked (retnot);
+ pw->dbpw->freqSB->setValue (commonthre);
+
+ pw->dbpw->regExpLE->setText (regaddchar);
+ pw->dbpw->ignoreLE->setText (remchar);
+
+ pw->dbpw->authorLE->setText (autoauthor);
+ pw->dbpw->autoAddCB_2->setChecked (autoup);
+
+
+
+}
+
+
+void
+KDBSearchEngine::updateSettings ()
+{
+ if (pw == 0)
+ return;
+
+ QString newName = pw->dbpw->dirInput->url ();
+
+ if (newName != dbname)
+ {
+ kdDebug (0) << "Database changed" << endl;
+ dbname = newName;
+ if (dbOpened)
+ dbOpened = loadDatabase (dbname);
+ }
+
+ sens = pw->dbpw->caseSensitiveCB->isChecked ();
+ norm = pw->dbpw->normalizeCB->isChecked ();
+ comm = pw->dbpw->removeContextCB->isChecked ();
+
+ int tmpRule = 0;
+ if (pw->dbpw->RegExpRB->isChecked ())
+ tmpRule = RegExp;
+ else
+ {
+ if (pw->dbpw->equalCB->isChecked ())
+ tmpRule += Equal;
+ if (pw->dbpw->containsCB->isChecked ())
+ tmpRule += Contains;
+ if (pw->dbpw->containedCB->isChecked ())
+ tmpRule += Contained;
+ }
+
+ defRule = tmpRule;
+
+ defLimit1 = pw->dbpw->oneWordSubSB->text ().toInt ();
+ defLimit2 = pw->dbpw->twoWordSubSB->text ().toInt ();
+ defSub1 = pw->dbpw->oneWordSubCB->isChecked ();
+ defSub2 = pw->dbpw->twoWordSubCB->isChecked ();
+
+ listmax = pw->dbpw->maxSB->value ();
+ thre = pw->dbpw->thresholdSL->value ();
+ threorig = pw->dbpw->thresholdOrigSL->value ();
+
+ if (pw->dbpw->allRB->isChecked ())
+ mode = MD_ALL_DB;
+ if (pw->dbpw->slistRB->isChecked ())
+ mode = MD_GOOD_KEYS;
+ if (pw->dbpw->rlistRB->isChecked ())
+ mode = MD_ALL_GOOD_KEYS;
+
+
+ regaddchar = pw->dbpw->regExpLE->text ();
+ remchar = pw->dbpw->ignoreLE->text ();
+
+ retnot = pw->dbpw->nothingCB->isChecked ();
+ commonthre = pw->dbpw->freqSB->value ();
+
+ autoauthor = pw->dbpw->authorLE->text ();
+ autoup = pw->dbpw->autoAddCB_2->isChecked ();
+
+
+}
+
+void
+KDBSearchEngine::setLastError (const QString & er)
+{
+ lasterror = er;
+}
+
+QString
+KDBSearchEngine::translate (const QString & text, const uint pluralForm)
+{
+ if (!openDb ())
+ return QString::null;
+/*
+
+if(!dbOpened)
+ {
+ dbOpened=loadDatabase(dbname); //Try first to open it now
+ if(!dbOpened) // Still not opened!!
+ {
+ //emit anerror
+ hasError(i18n("Database not opened"));
+ return QString::null;
+ }
+ }
+*/
+
+ DataBaseItem dbit = dm->getItem (text);
+
+ if (dbit.isNull ())
+ return QString::null;
+ if (dbit.numTra == 1)
+ return dbit.translations[0].translation;
+
+ uint32 n = dbit.numTra;
+ uint32 max = 0, nmax = 0;
+ for (uint32 i = 0; i < n; i++)
+ if (dbit.translations[i].numRef > max)
+ {
+ nmax = i;
+ max = dbit.translations[i].numRef;
+ }
+
+ return dbit.translations[nmax].translation;
+
+
+}
+
+QValueList < KeyAndScore > KDBSearchEngine::searchWords (QString phrase,
+ int threshold,
+ int thresholdorig,
+ uint32 max)
+{
+ QValueList < QString > wordlist;
+
+ if (!openDb ())
+ {
+ QValueList < KeyAndScore > a;
+ return a;
+ }
+
+ progressStarts (i18n ("Searching words"));
+
+ QValueList < QString >::Iterator wlit;
+ wordlist = dm->wordsIn (phrase);
+ int
+ nw = wordlist.count ();
+//QMemArray<WordItem> wi(nw);
+ QMemArray < uint32 > numofloc (nw), currentloc (nw);
+ QMemArray < int >
+ score (nw);
+ QMemArray < uint32 * >loc (nw), locorig (nw);
+ QValueList < uint32 > resloc;
+ QValueList < int >
+ resfound;
+ QValueList < KeyAndScore > keylist;
+//wi.resize(wordlist.count());
+ int
+ totalprogress = 0;
+ int
+ totrec = dm->count ();
+ uint32
+ cthre = totrec * commonthre / 10000;
+ int
+ i = 0, common = 0;
+ for (wlit = wordlist.begin (); wlit != wordlist.end (); ++wlit)
+ {
+ WordItem
+ wi = dm->getWordLocations (*wlit);
+ if (!wi.notFound ())
+ {
+ if (wi.count < cthre)
+ score[i] = 1;
+ else
+ {
+ score[i] = 0;
+ common++;
+ }
+
+ locorig[i] = loc[i] = wi.locations;
+ totalprogress += numofloc[i] = wi.count;
+ currentloc[i] = 0;
+// score[i]=wi.score;
+ //wi[i]=WordItem(wi[i]);
+ //wi[i].locations.detach();
+ i++;
+// }
+ // else
+ // common++;
+
+
+
+ }
+ }
+ bool
+ cs = (common == nw); //All words are common;
+ if (totalprogress == 0)
+ totalprogress = 1;
+ int
+ step = totalprogress / 30 + 1;
+ int
+ count = 0;
+ int
+ thrs = (wordlist.count () * threshold) / 100;
+ if (thrs < 1)
+ thrs = 1; // whole database ???
+
+ int
+ tot = i;
+//nt32 jmin=0;
+ int
+ found;
+ uint32
+ min; //Big ?
+ bool
+ empty = false;
+
+
+ while (!empty)
+ {
+
+ empty = true;
+ found = retnot ? common : 0;
+ if (thrs <= found)
+ thrs = found + 1; // whole database ???
+
+ min = BIGNUMBER;
+ for (int j = 0; j < tot; j++)
+ if (cs || score[j])
+ {
+ if (numofloc[j] > currentloc[j]) // Check if there's still something to do.
+ empty = false;
+ if (loc[j][0] < min) //Found the minimum head
+ min = loc[j][0];
+
+
+ }
+ if (min != BIGNUMBER)
+ {
+ for (int j = 0; j < tot; j++)
+ if (cs || score[j])
+ {
+ if (loc[j][0] == min) //Count the heads, move forward
+ {
+ found++;
+ count++;
+ //check stopnow here
+ if (count % step == 0)
+ {
+ emit
+ progress (100 * count / totalprogress);
+ kapp->processEvents (100);
+ }
+ if (stopNow)
+ {
+ return keylist;
+ }
+
+ currentloc[j]++;
+ if (numofloc[j] == currentloc[j]) //End reached
+ loc[j][0] = BIGNUMBER; //so set head to a big number
+ else //Go on..
+ {
+ loc[j]++;
+ }
+ }
+ } //end of for
+ bool
+ inserted = false;
+
+
+
+ if (found >= thrs)
+ {
+ //Words count in key.
+ int
+ nword = 0;
+
+ int
+ in = 0, len = 0;
+ QString
+ keyst = dm->getKey (min);
+ QRegExp
+ reg ("[a-zA-Z0-9_%" /*+remchar */ + regaddchar + "]+");
+ while ((in = reg.search (keyst, in + len)) != -1)
+ {
+ nword++;
+ len = reg.matchedLength ();
+ }
+
+ if (found >= nword * thresholdorig / 100) //
+ {
+
+ if (resfound.count () <= max
+ || (*resfound.end () < found))
+ if ((*resfound.end ()) >= found)
+ {
+ inserted = true;
+ resloc.append (min);
+ resfound.append (found);
+
+ }
+ else
+ for (uint32 j = 0; j < resloc.count ();
+ j++)
+ {
+ if (resfound[j] < found || (resfound[j] == found && 0)) //Orig word
+ {
+ resloc.insert (resloc.at (j),
+ min);
+ resfound.insert (resfound.
+ at (j),
+ found);
+ inserted = true;
+ break;
+ }
+ }
+ if (!inserted)
+ {
+ resloc.append (min);
+ resfound.append (found);
+ }
+
+ }
+ }
+
+ }
+
+ }
+ int
+ nres = (resloc.count () < max) ? resloc.count () : max;
+
+ for (int j = 0; j < nres; j++)
+ {
+ QString
+ strkey = dm->getKey (resloc[j]);
+ int
+ stdscore = KDBSearchEngine::score (phrase, strkey);
+ int
+ sc = 0;
+
+ if (stdscore < 99)
+ {
+ int
+ in = 0, len = 0, nword = 0;
+ int
+ remove = retnot ? common : 0;
+ QRegExp
+ reg ("[a-zA-Z0-9_%" /*+remchar */ + regaddchar + "]+");
+ while ((in = reg.search (strkey, in + len)) != -1)
+ {
+ nword++;
+ len = reg.matchedLength ();
+ }
+
+// kdDebug(0) << nword << "NWORD " << resfound[j] << "FOUND "
+// << resfound[j]-remove << "REAL " << remove << "to be remove " << endl;
+ if (nword < 1)
+ nword = 1;
+ sc = 70 - resfound[j] * 70 / nw + abs (nword -
+ (resfound[j] -
+ remove)) * 30 /
+ nword + 2;
+ sc = 100 - sc;
+// kdDebug(0) <<" Score : " << sc << endl;
+
+ }
+ else
+ sc = stdscore;
+
+ KeyAndScore
+ key (strkey, sc);
+
+// kdDebug(0) << (QString) key << " [" << key.score << "]" << endl;
+ keylist.append (key);
+ }
+
+//kdDebug(0) << "Here!" << endl;
+
+ for (int j = 0; j < tot; j++)
+ {
+ free (locorig[j]);
+ }
+ progressStarts (i18n ("Process output"));
+ return keylist;
+}
+
+void
+KDBSearchEngine::stringChanged (const QStringList & o,
+ const QString & translated, const uint,
+ const QString &)
+{
+
+ QString orig = o.first (); // FIXME: plural forms
+
+ // skip empty originals or translated texts
+ if (orig.isEmpty () || translated.isEmpty ())
+ return;
+
+ if (autoup)
+ {
+ if (openDb (true)) //true= no ask
+ {
+
+ dm->putNewTranslation (orig, translated,
+ dm->catalogRef (directory (edited, 0),
+ autoauthor, edited));
+ //kdDebug(0) << "Changed " << orig << " " << translated << endl;
+ dm->sync ();
+ }
+ }
+
+}
+
+void
+KDBSearchEngine::setEditedFile (const QString & file)
+{
+
+ edited = file; //kdDebug(0) << edited << endl;
+}
+
+KeyAndScore::KeyAndScore (const QString & a, int sc):
+QString (a)
+{
+ score = sc;
+}
+
+KeyAndScore::KeyAndScore ():QString ()
+{
+ score = 0;
+}
+
+#include "KDBSearchEngine.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.h b/kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.h
new file mode 100644
index 00000000..058444db
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.h
@@ -0,0 +1,333 @@
+
+/***************************************************************************
+ KDBSearchEngine.h - description
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000 by Andrea Rizzi
+ email : rizzi@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; version 2 of the License. *
+ * *
+ * 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. *
+ ***************************************************************************/
+/*
+ Translation search engine
+
+
+ Copyright 2000
+ Andrea Rizzi rizzi@kde.org
+
+*/
+
+
+/*
+ * This is a database engine specific
+ * structure, I think I must found a way to
+ * make it more "standard"
+ */
+
+#ifndef _KDBSEARCH_ENGINE_
+#define _KDBSEARCH_ENGINE_
+#include <qobject.h>
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qmemarray.h>
+#include <qvaluelist.h>
+
+
+#include "database.h"
+#include "searchengine.h"
+#include "preferenceswidget.h"
+
+
+//value of mode
+#define MD_ALL_DB 1
+#define MD_GOOD_KEYS 2
+#define MD_ALL_GOOD_KEYS 3
+#define MD_IN_TRANSLATION 4
+
+class SearchEntry
+{
+ public:
+ QString string;
+ int rules;
+};
+
+class KeyAndScore : public QString
+{
+ public:
+ KeyAndScore();
+ KeyAndScore(const QString &a,int sc);
+ int score;
+};
+
+typedef QValueList<SearchEntry> SearchList;
+
+/* USE searchengine.h structure
+class CatalogDescription
+{
+ public:
+ char language[6]; // How many character chinese language needs?
+ // QString is better ?
+ QString filename;
+ QString dateOfScan; //When you add this to database (last time)
+ QString authorOfScan;
+ QString fileHeader; //msgid ""
+};
+
+ */
+
+class KDBSearchEngine : public SearchEngine
+{
+ Q_OBJECT
+
+public:
+
+
+ KDBSearchEngine(QObject *parent=0,const char *name=0);
+ ~KDBSearchEngine();
+ enum Rules {Equal = 1, Contains = 2, Contained = 4, RegExp = 8};
+ enum FormatRules { Dots = 1, Ampersand = 2, FirstWordUpper = 4, //Not yet used
+ AllWordUpper = 8, AmpersanAlwaysFirst = 16 };
+
+ /*
+ Set the directory where db file are located
+ */
+
+ void setDBName(QString filename);
+
+ /*
+ Set if the research have to consider multiple spaces as a single one.
+ */
+
+ void setNormalizeSpace(bool normalize);
+
+ /*
+ Set if the research have to be Case Sensitive or not
+ */
+
+ void setCaseSensitive(bool sensitive);
+
+
+ /*
+ ignore ":_ bla bla \n" in msgid
+
+ */
+
+ void setRemoveInternalComment(bool internalcomment);
+
+ /*
+ Set the a string containing all char that must be ignored
+ during the search.
+ */
+
+
+ void setRemoveCharString(QString chartoremove);
+
+ /*
+ Enable an output filter that format Uppercase/lowercase
+ method could be;
+ 0 = Disabled;
+ 1 = English pattern;
+ 2 = Only first;
+ */
+
+ void enableCapitalFilter(int method);
+
+ /*
+ Enable an output filter that format special characters
+ method could be;
+ 0 = Disabled;
+ 1 = Put ... at the end if needed (remove if present but no needed);
+ 2 = Put an accelerator (or remove);
+ 4 = Remove %* if not present in msgid.
+ 8 = Change %d,%s etc with %1 %2 etc if needed.
+ */
+
+ void enableCharFilter(int method);
+
+ /*
+ Sets the rules to decide when 2 string match (Uppercase and remove char
+ are not set here)
+ 1 = EQUAL
+ 2 = SEARCH STRING IS CONTAINED IN DATABASE STRING (use with care, if you search nothing
+ it will produce a dangerouse output)
+ 4 = DATABASE STRING IS CONTAINED IN SEARCH STRING (it exclude msgid "")
+ 8 = String is a regexp. (exclude 1 2 4)
+ */
+
+ void setMatchingRules(int rules);
+
+ /*
+ Search Engine methods reimplemented
+ */
+
+
+
+ virtual bool messagesForFilter(const SearchFilter* filter
+ , QValueList<SearchResult>& resultList, QString& error);
+
+
+ virtual void setLanguageCode(const QString& lang);
+ virtual void setLanguage(const QString& languageCode, const QString& languageName);
+
+ virtual void setEditedFile(const QString& file);
+
+ virtual bool isReady() const ;
+ 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();
+
+ virtual QString translate(const QString& text, uint pluralForm);
+
+ virtual void stringChanged( const QStringList& orig, const QString& translated
+ , const uint translationPluralForm, const QString& description);
+
+
+public slots:
+
+ void scan();
+ void scanRecur();
+ void scanFile();
+ /*
+ Add a search string in the list of the string to search for.
+ Returns the ID of the string in the list.
+ Returns -1 if there is a problem (may be search in
+ progress)
+ */
+
+ int addSearchString(QString searchString, int rule=Equal);
+
+ /*
+ Start the research in the database of all the string in the list
+ search mode -1 means use global mode;
+ */
+ bool startSearchNow(int searchmode=-1);
+
+ /*
+ Start a search for a single string
+ If the number of word of your string is less than patternXlimit
+ the KDBSearchEngine will search for all string with X * substituted to
+ X word.
+ For example if pattern1limit is 4 and you search "My name is Andrea"
+ This string will also match with:
+ "Your name is Andrea", "My dog is Andrea", "My name was Andrea", "My name is Joe"
+
+ Do not set pattern2limit too high.
+
+ If a patternlimit is > 0 rules 8 (* means any word) is added.
+
+ */
+
+ bool startSingleSearch(QString searchString,unsigned int pattern1Limit,unsigned int pattern2Limit,
+ bool inTranslation=false);
+
+ /*
+ Start a search for a list of string
+ */
+
+// bool startListSearch(QPtrList<QString> searchStrList);
+
+/*
+ * Return a list of key in database that contains some
+ * words of the given string phrase.
+ * thresholdin is a number from 0 to 100 a key is good
+ * if at least the threshold% of words are found
+ * thresholdout a key is good if the found words represnt
+ * at least the thresholdorig% of the words in the key
+ * max is the maximum number of results
+ */
+
+QValueList<KeyAndScore> searchWords(QString phrase,int threshold,
+ int thresholdorig ,uint32 max);
+
+
+ /*
+ Stop the current search
+ */
+
+ virtual void stopSearch();
+ virtual bool startSearch(const QString& text, uint pluralForm, const SearchFilter* filter);
+ virtual bool startSearchInTranslation(QString s);
+
+ void clearList();
+signals:
+ void found(SearchResult *);
+private slots:
+ void updateSettings(); //Use widget settings
+ void setSettings(); //Fill widget with actual settings
+ void prefDestr();
+ void setLastError(const QString&);
+ void repeat();
+private:
+ /*
+ Reload database info (and keep the dbase opened).
+ */
+ bool loadDatabase(QString database,bool);
+
+ bool openDb(bool);
+
+ PreferencesWidget *pw;
+ bool IAmReady;
+ int methodFilterChar;
+ int methodFilterCapital;
+ int defRule;
+ int defLimit1;
+ int defLimit2;
+ int thre;
+ int threorig;
+ int commonthre;
+ int listmax;
+ int mode;
+ bool retnot;
+ bool defSub1;
+ bool defSub2;
+ bool stopNow;
+ bool searching;
+ bool norm,sens,comm;
+ int numofresult;
+ char * filename;
+ QString remchar;
+ QString regaddchar;
+ QString dbname;
+ bool dbOpened;
+// GDBM_FILE db;
+ DataBaseManager * dm;
+// datum key, value;
+// QMemArray<CatalogDescription *> catinfo;
+ SearchList searchStringList;
+ int totalRecord;
+ QString lasterror;
+ QString lang;
+ bool scanInProgress;
+ QString edited;
+ bool autoup;
+ QString autoauthor;
+};
+
+#endif
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/Makefile.am b/kbabel/kbabeldict/modules/dbsearchengine/Makefile.am
new file mode 100644
index 00000000..8504999a
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/Makefile.am
@@ -0,0 +1,34 @@
+## Makefile.am for DBSE
+
+# 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_dbsearchengine.la
+
+# set the include path for X, qt and KDE
+INCLUDES = -I$(srcdir)/../.. -I../../../common -I$(srcdir)/../../../common $(all_includes) $(DBIV_INCLUDES)
+
+# which sources should be compiled for kbabel
+kbabeldict_dbsearchengine_la_SOURCES = KDBSearchEngine.cpp preferenceswidget.cpp \
+ dbse_factory.cpp dbseprefwidget.ui database.cpp dbscan.cpp
+#database.cpp dbscan.cpp
+kbabeldict_dbsearchengine_la_LIBADD = ../../libkbabeldictplugin.la ../../../common/libkbabelcommon.la $(LIB_KDEUI) $(LIB_KIO) $(LIB_DBIV)
+kbabeldict_dbsearchengine_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined \
+ $(DBIV_LDFLAGS)
+
+
+# these are the headers for your project
+noinst_HEADERS = KDBSearchEngine.h preferenceswidget.h dbse_factory.h \
+ database.h dbscan.h
+
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+kde_services_DATA = dbsearchengine.desktop
+EXTRA_DIST = $(kde_services_DATA)
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/STRUCTURE b/kbabel/kbabeldict/modules/dbsearchengine/STRUCTURE
new file mode 100644
index 00000000..0a53a0fe
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/STRUCTURE
@@ -0,0 +1,25 @@
+
+
+key = original text
+
+data
+ 0..3 num of translation (n)
+
+ translations
+ 0..3 num of file references (m)
+ 4..(4+m*4) file references
+ 4+m*4..first\0 translation
+
+
+----------------------------------------------------
+Files structure.
+
+
+"it" is the language
+
+catalogsinfo.it.db //Info about the catalog
+keysindex.it.db //index of numofkeys->key
+translations.it.db //guess.. (key->translation)
+wordsindex.it.db //index of word->numofkey
+
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/TODO b/kbabel/kbabeldict/modules/dbsearchengine/TODO
new file mode 100644
index 00000000..0e7fbd3a
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/TODO
@@ -0,0 +1,27 @@
+TODO List fore KDE Database Translation Search Engine
+
+-Finish the port (use settings) done
+-Improve settings (filter output)
+-Database handling (and creation...) Done
+-output filters
+-fix fix fix...
+
+-delete item if putItem(nullitem)
+-use matthias mask function for regexp
+-remove bug of word split F&ormat is F ormat <- add remchar to charregexp
+
+
+Major rewrite:
+-New settings interface.
+-addFunction from dbscan to database Done ?
+-Edit function
+-database manager
+-download compendium from the internet
+
+Matthias ask:
+- searching in translations, equivalent to searching in msgids (SearchEngine::startTranslationSearch(QString s) )
+- the absolute path of the files and maybe the number of the entry in the file ( maybe I will add this information to the TranslationInfo )
+- the possibility to get a list of all entries in a po file from the database. For this, I think, I will create a interface and send it to you. Maybe something like this: class TranslationDatabase {
+public: // name is something like "kbabel.po" QList<CatalogItem> entriesOfFile(QString name); }
+
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/configure.in.bot b/kbabel/kbabeldict/modules/dbsearchengine/configure.in.bot
new file mode 100644
index 00000000..58d6118f
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/configure.in.bot
@@ -0,0 +1,5 @@
+if test "x$with_berkeley_db" = xcheck && test -z "$LIB_DBIV"; then
+ echo ""
+ echo "Dictionary plugin \"Translation Database\" for KBabel will not be built! Please install Berkeley Database IV. See http://www.sleepycat.com for more information.)"
+ echo ""
+fi
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/configure.in.in b/kbabel/kbabeldict/modules/dbsearchengine/configure.in.in
new file mode 100644
index 00000000..fbc3f1a8
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/configure.in.in
@@ -0,0 +1,143 @@
+AC_ARG_WITH(berkeley-db,
+ [AC_HELP_STRING(--with-berkeley-db,
+ [enable the dictionary plugin based on Berkeley DB IV @<:@default=check@:>@])],
+ [], with_berkeley_db=check)
+
+LIB_DBIV=""
+if test "x$with_berkeley_db" != xno; then
+
+AC_MSG_CHECKING([for Berkeley Database IV])
+
+db_libraries=""
+db_includes=""
+db_name=""
+ac_db_name="db"
+ac_db_includes=""
+ac_db_libraries=""
+ac_db_include_file="db.h"
+
+AC_ARG_WITH(db-dir,
+ AC_HELP_STRING([--with-db-dir=DIR],[where the root of Berkeley DB IV is installed]),
+ [ ac_db_includes=-I"$withval"/include
+ ac_db_libraries=-L"$withval"/lib
+ ])
+AC_ARG_WITH(db-include-dir,
+ AC_HELP_STRING([--with-db-include-dir=DIR],[where the includes of Berkeley DB IV are installed]),
+ [ ac_db_includes=-I"$withval"
+ ])
+AC_ARG_WITH(db-include,
+ AC_HELP_STRING([--with-db-include=FILE],[path to the Berkeley DB IV header file]),
+ [ ac_db_include_file=-I"$withval"
+ ])
+AC_ARG_WITH(db-lib-dir,
+ AC_HELP_STRING([--with-db-lib-dir=DIR],[where the libs of Berkeley DB IV are installed]),
+ [ ac_db_libraries=-L"$withval"
+ ])
+AC_ARG_WITH(db-name,
+ AC_HELP_STRING([--with-db-name=NAME],[name of the Berkeley DB IV library (default db)]),
+ [ ac_db_name="$withval"
+ ])
+
+AC_DEFUN([KDE_CHECK_DB_VERSION],
+[
+ifelse($3,,,[LIBS="$kde_db_safe -l$3"])
+AC_TRY_LINK([
+#include <$2>
+],
+[
+#if DB_VERSION_MAJOR == 4
+DB *db;
+#if DB_VERSION_MINOR > 0
+db->open( db, NULL, "test.db", NULL, DB_BTREE, DB_CREATE, 0644 );
+#else
+db->open( db, "test.db", NULL, DB_BTREE, DB_CREATE, 0644 );
+#endif
+#else
+error
+#endif
+],
+kde_cv_berk_database=$1
+)
+])
+
+AC_CACHE_VAL(kde_cv_berk_database,
+[
+kde_safe_LDFLAGS=$LDFLAGS
+kde_db_safe_LIBS=$LIBS
+LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $all_libraries $ac_db_libraries $all_includes $ac_db_includes"
+
+kde_cv_berk_database=NO
+if test "xNO" = "x$kde_cv_berk_database" ; then
+ KDE_CHECK_DB_VERSION($ac_db_name, $ac_db_include_file, $ac_db_name)
+fi
+if test "xNO" = "x$kde_cv_berk_database" ; then
+ KDE_CHECK_DB_VERSION(db4, db4/db.h, db4)
+fi
+if test "xNO" = "x$kde_cv_berk_database" ; then
+ KDE_CHECK_DB_VERSION(db4-db, db.h, db4)
+fi
+if test "xNO" = "x$kde_cv_berk_database" ; then
+ KDE_CHECK_DB_VERSION(db, db.h, db)
+fi
+
+LIBS=$kde_db_safe_LIBS
+LDFLAGS=$kde_safe_LDFLAGS
+
+])
+
+kde_db_header=""
+DBSEARCHENGINE=dbsearchengine
+
+case "$kde_cv_berk_database" in
+ NO)
+ AC_MSG_RESULT(no)
+ LIB_DBIV=""
+ DBSEARCHENGINE=""
+ ;;
+ db)
+ LIB_DBIV="-l$ac_db_name"
+ kde_db_header=db.h
+ AC_MSG_RESULT(-l$ac_db_name)
+ AC_DEFINE_UNQUOTED(HAVE_DB_DB_H, 1, [DB 4 header location] )
+ ;;
+ db4-db)
+ LIB_DBIV='-ldb4'
+ kde_db_header=db.h
+ AC_MSG_RESULT("flag is -ldb4 and header is db.h")
+ AC_DEFINE_UNQUOTED(HAVE_DB_DB_H, 1, [DB 4 header location] )
+ ;;
+ db4)
+ LIB_DBIV='-ldb4'
+ kde_db_header=db4/db.h
+ AC_MSG_RESULT(-ldb4)
+ AC_DEFINE_UNQUOTED(HAVE_DB4_DB_H, 1, [DB 4 header location] )
+ ;;
+ $ac_db_name)
+ LIB_DBIV="-l$ac_db_name"
+ kde_db_header="$ac_db_include_file"
+ AC_MSG_RESULT(user specified $ac_db_name)
+ if test "x$ac_db_include_file" = "xdb.h" ; then
+ AC_DEFINE_UNQUOTED(HAVE_DB_DB_H, 1, [DB 4 header location] )
+ else
+ AC_DEFINE_UNQUOTED(USE_DB_H_PATH, <$ac_db_include_file>, [DB 4 header path])
+ fi
+
+ ;;
+esac
+
+DBIV_LDFLAGS="$ac_db_libraries"
+DBIV_INCLUDES="$ac_db_includes"
+DBIV_NAME="$ac_db_name"
+
+if test "x$with_berkeley_db" != xcheck && test -z "$LIB_DBIV"; then
+ AC_MSG_ERROR([--with-berkeley-db was given, but test for Berkeley DB IV failed])
+fi
+fi
+
+AC_SUBST(DBIV_INCLUDES)
+AC_SUBST(DBIV_LDFLAGS)
+AC_SUBST(DBIV_NAME)
+
+AC_SUBST(LIB_DBIV)
+
+AM_CONDITIONAL(include_DBSEARCHENGINE, test -n "$DBSEARCHENGINE")
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/database.cpp b/kbabel/kbabeldict/modules/dbsearchengine/database.cpp
new file mode 100644
index 00000000..003a3a95
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/database.cpp
@@ -0,0 +1,1533 @@
+/***************************************************************************
+ database.cpp -
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000 by Andrea Rizzi
+ email : rizzi@kde.org
+ ***************************************************************************/
+
+/*
+ Translation search engine
+
+
+ Copyright 2000
+ Andrea Rizzi rizzi@kde.org
+ Copyright 2003 Stanislav Visnovsky visnovsky@kde.org
+
+ License GPL v 2.0
+
+ * *
+ * 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 <stdlib.h>
+#include <kdebug.h>
+#include <string.h>
+#include <resources.h>
+#include "database.h"
+#include <unistd.h>
+
+#include <qfile.h>
+
+#include <ktempfile.h>
+#include <kio/netaccess.h>
+
+WordItem::WordItem (char *data, QString w)
+{
+ word = w;
+
+ count = *(uint32 *) data;
+
+ data += 4;
+//score=*(int *)data;
+ data += 4;
+
+
+ locations = (uint32 *) malloc (4 * count);
+ memcpy (locations, data, 4 * count);
+
+
+}
+
+WordItem::WordItem (QString w)
+{
+ locations = NULL;
+ count = 0;
+ word = w;
+ score = -1; // it means no references found.
+}
+
+/*
+
+WordItem::WordItem(const WordItem &wi)
+{
+ count=wi.count;
+ score=wi.score;
+ word=wi.word;
+ locations.duplicate(wi.locations);
+ locations.detach();
+}
+
+WordItem& WordItem::operator=(const WordItem & wi )
+{
+WordItem *i=new WordItem(wi);
+i->locations.detach();
+return *i;
+}
+*/
+
+bool
+WordItem::notFound ()
+{
+ return (score == -1);
+}
+
+InfoItem::InfoItem ()
+{
+ catalogName = "No catalog";
+ lastTranslator = "No translator";
+ lastFullPath = "";
+ charset = "No charset";
+ language = "No language";
+}
+
+InfoItem::InfoItem (const char *rawData, QString lang)
+{
+ const char *rd;
+ rd = rawData;
+ int len;
+ unsigned int secs;
+ // I'll change the charset handling if needed
+
+ charset = "Utf8";
+
+ catalogName = QString::fromUtf8 (rd);
+ len = strlen (rd) + 1;
+ rd += len;
+ lastTranslator = QString::fromUtf8 (rd);
+ len = strlen (rd) + 1;
+ rd += len;
+ secs = *(unsigned int *) rd;
+ revisionDate.setTime_t (secs);
+ rd += 4;
+ lastFullPath = QString::fromUtf8 (rd);
+ len = strlen (rd) + 1;
+ rd += len;
+
+
+ language = lang;
+}
+
+void
+InfoItem::rawData (char *rawData)
+{
+ char *rd;
+ rd = rawData;
+
+ strcpy (rd, catalogName.utf8 ());
+ rd += strlen (rd) + 1;
+ strcpy (rd, lastTranslator.utf8 ());
+ rd += strlen (rd) + 1;
+
+
+ //QDate Time problem!!!!!!!!!!!
+ QDateTime zeroDate;
+ zeroDate.setTime_t (0);
+ *(unsigned int *) rd = -revisionDate.secsTo (zeroDate);
+ rd += 4;
+ strcpy (rd, lastFullPath.utf8 ());
+ rd += strlen (rd) + 1;
+
+ *rd = 0; //Empty for further info
+
+}
+
+int
+InfoItem::size ()
+{
+ int _size;
+ _size = 0;
+ _size += 1; // 1 Empty field;
+ _size += 3; // Terminating \0 of next 3 strings
+ _size += 4; // Int size (date)
+ _size += strlen (catalogName.utf8 ());
+ _size += strlen (lastTranslator.utf8 ());
+ _size += strlen (lastFullPath.utf8 ());
+
+ return _size;
+}
+
+// this is a quick hack to copy a local file
+int
+copy_hack (QFile & input, QFile & output)
+{
+ if (!input.isOpen ())
+ {
+ if (!input.open (IO_ReadOnly))
+ return -1;
+ }
+
+ if (!output.isOpen ())
+ {
+ if (!output.open (IO_WriteOnly))
+ return -1;
+ }
+
+ char buffer[10240];
+ int s = 0;
+ while (!input.atEnd ())
+ {
+ s = input.readBlock (buffer, 10240);
+ output.writeBlock (buffer, s);
+ }
+ output.close ();
+ input.close ();
+ return 0;
+}
+
+DataBaseItem::DataBaseItem ()
+{
+ numTra = 0;
+ location = 0;
+}
+
+DataBaseItem::DataBaseItem (char *_key, char *_data)
+{
+
+ char *data = _data;
+ key = QString::fromUtf8 (_key);
+
+ unsigned int i, r;
+ numTra = *(uint32 *) data;
+ data += 4;
+ location = *(uint32 *) data;
+ data += 4;
+
+ for (i = 0; i < numTra; i++)
+ {
+
+ TranslationItem tr;
+ tr.numRef = *(uint32 *) data;
+
+ data += 4;
+ for (r = 0; r < tr.numRef; r++)
+ {
+
+ int ref;
+ ref = *(uint32 *) data;
+ data += 4;
+
+ tr.infoRef.append (ref);
+ }
+ tr.translation = QString::fromUtf8 ((const char *) data);
+ translations.append (tr);
+ data += strlen (data) + 1;
+
+ }
+
+}
+
+uint32
+DataBaseItem::sizeKey ()
+{
+ return strlen (key.utf8 ()) + 1;
+}
+
+uint32
+DataBaseItem::sizeData ()
+{
+ unsigned int i, _size = 4;
+ _size += numTra * 4;
+ _size += 4; // location
+ for (i = 0; i < numTra; i++)
+ {
+ _size += strlen (translations[i].translation.utf8 ()) + 1; // +1 is for \0
+ _size += translations[i].numRef * 4;
+ }
+ return _size;
+}
+
+void
+DataBaseItem::toRawKey (char *_key)
+{
+ strcpy (_key, key.utf8 ());
+}
+
+void
+DataBaseItem::toRawData (char *_data)
+{
+ char *data = _data;
+ unsigned int i, r;
+
+ *(uint32 *) data = numTra;
+
+ data += 4;
+
+ *(uint32 *) data = location;
+ data += 4;
+
+ for (i = 0; i < numTra; i++)
+ {
+ TranslationItem tr (translations[i]);
+ *(uint32 *) data = tr.numRef;
+ data += 4;
+ for (r = 0; r < tr.numRef; r++)
+ {
+ *(uint32 *) data = tr.infoRef[r]; //sub i with r
+
+ data += 4;
+ }
+ strcpy ((char *) data, tr.translation.utf8 ());
+ data += strlen (tr.translation.utf8 ()) + 1;
+ }
+
+}
+
+
+DataBaseManager::DataBaseManager (QString directory, QString lang,
+ QObject * parent, const char *name):
+QObject (parent, name)
+{
+ QString filename;
+
+ language = lang;
+ iAmOk = true;
+ basedir = directory;
+ indexDb = wordDb = infoDb = db = 0;
+ openDataBase ();
+
+
+}
+
+void
+DataBaseManager::openDataBase ()
+{
+ kdDebug () << "Opendatabase" << endl;
+ QString directory;
+ directory = basedir;
+ QString ll = "." + language;
+ if (ll == ".")
+ ll = ".NOLANG";
+
+ QString transfilename = "%1/translations%2.db";
+ transfilename = transfilename.arg (directory).arg (ll);
+
+ QString infofilename = "%1/catalogsinfo%2.db";
+ infofilename = infofilename.arg (directory).arg (ll);
+
+ QString wordsfilename = "%1/wordsindex%2.db";
+ wordsfilename = wordsfilename.arg (directory).arg (ll);
+
+ QString keysfilename = "%1/keysindex%2.db";
+ keysfilename = keysfilename.arg (directory).arg (ll);
+
+ cursor = 0;
+ int ret;
+
+ if (!db)
+ db_create (&db, 0, 0);
+
+ db_create (&infoDb, 0, 0);
+ db_create (&wordDb, 0, 0);
+ db_create (&indexDb, 0, 0);
+
+ ret = db->open (db,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ transfilename.local8Bit (), 0, DB_BTREE, 0, 0644);
+
+ if (ret == DB_OLD_VERSION)
+ {
+ kdDebug (KBABEL_SEARCH) << "Trying upgrade" << endl;
+ // try upgrade
+
+ KTempFile transFile, infoFile, keysFile, wordsFile;
+
+ // do the upgrade on the translation file
+ QFile transfilenameFile (transfilename);
+
+ if ((ret = copy_hack (transfilenameFile, *transFile.file ())) == 0)
+ {
+ ret = db->upgrade (db, transFile.name ().local8Bit (), 0);
+ }
+
+ if (ret != 0)
+ {
+ kdDebug (KBABEL_SEARCH) << "Cannot upgrade translations, " <<
+ ret << endl;
+ // cleanup
+ transFile.unlink ();
+ iAmOk = false;
+ emit cannotOpenDB (ret);
+ return;
+ }
+
+ // do the upgrade on the info file
+ QFile infofilenameFile (infofilename);
+ if ((ret = copy_hack (infofilenameFile, *infoFile.file ())) == 0)
+ {
+ ret =
+ infoDb->upgrade (infoDb, infoFile.name ().local8Bit (),
+ 0);
+ }
+
+ if (ret != 0)
+ {
+ kdDebug (KBABEL_SEARCH) << "Cannot upgrade catalogsinfo" <<
+ endl;
+ // cleanup
+ transFile.unlink ();
+ infoFile.unlink ();
+ iAmOk = false;
+ emit cannotOpenDB (ret);
+ return;
+ }
+
+ // do the upgrade on the words file
+ QFile wordfilenameFile (wordsfilename);
+ if ((ret = copy_hack (wordfilenameFile, *wordsFile.file ())) == 0)
+ {
+ ret =
+ wordDb->upgrade (wordDb, wordsFile.name ().local8Bit (),
+ 0);
+ }
+
+ if (ret != 0)
+ {
+ kdDebug (KBABEL_SEARCH) << "Cannot upgrade words" << endl;
+ // cleanup
+ transFile.unlink ();
+ infoFile.unlink ();
+ wordsFile.unlink ();
+ iAmOk = false;
+ emit cannotOpenDB (ret);
+ return;
+ }
+
+ // do the upgrade on the keys file
+ QFile keysfilenameFile (keysfilename);
+ if ((ret = copy_hack (keysfilenameFile, *keysFile.file ())) == 0)
+ {
+ ret =
+ indexDb->upgrade (indexDb, keysFile.name ().local8Bit (),
+ 0);
+ }
+
+ if (ret != 0)
+ {
+ kdDebug (KBABEL_SEARCH) << "Cannot upgrade keys" << endl;
+ // cleanup
+ transFile.unlink ();
+ infoFile.unlink ();
+ wordsFile.unlink ();
+ keysFile.unlink ();
+ iAmOk = false;
+ emit cannotOpenDB (ret);
+ return;
+ }
+
+ kdDebug (KBABEL_SEARCH) << "Files upgraded, copying" << endl;
+ // use temporary file instead
+ if (ret == 0)
+ {
+ KIO::NetAccess::del (KURL::fromPathOrURL (transfilename));
+ copy_hack (*transFile.file (), transfilenameFile);
+ transFile.unlink ();
+
+ KIO::NetAccess::del (KURL::fromPathOrURL (infofilename));
+ copy_hack (*infoFile.file (), infofilenameFile);
+ infoFile.unlink ();
+
+ KIO::NetAccess::del (KURL::fromPathOrURL (wordsfilename));
+ copy_hack (*wordsFile.file (), wordfilenameFile);
+ wordsFile.unlink ();
+
+ KIO::NetAccess::del (KURL::fromPathOrURL (keysfilename));
+ copy_hack (*keysFile.file (), keysfilenameFile);
+ keysFile.unlink ();
+
+ ret = db->open (db,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ transfilename.local8Bit (), 0, DB_BTREE, 0,
+ 0644);
+ if (ret != 0)
+ {
+ kdWarning (KBABEL_SEARCH) <<
+ "transFilename database can't be opened." << endl;
+ kdWarning (KBABEL_SEARCH) <<
+ "Please, report this incident and how to reproduce it to kbabel@kde.org."
+ << endl;
+ iAmOk = false;
+ emit cannotOpenDB (ret);
+ return;
+ }
+
+ }
+ kdDebug (KBABEL_SEARCH) << "Upgrade done OK" << endl;
+ }
+
+// Open catalogs information database
+
+
+
+ ret = infoDb->open (infoDb,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ infofilename.local8Bit (), 0, DB_RECNO, 0, 0644);
+ if (ret != 0)
+ {
+ iAmOk = false;
+ emit cannotOpenDB (ret);
+ //Process error here.
+ }
+ else
+ loadInfo ();
+
+
+
+// Words index database
+
+ ret = wordDb->open (wordDb,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ wordsfilename.local8Bit (), 0, DB_BTREE, 0, 0644);
+ if (ret != 0)
+ {
+ iAmOk = false;
+ emit cannotOpenDB (ret);
+ //Process error here.
+ }
+
+//Index of keys.
+
+ ret = indexDb->open (indexDb,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ keysfilename.local8Bit (), 0, DB_RECNO, 0, 0644);
+ if (ret != 0)
+ {
+ iAmOk = false;
+ emit cannotOpenDB (ret);
+ //Process error here.
+ }
+
+
+}
+
+void
+DataBaseManager::closeDataBase ()
+{
+ if (iAmOk)
+ {
+ db->sync (db, 0);
+ db->close (db, 0);
+
+ infoDb->sync (infoDb, 0);
+ infoDb->close (infoDb, 0);
+
+ wordDb->sync (wordDb, 0);
+ wordDb->close (wordDb, 0);
+
+ indexDb->sync (indexDb, 0);
+ indexDb->close (indexDb, 0);
+
+ // can not be opened again
+ indexDb = wordDb = infoDb = db = 0;
+
+ }
+
+}
+
+
+// I'm not sure this is a good function !!!
+
+void
+DataBaseManager::sync ()
+{
+// if(iAmOk)
+// {
+// db->sync(db,0);
+// infoDb->sync(infoDb,0);
+// cursor=0;
+// }
+
+ // closeDataBase();
+// openDataBase();
+
+ db->sync (db, 0);
+ infoDb->sync (infoDb, 0);
+ wordDb->sync (wordDb, 0);
+ indexDb->sync (indexDb, 0);
+ loadInfo ();
+}
+
+
+DataBaseManager::~DataBaseManager ()
+{
+ closeDataBase ();
+}
+
+int
+DataBaseManager::putItem (DataBaseItem * item, bool ow)
+{
+ DBT key, data;
+
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
+
+ bool ret;
+
+ uint32 loc = 0;
+ if (item->location == 0)
+ {
+ loc = item->location = appendKey (item->key);
+// kdDebug(0) << "New key " << item->location << endl;
+ }
+ key.size = item->sizeKey ();
+ data.size = item->sizeData ();
+
+ key.data = malloc (key.size);
+ data.data = malloc (data.size);
+
+
+ item->toRawKey ((char *) key.data);
+ item->toRawData ((char *) data.data);
+
+
+ if (ow)
+ ret = db->put (db, 0, &key, &data, 0);
+ else
+ ret = db->put (db, 0, &key, &data, DB_NOOVERWRITE);
+
+//check ret
+
+ if (loc != 0) //I'm new!
+ {
+ uint32 location = loc;
+
+ QValueList < QString > wlist;
+
+ wlist = wordsIn (item->key);
+
+ QValueList < QString >::Iterator wlistit;
+
+ for (wlistit = wlist.begin (); wlistit != wlist.end (); ++wlistit)
+ {
+ addLocation (*wlistit, location);
+ }
+
+ }
+
+ free (key.data);
+ free (data.data); //READ DOCU !!!!
+
+ return ret;
+
+}
+
+DataBaseItem
+DataBaseManager::getItem (QString key)
+{
+ if (!iAmOk)
+ return DataBaseItem ();
+
+
+ DBT _key, data;
+
+ memset (&_key, 0, sizeof (DBT));
+
+ memset (&data, 0, sizeof (DBT));
+
+ int len = strlen (key.utf8 ());
+ _key.data = malloc (len + 1);
+ _key.size = len + 1;
+ strcpy ((char *) _key.data, key.utf8 ());
+
+
+ int ret;
+ ret = db->get (db, 0, &_key, &data, 0);
+
+ if (ret != 0)
+ {
+ free (_key.data);
+ return DataBaseItem (); //return an empty database item
+ }
+
+ DataBaseItem returnItem =
+ DataBaseItem ((char *) _key.data, (char *) data.data);
+
+ free (_key.data);
+ return returnItem;
+
+}
+
+
+
+
+DataBaseItem
+DataBaseManager::cursorGet (uint32 flags)
+{
+
+ if (!iAmOk)
+ return DataBaseItem ();
+ int re;
+ DBT key, data;
+
+ memset (&key, 0, sizeof (DBT));
+
+ memset (&data, 0, sizeof (DBT));
+
+ if (cursor == 0)
+ re = db->cursor (db, 0, &cursor, 0);
+
+ int ret;
+ if ((ret = cursor->c_get (cursor, &key, &data, flags)) == 0)
+ {
+ return DataBaseItem ((char *) key.data, (char *) data.data);
+ }
+ else
+ {
+ kdDebug (KBABEL_SEARCH) << QString ("...cursor getting...%1").
+ arg (ret) << endl;
+
+ return DataBaseItem ();
+ }
+}
+
+
+DataBaseItem
+DataBaseManager::firstItem ()
+{
+ return cursorGet (DB_FIRST);
+}
+
+DataBaseItem
+DataBaseManager::currentItem ()
+{
+ return cursorGet (DB_CURRENT);
+}
+
+
+DataBaseItem
+DataBaseManager::nextItem ()
+{
+ return cursorGet (DB_NEXT);
+}
+
+
+bool
+DataBaseManager::isOk ()
+{
+ return iAmOk;
+}
+
+int
+DataBaseManager::count ()
+{
+ DB_BTREE_STAT *dstat = 0;
+#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3
+ db->stat (db, NULL, &dstat, DB_FAST_STAT);
+#else
+ db->stat (db, &dstat, DB_FAST_STAT);
+#endif
+ int ret = dstat->bt_nkeys;
+ free (dstat);
+
+ return ret;
+}
+
+int
+DataBaseManager::current ()
+{
+// THIS FUNCTION SEEM TO NOT WORK (not used)
+ if (!iAmOk)
+ return 0;
+
+ DBT key, data;
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
+
+ if (cursor != 0)
+ db->cursor (db, 0, &cursor, 0);
+ cursor->c_get (cursor, &key, &data, DB_GET_RECNO);
+ return *(uint32 *) (data.data);
+
+}
+
+int
+DataBaseManager::createDataBase (QString directory,
+ QString language, int mode)
+{
+ QString filename;
+ QString ll = "." + language;
+ if (ll == ".")
+ ll = ".NOLANG";
+ filename = "%1/translations%2.db";
+ filename = filename.arg (directory).arg (ll);
+
+ rename (filename.local8Bit (), filename.local8Bit () + ",old");
+
+//kdDebug(0) << QString("Creating %1").arg(filename) << endl;
+
+ iAmOk = true;
+
+ int ret;
+
+ if (!db)
+ {
+ if (db_create (&db, 0, 0) != 0)
+ {
+ kdDebug() << "db_create db failed" << endl;
+ iAmOk = false;
+ return false;
+ }
+ }
+
+ db->set_flags (db, DB_RECNUM);
+ ret = db->open (db,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ filename.local8Bit (), 0, DB_BTREE, DB_CREATE | DB_EXCL,
+ mode);
+ if (ret != 0)
+ {
+ kdDebug() << "db->open " << filename << " " << mode << " failed" << endl;
+ iAmOk = false;
+ }
+
+
+ filename = "%1/catalogsinfo%2.db";
+ filename = filename.arg (directory).arg (ll);
+ rename (filename.local8Bit (), filename.local8Bit () + ",old");
+
+ db_create (&infoDb, 0, 0);
+ ret = infoDb->open (infoDb,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ filename.local8Bit (), 0, DB_RECNO, DB_CREATE, mode);
+ if (ret != 0)
+ iAmOk = false;
+
+
+
+ filename = "%1/wordsindex%2.db";
+ filename = filename.arg (directory).arg (ll);
+ rename (filename.local8Bit (), filename.local8Bit () + ",old");
+
+ db_create (&wordDb, 0, 0);
+ ret = wordDb->open (wordDb,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ filename.local8Bit (), 0, DB_BTREE, DB_CREATE, mode);
+ if (ret != 0)
+ iAmOk = false;
+
+
+
+ filename = "%1/keysindex%2.db";
+ filename = filename.arg (directory).arg (ll);
+ rename (filename.local8Bit (), filename.local8Bit () + ",old");
+
+ db_create (&indexDb, 0, 0);
+ ret = indexDb->open (indexDb,
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ filename.local8Bit (), 0, DB_RECNO, DB_CREATE, mode);
+ if (ret != 0)
+ iAmOk = false;
+
+
+
+ if (iAmOk)
+ loadInfo ();
+ else
+ kdDebug (KBABEL_SEARCH) << QString ("I am NOT ok : %1").
+ arg (ret) << endl;
+
+//THIS IS WRONG, rewrite the error handling.
+ return iAmOk;
+
+}
+
+InfoItem
+DataBaseManager::getCatalogInfo (int n)
+{
+
+ DBT key;
+ DBT data;
+
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
+
+ key.data = &n;
+ key.size = 4;
+
+//Check for errors
+ int ret = infoDb->get (infoDb, 0, &key, &data, 0); //DB_SET_RECNO);
+
+ if (ret)
+ {
+ return InfoItem ();
+ }
+
+// kdDebug(0) << QString("Trad %1").arg(ret) << endl;
+
+ InfoItem it ((char *) data.data, language);
+//free(data.data); // Read docu for this!!!!
+
+ return it;
+
+}
+
+int
+DataBaseManager::addCatalogInfo (InfoItem * catInfo, int cat = -1)
+{
+ DBT data;
+ DBT key;
+
+ // clean up data
+ memset (&data, 0, sizeof (DBT));
+ memset (&key, 0, sizeof (DBT));
+
+ int ret = 0, err;
+ if (cat >= 0)
+ ret = cat;
+ key.size = 4;
+ key.data = &ret;
+ data.size = catInfo->size ();
+ data.data = malloc (data.size);
+
+ catInfo->rawData ((char *) data.data);
+
+ // store the catalog data into database
+ if (cat >= 0)
+ err = infoDb->put (infoDb, 0, &key, &data, 0);
+ else
+ err = infoDb->put (infoDb, 0, &key, &data, DB_APPEND);
+
+
+ ret = *(int *) key.data;
+
+ // Append to the list of catalogInfo
+ info.append (*catInfo);
+
+ // cleanup unneeded data memory
+ free (data.data);
+ return ret;
+}
+
+int
+DataBaseManager::searchCatalogInfo (QString location)
+{
+ int n = 0;
+ QValueList < InfoItem >::Iterator it;
+ for (it = info.begin (); it != info.end (); ++it)
+ {
+ n++;
+ if ((*it).catalogName == location)
+ return n;
+ }
+ return -1;
+}
+
+bool
+DataBaseManager::putCatalogInfo (int refnum, InfoItem * catInfo)
+{
+ DBT data;
+ DBT key;
+
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
+
+ int ret;
+ key.size = 4;
+ key.data = &refnum;
+
+ data.size = catInfo->size ();
+ data.data = malloc (data.size);
+ catInfo->rawData ((char *) data.data);
+
+ ret = infoDb->put (infoDb, 0, &key, &data, 0);
+
+ free (data.data);
+
+ return (ret == 0);
+}
+
+void
+DataBaseManager::loadInfo ()
+{
+ int nrec;
+ DB_BTREE_STAT *stat;
+// memset(&stat,0,sizeof(DB_BTREE_STAT));
+#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3
+ if (infoDb->stat (infoDb, NULL, &stat, DB_FAST_STAT))
+ fprintf (stderr, "Cannot stat\n");
+#else
+ if (infoDb->stat (infoDb, &stat, DB_FAST_STAT))
+ fprintf (stderr, "Cannot stat\n");
+#endif
+ nrec = stat->bt_nkeys;
+ free (stat);
+
+ info.clear ();
+ for (int i = 1; i <= nrec; i++) // I think DB2 Recno are 1 based.
+ {
+ info.append (getCatalogInfo (i));
+ }
+
+}
+
+
+QValueList < QString > DataBaseManager::wordsIn (QString string)
+{
+ QString
+ a;
+ QValueList < QString > words;
+ int
+ i,
+ l;
+
+ a = string.simplifyWhiteSpace ();
+ a = a.stripWhiteSpace ();
+ a = a.lower ();
+ l = a.length ();
+
+ int
+ c = 0;
+ //words.setAutoDelete(true); //Not sure... check if it is en.
+ QString
+ m;
+ for (i = 0; i < l; i++)
+ if (a[i].isLetterOrNumber ())
+ {
+ m += a[i];
+ }
+ else if (a[i].isSpace ())
+ {
+ words.append (m);
+ c++; // C++ ;-)
+ m = "";
+ }
+ words.append (m);
+
+ return words;
+}
+
+
+
+WordItem
+DataBaseManager::getWordLocations (QString word)
+{
+
+ QString keystring = word.lower ();
+
+ DBT key;
+ DBT data;
+
+ char *keydata;
+
+ int intlen = strlen (keystring.utf8 ());
+
+ keydata = (char *) malloc (intlen + 1);
+ strcpy (keydata, keystring.utf8 ());
+
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
+
+ key.data = keydata;
+ key.size = intlen + 1;
+
+//Check for errors
+ int ret = wordDb->get (wordDb, 0, &key, &data, 0); //DB_SET_RECNO);
+//MAYBE THIS WORD IS NO WHERE!!
+ if (ret)
+ {
+ free (keydata);
+ return WordItem (keystring);
+ }
+
+
+ WordItem it ((char *) data.data, keystring);
+
+ free (keydata);
+
+
+// kdDebug(0) << ((uint32 *)it.locations.data())[0] << endl;
+
+ return it;
+
+}
+
+
+bool
+DataBaseManager::addLocation (QString word, unsigned int location)
+{
+
+ QString keystring = word.lower ();
+
+
+ DBT key;
+ DBT data;
+
+ char *keydata;
+ char *newdata;
+
+ int intlen = strlen (keystring.utf8 ());
+
+ keydata = (char *) malloc (intlen + 1);
+ strcpy (keydata, keystring.utf8 ());
+
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
+
+ key.data = keydata;
+ key.size = intlen + 1;
+
+ strcpy ((char *) key.data, keystring.utf8 ());
+
+//Check for errors
+ int ret = wordDb->get (wordDb, 0, &key, &data, 0); //DB_SET_RECNO);
+
+//Check if you get something or not
+ if (ret == 0) // CHANGE IT!!!!! if found something
+ {
+ uint32 *d;
+ d = (uint32 *) data.data;
+ uint32 num = d[0];
+ uint32 loc = 0; //Position from 0 to num-1
+ int totalrecord = count ();
+ uint32 step = 1;
+
+ int antibounce = 0;
+//d+=4;
+//int score=d[1];
+//d+=4;
+ bool forward, end = false;
+
+ d[1] = 0; //Before the begin...
+
+ d += 2; //1 uint32!
+
+
+//Try to guess...
+ loc = location * num / totalrecord + 1;
+ if (loc >= num)
+ loc = num - 1;
+
+
+
+
+//Continue if next is smaller or if previous is greater
+//before the while check if it is ok
+ if (loc == 0)
+ {
+ if (d[loc] > location)
+ end = true;
+ else
+ loc = 1;
+ }
+
+ if ((loc == num) && !end)
+ {
+ if (d[loc - 1] < location)
+ end = true;
+ else
+ loc = num - 1;
+ }
+
+
+
+ while ((!end) && ((forward = (d[loc]) < location)
+ || ((loc > 0) && (d[loc - 1] > location))))
+ {
+
+ antibounce++;
+ //calculate step or use antibounce
+ if (abs ((int) d[loc] - (int) location) < 50
+ || antibounce > 100)
+ step = 1; //Go linear...
+ else
+ {
+ step =
+ (abs (d[loc] - location) * num) / totalrecord + 1;
+
+ }
+
+ kdDebug (KBABEL_SEARCH) << "Insert:" << location <<
+ " We are at: " << loc << " i.e. " << d[loc] << " Step:"
+ << step << endl;
+ if (loc > 0)
+ {
+ if (forward)
+ kdDebug (KBABEL_SEARCH) << "Go " << "forward" <<
+ " prev is " << d[loc - 1] << endl;
+ else
+ kdDebug (KBABEL_SEARCH) << "Go " << "backward" <<
+ " prev is " << d[loc - 1] << endl;
+ }
+
+ if (forward)
+ {
+ if (loc + step < num)
+ loc += step; // Go forward
+ else
+ loc = num; // Go to num
+ }
+ else
+ {
+ if (loc > step)
+ loc -= step; //Go backward
+ else
+ loc = 0; // Go to 0
+ }
+
+ //Now check if I am in the right place [THIS IS NOT NECESSARY]
+
+ //check if loc and loc -1 are well defined 1<loc<num-1
+ if (loc > num)
+ loc = num; //Must not happen, idem
+
+ if (loc == 0)
+ {
+ if (d[loc] > location)
+ end = true;
+ else
+ loc = 1;
+ }
+
+ if ((loc == num) && !end)
+ {
+ if (d[loc - 1] < location)
+ end = true;
+ else
+ loc = num - 1;
+ }
+
+ }
+
+ if (loc == num)
+ kdDebug (KBABEL_SEARCH) << "END" << endl;
+ if (loc == 0)
+ kdDebug (KBABEL_SEARCH) << "BEGIN" << endl;
+
+ if (loc > 0)
+ kdDebug (KBABEL_SEARCH) << location << " inserted between " <<
+ d[loc - 1] << " and " << d[loc] << endl;
+
+ if ((loc < num && location == d[loc]) || (loc > 0 && location == d[loc - 1])) //What about word repetition
+ {
+ free (keydata);
+ return true; //Why true ??
+ }
+
+
+
+//Now insert and put back in the database!
+ newdata = (char *) malloc (4 * (num + 3)); //uint32*(num+score+1..NUM+new)
+ memcpy (newdata, data.data, 4 + 4 + 4 * loc);
+ char *secondpart = (char *) data.data;
+ secondpart += 4 * (loc + 2);
+ memcpy ((newdata + 4 * (loc + 3)), secondpart, (num - loc) * 4);
+ uint32 *intdata = (uint32 *) newdata;
+ intdata[0] = num + 1;
+ //ADD HERE code to recalc score
+ intdata[loc + 2] = location;
+
+//ok send it to database!
+ memset (&data, 0, sizeof (DBT));
+
+ data.data = newdata;
+ data.size = 4 * (3 + num);
+ } //found sounthing
+ else
+ { //found nothing
+ newdata = (char *) malloc (4 * 3);
+ uint32 *intdata = (uint32 *) newdata;
+ intdata[0] = 1;
+ intdata[1] = 1;
+ intdata[2] = location;
+ memset (&data, 0, sizeof (DBT));
+ data.data = newdata;
+ data.size = 4 * 3;
+ }
+
+ memset (&key, 0, sizeof (DBT));
+//memset(&data,0,sizeof(DBT));
+
+ key.data = keydata;
+ key.size = intlen + 1;
+
+ ret = wordDb->put (wordDb, 0, &key, &data, 0); //DB_SET_RECNO);
+
+
+ free (newdata);
+ free (keydata);
+//return it;
+
+ return true;
+}
+
+
+bool
+DataBaseManager::removeLocation (QString /*word */ , int /*location */ )
+{
+
+//#warning TODO: REMOVE LOCATION
+ return true;
+
+}
+
+uint32
+DataBaseManager::appendKey (QString _key)
+{
+
+ DBT key;
+ DBT data;
+
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
+
+
+ uint32 ret = 0, err;
+ key.size = 4;
+ key.data = &ret;
+
+ data.size = strlen (_key.utf8 ()) + 1;
+ data.data = malloc (data.size);
+
+ strcpy ((char *) data.data, _key.utf8 ());
+
+ err = indexDb->put (indexDb, 0, &key, &data, DB_APPEND);
+
+ if (err)
+ ret = 0;
+ else
+ ret = *(uint32 *) key.data;
+
+//kdDebug(0) << QString("Append result %1,err = %1").arg(ret).arg(err) << endl;
+
+
+ free (data.data);
+
+ return ret;
+
+}
+
+QString
+DataBaseManager::getKey (uint32 n)
+{
+
+ DBT key;
+ DBT data;
+
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
+
+ key.data = &n;
+ key.size = 4;
+
+//Check for errors
+ int ret = indexDb->get (indexDb, 0, &key, &data, 0); //DB_SET_RECNO);
+ if (ret)
+ return QString::null;
+
+ return QString::fromUtf8 ((char *) data.data);
+
+// kdDebug(0) << QString("Trad %1").arg(ret) << endl;
+
+}
+
+int
+DataBaseManager::catalogRef (QString location, QString author, QString path)
+{
+ InfoItem cinfo;
+ int cat, catnum;
+ cat = searchCatalogInfo (location);
+
+ if (cat == -1) //Not exist
+ {
+ cinfo.catalogName = location;
+ cinfo.lastTranslator = author;
+ cinfo.lastFullPath = path;
+ //TO DO:
+ // //Add date info
+
+ kdDebug (0) << "New catalog " << endl;
+ catnum = addCatalogInfo (&cinfo);
+ //sync();
+ kdDebug (0) << "Ref " << catnum << endl;
+ }
+ else
+ {
+ cinfo = getCatalogInfo (cat);
+ //Update date.
+
+ //last path must be updated
+ cinfo.lastFullPath = path;
+ kdDebug (0) << "New full path " << path << endl;
+ kdDebug (0) << "Ref " << cat << endl;
+
+ catnum = addCatalogInfo (&cinfo, cat);
+ kdDebug (0) << " must be equal to " << catnum << endl;
+
+ catnum = cat;
+ }
+
+ return catnum;
+}
+
+int
+DataBaseManager::putNewTranslation (QString key, QString tran, int catalog,
+ bool ow)
+{
+ int catnum = catalog;
+ int count = 0;
+ QString msgid = key;
+ DataBaseItem dbit = getItem (msgid);
+
+ if (dbit.numTra == 0) //Not found
+ {
+ dbit.numTra += 1;
+
+ // use local variable, dbit.translations is QValueList and
+ // will create own copy
+ TranslationItem tra;
+ tra.numRef = 1;
+ tra.translation = tran;
+ tra.infoRef.append (catnum);
+ dbit.translations.append (tra);
+ dbit.key = key;
+
+ //Check ret value
+ count++;
+
+ int aa = putItem (&dbit);
+ if (aa)
+ kdDebug (0) << QString ("-----------put code ") << aa << endl;
+ }
+ else
+ {
+ // key exists
+
+ QString msgstr = tran;
+ bool found_catalog_info = false, foundTr = false, isThisOne = false;
+
+ QValueList < TranslationItem >::Iterator ittr;
+ bool rem = false;
+
+ // check all translations in the list
+ for (ittr = dbit.translations.begin ();
+ ittr != dbit.translations.end (); rem ? ittr : ++ittr)
+ {
+ rem = false;
+ found_catalog_info = false;
+
+ // is the translation one we should put there?
+ isThisOne = (*ittr).translation == msgstr;
+
+ // is there the catnum we are looking for?
+ if ((*ittr).infoRef.find (catnum) != (*ittr).infoRef.end ())
+ {
+ found_catalog_info = true;
+ if (ow && !isThisOne)
+ {
+ // I'll look for my catalog reference to del old
+ kdDebug (0) << "Removing the old translation " << endl;
+ (*ittr).numRef -= 1;
+ (*ittr).infoRef.remove (catnum);
+ if ((*ittr).numRef == 0)
+ {
+ dbit.numTra -= 1;
+ // point the iterator to the next valid item
+ ittr = dbit.translations.remove (ittr);
+ rem = true;
+ }
+ }
+ }
+
+ if (isThisOne)
+ {
+ if (!found_catalog_info)
+ {
+ //There are no reference of this catalog for this translation => add it
+ (*ittr).infoRef.append (catnum);
+ (*ittr).numRef += 1;
+ }
+ foundTr = true; // Ok, we found this translation, no need to add it.
+ }
+ }
+
+ if (!foundTr) //This translation is new => Add it !
+ {
+ count++;
+ TranslationItem tra;
+ tra.numRef = 1;
+ tra.translation = msgstr;
+ tra.infoRef.append (catnum);
+
+ dbit.translations.append (tra);
+ dbit.numTra += 1;
+ }
+
+ //put the new item in database overwriting the old one.
+ //Check ret value
+ int aa = putItem (&dbit, true);
+ if (aa)
+ kdDebug (0) << QString ("-----------put code ") << aa << endl;
+
+ }
+ return count;
+}
+
+
+void
+DataBaseManager::rebuildIndexes ()
+{
+// uint32 loc;
+#if 0
+//Reset the 2 databases here.
+
+ while (0 /*browse keys here */ )
+ {
+ loc = item->location = appendKey (item->key);
+
+ uint32 location = loc;
+
+ QValueList < QString > wlist;
+
+ wlist = wordsIn (item->key);
+
+ QValueList < QString >::Iterator wlistit;
+
+ for (wlistit = wlist.begin (); wlistit != wlist.end (); ++wlistit)
+ {
+ addLocation (*wlistit, location);
+ }
+
+ }
+#endif
+}
+
+
+
+#include "database.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/database.h b/kbabel/kbabeldict/modules/dbsearchengine/database.h
new file mode 100644
index 00000000..bf4767df
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/database.h
@@ -0,0 +1,329 @@
+/***************************************************************************
+ database.h -
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000 by Andrea Rizzi
+ email : rizzi@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. *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+/*
+ Translation search engine
+
+
+ Copyright 2000
+ Andrea Rizzi rizzi@kde.org
+
+*/
+
+
+#ifndef _DATABASE_H_
+#define _DATABASE_H_
+
+#include <config.h>
+
+#ifdef USE_DB_H_PATH
+#include USE_DB_H_PATH
+#else
+#ifdef HAVE_DB4_DB_H
+#include <db4/db.h>
+#else
+#include <db.h>
+#endif
+#endif
+
+#define uint32 u_int32_t
+
+#include <qvaluelist.h>
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qobject.h>
+#include <qdatetime.h>
+#include <qcstring.h> //bytearray
+
+
+class WordItem // Returned by getWordLocations
+{
+ public:
+
+ WordItem(char *data,QString w);
+ WordItem(QString w);
+ //WordItem(const WordItem &wi);
+ //WordItem& operator=(const WordItem & wi );
+
+ //The word (key in database)
+ QString word;
+ //Sorted locations
+ //QByteArray locations; //too many problems with this..
+ //NOTE:
+ //This is allocated only if you call WordItem(char *data,QString w);
+ //YOU MUST FREE IT when you do not need it anymore
+ //No destructor will do it !!!
+
+ uint32 *locations;
+
+
+ uint32 count;
+ //Is this word common ?
+ int score;
+
+ bool notFound();
+};
+
+
+class InfoItem
+{
+ public:
+
+ //Create the NO INFO item
+ InfoItem();
+
+ // Create an info item from raw data
+ InfoItem(const char *rawData,QString lang);
+
+ QString catalogName;
+ QString lastFullPath;
+
+ QString lastTranslator;
+ QDateTime revisionDate;
+ QString charset;
+ QString language;
+
+
+ int size();
+ void rawData(char *);
+
+};
+
+class TranslationItem
+{
+ public:
+ QString translation;
+ QValueList<int> infoRef;
+ uint32 numRef;
+
+};
+
+class DataBaseItem
+{
+ public:
+ /*
+ Create empty class;
+ */
+ DataBaseItem();
+
+ /*
+ Create a DataBaseItem from raw data
+ */
+ DataBaseItem(char *_key,char *_data);
+
+ /*
+ return the size (in raw data) of this item.
+ */
+ uint32 sizeData();
+ uint32 sizeKey();
+
+ bool isNull() { return (numTra==0); }
+
+ /*
+ You MUST allocate data of sizeData() byte.
+ */
+ void toRawData(char *_data);
+ void toRawKey(char *_key);
+
+ QString key;
+ QValueList<TranslationItem> translations;
+ uint32 numTra;
+ uint32 location;
+};
+
+class DataBaseManager : public QObject
+{
+
+ Q_OBJECT
+
+ public:
+ /*
+ Main constructor.
+ directory is the name of the directory where the database structre
+ is stored.
+
+ DIRECTORY/translations.$LANG.db The trasnaltion archive
+ DIRECTORY/catalogsinfo.$LANG.db Info about catalogs
+
+ //Not yet implemented
+ DIRECTORY/wordsindex.$LANG.db Index of words
+
+
+ */
+
+ DataBaseManager(QString directory,QString lang,QObject *parent=0,const char *name=0);
+ ~DataBaseManager();
+ /*
+ Create a new databse structure.
+
+ */
+ int createDataBase(QString directory,QString language,int mode=0664);
+
+
+
+
+ /*
+ Put a DataBaseItem into the database.
+
+ if ow==false enter the new DataBaseItem only
+ if the key of DataBaseItem does not previously exist
+
+ It also update the wordIndex.
+
+ */
+
+ int putItem(DataBaseItem *item,bool ow=false);
+
+ DataBaseItem getItem(QString key);
+
+ /*
+ @return the first entry in the database.
+ */
+
+ DataBaseItem firstItem();
+
+ /*
+ @return the current entry of the database.
+ */
+
+ DataBaseItem currentItem();
+
+ /*
+ @return the next entry in the database.
+ */
+
+ DataBaseItem nextItem();
+
+
+ /*
+ * Add a new translation to the database
+ * catalog is a valid catalog refnum (use catalogRef to get one)
+ * if ow is true a translation of a key coming from catalog is
+ * overwritten if you provide a new translation
+ */
+
+ int putNewTranslation(QString key,QString tran,int catalog,bool ow=true);
+
+ /*
+ @return info about catalog n
+ */
+
+ InfoItem getCatalogInfo(int n);
+
+ /*
+ Add an entry to catalogsinfo database and
+ @return a refnum for the new added item
+ */
+
+ int addCatalogInfo(InfoItem *catInfo,int);
+
+ /*
+ Search an Item with the same "location" and
+ @return its refnum.
+ */
+
+ int searchCatalogInfo(QString location);
+
+ /* Get a catalog info for location,
+ * if it doesn't exist it will create one.
+ * @return the refnum
+ */
+
+ int catalogRef(QString location,QString author,QString path);
+
+ /*
+ Put at refnum the catInfo
+ @return true if everything is OK
+ */
+
+ bool putCatalogInfo(int refnum, InfoItem *catInfo);
+
+ /*
+ Get word info
+ */
+ WordItem getWordLocations(QString word);
+
+ /*
+ Add a location for word
+ */
+ bool addLocation(QString word, unsigned int location);
+
+ /*
+ Remove location for word
+ */
+ bool removeLocation(QString word, int location);
+
+
+ /*
+ * Rebuild location and word indexes
+ */
+ void rebuildIndexes();
+
+ uint32 appendKey(class QString);
+
+ QString getKey(uint32 n);
+
+ /*
+ Load the catalogs info.
+ */
+ void loadInfo();
+
+
+ void sync();
+
+ bool isOk();
+ int count();
+ int current();
+
+ void openDataBase();
+ void closeDataBase();
+
+ static QValueList<QString> wordsIn(QString string);
+
+ signals:
+
+ void cannotOpenDB(int);
+
+
+ protected:
+ DataBaseItem cursorGet(uint32 flags);
+
+ QString language;
+ QString basedir;
+ QValueList<InfoItem> info;
+
+ DB *db,*infoDb,*wordDb,*indexDb;
+ DBC *cursor;
+ bool iAmOk;
+ bool indexOk; //Database could word without word index
+};
+
+
+
+
+
+#endif
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/dbscan.cpp b/kbabel/kbabeldict/modules/dbsearchengine/dbscan.cpp
new file mode 100644
index 00000000..87b39e61
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/dbscan.cpp
@@ -0,0 +1,197 @@
+/***************************************************************************
+ dbscan.cpp - Scan for po files to add in the DB
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000 by Andrea Rizzi
+ email : rizzi@kde.org
+ ***************************************************************************/
+
+/*
+ Translation search engine
+
+
+ Copyright 2000
+ Andrea Rizzi rizzi@kde.org
+
+ License GPL v 2.0
+
+ * *
+ * 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 "dbscan.h"
+
+#include <qdir.h>
+#include <qfile.h>
+#include <kapplication.h>
+#include <kurl.h>
+#include <kdebug.h>
+
+using namespace KBabel;
+
+PoScanner::PoScanner(DataBaseManager *dbm,
+ QObject *parent,const char *name):QObject(parent,name)
+{
+dm=dbm;
+removeOldCatalogTranslation=false; //Check if this flag do something.
+count=0;
+}
+
+bool PoScanner::scanPattern(QString pathName,QString pattern,bool rec)
+{
+int tot;
+
+//Only one progress bar!!
+bool pb=false;
+static bool called=false;
+if (!called)
+{ pb=true; count=0;}
+called=true;
+
+kdDebug(0) << QString("cat: %1, %2").arg(pathName).arg(pattern) << endl;
+
+if(pb)
+{emit patternStarted();
+emit patternProgress(0);
+}
+ QDir d(pathName,pattern);
+ d.setMatchAllDirs(true);
+ const QFileInfoList* files = d.entryInfoList();
+ tot=files->count();
+ QPtrListIterator<QFileInfo> it(*files);
+kdDebug(0) << tot << endl;
+ for ( int i=0; i<tot; i++ )
+ {
+ if ((*it)->isDir())
+ {
+ if(rec)
+ {
+ kdDebug(0) << d[i] << endl;
+ if(d[i]!="." && d[i]!="..")
+ scanPattern(pathName+"/"+d[i],pattern,true);
+ }
+ } else
+ {
+ kdDebug(0) << d[i] << endl;
+ scanFile(pathName+"/"+d[i]);
+ }
+
+ if(pb)
+
+ emit patternProgress(100*i/tot);
+
+ //printf( "%s\n", d[i] );
+
+ ++it;
+ }
+
+
+
+if(pb)
+emit patternProgress(100);
+
+
+if(pb)
+emit patternFinished();
+if(pb){called=false;count=0;}
+
+return true;
+}
+
+
+
+
+bool PoScanner::scanFile(QString fileName)
+{
+
+
+emit fileStarted();
+
+InfoItem cinfo;
+Catalog * catalog=new Catalog(this,"ScanPoCatalog");
+
+
+QString location=fileName.right(fileName.length()-fileName.findRev("/")-1);
+connect(catalog,SIGNAL(signalProgress(int)),this,SIGNAL(fileLoading(int)));
+emit filename(location);
+emit fileProgress(0);
+emit fileLoading(0);
+
+KURL u(fileName);
+
+ConversionStatus rr=catalog->openURL(u);
+if(rr != OK && rr !=RECOVERED_PARSE_ERROR )
+{
+ delete catalog;
+ return false;
+}
+emit fileLoading(100);
+
+QString author;
+if(rr != HEADER_ERROR)
+ author=catalog->lastTranslator();
+else author=QString("unknown");
+
+int catnum=dm->catalogRef(location,author,fileName);
+
+uint i,tot;
+tot=catalog->numberOfEntries();
+//DataBaseItem dbit;
+bool fuzzy;
+bool untra;
+
+//kdDebug(0) << QString("Tot: %1").arg(tot) << endl;
+
+for (i=0;i<tot;i++) //Skip header = ????
+{
+
+ //Faster ?
+ if(i % 10==0)
+ {
+ emit fileProgress(100*i/tot);
+ emit added(count);
+ kapp->processEvents(100);
+ }
+
+ fuzzy=catalog->isFuzzy(i);
+ untra=catalog->isUntranslated(i);
+
+
+ if(!fuzzy && !untra)
+ {
+ int res;
+ QString msgid,msgstr;
+ msgid=catalog->msgid(i,true).first();
+ kdWarning() << "Translation database does not support plural forms" << endl;
+ msgstr=catalog->msgstr(i).first();
+ res=dm->putNewTranslation(msgid,msgstr,catnum,false);
+ count+=res;
+ }
+
+
+}
+
+
+// kdDebug(0) << QString("File finished") << endl;
+
+emit fileProgress(0);
+emit fileLoading(0);
+emit fileFinished();
+// dm->loadInfo(); // Sync the list of catalogs NOT NEEDED (?)
+
+delete catalog;
+
+//clear();
+return true;
+
+}
+#include "dbscan.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/dbscan.h b/kbabel/kbabeldict/modules/dbsearchengine/dbscan.h
new file mode 100644
index 00000000..c151509e
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/dbscan.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ dbscan.h -
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000 by Andrea Rizzi
+ email : rizzi@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. *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+/*
+ Translation search engine
+
+
+ Copyright 2000
+ Andrea Rizzi rizzi@kde.org
+
+*/
+
+
+#ifndef _DBSCAN_H_
+#define _DBSCAN_H_
+
+#include <catalog.h>
+#include "database.h"
+
+class PoScanner : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ PoScanner(DataBaseManager *dbm,QObject *parent=0,const char *name=0);
+
+ /*
+ Scan a single PO file.
+ */
+ bool scanFile(QString fileName);
+
+ /*
+ Scan a list of space separated files with possible MetaCharacters
+ */
+ bool scanPattern(QString pathName,QString pattern="*.po",bool rec=false);
+
+
+
+
+signals:
+ void fileStarted();
+ void fileProgress(int);
+ void fileFinished();
+ void fileLoading(int);
+ void patternStarted();
+ void patternProgress(int);
+ void patternFinished();
+ void added(int);
+ void filename(QString);
+private:
+
+ // If true when a translation is found in a CATALOG the old translation for this CATALOG
+ // will be removed
+ bool removeOldCatalogTranslation;
+ int count;
+ DataBaseManager *dm;
+// InfoItem cinfo;
+};
+
+
+#endif
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/dbse_factory.cpp b/kbabel/kbabeldict/modules/dbsearchengine/dbse_factory.cpp
new file mode 100644
index 00000000..37332167
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/dbse_factory.cpp
@@ -0,0 +1,82 @@
+
+#include <klocale.h>
+#include <kinstance.h>
+#include <kaboutdata.h>
+#include <kdebug.h>
+
+#include "dbse_factory.h"
+#include "KDBSearchEngine.h"
+
+
+extern "C"
+{
+ KDE_EXPORT void *init_kbabeldict_dbsearchengine()
+ {
+ return new DbSeFactory;
+ }
+}
+
+
+KInstance *DbSeFactory::s_instance = 0;
+KAboutData *DbSeFactory::s_about = 0;
+
+
+DbSeFactory::DbSeFactory( QObject *parent, const char *name)
+ : KLibFactory(parent,name)
+{
+}
+
+DbSeFactory::~DbSeFactory()
+{
+ if(s_instance)
+ {
+ delete s_instance;
+ s_instance=0;
+ }
+
+ if(s_about)
+ {
+ delete s_about;
+ s_about=0;
+ }
+}
+
+
+QObject *DbSeFactory::createObject( QObject *parent, const char *name,
+ const char *classname, const QStringList &)
+{
+ if(QCString(classname) != "SearchEngine")
+ {
+ kdError() << "not a SearchEngine requested" << endl;
+ return 0;
+ }
+
+ KDBSearchEngine *se = new KDBSearchEngine(parent,name);
+
+ emit objectCreated(se);
+ return se;
+}
+
+
+KInstance *DbSeFactory::instance()
+{
+ if(!s_instance)
+ {
+
+ s_about = new KAboutData( "kdbsearchengine",
+ I18N_NOOP("Translation Database")
+ , "0.3" ,
+I18N_NOOP("A fast translation search engine based on databases")
+ , KAboutData::License_GPL
+ , I18N_NOOP("Copyright 2000-2001 by Andrea Rizzi")
+ ,0,0, "rizzi@kde.org");
+
+ s_about->addAuthor("Andrea Rizzi",0,"rizzi@kde.org");
+
+ s_instance = new KInstance(s_about);
+ }
+
+ return s_instance;
+}
+
+#include "dbse_factory.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/dbse_factory.h b/kbabel/kbabeldict/modules/dbsearchengine/dbse_factory.h
new file mode 100644
index 00000000..6a9f9f3d
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/dbse_factory.h
@@ -0,0 +1,26 @@
+#ifndef DBSE_FACTORY_H
+#define DBSE_FACTORY_H
+
+#include <klibloader.h>
+class KInstance;
+class KAboutData;
+
+class DbSeFactory : public KLibFactory
+{
+ Q_OBJECT
+public:
+ DbSeFactory( QObject *parent=0, const char *name=0);
+ ~DbSeFactory();
+
+ 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/dbsearchengine/dbsearchengine.desktop b/kbabel/kbabeldict/modules/dbsearchengine/dbsearchengine.desktop
new file mode 100644
index 00000000..6aed2e40
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/dbsearchengine.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Type=Service
+Name=Translation Database for KBabelDict
+Name[bg]=БД с преводи за KBabelDict
+Name[br]=Stlennvon geriaoueg evit KBabelDict
+Name[bs]=Baza prijevoda za KBabelDict
+Name[ca]=Base de dades de traducció per a KBabelDict
+Name[cs]=Databáze překladů pro KBabelDict
+Name[cy]=Cronfa ddata Cyfieithiadau i KBabelDict
+Name[da]=Oversættelsesdatabase for KBabelDict
+Name[de]=Übersetzungsdatenbank für KBabelDict
+Name[el]=Βάση δεδομένων μετάφρασης για το KBabelDict
+Name[es]=Base de datos de traducciones para KBabelDict
+Name[et]=KBabelDicti tõlgete andmebaas
+Name[eu]=Itzulpen datu-basea KBabelDict-entzat
+Name[fa]=دادگان ترجمه برای KBabelDict
+Name[fi]=KBabelDict-ohjelman käännöstietokanta
+Name[fr]=Base de données des traductions pour KBabelDict
+Name[ga]=Cuimhne Aistriúcháin le haghaidh KBabelDict
+Name[gl]=Base de datos de traducións de KBabelDict
+Name[hi]=के-बेबल-डिक्श के लिए अनुवाद डाटाबेस
+Name[hu]=Fordítási adatbázis a KBabelDicthez
+Name[is]=Þýðingagagnagrunnur fyrir KBabel orðabókina
+Name[it]=Banca dati di traduzioni per KBabelDict
+Name[ja]=KBabelDict トランザクションデータベース
+Name[ka]=თარგმნის მონაცემთა ბაზა KBabelDict-სთვის
+Name[kk]=KBabelDict-тың аударма деректер қоры
+Name[lt]=KBabelDict vertimų duomenų bazė
+Name[ms]=Pangkalan Data Penterjemahan KBabelDict
+Name[nb]=Oversettelsesdatabase for KBabelDict
+Name[nds]=Översettendatenbank för KBabelDict
+Name[ne]=KBabelDict का लागि अनुबाद डाटाबेस
+Name[nl]=Vertalingendatabase voor KBabelDict
+Name[nn]=Omsetjingsdatabase for KBabelDict
+Name[pa]=ਕੇਬਬੇਲ-ਸ਼ਬਦ-ਕੋਸ਼ ਲਈ ਅਨੁਵਾਦ ਡਾਟਾਬੇਸ
+Name[pl]=Baza tłumaczeń dla KBabelDict
+Name[pt]=Base de Dados de Traduções do KBabelDict
+Name[pt_BR]=Banco de Dados de Traduções para o KBabelDict
+Name[ru]=База данных переводов для KBabelDict
+Name[sk]=Databáza prekladov pre KBabelDict
+Name[sl]=Zbirka prevodov za KBabelDict
+Name[sr]=Преводилачка база података за KBabelDict
+Name[sr@Latn]=Prevodilačka baza podataka za KBabelDict
+Name[sv]=Översättningsdatabas för Kbabeldict
+Name[ta]=Kபாபேலுக்கான மொழிபெயர்ப்பு தரவுத்தளம்
+Name[tg]=Базаи маълумоти тарҷумаҳо барои KBabelDict
+Name[tr]=KBabelDict için Çeviri Veritabanı
+Name[uk]=База даних перекладів для KBabelDict
+Name[zh_CN]=KBabelDict 的翻译数据库
+Name[zh_TW]=KBabelDict 翻譯資料庫
+X-KDE-Library=kbabeldict_dbsearchengine
+ServiceTypes=KBabelDictModule
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/dbseprefwidget.ui b/kbabel/kbabeldict/modules/dbsearchengine/dbseprefwidget.ui
new file mode 100644
index 00000000..d18ecaef
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/dbseprefwidget.ui
@@ -0,0 +1,1036 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>DBSearchEnginePref</class>
+<author>Andrea Rizzi &lt;rizzi@kde.org&gt;</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>DBSEPrefWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>414</width>
+ <height>426</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>TabWidget6</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string></string>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget4</cstring>
+ </property>
+ <attribute name="title">
+ <string>Generic</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>ButtonGroup2</cstring>
+ </property>
+ <property name="title">
+ <string>Search Mode</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>allRB</cstring>
+ </property>
+ <property name="text">
+ <string>Search in whole database (slow)</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Scroll the whole database and return everything that matches
+according to the rules defined in tabs &lt;strong&gt; Generic &lt;/strong&gt;
+and &lt;strong&gt;Match&lt;/strong&gt;</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>slistRB</cstring>
+ </property>
+ <property name="text">
+ <string>Search in list of "good keys" (best)</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Search in a list of &lt;em&gt;good keys&lt;/em&gt; (see &lt;strong&gt;Good keys&lt;/strong&gt; tab) with rules defined in &lt;strong&gt;Search&lt;/strong&gt; tab.
+This is the best way to search because the &lt;em&gt;good keys&lt;/em&gt; list probably contains all the keys that match with your query. However, it is smaller than the whole database.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="2" column="0">
+ <property name="name">
+ <cstring>rlistRB</cstring>
+ </property>
+ <property name="text">
+ <string>Return the list of "good keys" (fast)</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Returns the whole &lt;em&gt;good keys&lt;/em&gt; list. Rules defined in &lt;strong&gt;Search&lt;/strong&gt; tab are ignored.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>caseSensitiveCB</cstring>
+ </property>
+ <property name="text">
+ <string>Case sensitive</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;If it is checked the search will be case sensitive. It is ignored if you use &lt;em&gt;Return the list of "good keys"&lt;/em&gt; search mode.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>normalizeCB</cstring>
+ </property>
+ <property name="text">
+ <string>Normalize white space</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Remove white spaces at the beginning and at the end of the phrase.
+It also substitutes groups of more than one space character with only one space character.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>removeContextCB</cstring>
+ </property>
+ <property name="text">
+ <string>Remove context comment</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Remove, if exists, the _:comment</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout11</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Character to be ignored:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>ignoreLE</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget5</cstring>
+ </property>
+ <attribute name="title">
+ <string>Search</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>ButtonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Matching Method</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>Spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>Spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="2" column="1">
+ <property name="name">
+ <cstring>containedCB</cstring>
+ </property>
+ <property name="text">
+ <string>Query is contained</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Match if query is contained in database string</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="1">
+ <property name="name">
+ <cstring>containsCB</cstring>
+ </property>
+ <property name="text">
+ <string>Query contains</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Match if query contains the database string</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>normalTextRB</cstring>
+ </property>
+ <property name="text">
+ <string>Normal text</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Consider the search string as normal text.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>equalCB</cstring>
+ </property>
+ <property name="text">
+ <string>Equal</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="tristate">
+ <bool>false</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Match if query and database string are equal</string>
+ </property>
+ </widget>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>Spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QRadioButton" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>RegExpRB</cstring>
+ </property>
+ <property name="text">
+ <string>Regular expression</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Consider the search string as a regular expression</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>GroupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Word Substitution</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;If you use one or two &lt;em&gt;word substitution&lt;/em&gt; each time you search a phrase with less than the specified number of words, the search engine will also search for all phrases that differ from the original one in one or two words.&lt;p&gt;
+&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
+If you search for &lt;em&gt;My name is Andrea&lt;/em&gt; and you have activated &lt;em&gt;one word substitution&lt;/em&gt; you may also find phrases like &lt;em&gt;My name is Joe&lt;/em&gt; or &lt;em&gt;Your name is Andrea&lt;/em&gt;.</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>Spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>oneWordSubCB</cstring>
+ </property>
+ <property name="text">
+ <string>Use one word substitution</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="tristate">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>Spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Max number of words in the query:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="2">
+ <property name="name">
+ <cstring>twoWordSubSB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maxValue">
+ <number>14</number>
+ </property>
+ <property name="value">
+ <number>10</number>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>twoWordSubCB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Use two word substitution</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Max number of words in the query:</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="5" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Layout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel5_3</cstring>
+ </property>
+ <property name="text">
+ <string>[A-Za-z0-9_%</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>regExpLE</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel6_2</cstring>
+ </property>
+ <property name="text">
+ <string>]</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="4" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Local characters for regular expressions:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="2">
+ <property name="name">
+ <cstring>oneWordSubSB</cstring>
+ </property>
+ <property name="maxValue">
+ <number>200</number>
+ </property>
+ <property name="minValue">
+ <number>2</number>
+ </property>
+ <property name="value">
+ <number>40</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget6</cstring>
+ </property>
+ <attribute name="title">
+ <string>Database</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>TextLabel7_2</cstring>
+ </property>
+ <property name="text">
+ <string>Database folder:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>dirInput</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>autoAddCB_2</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Auto add entry to database</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Automatically add an entry to the database if a new translation is notified by someone (may be kbabel)</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1_4</cstring>
+ </property>
+ <property name="text">
+ <string>Auto added entry author:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>authorLE</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Put here the name and email address that you want to use as &lt;em&gt;last translator&lt;/em&gt; filed when you auto-add entry to the database (e.g. when you modify a translation with kbabel).&lt;p&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QPushButton" row="4" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>scanFilePB</cstring>
+ </property>
+ <property name="text">
+ <string>Scan Single PO File...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="5" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>scanPB_2</cstring>
+ </property>
+ <property name="text">
+ <string>Scan Folder...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="6" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>scanrecPB</cstring>
+ </property>
+ <property name="text">
+ <string>Scan Folder &amp;&amp; Subfolders...</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="8" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Layout5</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>filenameLB</cstring>
+ </property>
+ <property name="text">
+ <string>Scanning file:</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>entriesLB</cstring>
+ </property>
+ <property name="text">
+ <string>Entries added:</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="9" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QProgressBar" row="2" column="1">
+ <property name="name">
+ <cstring>processPB</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="centerIndicator">
+ <bool>true</bool>
+ </property>
+ <property name="indicatorFollowsStyle">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Total progress:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>TextLabel3_3</cstring>
+ </property>
+ <property name="text">
+ <string>Processing file:</string>
+ </property>
+ </widget>
+ <widget class="QProgressBar" row="0" column="1">
+ <property name="name">
+ <cstring>totalPB</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="centerIndicator">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QProgressBar" row="1" column="1">
+ <property name="name">
+ <cstring>loadingPB</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="centerIndicator">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Loading file:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QPushButton" row="10" column="2">
+ <property name="name">
+ <cstring>exportPB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Export...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="10" column="0">
+ <property name="name">
+ <cstring>statPB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Statistics</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="10" column="1">
+ <property name="name">
+ <cstring>repeatPB</cstring>
+ </property>
+ <property name="text">
+ <string>Repeated Strings</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Good Keys</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>GroupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Generic</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Here you can define how to fill the &lt;em&gt;good keys list&lt;/em&gt;.&lt;p&gt;
+You can set the minimum number of words of the query that a key must have to be inserted in the &lt;em&gt;good keys list&lt;/em&gt;.&lt;p&gt;
+You can also set the minimum number of words of the key that the query must have to insert the key in the list.&lt;p&gt;
+These two numbers are the percentage of the total number of words. If the result of this percentage is less than one, the engine will set it to one.&lt;p&gt;
+Finally you can set the maximum number of entries in the list.</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Minimum number of words of the key also in the query (%):</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ <widget class="QSlider" row="1" column="0">
+ <property name="name">
+ <cstring>thresholdSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>SpinBox5</cstring>
+ </property>
+ <property name="suffix">
+ <string>%</string>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Minimum number of query words in the key (%):</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="4" column="1">
+ <property name="name">
+ <cstring>maxSB</cstring>
+ </property>
+ <property name="maxValue">
+ <number>5000</number>
+ </property>
+ <property name="value">
+ <number>30</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="1">
+ <property name="name">
+ <cstring>SpinBox6</cstring>
+ </property>
+ <property name="suffix">
+ <string>%</string>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>TextLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>Max list length:</string>
+ </property>
+ </widget>
+ <widget class="QSlider" row="3" column="0">
+ <property name="name">
+ <cstring>thresholdOrigSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>GroupBox3_2</cstring>
+ </property>
+ <property name="title">
+ <string>Frequent Words</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Discard words more frequent than:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>freqSB</cstring>
+ </property>
+ <property name="suffix">
+ <string>/10000</string>
+ </property>
+ <property name="maxValue">
+ <number>10000</number>
+ </property>
+ <property name="lineStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>nothingCB</cstring>
+ </property>
+ <property name="text">
+ <string>Frequent words are considered as in every key</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>thresholdSL</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>SpinBox5</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>thresholdOrigSL</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>SpinBox6</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>SpinBox5</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>thresholdSL</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>SpinBox6</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>thresholdOrigSL</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in declaration">klocale.h</include>
+ <include location="global" impldecl="in declaration">kseparator.h</include>
+</includes>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/makemsgdb.C b/kbabel/kbabeldict/modules/dbsearchengine/makemsgdb.C
new file mode 100644
index 00000000..a83d947b
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/makemsgdb.C
@@ -0,0 +1,327 @@
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <gdbm.h>
+#include <string.h>
+
+void removechar (char *s, int c)
+{
+ int i, l;
+ l = strlen (s);
+ if ((c >= l) || (c < 0))
+ return;
+ for (i = c; i < l; i++)
+ s[i] = s[i + 1];
+}
+void removeallc (char *s, char c)
+{
+ char *pos;
+ while ((pos = strchr (s, c)) != 0)
+ removechar (s, (long int) pos - (long int) s);
+
+}
+
+void normalizestr (char *s)
+{
+ char *pos;
+ while ((pos = strstr (s, "#~")) != 0) {
+ removechar (s, (long int) pos - (long int) s);
+ removechar (s, (long int) pos - (long int) s);
+ }
+ while (strchr (s, ' ') == s)
+ removechar (s, 0);
+}
+
+void freadline(char *buff,FILE *f)
+{
+char c;
+while ((fread(&c,1,1,f)==1) && (c!='\n'))
+ {
+ *buff=c;
+ buff++;
+ }
+*buff=0;
+
+}
+
+int makePoDb(const char* sourceName,const char* outputName)
+{
+static bool open = false;
+int m=0,n=0,h=0;
+GDBM_FILE db;
+datum key,value;
+char *s,a[20000],b[2000],k[2000],v[2000];
+int i,*np,nmax=0,co=-1,oldref[2000];
+long int tim;
+FILE *mlf;
+bool nextIsFuzzy;
+bool isAMsgId=true;
+/* char keystring[1000],valuestring[1000]; */
+
+/*Read headers, refnum end other info */
+db = gdbm_open((char *)outputName,1024,GDBM_READER,0666,0);
+mlf = fopen(sourceName,"r");
+if(strrchr(sourceName,'/')!=0)
+sourceName=strrchr(sourceName,'/')+1;
+
+if(!(db==0))
+ {
+ printf("ciao\n");
+ key.dptr=a;
+ strcpy(a,"__@REFNUM__");
+ key.dsize=strlen(a)+1;
+ value = gdbm_fetch(db,key);
+ np=(int*)value.dptr;
+ nmax=*np;
+ for(i=0;i<nmax;i++) {
+ sprintf(a,"__@%d__",i);
+ key.dsize=strlen(a)+1;
+ value = gdbm_fetch(db,key);
+ if(strcmp(value.dptr,sourceName)==0)
+ oldref[++co]=i;
+ // printf("File %s in Date %s\nRef # %d, oldref[%d]=%d\n",value.dptr,value.dptr+1+strlen(value.dptr),i,co,oldref[co]);
+ }
+ gdbm_close(db);
+ }
+
+
+db = gdbm_open((char *)outputName,1024,GDBM_WRCREAT,0666,0);
+if(db==0) return 0;
+
+nmax++;
+//sourceName=strrchr(sourceName,'/')+1;
+ if(open) return 0;
+ open=true;
+
+ key.dptr=a;
+ strcpy(a,"__@REFNUM__");
+ key.dsize=strlen(a)+1;
+ value.dptr=(char *)&nmax;
+ value.dsize=4;
+ gdbm_store(db,key,value,GDBM_REPLACE);
+ sprintf(a,"__@%d__",nmax-1);
+ key.dsize=strlen(a)+1;
+ strcpy(v,sourceName);
+ value.dptr=v;
+ time(&tim);
+// ctime(&tim);
+ // fprintf(stderr,"%s %s\n",v,ctime(&tim));
+ strcpy(v+strlen(v)+1,ctime(&tim));
+ value.dsize=strlen(v)+2+strlen(v+strlen(v)+1);
+ gdbm_store(db,key,value,GDBM_REPLACE);
+
+ while(!feof(mlf))
+ {
+ freadline(a,mlf);
+ normalizestr(a);
+// printf("#%s#\n",a);
+
+// while (st.find("#~")==0)
+// st = st.right(st.length()-2);
+// while (st.find(" ")==0)
+// st = st.right(st.length()-1);
+
+ if(isAMsgId) nextIsFuzzy=false;
+ if(strstr(a,"#,")==a)
+ if(strstr(a,"fuzzy")!=0) nextIsFuzzy=true;
+ isAMsgId=(strstr(a,"msgid"));
+ if(isAMsgId && !nextIsFuzzy)
+ {
+ *b='\0';
+ clearerr(mlf);
+ while(!feof(mlf) && !(strstr(a,"msgstr")==a))
+ {
+ strcat(b,strchr(a,'"')+1);
+ *strrchr(b,'\"')= '\0'; //"
+ freadline(a,mlf);
+ normalizestr(a);
+
+
+ if(b+strlen(b)==strstr(b,"\\n")+2)
+ {
+ b[strlen(b)-2]='\n';
+ b[strlen(b)-1]='\0';
+ }
+ }
+
+ // fprintf(stderr,"MSGID#%s#\n",b);
+ //}
+
+ if(b[0]!='\0') {
+ key.dptr=k;
+ strcpy(k,b);
+ key.dsize=strlen(key.dptr)+1;
+ int lines=0;
+ *b='\0';
+ while(!feof(mlf) && !(strstr(a,"msgid")==a) && !(strchr(a,'"')==0))
+ {
+ lines++;
+ strcat(b,strchr(a,'"')+1);
+ *strrchr(b,'\"')= '\0'; //"
+ freadline(a,mlf);
+ normalizestr(a);
+
+
+ if(b+strlen(b)==strstr(b,"\\n")+2)
+ {
+ b[strlen(b)-2]='\n';
+ b[strlen(b)-1]='\0';
+ }
+ }
+ value.dptr=v;
+ int *t;
+ int *nr,*re; //,*md; //Number of references,ref
+
+ t=(int *)value.dptr;
+ *t=1;
+ strcpy(value.dptr+4,b);
+ nr=(int *)(value.dptr+4+strlen(value.dptr+4)+1);
+ *nr=1;
+ nr++;
+ *nr=nmax-1;
+ value.dsize=strlen(value.dptr+4)+1+4+8;
+ // fprintf(stderr,"MSGSTR#%s#nref=%d\n",value.dptr+4,
+// *(int*)(value.dptr+4+strlen(value.dptr+4)+1 ));
+
+ if(b[0]!='\0') {
+ if(gdbm_store(db,key,value,GDBM_INSERT))
+ {
+ // fprintf(stderr,"*** Key exists ***\n");
+
+ gdbm_sync(db);
+ gdbm_close(db);
+ db = gdbm_open((char *)outputName,1024,GDBM_READER,0,0);
+ datum oldvalue;
+ oldvalue= gdbm_fetch(db,key);
+ gdbm_sync(db);
+ gdbm_close(db);
+ db = gdbm_open((char *)outputName,1024,GDBM_WRCREAT,0,0);
+
+ t=(int *)oldvalue.dptr;
+ int i,r,j; //counters
+ int v=*t; //Number of strings
+ int *nr,*re,*md; //Number of references,ref
+ bool exist=false,here,modif=false;
+ char *os=oldvalue.dptr+4;
+ // fprintf(stderr,"**Searching string #%s#\n",b);
+ for(i=0;i<v;i++)
+ {
+
+ exist=false; //REMOVE THIS LINE!!!
+ here=false;
+ // fprintf(stderr,"**STRING %d #%s# len=%d %s\n",i,os,strlen(os),b);
+ if(strcmp(os,b)==0) {
+ exist=true;
+ here=true;
+ // fprintf(stderr,"That's good\n");
+ }
+ os+=strlen(os)+1; //End of string
+ nr=(int *)os;
+ os+=(*nr+1)*4;
+ re=nr;
+ modif=false;
+ // fprintf(stderr,"refernces %d\n",*nr);
+ for(j=0;j<*nr;j++)
+ {
+ re++;
+
+ if(here)
+ {
+ // printf("reference #%d\n",*re);
+ for(r=0;r<=co;r++)
+ {
+ // fprintf(stderr,"%d==%d ?-->",oldref[co],*re);
+ if(oldref[r]==*re)
+ {
+ modif=true;
+ // fprintf(stderr,"Yes\n");
+ *re=(nmax-1);
+ } //else fprintf(stderr,"No\n");
+ }
+ // fprintf(stderr,"qui\n");
+ if(!modif)
+ md=nr;
+ // fprintf(stderr,"modif %s\n",modif ? "true":"false");
+ }
+ }
+
+ }
+
+ if(!exist)
+ {
+ int oldlen=(long int)os-(long int)oldvalue.dptr-4;
+ memcpy(a+4,oldvalue.dptr+4,oldlen);
+// fprintf(stderr,"***!exist Old len is %d+4 1st str is %s\n",oldlen,a+4);
+ v++;
+ t=(int *)a;
+ *t=v;
+ // fprintf(stderr,"b=%s",b);
+ strcpy(a+4+oldlen,b);
+ re=(int *)(a+4+oldlen+strlen(b)+1);
+ *re=1;
+ re++;
+ *re=nmax-1;
+ //fprintf(stderr,"a+4=%s a+4+oldlen=%s",a+4,a+4+oldlen);
+ value.dptr=a;
+ value.dsize=oldlen+strlen(b)+1+4+8;
+ gdbm_store(db,key,value,GDBM_REPLACE);
+ n++;
+ } else
+ {
+ if(!modif)
+ {
+// fprintf(stderr,"grossa crisi %d\n",*md);
+// fprintf(stderr,"Old num of ref \n");
+ int oldlen1=(long int)(md)-(long int)(oldvalue.dptr)-4;
+ int oldlen2=(long int)(os)-(long int)(md)-4; //-4 because nr
+ memcpy(a+4,oldvalue.dptr+4,oldlen1);
+ memcpy(a+4+oldlen1+8,oldvalue.dptr+4+oldlen1+4,oldlen2);
+ re=(int *)(a+4+oldlen1);
+ *re=(*md )+1;
+ // *re++;
+ re++;
+ *re=nmax-1;
+ t=(int *)a;
+ *t=v;
+ value.dptr=a;
+ value.dsize=oldlen1+oldlen2+4+8;
+ gdbm_store(db,key,value,GDBM_REPLACE);
+ n++;
+ }
+ else //if (modif)
+ {
+ value.dptr=oldvalue.dptr;
+ value.dsize=oldvalue.dsize;
+ gdbm_store(db,key,value,GDBM_REPLACE);
+ }
+ }
+
+ h++;
+ } else {
+
+ m++;
+ }
+ }
+ }
+
+ }
+
+
+ }
+
+ fclose(mlf);
+ gdbm_close(db);
+ open=false;
+ printf("new Key in database %d\n old key found %d\n value added %d\n",m,h,n);
+ return m+n;
+}
+
+
+
+main(int argc,char **argv)
+{
+int i;
+for(i=1;i<argc;i++)
+ printf("File %s:\nEntry added to dbase: %d\n",argv[i],makePoDb(argv[i],"messages2.db"));
+
+}
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/preferenceswidget.cpp b/kbabel/kbabeldict/modules/dbsearchengine/preferenceswidget.cpp
new file mode 100644
index 00000000..3bb65934
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/preferenceswidget.cpp
@@ -0,0 +1,111 @@
+#include <qradiobutton.h>
+#include <qslider.h>
+#include <qspinbox.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <klocale.h>
+#include <kfiledialog.h>
+#include <kurlrequester.h>
+#include <qtoolbutton.h>
+#include <klineedit.h>
+#include <kstandarddirs.h>
+
+#include "dbseprefwidget.h"
+#include "preferenceswidget.h"
+
+PreferencesWidget::PreferencesWidget(QWidget *parent, const char* name)
+ : PrefWidget(parent,name)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+// QLabel *label = new QLabel(i18n("Settings for KDE database search engine"),this);
+// layout->addWidget(label);
+
+ dbpw = new DBSearchEnginePref(this);
+ dbpw->dirInput->setMode(KFile::Directory | KFile::LocalOnly);
+
+ layout->addWidget(dbpw);
+ resize(QSize(200,200).expandedTo(minimumSizeHint()));
+
+// connect(dbpw->browseTB_3,SIGNAL(clicked()),SLOT(browse1()));
+
+ emit restoreNow(); //Fill with actual params.
+
+}
+
+PreferencesWidget::~PreferencesWidget()
+{
+}
+
+void PreferencesWidget::apply()
+{
+emit applyNow();
+}
+
+void PreferencesWidget::cancel()
+{
+emit restoreNow();
+}
+
+void PreferencesWidget::standard()
+{
+
+
+dbpw->caseSensitiveCB->setChecked(false);
+dbpw->normalizeCB->setChecked(true);
+dbpw->removeContextCB->setChecked(true);
+
+dbpw->oneWordSubCB->setChecked(true);
+dbpw->twoWordSubCB->setChecked(false);
+
+
+dbpw->RegExpRB->setChecked(false);
+dbpw->normalTextRB->setChecked(true);
+dbpw->equalCB->setChecked( true );
+dbpw->containsCB->setChecked( true);
+dbpw->containedCB->setChecked( true );
+
+
+dbpw->oneWordSubSB->setValue(20);
+dbpw->twoWordSubSB->setValue(8);
+
+dbpw->maxSB->setValue(500);
+dbpw->thresholdSL->setValue(50);
+dbpw->thresholdOrigSL->setValue(50);
+
+dbpw->allRB->setChecked( false);
+dbpw->slistRB->setChecked( true);
+dbpw->rlistRB->setChecked( false );
+
+dbpw->nothingCB->setChecked(true);
+dbpw->freqSB->setValue(300);
+
+dbpw->ignoreLE->setText("&.:");
+
+dbpw->autoAddCB_2->setChecked(true);
+
+QString defaultDir;
+ KStandardDirs * dirs = KGlobal::dirs();
+ if(dirs)
+ {
+ defaultDir = dirs->saveLocation("data");
+ if(defaultDir.right(1)!="/")
+ defaultDir+="/";
+ defaultDir += "kbabeldict/dbsearchengine";
+ }
+
+ dbpw->dirInput->setURL(defaultDir);
+}
+
+void PreferencesWidget::setName(QString n)
+{
+dbpw->filenameLB->setText(i18n("Scanning file: %1").arg(n));
+}
+
+void PreferencesWidget::setEntries(int i)
+{
+dbpw->entriesLB->setText(i18n("Entries added: %1").arg(i));
+
+}
+
+#include "preferenceswidget.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine/preferenceswidget.h b/kbabel/kbabeldict/modules/dbsearchengine/preferenceswidget.h
new file mode 100644
index 00000000..599408cd
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine/preferenceswidget.h
@@ -0,0 +1,28 @@
+#ifndef PREFERENCESWIDGET_H
+#define PREFERENCESWIDGET_H
+
+#include "searchengine.h"
+#include "dbseprefwidget.h"
+
+class PreferencesWidget : public PrefWidget
+{
+ Q_OBJECT
+
+public:
+ PreferencesWidget(QWidget *parent=0, const char* name=0);
+ virtual ~PreferencesWidget();
+
+ virtual void apply();
+ virtual void cancel();
+ virtual void standard();
+ DBSearchEnginePref *dbpw;
+public slots:
+ void setName(QString);
+ void setEntries(int);
+signals:
+ void applyNow();
+ void restoreNow();
+
+};
+
+#endif
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/AUTHOR b/kbabel/kbabeldict/modules/dbsearchengine2/AUTHOR
new file mode 100644
index 00000000..2a79312d
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/AUTHOR
@@ -0,0 +1 @@
+Andrea Rizzi <rizzi@kde.org> \ No newline at end of file
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/KDBSearchEngine2.cpp b/kbabel/kbabeldict/modules/dbsearchengine2/KDBSearchEngine2.cpp
new file mode 100644
index 00000000..5bf088b8
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/KDBSearchEngine2.cpp
@@ -0,0 +1,686 @@
+/***************************************************************************
+ KDBSearchEngine2.cpp - description
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000-2003 by Andrea Rizzi
+ email : rizzi@kde.org
+***************************************************************************/
+
+/*
+ Translation search engine. Version II
+
+
+ Copyright 2000-2003
+ Andrea Rizzi rizzi@kde.org
+
+ License GPL v 2.0
+
+ * *
+ * 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 "algorithms.h"
+#include "chunk.h"
+#include "database.h"
+#include "KDBSearchEngine2.h"
+#include "dbscan.h"
+#include <klineedit.h>
+#include <kapplication.h>
+#include <qpushbutton.h>
+#include <kurlrequester.h>
+#include <qcheckbox.h>
+#include <knuminput.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+
+#include <qmap.h>
+
+#include <kdebug.h>
+#define i18n (const char *)
+
+KDBSearchEngine2::KDBSearchEngine2(QObject *parent,const char*name)
+ : SearchEngine(parent,name)
+ {
+ pw=0;
+ dbDirectory=".";
+
+ di=0; //Database Interface is not yet initialized
+
+ connect(this,SIGNAL(hasError(QString)),SLOT(setLastError(QString)));
+
+ searching=false; // i'm not searching
+ iAmReady=true; //there are no reason to say I'm not ready.
+
+}
+
+
+KDBSearchEngine2::~KDBSearchEngine2()
+{
+ if(di)
+ delete di; //delete database interface
+}
+
+bool KDBSearchEngine2::startSearch(QString str)
+{
+ kdDebug(0) << "Start a new search. Looking for: " << str << endl;
+
+ static QString queryString;
+
+ queryString=str; //set the latest query string (note: it is static)
+
+ if(autoupdate)
+ {
+ updateSettings();
+ }
+
+
+ if(!init()) return false; //-check initialization
+ di->stop(true); //stop all new emits from database interface
+ emit started(); //say everybody we are starting
+
+ if(searching) return true; //We already have a search loop, as soon as we come back
+ //on the search loop we will start the new search (queryString).
+
+ searching=true; //really start searching
+
+ QString searchingString;
+
+ do //Search loop, it stops only when finished and latest searched string is the actual query string.
+ {
+ searchingString=queryString; //-set new search string
+ di->stop(false); //-unlock searching
+
+ if(numberOfResult<1) numberOfResult=1;
+
+// di->singleWordMatch(searchingString,0,true);
+
+ GenericSearchAlgorithm strategy(di,&settings);
+
+ //Let's create a search sequence:
+ ExactSearchAlgorithm exact(di,&settings);
+ AlphaSearchAlgorithm alpha(di,&settings);
+ SentenceArchiveSearchAlgorithm sent(di,&settings);
+ ChunkByChunkSearchAlgorithm sbys(di,&settings);
+ ChunkByChunkSearchAlgorithm wbyw(di,&settings);
+ CorrelationSearchAlgorithm corr(di,&settings);
+ FuzzyChunkSearchAlgorithm fs(di,&settings);
+ FuzzyChunkSearchAlgorithm fw(di,&settings);
+
+ SentenceChunkFactory sf(di);
+ sbys.setChunkFactory(&sf);
+ fs.setChunkFactory(&sf);
+
+
+ WordChunkFactory wf(di);
+ wbyw.setChunkFactory(&wf);
+ fw.setChunkFactory(&wf);
+
+ strategy.addAlgorithm(&exact);
+ strategy.addAlgorithm(&alpha);
+ strategy.addAlgorithm(&sent);
+ strategy.addAlgorithm(&sbys);
+ //strategy.addAlgorithm(&fs);
+ strategy.addAlgorithm(&fw);
+ strategy.addAlgorithm(&corr);
+ strategy.addAlgorithm(&wbyw);
+
+
+ connect(&strategy,SIGNAL(newResult(QueryResult)),this,SLOT(receiveResult(QueryResult)));
+ strategy.exec(searchingString); disconnect(&strategy,SIGNAL(newResult(QueryResult)),this,SLOT(receiveResult(QueryResult)));
+
+
+ kdDebug(0) << "End of search for " << searchingString << endl;
+ }
+ while(searchingString!=queryString);
+ kdDebug(0) << "Exiting the search loop" << endl;
+ //if != someone asked a different string when we was searching
+ //so we restart our search (maybe a cleanresult is needed?).
+
+
+ di->stop(false); //-clean searching locks
+ searching=false; //-clean searching locks
+ emit finished(); //Finished
+
+ return true;
+
+}
+
+
+
+
+
+bool KDBSearchEngine2::startSearchInTranslation(QString str)
+{
+ if(autoupdate)
+ {
+ updateSettings();
+ }
+
+ //TODO!!!!
+ return true;
+
+}
+
+
+
+bool KDBSearchEngine2::messagesForPackage(const QString& package
+ , QValueList<Message>& resultList, QString& error)
+{
+ //FIXME implement this (needs filters)
+ return true;
+}
+
+
+void KDBSearchEngine2::setLastError(QString er)
+{
+ lasterror=er;
+}
+
+QString KDBSearchEngine2::translate(const QString text)
+{
+ ExactSearchAlgorithm exact(di,&settings);
+
+ return exact.exec(text)[0].result();
+
+}
+
+
+void KDBSearchEngine2::receiveResult(QueryResult r)
+{
+
+ SearchResult se; // Create a new SearchResult for our QueryResult
+
+ se.translation=r.richResult();
+ se.found=r.richOriginal();
+
+ se.plainTranslation=r.result();
+ se.plainFound=r.original();
+ se.score=r.score();
+
+ emit resultFound(&se); // dispatch the new SearchResult
+
+}
+
+
+/* A SEARCH RESULT CONTAINS (see searchengine.h)
+ QString requested;
+ QString found;
+ QString translation;
+ QString plainTranslation;
+ QString plainFound;
+ QString plainRequested;
+ int score;
+ QPtrList<TranslationInfo> descriptions;
+*/
+
+
+
+bool KDBSearchEngine2::init()
+{
+ if(di!=0) return true; //if there already is a DBinterface we are ok
+ else
+ {
+ di = new DataBaseInterface(dbDirectory,&settings);
+ connect(di,SIGNAL(newResult(QueryResult)),this,SLOT(receiveResult(QueryResult)));
+ //FIXME: what wbout ready()
+ if(!di->mainOk()) return false; //check if the main DB is OK.
+
+ return true;
+ }
+
+}
+const KAboutData *KDBSearchEngine2::about() const
+{
+ return DbSe2Factory::instance()->aboutData();
+}
+
+void KDBSearchEngine2::stringChanged( QString orig, QString translated
+ , QString description)
+{
+
+ if(!init()) return;
+ //if(translated.isEmpty()) return;
+ InputInfo ii;
+ if(description.find("fuzzy",false)==-1)
+ di->addEntry(orig,translated,&ii);
+
+}
+
+PrefWidget * KDBSearchEngine2::preferencesWidget(QWidget *parent)
+{
+
+ pw = new KDB2PreferencesWidget(parent);
+ kdDebug(0) << "new KDB2 preferences widget" << endl;
+ setSettings();
+ connect(pw,SIGNAL(restoreNow()),this,SLOT(setSettings()));
+ connect(pw,SIGNAL(applyNow()),this,SLOT(updateSettings()));
+ connect(pw,SIGNAL(destroyed()),this,SLOT(prefDestr()));
+
+
+ connect(pw->dbpw->scanAll,SIGNAL(clicked()),this,SLOT(scanAllPressed()));
+ connect(pw->dbpw->scanSource,SIGNAL(clicked()),this,SLOT(scanNowPressed()));
+ connect(pw->dbpw->addSource,SIGNAL(clicked()),this,SLOT(addSource()));
+ connect(pw->dbpw->editSource,SIGNAL(clicked()),this,SLOT(editSource()));
+ connect(pw->dbpw->removeSource,SIGNAL(clicked()),this,SLOT(removeSource()));
+
+
+ return pw;
+}
+
+void KDBSearchEngine2::saveSettings(KConfigBase *config)
+{
+ KConfigGroupSaver cgs(config,"KDBSearchEngine2");
+
+
+
+ config->writeEntry("DBDirectory",dbDirectory);
+ config->writeEntry("AutoAdd",autoAdd);
+ config->writeEntry("UseSentence",useSentence);
+ config->writeEntry("UseGlossary",useGlossary);
+ config->writeEntry("UseExact",useExact);
+ config->writeEntry("UseDivide",useDivide);
+ config->writeEntry("UseAlpha",useAlpha);
+ config->writeEntry("UseWordByWord",useWordByWord);
+ config->writeEntry("UseDynamic",useDynamic);
+ config->writeEntry("NumberOfResults",numberOfResult);
+
+ config->writeEntry("ScoreDivide",settings.scoreDivide);
+ config->writeEntry("ScoreExact",settings.scoreExact);
+ config->writeEntry("ScoreSentence",settings.scoreSentence);
+ config->writeEntry("ScoreWordByWord",settings.scoreWordByWord);
+ config->writeEntry("ScoreGlossary",settings.scoreGlossary);
+ config->writeEntry("ScoreAlpha",settings.scoreAlpha);
+ config->writeEntry("ScoreDynamic",settings.scoreDynamic);
+ config->writeEntry("MinimumScore",settings.minScore);
+ config->writeEntry("FirstCapital",settings.firstCapital);
+ config->writeEntry("AllCapital",settings.allCapital);
+ config->writeEntry("Accelerator",settings.accelerator);
+ config->writeEntry("SameLetter",settings.sameLetter);
+
+ uint sourceNumber=0;
+ config->writeEntry("NumberOfDBImportSources",sources.count());
+
+ for(QMap<QString,MessagesSource>::iterator sourceIt=sources.begin() ; sourceIt!=sources.end(); ++sourceIt)
+ {
+ sourceNumber++;
+ config->setGroup("DBImportSource-"+QString::number(sourceNumber));
+ config->writeEntry("Name",sourceIt.key());
+ sourceIt.data().writeConfig(config);
+ }
+}
+
+void KDBSearchEngine2::readSettings(KConfigBase *config)
+{
+
+ /*QString defaultDir;
+ KStandardDirs * dirs = KGlobal::dirs();
+ if(dirs)
+ {
+ defaultDir = dirs->saveLocation("data");
+ if(defaultDir.right(1)!="/")
+ defaultDir+="/";
+ defaultDir += "kbabeldict/dbsearchengine2";
+ }
+*/
+ KConfigGroupSaver cgs(config,"KDBSearchEngine2");
+
+ // dbDirectory=config->readEntry("DBDirectory",defaultDir);
+ autoAdd=config->readBoolEntry("AutoAdd",true);
+ useSentence=config->readBoolEntry("UseSentence",true);
+ useGlossary=config->readBoolEntry("UseGlossary",true);
+ useExact=config->readBoolEntry("UseExact",true);
+ useDivide=config->readBoolEntry("UseDivide",true);
+ useAlpha=config->readBoolEntry("UseAlpha",true);
+ useWordByWord=config->readBoolEntry("UseWordByWord",true);
+ useDynamic=config->readBoolEntry("UseDynamic",true);
+ numberOfResult=config->readNumEntry("NumberOfResults",5);
+
+ settings.scoreDivide=config->readNumEntry("ScoreDivide",90);
+ settings.scoreExact=config->readNumEntry("ScoreExact",100);
+ settings.scoreSentence=config->readNumEntry("ScoreSentence",90);
+ settings.scoreWordByWord=config->readNumEntry("ScoreWordByWord",70);
+ settings.scoreGlossary=config->readNumEntry("ScoreGlossary",98);
+ settings.scoreAlpha=config->readNumEntry("ScoreAlpha",98);
+ settings.scoreDynamic=config->readNumEntry("ScoreDynamic",80);
+ settings.minScore=config->readNumEntry("MinimumScore",60);
+ settings.firstCapital=config->readBoolEntry("FirstCapital",true);
+ settings.allCapital=config->readBoolEntry("AllCapital",false);
+ settings.accelerator=config->readBoolEntry("Accelerator",true);
+ settings.sameLetter=config->readBoolEntry("SameLetter",true);
+
+ uint numberOfSources=config->readNumEntry("NumberOfDBImportSources",0);
+ kdDebug(0) << "Found "<< numberOfSources << " sources" << endl;
+ for(uint sourceNumber=1;sourceNumber<=numberOfSources;sourceNumber++)
+ {
+ config->setGroup("DBImportSource-"+QString::number(sourceNumber));
+ QString name=config->readEntry("Name");
+ sources[name].readConfig(config);
+ }
+ if(pw)
+ setSettings();
+
+}
+
+void KDBSearchEngine2::setSettings()
+{
+ if(pw) {
+ pw->dbpw->dbDirectory->setURL(dbDirectory);
+ pw->dbpw->autoUpdate->setChecked(autoAdd);
+
+ pw->dbpw->useSentence->setChecked(useSentence);
+ pw->dbpw->useGlossary->setChecked(useGlossary);
+ pw->dbpw->useExact->setChecked(useExact);
+ pw->dbpw->useDivide->setChecked(useDivide);
+ pw->dbpw->useAlpha->setChecked(useAlpha);
+ pw->dbpw->useWordByWord->setChecked(useWordByWord);
+ pw->dbpw->useDynamic->setChecked(useDynamic);
+ pw->dbpw->numberOfResult->setValue(numberOfResult);
+ pw->dbpw->scoreDivide->setValue(settings.scoreDivide);
+ pw->dbpw->scoreExact->setValue(settings.scoreExact);
+ pw->dbpw->scoreSentence->setValue(settings.scoreSentence);
+ pw->dbpw->scoreWordByWord->setValue(settings.scoreWordByWord);
+ pw->dbpw->scoreGlossary->setValue(settings.scoreGlossary);
+ pw->dbpw->scoreAlpha->setValue(settings.scoreAlpha);
+ pw->dbpw->scoreDynamic->setValue(settings.scoreDynamic);
+ pw->dbpw->minScore->setValue(settings.minScore);
+ pw->dbpw->firstCapital->setChecked(settings.firstCapital);
+ pw->dbpw->allCapital->setChecked(settings.allCapital);
+ pw->dbpw->accelerator->setChecked(settings.accelerator);
+ pw->dbpw->sameLetter->setChecked(settings.sameLetter);
+
+ //pw->dbpw->checkLang->setChecked(true);
+ //pw->dbpw->useFilters->setChecked(false);
+ //pw->dbpw->dateToday->setChecked(false);
+ pw->dbpw->sourceList->clear();
+ for(QMap<QString,MessagesSource>::iterator sourceIt=sources.begin() ; sourceIt!=sources.end(); ++sourceIt)
+ {
+ pw->dbpw->sourceList->insertItem(sourceIt.key());
+ }
+ }
+
+}
+
+void KDBSearchEngine2::updateSettings()
+{
+ if(!pw) return;
+
+ QString newdb = pw->dbpw->dbDirectory->url();
+ if(newdb !=dbDirectory)
+ {
+ kdDebug(0) << "Recreate DB-Interface cause dbdir is changed" << endl;
+ dbDirectory=newdb;
+ if (di!=0) delete di;
+ di= new DataBaseInterface(dbDirectory,&settings);
+ }
+
+ autoAdd=pw->dbpw->autoUpdate->isChecked();
+
+ useSentence=pw->dbpw->useSentence->isChecked();
+ useGlossary=pw->dbpw->useGlossary->isChecked();
+ useExact=pw->dbpw->useExact->isChecked();
+ useDivide=pw->dbpw->useDivide->isChecked();
+ useAlpha=pw->dbpw->useAlpha->isChecked();
+ useWordByWord=pw->dbpw->useWordByWord->isChecked();
+ useDynamic=pw->dbpw->useDynamic->isChecked();
+
+ numberOfResult=pw->dbpw->numberOfResult->value();
+
+ settings.scoreWordByWord=pw->dbpw->scoreWordByWord->value();
+ settings.scoreGlossary=pw->dbpw->scoreGlossary->value();
+ settings.scoreDivide=pw->dbpw->scoreDivide->value();
+ settings.scoreExact=pw->dbpw->scoreExact->value();
+ settings.scoreSentence=pw->dbpw->scoreSentence->value();
+ settings.scoreAlpha=pw->dbpw->scoreAlpha->value();
+ settings.scoreDynamic=pw->dbpw->scoreDynamic->value();
+
+ settings.minScore=pw->dbpw->minScore->value();
+
+ settings.firstCapital=pw->dbpw->firstCapital->isChecked();
+ settings.allCapital=pw->dbpw->allCapital->isChecked();
+ settings.accelerator=pw->dbpw->accelerator->isChecked();
+ settings.sameLetter=pw->dbpw->sameLetter->isChecked();
+
+ //pw->dbpw->editRule->
+ //pw->dbpw->deleteRule->
+ //pw->dbpw->customRules->
+
+ /*
+pw->dbpw->checkLang->
+pw->dbpw->useFilters->
+pw->dbpw->dateToday->
+
+pw->dbpw->removeSource->
+pw->dbpw->scanSource->
+pw->dbpw->addSource->
+pw->dbpw->sourceDir->
+pw->dbpw->scanAll->
+pw->dbpw->sourceList->
+*/
+
+}
+
+
+/*void KDBSearchEngine2::scanSource(QString sourceName)
+{
+ //FIXME: an error here would be nice
+ if(!init()) return;
+
+
+ for(QValueList<MessagesSource>::iterator sourceIt=sources.begin() ; sourceIt!=sources.end(); sourceIt++)
+ {
+ if((*sourceIt).getName()==sourceName)
+ {
+ QValueList<KURL> urls=(*sourceIt).urls();
+ PoScanner ps(di);
+ for(QValueList<KURL>::iterator urlIt=urls.begin();urlIt!=urls.end();urlIt++)
+ ps.scanFile(*urlIt);
+
+ //We suppose name are unique so no need for further scrolling
+ return ;
+ }
+ }
+}*/
+void KDBSearchEngine2::scanNowPressed()
+{
+ if(!pw)
+ {
+ kdDebug(0) << "We should not be here, scanNow called without a pw!" << endl;
+ return;
+ }
+ QString sourceName;
+ sourceName=pw->dbpw->sourceList->currentText();
+ if(!init()) return;
+ if(sources.contains(sourceName))
+ {
+ QValueList<KURL> urls=sources[sourceName].urls();
+ PoScanner ps(di);
+ for(QValueList<KURL>::iterator urlIt=urls.begin();urlIt!=urls.end();++urlIt)
+ ps.scanURL(*urlIt);
+
+ }
+ else
+ {
+ kdDebug(0) << "source name not found in our MAP. This is a bug." << endl;
+ }
+}
+
+void KDBSearchEngine2::scanAllPressed()
+{
+ //FIXME: an error here would be nice too
+ if(!init()) return;
+ PoScanner ps(di);
+
+
+ for(QMap<QString,MessagesSource>::iterator sourceIt=sources.begin() ; sourceIt!=sources.end(); ++sourceIt)
+ {
+ QValueList<KURL> urls=(*sourceIt).urls();
+ for(QValueList<KURL>::iterator urlIt=urls.begin();urlIt!=urls.end();++urlIt)
+ ps.scanURL(*urlIt);
+ }
+}
+
+void KDBSearchEngine2::editSource()
+{
+ if(!pw)
+ {
+ kdDebug(0) << "We should not be here, editSource called without a pw!" << endl;
+ return;
+ }
+ QString sourceName;
+ sourceName=pw->dbpw->sourceList->currentText();
+
+ if(sources.contains(sourceName))
+ {
+ bool nameIsNew;
+ QString newName;
+ SourceDialog sd;
+ do{
+ sources[sourceName].setDialogValues(&sd);
+ sd.sourceName->setText(sourceName);
+ if(sd.exec()==QDialog::Accepted)
+ {
+ sources[sourceName].getDialogValues(&sd);
+ newName= sd.sourceName->text();
+ } else
+ {
+ return;
+ }
+ nameIsNew=sources.contains(newName);
+ if(newName!=sourceName && !nameIsNew)
+ {
+
+ KMessageBox::error(0,
+ i18n("The name you chose is already used.\nPlease change the source name."),
+ i18n("Name is Not Unique"));
+ kdDebug(0) << "Name is not uniqe" << endl;
+ }
+ }while(newName!=sourceName && !nameIsNew);
+
+ if(newName!=sourceName){
+ sources[newName]=sources[sourceName];
+ sources.remove(sourceName);
+ }
+ pw->dbpw->sourceList->changeItem(newName,pw->dbpw->sourceList->currentItem());
+
+ }
+ else
+ {
+ kdDebug(0) << "source name not found in our MAP. This is a bug." << endl;
+ }
+
+}
+void KDBSearchEngine2::removeSource()
+{
+
+ if(!pw)
+ {
+ kdDebug(0) << "We should not be here, delteSource called without a pw!" << endl;
+ return;
+ }
+ QString sourceName;
+ sourceName=pw->dbpw->sourceList->currentText();
+ sources.remove(sourceName);
+ pw->dbpw->sourceList->removeItem(pw->dbpw->sourceList->currentItem());
+
+}
+
+void KDBSearchEngine2::addSource()
+{
+ QString newName;
+ SourceDialog sd;
+ bool nameIsNew;
+ do{
+ if(sd.exec()==QDialog::Accepted)
+ {
+ newName= sd.sourceName->text();
+ nameIsNew=!sources.contains(newName);
+ }
+ else
+ {
+ return;
+ }
+ // nameIsNew=sources.contains(newName);
+ if(!nameIsNew)
+ {
+ KMessageBox::error(0,i18n("The name you chose is already used.\nPlease change the source name."),
+ i18n("Name is Not Unique"));
+ kdDebug(0) << "Name is not uniqe" << endl;
+ }
+ else
+ {
+ sources[newName].getDialogValues(&sd);
+ }
+ }while(!nameIsNew);
+
+ pw->dbpw->sourceList->insertItem(newName);
+
+
+}
+QString KDBSearchEngine2::searchTranslation( const QString text, int & score )
+{
+ GenericSearchAlgorithm strategy(di,&settings);
+ strategy.setMaxResultNumber(1);
+
+ ExactSearchAlgorithm exact(di,&settings);
+ AlphaSearchAlgorithm alpha(di,&settings);
+ SentenceArchiveSearchAlgorithm sent(di,&settings);
+
+ strategy.addAlgorithm(&exact);
+ strategy.addAlgorithm(&alpha);
+ strategy.addAlgorithm(&sent);
+
+ QueryResult firstRes=strategy.exec(text)[0];
+ score=firstRes.score();
+ return firstRes.result();
+
+}
+
+QString KDBSearchEngine2::fuzzyTranslation( const QString text, int & score )
+{
+ GenericSearchAlgorithm strategy(di,&settings);
+ strategy.setMaxResultNumber(1);
+ ExactSearchAlgorithm exact(di,&settings);
+ AlphaSearchAlgorithm alpha(di,&settings);
+ SentenceArchiveSearchAlgorithm sent(di,&settings);
+ ChunkByChunkSearchAlgorithm sbys(di,&settings);
+ ChunkByChunkSearchAlgorithm wbyw(di,&settings);
+ FuzzyChunkSearchAlgorithm fs(di,&settings);
+ FuzzyChunkSearchAlgorithm fw(di,&settings);
+
+ SentenceChunkFactory sf(di);
+ sbys.setChunkFactory(&sf);
+ fs.setChunkFactory(&sf);
+
+
+ WordChunkFactory wf(di);
+ wbyw.setChunkFactory(&wf);
+ fw.setChunkFactory(&wf);
+
+ strategy.addAlgorithm(&exact);
+ strategy.addAlgorithm(&alpha);
+ strategy.addAlgorithm(&sent);
+ strategy.addAlgorithm(&sbys);
+ //strategy.addAlgorithm(&fs);
+ strategy.addAlgorithm(&fw);
+ strategy.addAlgorithm(&wbyw);
+
+
+ QueryResult firstRes=strategy.exec(text)[0];
+ score=firstRes.score();
+ return firstRes.result();
+
+
+}
+
+//FIXME: ProgressBasr, progressbar,progressbasr
+#include "KDBSearchEngine2.moc"
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/KDBSearchEngine2.h b/kbabel/kbabeldict/modules/dbsearchengine2/KDBSearchEngine2.h
new file mode 100644
index 00000000..0db19c6c
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/KDBSearchEngine2.h
@@ -0,0 +1,202 @@
+/* ****************************************************************************
+
+DBSE2
+Andrea Rizzi
+
+**************************************************************************** */
+
+#ifndef DBSEARCH_ENGINE2_H
+#define DBSEARCH_ENGINE2_H
+
+#include <searchengine.h>
+#include <qdialog.h>
+
+#include "database.h"
+#include "dbse2_factory.h"
+#include "preferenceswidget.h"
+#include "dbscan.h"
+#include "sourcedialog.h"
+
+//#include "DBSESettings.h"
+
+class KDBSearchEngine2 : public SearchEngine
+{
+ Q_OBJECT
+
+ public:
+
+ KDBSearchEngine2(QObject *parent=0, const char *name=0);
+ virtual ~KDBSearchEngine2();
+
+ //init if needed.
+ bool init();
+
+ /** @return true, if a search is currently active */
+ bool isSearching() const {return searching;}
+
+ void stopSearch() { if(di) di->stop();}
+
+
+
+ /** @returns true, if it was initialized correctly */
+ bool isReady() const {return iAmReady; }
+
+
+ void saveSettings(KConfigBase *config);
+ void readSettings(KConfigBase *config);
+
+
+ QString translate(const QString text);
+
+ QString fuzzyTranslation(const QString text, int &score);
+ QString searchTranslation(const QString, int &score );
+
+ /**
+ * Finds all messages belonging to package package. If nothing is found,
+ * the list is empty.
+ * @param package The name of the file, something like "kbabel.po"
+ * @param resultList Will contain the found messages afterwards
+ * @param error If an error occured, this should contain a description
+ *
+ * @return true, if successfull
+ */
+ bool messagesForPackage(const QString& package
+ , QValueList<Message>& resultList, QString& error);
+
+ /**
+ * @returns true, if the searchresults are given as rich text
+ * the default implementation returns false
+ */
+ bool usesRichTextResults(){return true;}
+
+ /** @returns true, if the the entries in the database can be edited */
+ bool isEditable(){return false;}
+
+ /**
+ * @returns a widget which lets the user setup all preferences of this
+ * search engine. The returned widget should not be bigger than
+ * 400x400. If you need more space, you maybe want to use
+ * a tabbed widget.
+ * @param parent the parent of the returned widget
+ */
+ virtual PrefWidget* preferencesWidget(QWidget *parent);
+
+ /** @returns information about this SearchEngine */
+ virtual const KAboutData *about() const;
+
+ /** @returns the i18n name of this search engine */
+ QString name() const {return i18n("DB SearchEngine II");}
+
+ /** @returns a untranslated name of this engine */
+ QString id() const {return "dbse2";}
+
+ /** @returns the last error message */
+ QString lastError() {return lasterror;}
+
+
+ /**
+ * sets the engine to always ask the preferences dialog for settings
+ * if is existing before starting the search.
+ */
+ virtual void setAutoUpdateOptions(bool activate)
+ {
+ autoupdate=activate;
+ }
+
+
+
+ public slots:
+
+ void receiveResult(QueryResult r);
+
+ /**
+ * starts a search for string s in the original text
+ * @returns false, if an error occured. Use @ref lastError
+ * to get the last error message
+ */
+ bool startSearch(QString s);
+
+ /**
+ * starts a search for string s in the translated text
+ * @returns false, if an error occured. Use @ref lastError
+ * to get the last error message
+ */
+ bool startSearchInTranslation(QString s);
+
+
+ /** stops a search */
+ // virtual void stopSearch() ;
+
+
+ /**
+ * This method allows a search engine to use different settings depending
+ * on the edited file. The default implementation does nothing.
+ * @param file The edited file with path
+ */
+ // virtual void setEditedFile(QString file);
+
+ /**
+ * This method allows a search engine to use different settings depending
+ * on the edited package. The default implementation does nothing.
+ * @param package The name of the package, that is currently translated.
+ */
+ // virtual void setEditedPackage(QString package);
+
+ /**
+ * This method allows a search engine to use different settings depending
+ * on the language code. The default implementation does nothing.
+ * @param lang The current language code (e.g. de).
+ */
+ // virtual void setLanguageCode(QString lang);
+ // virtual void setLanguage(QString languageCode, QString languageName);
+
+
+
+ /**
+ * This method is called, if something has been changed in the
+ * current file. See @ref setEditedFile if you want to know the file
+ * name
+ * @param orig the original string
+ * @param translation the translated string
+ */
+
+ void stringChanged( QString orig, QString translated
+ , QString description);
+
+ //void scan();
+
+ void setLastError(QString er);
+
+ //Slots for preference dialog
+ // void scanSource(QString sourceName);
+ void scanNowPressed();
+ void scanAllPressed();
+ void editSource();
+ void removeSource();
+ void addSource();
+
+
+ private:
+ DataBaseInterface *di;
+ bool searching;
+ bool iAmReady;
+ bool autoupdate;
+ QString lasterror;
+ KDB2PreferencesWidget *pw;
+
+ //PrefWidg -> DBSE
+ void updateSettings();
+ //DBSE -> PrefWidg
+ void setSettings();
+
+ DBSESettings settings;
+ QString dbDirectory;
+ bool autoAdd,useSentence,useGlossary,useExact;
+ bool useDivide,useAlpha,useWordByWord,useDynamic;
+ uint numberOfResult;
+ QMap<QString,MessagesSource> sources;
+
+};
+
+
+#endif // SEARCH_ENGINE2_H
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/Makefile.am b/kbabel/kbabeldict/modules/dbsearchengine2/Makefile.am
new file mode 100644
index 00000000..cdcd3083
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/Makefile.am
@@ -0,0 +1,34 @@
+## Makefile.am for DBSE2
+
+# 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_dbsearchengine2.la
+
+# set the include path for X, qt and KDE
+INCLUDES = -I$(srcdir)/../.. -I$(srcdir)/../../../common $(all_includes) -I$(DBIV_INCLUDES)
+
+# which sources should be compiled for kbabel
+kbabeldict_dbsearchengine2_la_SOURCES = dbscan.cpp preferenceswidget.cpp dbse2.ui KDBSearchEngine2.cpp database.cpp dbentries.cpp dbse2_factory.cpp sourcedialog.ui algorithms.cpp chunk.cpp
+
+#kbabeldict_dbsearchengine2_la_SOURCES = KDBSearchEngine2.cpp database.cpp dbentries.cpp dbse2_factory.cpp
+kbabeldict_dbsearchengine2_la_LIBADD = ../../libkbabeldictplugin.la ../../../common/libkbabelcommon.la $(LIB_KDEUI) $(LIB_KIO) $(LIB_DBIV)_cxx
+kbabeldict_dbsearchengine2_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined -L$(DBIV_LDFLAGS)
+
+
+# these are the headers for your project
+noinst_HEADERS = KDBSearchEngine2.h database.h dbentries.h dbse2_factory.h
+#chunk.h algorithms.h
+
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+kde_services_DATA = dbsearchengine2.desktop
+EXTRA_DIST = $(kde_services_DATA)
+
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/README b/kbabel/kbabeldict/modules/dbsearchengine2/README
new file mode 100644
index 00000000..907ab84e
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/README
@@ -0,0 +1,21 @@
+If you want to test this new plugin:
+launch
+# make ; make install in this directory
+then (to create the database)
+# source compile
+# cp scan ~/mytestdir
+# cd ~/mytestdir
+# ./scan file.po (I suggest to download and scan $LANG.messages)
+
+ok now you can launch kbabel, you should be in the same
+directory you launched "scan" from.
+
+# kbabel
+
+
+change kbabel settings to use "DB Search Engine II" or use
+CTRL+2 to search.
+
+
+Bye
+Andrea
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/algorithms.cpp b/kbabel/kbabeldict/modules/dbsearchengine2/algorithms.cpp
new file mode 100644
index 00000000..0ca040e8
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/algorithms.cpp
@@ -0,0 +1,425 @@
+//
+// C++ Implementation: algorithms
+//
+// Description:
+//
+//
+// Author: Andrea Rizzi <rizzi@kde.org>, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "algorithms.h"
+#include <qstringlist.h>
+#include <kdebug.h>
+
+//FIXME: remove
+#define i18n (const char*)
+
+DataBaseInterface::ResultList ExactSearchAlgorithm::exec(const QString& query )
+{
+ DataBaseInterface::ResultList res;
+ DataBaseInterface::MainEntry e=di->get(query,0);
+
+ QStringList trs=e.second.getTranslations();
+
+ for(QStringList::iterator it=trs.begin();it!=trs.end();++it)
+ {
+
+ emit newResult(QueryResult(*it,e.first.getString(),settings->scoreExact));
+
+ res.push_back(QueryResult(*it));
+ }
+ kdDebug(0) <<"Exact algo found " << res.count() << "entries" << endl;
+ return res;
+}
+
+
+DataBaseInterface::ResultList GenericSearchAlgorithm::exec(const QString& query )
+{
+ DataBaseInterface::ResultList res;
+ // ExactSearchAlgorithm exact(query,settings);
+ uint countResults=0;
+ for(QValueList<AbstractSearchAlgorithm *>::iterator algoit = algoChain.begin(); algoit!=algoChain.end() && countResults < maxResults; algoit++)
+ {
+ connect(*algoit,SIGNAL(newResult(QueryResult)),this,SIGNAL(newResult(QueryResult)));
+ kdDebug(0) << "Algo pointer" << (*algoit) << endl;
+ res+=(*algoit)->exec(query);
+ countResults=res.count();
+ kdDebug(0) << "Count = " << countResults << endl;
+ disconnect(*algoit,SIGNAL(newResult(QueryResult)),this,SIGNAL(newResult(QueryResult)));
+ }
+ return res;
+}
+
+void GenericSearchAlgorithm::addAlgorithm( AbstractSearchAlgorithm * algo )
+{
+ algoChain.append(algo);
+}
+
+DataBaseInterface::ResultList AlphaSearchAlgorithm::exec( const QString & query )
+{
+ DataBaseInterface::ResultList res;
+ DBItemMultiIndex::IndexList il=di->getAlpha(query);
+
+ for(DBItemMultiIndex::IndexList::iterator it=il.begin();it!=il.end()&&!di->stopNow();++it)
+ {
+ DataBaseInterface::MainEntry e=di->getFromIndex(*it);
+ QStringList trs=e.second.getTranslations();
+ for(QStringList::iterator it=trs.begin();it!=trs.end() && !di->stopNow();++it)
+ {
+ QueryResult r(di->format(di->simple(*it,true),query),e.first.getString(),settings->scoreAlpha);
+ emit newResult(r);
+ res.push_back(r);
+ }
+ }
+ kdDebug(0) <<"Alpha algo found " << res.count() << "entries" << endl;
+
+ return res;
+}
+
+DataBaseInterface::ResultList SentenceArchiveSearchAlgorithm::exec( const QString & query )
+{
+ DataBaseInterface::ResultList res;
+
+ DataBaseInterface::MainEntry e = di->getSentence(query);
+
+ QStringList trs=e.second.getTranslations();
+
+ kdDebug(0) << "Count in sentence archive " << trs.count()<< endl;
+
+ for(QStringList::iterator it=trs.begin();it!=trs.end();++it)
+ {
+ QueryResult r(di->format(di->simple(*it,true),query),e.first.getString(),settings->scoreSentence);
+ emit newResult(r);
+
+ res.push_back(r);
+ }
+ kdDebug(0) <<"Sentence algo found " << res.count() << "entries" << endl;
+
+ return res;
+}
+
+DataBaseInterface::ResultList ChunkByChunkSearchAlgorithm::exec( const QString & query )
+{
+ ResultList res;
+ factory->setQuery(query);
+ QPtrList<AbstractChunk> chunks=factory->chunks();
+ kdDebug(0) << "Number of chunks " << chunks.count() << endl;
+ chunks.setAutoDelete(true); //I should delete the chunks myself
+ QStringList querySeparators=factory->separators();
+
+ //This prevents recursive loop.
+ if (chunks.count()<=1) return res;
+
+ QStringList translations,tmpTranslations;
+
+ translations.push_back(""); //FIXME this is needed to start , but is not good
+ int finalscore=0;
+ int i=0;
+ QMap<QString,bool> translationUsed;
+
+ //Loop on all chunk
+ for(AbstractChunk *it=chunks.first();it && !di->stopNow(); it=chunks.next())
+ {
+ kdDebug(0) << "Process next chunk" << endl;
+ int chunkscore=0;
+ QValueList<QueryResult> r=it->translations();
+ kdDebug(0) << "Number of results for this chunk " << r.count() << endl;
+
+ if(r.count()<1) {
+ // kdDebug(0) << "Nothing found for:" << it->translations() << endl;
+ chunkscore=-10;
+
+ }
+ else
+ {
+ //FIXME: check this, why 0? it is the best one?
+ chunkscore=r[0].score();
+ kdDebug(0) << "ChunkScore " << chunkscore << endl;
+ tmpTranslations.clear();
+
+
+ //Loop on results
+ translationUsed.clear();
+ for(ResultList::iterator it1=r.begin();it1!=r.end() &&!di->stopNow(); ++it1)
+ {
+ QString chunkTranslation= (*it1).result();
+ if(!translationUsed.contains(chunkTranslation))
+ {
+ translationUsed[chunkTranslation]=true;
+ kdDebug(0) << "a translation is: " << chunkTranslation << endl;
+ for(QStringList::iterator it2=translations.begin();it2!=translations.end() && !di->stopNow() ; it2++)
+ {
+ QString prevTranslation=*it2;
+ tmpTranslations.push_back(prevTranslation+chunkTranslation+querySeparators[i]);
+ kdDebug(0) << "..appending it to " << prevTranslation << endl;
+ }
+ }
+ }
+
+ translations=tmpTranslations;
+
+ }
+
+ //kdDebug(0) << it-> << r[0].result() << "#" << querySeparators[i] << endl;
+ i++;
+ finalscore+=chunkscore;
+
+ kdDebug(0) << "partial score " << finalscore;
+ }
+ kdDebug(0) << "this is finishd" << endl;
+ if(settings->scoreChunkByChunk==0)
+ settings->scoreChunkByChunk=1;
+// FIXME:fix the score system
+// finalscore/=(i*100*100/settings->scoreChunkByChunk); //change 100 to 120(?) to lower this result (done)
+
+ if (finalscore<50) return res;
+
+ for(QStringList::iterator it2=translations.begin();it2!=translations.end() && !di->stopNow() ; it2++)
+ {
+ QString theTranslation=*it2;
+ QueryResult qr(di->format(theTranslation,query),i18n("CHUNK BY CHUNK"),finalscore);
+ qr.setRichOriginal(i18n("<h3>Chunk by chunk</h3>CHANGE THIS TEXT!!!!This translation is"
+ "obtained translating the sentences and using a"
+ "fuzzy sentence translation database.<br>"
+ " <b>Do not rely on it</b>. Translations may be fuzzy.<br>"));
+ qr.setRichResult("<font color=#800000>"+theTranslation+"</font>") ;
+ emit newResult(qr);
+ res.push_back(qr);
+ }
+
+
+ return res;
+
+
+}
+
+ChunkByChunkSearchAlgorithm::ChunkByChunkSearchAlgorithm( DataBaseInterface * dbi, DBSESettings * sets ): AbstractSearchAlgorithm(dbi,sets) , factory(0)
+{
+
+}
+
+
+SentenceArchiveSearchAlgorithm::SentenceArchiveSearchAlgorithm( DataBaseInterface * dbi, DBSESettings * sets ): AbstractSearchAlgorithm(dbi,sets)
+{
+}
+
+FuzzyChunkSearchAlgorithm::FuzzyChunkSearchAlgorithm( DataBaseInterface * dbi, DBSESettings * sets ) : AbstractSearchAlgorithm(dbi,sets)
+{
+
+}
+
+
+DataBaseInterface::ResultList FuzzyChunkSearchAlgorithm::exec( const QString & query )
+{
+ //FIXME: this code is shit too
+ ResultList res;
+ factory->setQuery(query);
+ QPtrList<AbstractChunk> querychunks = factory->chunks();
+ querychunks.setAutoDelete(true);
+
+ typedef QMap<QString,QValueList<unsigned int> > ResultMap;
+ ResultMap rmap; //result of words index query
+ unsigned int notfound=0,frequent=0,nchunks = querychunks.count();
+
+ //Get index list for each word
+ for(AbstractChunk *it=querychunks.first(); it &&!di->stopNow() ; it=querychunks.next() )
+ {
+ QValueList<uint> locations = (*it).locationReferences();
+
+ if(locations.count()>0)
+ {
+ rmap[(*it).chunkString()] = locations;
+
+ if(locations.count()>1000) //FIXME NORMALIZE THIS!!!
+ {
+ frequent++;
+ kdDebug(0) << "\""<<(*it).chunkString() << "\" is frequent" <<endl;
+ }
+ }
+ else
+ notfound++;
+
+ }
+
+
+ //Now we have a map (rmap) "word in query->list of occurency"
+
+ QValueList<unsigned int>::iterator countpos[nchunks+1];
+
+
+ QValueList<unsigned int> il;
+ for(int i = 0;i<=nchunks&&!di->stopNow();i++)
+ countpos[i]=il.end();
+
+ unsigned int bestcount=0;
+ while(!rmap.isEmpty())
+ {
+ unsigned int ref,count;
+ ref=(unsigned int)-1;
+ count=0;
+
+
+ //This will find the min head and count how many times it occurs
+ for(ResultMap::iterator it = rmap.begin();it!=rmap.end()&&!di->stopNow();++it)
+ {
+ unsigned int thisref=it.data().first();
+ if(thisref<ref)
+ {
+ ref=thisref;
+ count=0;
+ }
+ if(thisref==ref)
+ {
+ count++;
+ }
+
+ }
+
+
+ for(ResultMap::iterator it = rmap.begin();it!=rmap.end()&&!di->stopNow();)
+ {
+ it.data().remove(ref);
+
+ //kdDebug(0)<< ((frequent<(nwords-notfound)) && (it.data().count()>350)) <<endl;
+ //FIXME: I think the frequent word check is not in the right place
+ if(it.data().isEmpty() || (((frequent+notfound)<nchunks) && (it.data().count()>1000)))
+ //very dirty hack...
+ {
+
+ ResultMap::iterator it2=it;
+ it++;
+ rmap.remove(it2);
+ }
+ else it++;
+
+ }
+
+ //This should be configurable or optimized:
+ if(count>=(nchunks-notfound)*0.50 && count!=0)
+ {
+ il.insert(countpos[count],ref);
+ for(unsigned int i = nchunks;i>=count;i--)
+ if(countpos[i]==countpos[count])
+ countpos[i]--;
+ }
+ }
+
+ //loop on number of words found
+ int bestscore=0;
+
+ for(unsigned int wf=nchunks;wf>0;wf-- ){
+ for(QValueList<unsigned int>::iterator it=countpos[wf];it!=countpos[wf-1] ;++it)
+ { //loop on entries with same number of word found
+ DataBaseInterface::MainEntry e;
+ e=di->getFromIndex(*it);
+ QStringList trs=e.second.getTranslations();
+ for(QStringList::iterator it=trs.begin();it!=trs.end()&&!di->stopNow();++it)
+ {
+ unsigned int cinr=factory->chunks(*it).count(); //chunk in result
+ //compute a score, lets kbabel sort now, it should be fast...
+ int score=90*wf/nchunks-(signed int)90*(((nchunks-cinr)>0)?(nchunks-cinr):(cinr-nchunks))/(nchunks*10);
+ if(score>bestscore) bestscore=score;
+ if(score>bestscore*0.40)
+ {
+ // kdDebug(0) << "s: "<<score << " wf: "<<wf<<" nwords: "<<nwords<<" winr: "<<winr
+ // <<" 90*wf/nwords: "<<90*wf/nwords << " -:" << 90*(((nwords-winr)>0)?(nwords-winr):(winr-nwords))/(nwords*10)<< endl;
+ // FIXME: format better the richtext
+ QString ori=e.first.getString();
+ QString re=di->format(di->simple(*it,true),query);
+ QueryResult r(re,ori,score);
+ for(QPtrListIterator<AbstractChunk> it(querychunks); it.current() && di->stopNow() ; ++it){
+ ori=ori.replace(QRegExp((*it)->chunkString(),false),"<font color=#000080><u><b>"+(*it)->chunkString()+"</b></u></font>");
+ }
+ r.setRichOriginal(ori);
+ if(!di->stopNow())
+ emit newResult(r);
+ res.push_back(r);
+ }
+ }
+ }
+ }
+ return res;
+
+}
+
+DataBaseInterface::ResultList CorrelationSearchAlgorithm::exec( const QString & query )
+{
+ //FIXME, this code is shit.
+ DataBaseInterface::ResultList res;
+ if(di->words(query).count()>1) return res;
+ QMap<QString,float> corRes = di->correlation(query,0,false);
+ float max=0,max1=0,max2=0;
+ QString best,best1,best2;
+
+ for(QMap<QString,float>::iterator it = corRes.begin(); it !=corRes.end(); ++it)
+ {
+ if(it.data()>max)
+ {
+ max2=max1;
+ best2=best1;
+ max1=max;
+ best1=best;
+ best = it.key();
+ max=it.data();
+
+ }
+
+
+ }
+ if(!best.isEmpty())
+ {
+ double myscore=0.01*max*settings->scoreDynamic;
+ QueryResult r(di->format(best,query),i18n("DYNAMIC DICT:"),myscore);
+ r.setRichOriginal(i18n("<h3>Dynamic Dictionary</h3>This is a dynamic dictionary created"
+ " looking for correlation of original and translated words.<br>"
+ " <b>Do not rely on it</b>. Translations may be fuzzy.<br>"));
+ r.setRichResult("<font size=+2 color=#A00000>"+di->format(best,query)+"</font>") ;
+ res.push_back(r);
+ if(!di->stopNow())
+ emit newResult(r);
+ }
+ if(!best1.isEmpty())
+ {
+ double myscore=0.01*max1*settings->scoreDynamic;
+ QueryResult r(di->format(best1,query),i18n("DYNAMIC DICT:"),myscore);
+ r.setRichOriginal(i18n("<h3>Dynamic Dictionary</h3>This is a dynamic dictionary created"
+ " looking for correlation of original and translated words.<br>"
+ " <b>Do not rely on it</b>. Translations may be fuzzy.<br>"));
+ r.setRichResult("<font size=+2 color=#800000>"+di->format(best1,query)+"</font>") ;
+ res.push_back(r);
+ if(!di->stopNow())
+ emit newResult(r);
+ }
+
+ kdDebug(0) << "Correlation algorithm found" << res.count() << "results";
+ return res;
+
+}
+
+GenericSearchAlgorithm::GenericSearchAlgorithm( DataBaseInterface * dbi, DBSESettings * sets ): AbstractSearchAlgorithm(dbi,sets)
+{
+ maxResults = 5; //FIXME use as default somthing from DBSESettings
+}
+
+SingleWordSearchAlgorithm::SingleWordSearchAlgorithm( DataBaseInterface * dbi, DBSESettings * sets ) : GenericSearchAlgorithm(dbi,sets),
+ exact(dbi,sets), alpha(dbi,sets), sentence(dbi,sets), corr(dbi,sets), chunk(dbi,sets),casefactory(dbi)
+ {
+ addAlgorithm(&exact);
+ addAlgorithm(&alpha);
+ addAlgorithm(&sentence);
+ chunk.setChunkFactory(&casefactory);
+ addAlgorithm(&chunk);
+ addAlgorithm(&corr);
+}
+
+DataBaseInterface::ResultList SingleWordSearchAlgorithm::exec( const QString & query )
+{
+ if(di->words(query).count()>1)
+ return ResultList();
+ return GenericSearchAlgorithm::exec(query);
+}
+
+
+//#include "algorithms.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/algorithms.h b/kbabel/kbabeldict/modules/dbsearchengine2/algorithms.h
new file mode 100644
index 00000000..5f9ee682
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/algorithms.h
@@ -0,0 +1,157 @@
+//
+// C++ Interface: strategies
+//
+// Description:
+//
+//
+// Author: Andrea Rizzi <rizzi@kde.org>, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef DBSE2_STRATEGIES_H
+#define DBSE2_STRATEGIES_H
+
+#include "database.h"
+#include "chunk.h"
+#include <qobject.h>
+
+class AbstractSearchAlgorithm : public QObject
+{
+ Q_OBJECT
+ public:
+
+ typedef QValueList<QueryResult> ResultList;
+
+ AbstractSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets)
+ {
+ di=dbi;
+ settings=sets;
+ }
+ /**
+ * this contains the algo and return some results.
+ */
+ virtual DataBaseInterface::ResultList exec(const QString& query)=0;
+
+ signals:
+ void newResult(QueryResult);
+
+ protected:
+ DataBaseInterface *di;
+ DBSESettings *settings;
+
+};
+
+
+
+class ExactSearchAlgorithm : public AbstractSearchAlgorithm
+{
+ Q_OBJECT
+ public:
+ ExactSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets) : AbstractSearchAlgorithm(dbi,sets) {}
+
+ virtual DataBaseInterface::ResultList exec(const QString& query);
+};
+
+class AlphaSearchAlgorithm : public AbstractSearchAlgorithm
+{
+ Q_OBJECT
+ public:
+ AlphaSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets) : AbstractSearchAlgorithm(dbi,sets) {}
+
+ virtual DataBaseInterface::ResultList exec(const QString& query);
+};
+
+class SentenceArchiveSearchAlgorithm : public AbstractSearchAlgorithm
+{
+ Q_OBJECT
+ public:
+ SentenceArchiveSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets) ;
+
+ virtual DataBaseInterface::ResultList exec(const QString& query);
+};
+
+class ChunkByChunkSearchAlgorithm : public AbstractSearchAlgorithm
+{
+ Q_OBJECT
+ public:
+ ChunkByChunkSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets);
+
+ virtual DataBaseInterface::ResultList exec(const QString& query);
+
+ void setChunkFactory(AbstractChunkFactory *_factory)
+ {
+ factory=_factory;
+ }
+ protected:
+ AbstractChunkFactory *factory;
+};
+
+class FuzzyChunkSearchAlgorithm : public AbstractSearchAlgorithm
+{
+ Q_OBJECT
+ public:
+ FuzzyChunkSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets);
+
+ virtual DataBaseInterface::ResultList exec(const QString& query);
+ void setChunkFactory(AbstractChunkFactory *_factory)
+ {
+ factory=_factory;
+ }
+ protected:
+ AbstractChunkFactory *factory;
+};
+
+class GenericSearchAlgorithm : public AbstractSearchAlgorithm
+{
+ Q_OBJECT
+ public:
+ GenericSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets) ;
+
+ virtual ResultList exec(const QString& query);
+
+ void addAlgorithm(AbstractSearchAlgorithm *algo);
+ void setMaxResultNumber(uint num){maxResults=num;}
+
+
+ protected:
+ QValueList<AbstractSearchAlgorithm *> algoChain;
+ uint maxResults;
+ };
+
+
+class CorrelationSearchAlgorithm : public AbstractSearchAlgorithm
+{
+ Q_OBJECT
+ public:
+ CorrelationSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets) : AbstractSearchAlgorithm(dbi,sets) {}
+ virtual ResultList exec(const QString& query);
+};
+
+
+
+class SingleWordSearchAlgorithm : public GenericSearchAlgorithm
+{
+ Q_OBJECT
+ public:
+ SingleWordSearchAlgorithm(DataBaseInterface *dbi,DBSESettings *sets);
+ virtual DataBaseInterface::ResultList exec(const QString& query);
+
+ private:
+ ExactSearchAlgorithm exact;
+ AlphaSearchAlgorithm alpha;
+ SentenceArchiveSearchAlgorithm sentence;
+ CorrelationSearchAlgorithm corr;
+ ChunkByChunkSearchAlgorithm chunk;
+ CaseBasedWordChunkFactory casefactory;
+};
+
+
+class UpdateChunkIndexAlgorithm
+{
+
+};
+
+
+
+#endif //DBSE2_STRATEGIES_H
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/chunk.cpp b/kbabel/kbabeldict/modules/dbsearchengine2/chunk.cpp
new file mode 100644
index 00000000..7c62748a
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/chunk.cpp
@@ -0,0 +1,203 @@
+//
+// C++ Implementation: chunk
+//
+// Description:
+//
+//
+// Author: Andrea Rizzi <rizzi@kde.org>, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "chunk.h"
+#include "algorithms.h"
+#include <kdebug.h>
+
+
+
+AbstractChunk::~AbstractChunk( )
+{
+}
+
+WordChunk::WordChunk( DataBaseInterface * di, QString _word ) : AbstractChunk(di)
+{
+ word=_word;
+}
+
+QValueList<QueryResult> WordChunk::translations( )
+{
+ DataBaseInterface::ResultList r;
+ SingleWordSearchAlgorithm sa(di,di->getSettings());
+ r=sa.exec(word);
+ return r;
+}
+
+//QValueList<QueryResult> WordChunk::translationsFromReference( uint reference )
+//{
+//}
+
+QValueList< uint > WordChunk::locationReferences( )
+{
+ QValueList<uint> res=di->getWordIndex(word);
+ kdDebug(0) << "Number of locations " << res.count() <<endl ;
+ return res;
+/* DBItemMainKey *k = new DBItemMainKey(word);
+ DBItemMultiIndex *d = new DBItemMultiIndex();
+ if(wordsindex->get(k,d)!=DB_NOTFOUND)
+ return d->getList();
+ else
+ return QValueList<uint> tmpList;
+*/
+}
+
+void WordChunk::setLocationReferences( QValueList< uint > )
+{
+}
+
+SentenceChunk::SentenceChunk( DataBaseInterface * di, QString _sentence ): AbstractChunk(di)
+{
+ sentence=_sentence;
+}
+
+QValueList<QueryResult> SentenceChunk::translations( )
+{
+ GenericSearchAlgorithm g(di,di->getSettings());
+
+ ExactSearchAlgorithm e(di,di->getSettings());
+ AlphaSearchAlgorithm a(di,di->getSettings());
+ SentenceArchiveSearchAlgorithm s(di,di->getSettings());
+
+ g.addAlgorithm(&e);
+ g.addAlgorithm(&a);
+ g.addAlgorithm(&s);
+
+ return g.exec(sentence);
+
+}
+
+//QValueList<QueryResult> SentenceChunk::translationsFromReference( uint reference )
+//{
+//
+//}
+
+QValueList< uint > SentenceChunk::locationReferences( )
+{
+}
+
+void SentenceChunk::setLocationReferences( QValueList< uint > )
+{
+}
+
+QPtrList< AbstractChunk> WordChunkFactory::chunks()
+{
+ QString str=di->simple(string);
+ QPtrList<AbstractChunk> list;
+ if(str.isEmpty()) return list;
+ _separators.clear();
+ kdDebug(0) << "Word chunks of:" <<str << endl;
+ int pos;
+ QString sep;
+ QRegExp r("(\\s)");
+ do {
+ pos=r.search(str);
+
+ sep=r.cap(1);
+ if(!str.left(pos).isEmpty()){
+ //WordChunk *c=new WordChunk(di,di->simple(str.left(pos)))
+ list.append(new WordChunk(di,str.left(pos)));
+ _separators.append(sep);
+ }
+ else
+ {
+ uint current=_separators.count()-1;
+ _separators[current]=_separators[current]+sep;
+ }
+ str=str.remove(0,pos+1);
+ } while(!str.isEmpty() && pos != -1);
+
+ return list;
+}
+
+
+
+QPtrList<AbstractChunk> SentenceChunkFactory::chunks()
+{
+ QString str=string;
+ QPtrList<AbstractChunk> list;
+ if(str.isEmpty()) return list;
+
+ // kdDebug(0) << s << endl;
+
+ int pos;
+
+
+ do {
+ QRegExp re("((\\.|;|\\?|\\!|:)( |$|\\\\n\\n))");
+ pos=re.search(str);
+ QString sep=re.cap(1);
+
+ if(!str.left(pos).isEmpty())
+ {
+ list.append(new SentenceChunk(di,str.left(pos).stripWhiteSpace()));
+ _separators.append(sep);
+ }
+ else
+ {
+ uint current=_separators.count()-1;
+ _separators[current]=_separators[current]+sep;
+ }
+
+ str=str.remove(0,pos+re.cap(1).length());
+ } while(!str.isEmpty() && pos != -1);
+
+
+ return list;
+
+}
+QPtrList< AbstractChunk > CaseBasedWordChunkFactory::chunks( )
+{
+ QString str=string;
+ QPtrList<AbstractChunk> list;
+ if(str.isEmpty()) return list;
+ uint slen=str.length();
+ kdDebug(0) << "CaseWordChunk string:" << str << endl;
+ QString tmpWord;
+ bool upcase;
+ for(uint i=0;i<=slen;i++)
+ {
+ bool tmpCase=(str[i]==str[i].upper());
+ if(upcase!=tmpCase)
+ {
+ if(!tmpWord.isEmpty() && !tmpWord.isNull()){
+ list.append(new WordChunk(di,tmpWord));
+ _separators.append("");
+ }
+ kdDebug(0) << "CaseWordChunk:" << tmpWord << endl;
+ tmpWord="";
+
+ }
+ tmpWord+=str[i];
+ upcase=tmpCase;
+ }
+
+ return list;
+}
+
+WordChunkFactory::WordChunkFactory( DataBaseInterface * _di ) : AbstractChunkFactory(_di)
+{
+}
+
+SentenceChunkFactory::SentenceChunkFactory( DataBaseInterface * _di ): AbstractChunkFactory(_di)
+{
+}
+
+CaseBasedWordChunkFactory::CaseBasedWordChunkFactory( DataBaseInterface * _di ): AbstractChunkFactory(_di)
+{
+}
+
+
+
+
+
+
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/chunk.h b/kbabel/kbabeldict/modules/dbsearchengine2/chunk.h
new file mode 100644
index 00000000..5c5fcb93
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/chunk.h
@@ -0,0 +1,151 @@
+//
+// C++ Interface: chunk
+//
+// Description:
+//
+//
+// Author: Andrea Rizzi <rizzi@kde.org>, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef DBSE2_CHUNK_H
+#define DBSE2_CHUNK_H
+#include <qstring.h>
+#include <qvaluelist.h>
+#include "database.h"
+
+/**
+ * Abstract class for text chunks.
+ * Examples of chunks are "Words" or "Sentences"
+ * This abstraction allow to use generic algorithm on chunks,
+ * like chunkByChunk translation or chunk indexing.
+ */
+class AbstractChunk
+{
+ public:
+ AbstractChunk(DataBaseInterface *_di) {di=_di;}
+ virtual ~AbstractChunk();
+ /**
+ * This function should return a list of translation for the current chunk.
+ */
+ virtual QValueList<QueryResult> translations()=0;
+
+ //FIXME: is this in the right place, better in factory? check that stuff
+ //virtual QValueList<QueryResult> translationsFromReference(uint reference)=0;
+ virtual QValueList<uint> locationReferences()=0;
+ virtual void setLocationReferences(QValueList<uint>)=0;
+ virtual QString chunkString()=0;
+
+ protected:
+ DataBaseInterface *di;
+};
+
+/**
+ * Concrete impl of Chunk, in this case chunks are words.
+ */
+class WordChunk : public AbstractChunk
+{
+ public:
+ WordChunk(DataBaseInterface *di,QString _word);
+ virtual QValueList<QueryResult> translations();
+ //virtual QValueList<QueryResult> translationsFromReference(uint reference);
+ virtual QValueList<uint> locationReferences();
+ virtual void setLocationReferences(QValueList<uint>);
+ virtual QString chunkString(){return word;}
+
+ //static QValueList<WordChunk> divide(QString);
+ private:
+ QString word;
+};
+
+/**
+ * Concrete impl of Chunk, in this case chunks are sentences.
+ */
+class SentenceChunk : public AbstractChunk
+{
+ public:
+ SentenceChunk(DataBaseInterface *di,QString _sentence);
+ virtual QValueList<QueryResult> translations();
+ //virtual QValueList<QueryResult> translationsFromReference(uint reference);
+ virtual QValueList<uint> locationReferences();
+ virtual void setLocationReferences(QValueList<uint>);
+ virtual QString chunkString(){return sentence;}
+
+ // static QValueList<SentenceChunk> divide(QString);
+
+ private:
+ QString sentence;
+};
+
+
+/**********************************
+ CHUNK FACTORIES
+**********************************/
+
+
+class AbstractChunkFactory
+{
+ public:
+ AbstractChunkFactory(DataBaseInterface *_di)
+ {
+ di=_di;
+ }
+ virtual ~AbstractChunkFactory(){}
+ virtual QPtrList<AbstractChunk> chunks()=0;
+ /**
+ Change th string and return the chunks
+ */
+ virtual QPtrList<AbstractChunk> chunks(const QString& s)
+ {
+ string=s;
+ return chunks();
+ }
+ /**
+ * Returns the list of separators of last @ref chunks() call
+ */
+
+ virtual QStringList separators(){ return _separators;}
+ void setQuery(const QString& s)
+ {
+ string=s;
+ }
+ protected:
+ QString string;
+ QStringList _separators;
+ DataBaseInterface *di;
+};
+
+class WordChunkFactory : public AbstractChunkFactory
+{
+ public:
+ WordChunkFactory(DataBaseInterface *_di);
+ /**
+ YOU SHOULD DELETE THE CHUNKS!!
+ */
+ virtual QPtrList<AbstractChunk> chunks();
+};
+
+class CaseBasedWordChunkFactory : public AbstractChunkFactory
+{
+ public:
+ CaseBasedWordChunkFactory(DataBaseInterface *_di);
+ /**
+ YOU SHOULD DELETE THE CHUNKS!!
+ */
+ virtual QPtrList<AbstractChunk> chunks();
+};
+
+class SentenceChunkFactory : public AbstractChunkFactory
+{
+ public:
+ SentenceChunkFactory(DataBaseInterface *_di);
+
+ /**
+ YOU SHOULD DELETE THE CHUNKS!!
+ */
+ virtual QPtrList<AbstractChunk> chunks();
+};
+
+
+#endif //_CHUNK_H_
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/database.cpp b/kbabel/kbabeldict/modules/dbsearchengine2/database.cpp
new file mode 100644
index 00000000..ea0e8379
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/database.cpp
@@ -0,0 +1,752 @@
+/*
+
+DBSE 3
+(c) 2000-2003 Andrea Rizzi
+License: GPLv2
+
+*/
+#include <math.h>
+#include "database.h"
+
+#include <qregexp.h>
+#include <qdict.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+#define i18n (const char*)
+
+
+
+
+
+
+DataBase::DataBase(QString dbpath,QString dbname, QString dblang) : Db(0,DB_CXX_NO_EXCEPTIONS)
+{
+
+ filename=dbpath+"."+dblang+".db";
+ database=dbname;
+
+}
+
+int DataBase::open(DBTYPE type,unsigned int flags)
+{
+ int ret;
+ ret = Db::open(
+#if DB_VERSION_MINOR > 0
+ NULL,
+#endif
+ (const char*)filename.local8Bit(),(const char *)database.local8Bit(),type,flags,0644);
+ mytype=type;
+ return ret;
+}
+
+unsigned int DataBase::getLast()
+{
+ if(mytype!=DB_RECNO)
+ return 0;
+
+ Dbc *cur;
+ cursor(0,&cur,0);
+ DBItemNum index;
+ DBItemMainKey key;
+ cur->get(&index,&key,DB_LAST);
+ return index.getNum();
+
+}
+
+
+
+
+
+QueryResult::QueryResult(QString r)
+{
+ res=r;
+}
+QueryResult::QueryResult(QString r,QString o,int s)
+{
+ res=r;
+ richr=r;
+ orig=o;
+ richo=o;
+ sco=s;
+}
+
+QueryResult::QueryResult()
+{
+ res="";
+}
+
+
+
+
+DataBaseInterface::DataBaseInterface(QString dir, DBSESettings *sets)
+{
+
+ //FIXME Better db names!!
+ main = openMyDataBase(dir+"/testm","main","it",DB_BTREE);
+ alpha = openMyDataBase(dir+"/testa","alpha","it",DB_BTREE);
+ numindex = openMyDataBase(dir+"/testn","numindex","it",DB_RECNO);
+ wordsindex = openMyDataBase(dir+"/testw","wordsindex","it",DB_BTREE);
+ sentence = openMyDataBase(dir+"/tests","sentence","it",DB_BTREE);
+ corr = openMyDataBase(dir+"/testc","corr","it",DB_BTREE);
+ transword = openMyDataBase(dir+"/testt","transword","it",DB_RECNO);
+
+ // kdDebug(0) << main << endl;
+ // kdDebug(0) << alpha << endl;
+ settings=sets;
+ _stopNow=false;
+}
+
+DataBaseInterface::~DataBaseInterface()
+{
+
+ if(main){
+ main->close(0);
+ delete main;
+ }
+ if(numindex){
+ numindex->close(0);
+ delete numindex;
+ }
+
+ if(alpha){
+ alpha->close(0);
+ delete alpha;
+ }
+ if(wordsindex){
+ wordsindex->close(0);
+ delete wordsindex;
+ }
+ if(sentence){
+ sentence->close(0);
+ delete sentence;
+ }
+
+}
+
+DataBase *DataBaseInterface::openMyDataBase(const QString& prefix,const QString& name,const QString& l,DBTYPE tt)
+{
+
+ DataBase *aDb = new DataBase(prefix,name,l);
+ if(aDb==0){
+ return 0;
+ }
+ else
+ {
+ if(aDb->open(tt)!=0)
+ {
+ kdDebug(0) << "Database '"<< name <<"'do not exist, I try to create it.." << endl;
+ //ask only the first time.
+ static bool create=( KMessageBox::questionYesNo(0,"Database do not exist. Do you want to create it now?",
+ i18n("Create Database"), i18n("Create"), i18n("Do Not Create"))==KMessageBox::Yes);
+ if(create)
+ if(aDb->open(tt,DB_CREATE)!=0)
+ {
+ kdDebug(0) << "...cannot create!!"<< endl;
+ return 0;
+ }
+ else
+ {
+ kdDebug(0) << "...done!" << endl;
+ return aDb;
+ }
+ }
+
+ }
+ return aDb;
+}
+
+/*
+ * query functions.
+ *
+ */
+
+
+DataBaseInterface::MainEntry DataBaseInterface::get(const QString& query,SearchFilter *filter)
+{
+ static int counter=1;
+ counter++;
+ DBItemMainKey k(query);
+ DBItemMainData d;
+ //int r=
+ main->get(&k,&d);
+ // kdDebug(0) << "MAINDB->GET returned: " << r << endl;
+ if(counter%5==0) kapp->processEvents(100);
+ // kdDebug(0) << "events processed" << endl;
+ return qMakePair(k,d);
+
+}
+
+/*
+ * put functions
+ * *
+ */
+
+
+bool DataBaseInterface::addEntry(QString original,QString translated,InputInfo *info)
+{
+ DBItemMainKey mk(original);
+ DBItemMainData md;
+ QMap<QString, int> correlationDiff;
+ bool newentry=false;
+ //try to get
+ kdDebug(0) << "Inserting the pair:" << endl;
+ kdDebug(0) << "ORIGINAL:" << original << endl;
+ kdDebug(0) << "TRANSLATED:" << translated << endl;
+
+ if(main->get(&mk,&md)==DB_NOTFOUND)
+ {
+ kdDebug(0) << "new entry" << endl;
+ newentry=true;
+ //This is a new entry, create index entry
+ DBItemNum *nind;
+ int newid=numindex->getLast()+1;
+ nind=new DBItemNum(newid);
+ numindex->put(nind,&mk);
+
+ delete nind;
+
+ md.clear();
+ md.setIndexnumber(newid);
+
+
+ //Update secondary index alpha
+ DBItemMainKey ka(simple(original));
+ DBItemMultiIndex in;
+ if(alpha->get(&ka,&in)==DB_NOTFOUND) in.clear() ;
+ //alpha->get(&ka,&in);
+ in.addEntry(newid);
+ alpha->put(&ka,&in);
+ kdDebug(0) << "Updating the word index " << endl;
+ //Update words index
+ QStringList ws=words(original);
+ for(QStringList::iterator it = ws.begin(); it!=ws.end(); ++it)
+ {
+ DBItemMainKey word(*it);
+ DBItemMultiIndex win;
+ if(wordsindex->get(&word,&win)==DB_NOTFOUND) win.clear();
+ win.addEntry(newid);
+ wordsindex->put(&word,&win);
+ }
+
+ kdDebug(0) << "new entry preparation DONE" << endl;
+ }
+ else
+ {
+
+ kdDebug(0) << "It exists!" <<endl;
+ }
+
+
+ //Update sentence index
+ QStringList so=sentences(original);
+ QStringList st=sentences(translated);
+ if(so.count()==st.count() && st.count() >1 ) //we already hav a database for single string.
+ {
+ kdDebug(0) << "inside sentence loop" << endl;
+ for(int i=0; i< so.count() ; i++)
+ {
+ DBItemMainKey sk(so[i]);
+ DBItemMainData sd;
+ if(sentence->get(&sk,&sd)==DB_NOTFOUND&&!newentry)
+ kdDebug(0) << "Warning: new sentence for old entry, do we changed sentence definition? " << endl;
+
+ kdDebug(0) << "here alive" << endl;
+
+ // if(clean)
+ sd.removeRef(info->ref());
+ kdDebug(0) << "now alive" << endl;
+ sd.addTranslation(st[i],info->ref());
+ kdDebug(0) << "still alive" << endl;
+
+ sentence->put(&sk,&sd);
+
+ }
+
+
+
+ }
+ kdDebug(0) << "Fuzzy sentence archive updated" << endl;
+
+
+
+ //Add that translation, link to ref for information on that translation
+
+ if(!translated.isEmpty())
+ {
+ //loop on all translations to update correlation
+ QStringList tmpTranslations=md.getTranslations();
+ for(QStringList::iterator otIt=tmpTranslations.begin(); otIt!=tmpTranslations.end();++otIt)
+ {
+ QStringList wt=words(*otIt);
+ for(QStringList::iterator it = wt.begin(); it!=wt.end(); ++it)
+ {
+ if(correlationDiff.contains(*it))
+ correlationDiff[*it]--;
+ else
+ correlationDiff[*it]=-1;
+ }
+ }
+
+ //clean so that we have only one translation per catalog.
+ md.removeRef(info->ref());
+ md.addTranslation(translated,info->ref());
+
+ tmpTranslations=md.getTranslations();
+ for(QStringList::iterator otIt=tmpTranslations.begin(); otIt!=tmpTranslations.end();++otIt)
+ {
+ QStringList wt=words(*otIt);
+ for(QStringList::iterator it = wt.begin(); it!=wt.end(); ++it)
+ {
+ if(correlationDiff.contains(*it))
+ correlationDiff[*it]++;
+ else
+ correlationDiff[*it]=1;
+ }
+ }
+
+ //FIXME: use the correlationDIff map somehow
+
+ }
+
+ //finally put!
+ return (main->put(&mk,&md)==0);
+
+}
+
+
+bool DataBaseInterface::removeEntry(QString original)
+{
+ DBItemMainKey mk(original);
+ DBItemMainData md;
+
+ //FIXME implement remove
+ //try to get
+ if(main->get(&mk,&md)==DB_NOTFOUND)
+ {
+ /* //This is a new entry, create index entry
+ DBItemNum *nind;
+ int newid=numindex->getLast()+1;
+ nind=new DBItemNum(newid);
+ numindex->put(nind,&mk);
+
+ delete nind;
+
+ md.clear();
+ md.setIndexnumber(newid);
+
+
+ //Update secondary index alpha
+ DBItemMainKey ka(simple(original));
+ DBItemMultiIndex in;
+ if(alpha->get(&ka,&in)==DB_NOTFOUND) in.clear() ;
+ //alpha->get(&ka,&in);
+ in.addEntry(newid);
+ alpha->put(&ka,&in);
+
+ //Update words index
+ QStringList ws=words(original);
+ for(QStringList::iterator it = ws.begin(); it!=ws.end(); it++)
+ {
+ DBItemMainKey word(*it);
+ DBItemMultiIndex win;
+ if(wordsindex->get(&word,&win)==DB_NOTFOUND) win.clear();
+ win.addEntry(newid);
+ wordsindex->put(&word,&win);
+ }
+
+ //Update sentence index
+ QStringList so=sentences(original);
+ QStringList st=sentences(translated);
+ if(so.count()==st.count() && st.count() >1 ) //we already hav a database for single string.
+ {
+ for(int i=0; i< so.count() ; i++)
+ {
+ DBItemMainKey sk(so[i]);
+ DBItemMainKey sd(st[i]); //should be a list i.e. main data?
+ sentence->put(&sk,&sd);
+
+ }
+ }
+
+*/
+ }
+
+
+ return false;
+
+}
+
+
+
+QMap<QString,float> DataBaseInterface::correlation(QString word,SearchFilter *filter,bool notify, float minSign)
+{
+ QDict<unsigned int> res;
+ // res.setAutoDelete(true);
+ QMap<QString, float>final;
+ DBItemMultiIndex::IndexList il;
+ unsigned int tot=0;
+ unsigned int background=0;
+ unsigned int nocck;
+ QString sword=simple(word);
+ DBItemMainKey *k = new DBItemMainKey(sword);
+ DBItemMultiIndex *d = new DBItemMultiIndex();
+ if(wordsindex->get(k,d)!=DB_NOTFOUND)
+ {
+
+ il=d->getList();
+ kdDebug(0) << il.count()<<endl;
+ tot=0;
+ for(QValueList<unsigned int>::iterator it=il.begin();it!=il.end();++it)
+ {
+ numindex->get(*it,k);
+
+
+ // QValueList<QueryResult> trad=exactMatch(k->getString(),filter);
+
+ MainEntry e=get(k->getString(),filter);
+ QStringList trad=e.second.getTranslations();
+
+ nocck=words(k->getString()).contains(sword);
+ for( QStringList::iterator it2=trad.begin();it2!=trad.end();++it2)
+ {
+
+ QStringList w=words(*it2);
+ unsigned int numWords = w.count()*10+1;
+ unsigned int wei=100000/sqrt(numWords); //weight (is the best one?)
+
+ background+=(numWords-nocck)*wei;
+ QDict<uint> count;
+ //count.setAutoDelete(true);
+ //FIXME:SET AUTODELETE FOR ALL DICTS
+ for(QStringList::iterator it1=w.begin();it1!=w.end();it1++)
+ {
+ uint *ip;
+ if(!(ip=count[*it1])) count.insert(*it1,new uint(1));
+ else
+ (*ip)++;
+ }
+
+ for(QStringList::iterator it1=w.begin();it1!=w.end();it1++)
+ {
+ uint *ip;
+ if(*(count[*it1])==nocck) //add only if same number of entry (it cuts articles)
+ if(!(ip=res[*it1])) res.insert(*it1,new uint(wei));
+ else
+ (*ip)+=wei;
+ }
+
+ }
+ }
+
+ unsigned int sqrBG=sqrt((1.0*background+1)/10000);
+
+ for(QDictIterator<uint> it(res) ; it.current(); ++it)
+ {
+ float sign=1.0*(*(it.current()))/(10000.0*sqrBG);
+ if(sign >minSign){
+ final[it.currentKey()]=sign;
+ kdDebug(0) << it.currentKey() <<" Score:" << 1.0*(*(it.current()))/10000 << "/" <<sqrBG << " = " <<sign << endl;
+ }
+ }
+
+ kdDebug(0) << "final count " <<final.count()<< endl;
+ }
+
+ return final;
+}
+
+QStringList DataBaseInterface::words(QString s)
+{
+ QString str=simple(s);
+ QStringList list;
+
+ int pos;
+
+ do {
+ pos=str.find(QRegExp("\\s"));
+ // if(!simple(str.left(pos)).isEmpty())
+ // list.append(simple(str.left(pos)));
+ if(!str.left(pos).isEmpty())
+ list.append(str.left(pos));
+ str=str.remove(0,pos+1);
+ } while(!str.isEmpty() && pos != -1);
+
+ return list;
+}
+
+QString DataBaseInterface::simple(QString str,bool ck)
+{
+ QString res;
+ if(ck)
+ res=str; //case keep
+ else
+ res=str.lower(); //lowercase
+ //FIXME: uncoment the foll. line (check speed)
+ res=res.replace(QRegExp("(<(.*)>)(.*)(</\\2>)"),"\\3"); //remove enclosing tags
+
+
+ //Try to get rid of regexps.
+ // res=res.replace(QRegExp("(('|-|_|\\s|[^\\w%])+)")," "); //strip non-word char
+ // res=res.replace(QRegExp("(('|-|_)+)")," "); //strip non-word char
+ // res=res.replace(QRegExp("[^\\w\\s%]"),""); //strip non-word char
+
+ QString r;
+ QChar c;
+ bool wasSpace=true;
+ uint len=res.length();
+ for(uint i=0; i<len;i++)
+ {
+ c=res[i];
+ if(c.isLetterOrNumber())
+ {
+ r+=c;
+ wasSpace=false;
+ }
+ else
+ {
+ if(!wasSpace && c.isSpace())
+ {
+ r+=' ';
+ wasSpace=true;
+ }
+ else
+ {
+ if(!wasSpace && (c=='-' || c=='\'' || c=='_'))
+ {
+ r+=' ';
+ wasSpace=true;
+ }
+ else
+ {
+ if(c=='%'){
+ r+=c;
+ wasSpace=false;
+ }
+ }
+ }
+ }
+ // wasSpace=c.isSpace();
+ }
+ if(r[len-1].isSpace())
+ r.truncate(len-1);
+ res=r;
+ //kdDebug(0) << "Simple: "<<res<< endl;
+ //res=res.simplifyWhiteSpace(); //remove double spaces
+ //res=res.stripWhiteSpace(); //" as " -> "as"
+
+ // kdDebug(0) << res << endl;
+ return res;
+}
+
+QStringList DataBaseInterface::sentences(QString s)
+{
+ QString str=s;
+ QStringList list;
+
+ // kdDebug(0) << s << endl;
+
+ int pos;
+
+
+ do {
+ QRegExp re("((\\.|;|\\?|\\!|:)( |$|\\\\n\\n))");
+ pos=re.search(str);
+ if(!str.left(pos).isEmpty())
+ list.append(str.left(pos).stripWhiteSpace());
+
+ kdDebug(0) << str.left(pos) << endl;
+
+ str=str.remove(0,pos+re.cap(1).length());
+ } while(!str.isEmpty() && pos != -1);
+
+
+ return list;
+}
+
+QStringList DataBaseInterface::sentencesSeparator(QString s)
+{
+ QString str=s;
+ QStringList list;
+
+ // kdDebug(0) << s << endl;
+
+ int pos;
+
+ do {
+ QRegExp re;
+ re.setPattern("([.:?!;]( |$|\\\\n\\n))");
+ pos = re.search(str);
+ QString separator=re.cap(1);
+ if(pos!=-1){
+ list.append(separator);
+ }
+
+ str=str.remove(0,pos+1);
+ } while(!str.isEmpty() && pos != -1);
+
+ return list;
+}
+
+bool DataBaseInterface::isUpper(QChar s)
+{
+ return s==s.upper();
+}
+
+bool DataBaseInterface::isLower(QChar s)
+{
+ return s==s.lower();
+}
+
+
+
+QString DataBaseInterface::format(QString _s,QString t)
+{
+ //FIXME use settings
+ //FIXME use regexp
+
+ QString s=_s;
+ QString noTagT=t.replace(QRegExp("(<(.*)>)(.*)(</\\2>)"),"\\3");
+ QChar first=noTagT[noTagT.find(QRegExp("\\w"))];
+ bool firstCapital=isUpper(first);
+
+ /*
+bool dotsAtEnd=(t.find("...")+3==t.length());
+bool gtgtAtEnd=(t.find(">>")+2==t.length());
+bool ltltAtEnd=(t.find("<<")==t.length()-2);
+
+bool columnAtEnd=(t.find(":")+1==t.length());
+*/
+
+ bool allupper=(t.upper()==t);
+
+
+ if(firstCapital)
+ s[0]=s[0].upper();
+ else
+ s[0]=s[0].lower();
+
+ //if(dotsAtEnd)
+ // s+="...";
+
+ /*if(gtgtAtEnd)
+ s+=">>";
+
+if(ltltAtEnd)
+ s+="<<";
+
+if(columnAtEnd)
+ s+=":";
+*/
+
+ if(allupper)
+ s=s.upper();
+
+ int pos=t.find(QRegExp("&"));
+ if(pos>=0) {
+ QChar accel=t[t.find(QRegExp("&"))+1];
+ if(accel!='&')
+ {
+
+ pos=s.find(accel,false);
+ if(pos<0)
+ pos=0;
+ s.insert(pos,"&");
+ }
+ }
+ s=formatRegExp(s,t,".*(\\.\\.\\.|:|>>|<<|\\.|\\?)$",
+ "^(.*)$",
+ "\\1@CAP1@");
+ s=formatRegExp(s,t,"(<(.*)>).*(\\.\\.\\.|:|>>|<<|\\.|\\?)*(</\\2>)$",
+ "^(.*)$",
+ "@CAP1@\\1@CAP3@@CAP4@");
+
+ return s;
+
+}
+
+
+QString DataBaseInterface::formatRegExp(QString _s, QString t, QString tre,QString stringSearch,QString stringReplace)
+{
+ QString s=_s;
+ QRegExp templateRegExp(tre);
+ //QString stringSearch = "(.*)!@CAP1@$"; // use @CAP1.. fot caps in templates
+ //QString stringReplace = "\\1@CAP1@"; // use \1, \2 for caps in str and @CAP1 fot caps in template
+
+
+ if(templateRegExp.exactMatch(t))
+ {
+ QStringList caps=templateRegExp.capturedTexts();
+ int i=0;
+ for(QStringList::iterator capit=caps.begin();capit!=caps.end();++capit)
+ {
+ QString phRegExp="(?!\\\\)@CAP"+QString::number(i)+"@";
+ //kdDebug(0) << "phRegExp: " << phRegExp << endl;
+ //kdDebug(0) << "cap[" << i << "]: "<< *capit<< endl;
+
+ stringReplace = stringReplace.replace(QRegExp(phRegExp),*capit);
+ stringSearch = stringSearch.replace(QRegExp(phRegExp),*capit);
+ i++;
+
+ }
+ // kdDebug(0) << "stringSearch " << stringSearch << endl;
+ // kdDebug(0) << "stringReplace " << stringReplace << endl;
+ QRegExp stringSearchRegExp = QRegExp(stringSearch);
+ // kdDebug(0) << "before: "<<s<<endl;
+ s = s.replace(stringSearchRegExp,stringReplace);
+ // kdDebug(0) << "after: "<<s<<endl;
+
+ }
+
+ return s;
+}
+
+DBItemMultiIndex::IndexList DataBaseInterface::getAlpha( const QString & query )
+{
+ DBItemMainKey *k = new DBItemMainKey(simple(query));
+ DBItemMultiIndex *d = new DBItemMultiIndex();
+ alpha->get(k,d);
+
+ return d->getList();
+}
+
+DataBaseInterface::MainEntry DataBaseInterface::getFromIndex( uint i )
+{
+ DBItemMainKey k;
+ numindex->get(i,&k);
+ return get(k.getString(),0); //FIXME: this is a BUG right now but the filter should be removed
+}
+
+DataBaseInterface::MainEntry DataBaseInterface::getSentence( const QString & query )
+{
+
+ static int counter=1;
+ counter++;
+ DBItemMainKey k(query);
+ DBItemMainData d;
+ sentence->get(&k,&d);
+ if(counter%5==0) kapp->processEvents(100);
+ return qMakePair(k,d);
+
+}
+
+DBItemMultiIndex::IndexList DataBaseInterface::getWordIndex( const QString & query )
+{
+ DBItemMainKey k = DBItemMainKey(query);
+ DBItemMultiIndex d = DBItemMultiIndex();
+ if(wordsindex->get(&k,&d)!=DB_NOTFOUND){
+ return d.getList();
+ }
+ else
+ {
+ QValueList<unsigned int> tmpList;
+ return tmpList;
+ }
+
+}
+
+
+
+//#include "database.moc.cpp"
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/database.h b/kbabel/kbabeldict/modules/dbsearchengine2/database.h
new file mode 100644
index 00000000..c447fa59
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/database.h
@@ -0,0 +1,237 @@
+/*
+
+ DBSE 3
+ (c) 2000-2003 Andrea Rizzi
+ License: GPLv2
+
+*/
+#ifndef DATABASE_2_H
+#define DATABASE_2_H
+
+#include <qstring.h>
+#include <qvaluelist.h>
+#include <db4/db_cxx.h>
+#include <qobject.h>
+#include <qregexp.h>
+
+#include "dbentries.h"
+
+
+class DBSESettings
+{
+public:
+ //DatabaseInterface Settings
+ uint scoreWordByWord;
+ uint scoreGlossary;
+ uint scoreDivide;
+ uint scoreExact;
+ uint scoreSentence;
+ uint scoreAlpha;
+ uint scoreDynamic;
+ uint scoreChunkByChunk;
+ uint minScore;
+ bool firstCapital;
+ bool allCapital;
+ bool accelerator;
+ bool sameLetter;
+
+
+
+};
+
+
+class DataBase : Db
+{
+ public:
+ DataBase(QString dbpath, QString dbname, QString dblang);
+
+ int open(DBTYPE type,unsigned int flags=0);
+
+//Standard access (overload std functions)
+
+
+
+int del(DBItem * key){
+ key->set();
+ int r = Db::del(0,key,0);
+ key->get();
+ return r;
+ }
+
+
+
+int get(DBItem * key,DBItem *data){
+ key->set();
+ data->set();
+ int r = Db::get(0,key,data,0);
+ key->get();
+ data->get();
+ return r;
+ }
+ int put(DBItem * key,DBItem *data,int fl=0){
+ key->set();
+ data->set();
+ int r= Db::put(0,key,data,0);
+ key->get();
+ data->get();
+ return r;
+ }
+
+ int del(DBItemNum * key){
+ int r = Db::del(0,key,0);
+ return r;
+ }
+
+ int get(DBItemNum * key,DBItem *data){
+ data->set();
+ int r = Db::get(0,key,data,0);
+ data->get();
+ return r;
+ }
+ int put(DBItemNum * key,DBItem *data)
+ {
+ data->set();
+ int r= Db::put(0,key,data,0);
+ data->get();
+ return r;
+ }
+
+//Overload, using this you loose the Key!!
+ int del(int i){DBItemNum n(i); return del(&n);}
+ int get(int i,DBItem *data){DBItemNum n(i); return get(&n,data);}
+ int put(int i,DBItem *data){DBItemNum n(i); return put(&n,data);}
+
+ unsigned int getLast();
+ int close(unsigned int i) {return Db::close( i); }
+
+//For scrolling
+ // int getFirst(DBItem *key,DBItem *data,QString table);
+ // int getNext(DBItem *key,DBItem *data,QString table);
+ // bool isEnd(QString table);
+private:
+ QString filename;
+ QString database;
+ DBTYPE mytype;
+};
+
+
+
+
+
+class QueryResult //from DBInterface to KDBSearchEngine
+{
+public:
+ QueryResult();
+ QueryResult(QString r);
+ QueryResult(QString r,QString o,int s);
+ void setRichResult(QString r) { richr=r; }
+ void setRichOriginal(QString r) { richo=r; }
+
+ QString richResult() {return richr;}
+ QString richOriginal() {return richo;}
+
+ QString result(){ return res; }
+ QString original() {return orig; }
+ int score() {return sco;}
+//info contains originalkey,catalog,date,author etc...
+ ResultInfo info(){ResultInfo i; i.info="no info"; return i;}
+
+
+private:
+ QString res;
+ QString orig;
+ QString richr;
+ QString richo;
+ int sco;
+
+};
+
+class SearchFilter
+{
+ int filter; //placeholder
+};
+
+
+
+class DataBaseInterface : public QObject
+{
+
+ public:
+ //move result list typedef to AbstractAlgorthm or somewhere else
+ typedef QValueList<QueryResult> ResultList;
+ typedef QPair<DBItemMainKey,DBItemMainData> MainEntry;
+
+ DataBaseInterface( QString dir, DBSESettings *sets);
+ ~DataBaseInterface();
+
+ //Ask the Database to stop now.
+ void stop(bool b=true) {_stopNow=b;}
+
+ //Search words
+ ResultList wordsMatch(QString query,SearchFilter *filter=0,bool notify=true);
+
+ //Edit database functions.
+ //addEntry and sync all the tables
+ bool addEntry(QString original,QString translated,InputInfo *info);
+ //FIXME:implement me!
+ bool removeEntry(QString original);
+
+ //FIXME: go persistent!
+ QMap<QString,float> correlation(QString word,SearchFilter *filter=0,bool notify=true,float minSign=0.2);
+
+
+ // Read the database
+ MainEntry get(const QString& query,SearchFilter *filter=0);
+ MainEntry getFromIndex(uint i);
+ DBItemMultiIndex::IndexList getAlpha(const QString& query);
+ DBItemMultiIndex::IndexList getWordIndex(const QString& query);
+ MainEntry getSentence(const QString& query);
+
+ //Database status check functions
+ bool mainOk() {return main!=0;}
+ bool catalogOk() {return catalog!=0;}
+ bool alphaOk() {return alpha!=0;}
+ bool sentenceOk() {return sentence!=0;}
+ bool numindexOk() {return numindex!=0;}
+ bool wordsindexOk() {return wordsindex!=0;}
+ bool externalOk() {return external!=0;}
+ bool wordOk() {return word!=0;}
+ bool transwordOk() {return transword!=0;}
+ bool correlationOk() {return corr!=0;}
+ bool stopNow() {return _stopNow;}
+
+ // signals:
+ // void newResult(QueryResult);
+
+ DBSESettings *getSettings() {return settings;}
+
+ private:
+ DataBase * openMyDataBase(const QString& prefix,const QString& name,const QString& l,DBTYPE tt);
+ DataBase *main;
+ DataBase *numindex;
+ DataBase *wordsindex;
+ DataBase *catalog;
+ DataBase *alpha;
+ DataBase *sentence;
+ DataBase *word;
+ DataBase *external;
+ DataBase *transword;
+ DataBase *corr;
+ bool _stopNow;
+ DBSESettings *settings;
+
+ //FIXME:Move to KBabel common library.
+ public:
+ QString format( QString _s,QString t);
+ QString formatRegExp(QString _s, QString t, QString tre,QString stringSearch,QString stringReplace);
+ static QStringList words(QString s);
+ static QStringList sentences(QString s);
+ static QStringList sentencesSeparator(QString s);
+ static QString simple(QString str,bool ck=false);
+ static bool isUpper(QChar s);
+ static bool isLower(QChar s);
+
+ };
+
+#endif
+
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/dbentries.cpp b/kbabel/kbabeldict/modules/dbsearchengine2/dbentries.cpp
new file mode 100644
index 00000000..4f048f9c
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbentries.cpp
@@ -0,0 +1,171 @@
+#include "dbentries.h"
+#include <qdatastream.h>
+
+
+void DBItem::set()
+{
+ QBuffer b(mydata);
+ b.open( IO_WriteOnly );
+ QDataStream s(&b);
+ write(&s);
+ b.close();
+ set_data(mydata.data());
+ set_size(mydata.size());
+
+}
+ void DBItem::get()
+ {
+ mydata.resize(get_size());
+ mydata.duplicate((const char *)get_data(),(unsigned int)get_size());
+
+ QDataStream *s = new QDataStream(mydata,IO_ReadOnly);
+ read(s);
+ delete s;
+ }
+
+
+
+DBItemMainKey::DBItemMainKey()
+{
+ sstr="";
+ //set();
+}
+
+DBItemMainKey::DBItemMainKey(QString searchstring)
+{
+ sstr=searchstring;
+ //set();
+}
+
+void DBItemMainKey::read(QDataStream *s)
+{
+*s >> sstr;
+}
+
+void DBItemMainKey::write(QDataStream *s)
+{
+ *s << sstr;
+ }
+
+
+
+
+
+DBItemMainData::DBItemMainData()
+{
+ clear();
+ //set();
+}
+
+void DBItemMainData::clear()
+{
+ indexnumber=0;
+ translations.clear();
+ //set();
+}
+
+void DBItemMainData::read(QDataStream *s)
+{
+*s >> indexnumber >> translations;
+}
+
+void DBItemMainData::write(QDataStream *s)
+{
+ *s << (Q_UINT32)indexnumber << translations;
+}
+
+void DBItemMainData::addTranslation(QString str, unsigned int ref)
+{
+//get();
+ if(translations[str].find(ref)==translations[str].end()) // If it do not exists
+ translations[str].append(ref); //add a new reference.
+ else
+ {
+
+ }
+//set();
+
+}
+
+void DBItemMainData::removeTranslation(QString str, unsigned int ref)
+{
+//get();
+ translations[str].remove(ref);
+ if(translations[str].isEmpty())
+ translations.remove(str);
+//set();
+
+}
+
+void DBItemMainData::removeRef( unsigned int ref)
+{
+//get();
+QMapIterator<QString,QValueList<unsigned int> > it2;
+ for(QMapIterator<QString,QValueList<unsigned int> > it = translations.begin();
+ it!= translations.end(); /* it++*/)
+ { //Dirty hack
+ it2=it;
+ it++;
+ if(it2.data().find(ref)!=it2.data().end())
+ removeTranslation(it2.key(),ref);
+ }
+
+//set();
+}
+
+QStringList DBItemMainData::getTranslations()
+{
+//get();
+QStringList result;
+ for(QMapIterator<QString,QValueList<unsigned int> > it = translations.begin();
+ it!= translations.end(); it++)
+ result.append(it.key());
+
+return result;
+
+}
+
+QValueList<unsigned int> DBItemMainData::getReferences(QString str)
+{
+//get();
+return translations[str]; //this also add a "str" entry but we do not call set()!
+}
+
+
+
+DBItemMultiIndex::DBItemMultiIndex()
+{
+list.clear();
+//set();
+}
+
+void DBItemMultiIndex::addEntry(unsigned int index)
+{
+// get();
+ if(list.find(index)==list.end())
+ {
+ list.append(index);
+ qHeapSort(list);
+ // set();
+
+ }
+
+}
+
+void DBItemMultiIndex::removeEntry(unsigned int index)
+{
+// get();
+ list.remove(index);
+// set();
+}
+
+
+void DBItemMultiIndex::read(QDataStream *s)
+{
+*s >> list;
+}
+
+void DBItemMultiIndex::write(QDataStream *s)
+{
+ *s << list;
+ }
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/dbentries.h b/kbabel/kbabeldict/modules/dbsearchengine2/dbentries.h
new file mode 100644
index 00000000..0a40878c
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbentries.h
@@ -0,0 +1,170 @@
+#ifndef DBENTRIES_H
+#define DBENTRIES_H
+
+#include <db4/db_cxx.h>
+#include <qstring.h>
+#include <qbuffer.h>
+#include <qmap.h>
+#include <qstringlist.h>
+#include <qdatetime.h>
+
+class CatalogInfo
+{
+
+ QString author;
+ QDateTime datetime;
+ QString filename;
+ QString filepath;
+
+
+};
+
+class ResultInfo
+{
+public:
+//Common info
+ QString original; //placeholder
+
+//
+//Multi reference info
+ QValueList<CatalogInfo> catalogs;
+
+ QString info;
+
+};
+
+class InputInfo
+{
+public:
+ unsigned int ref() {return 1;}
+
+};
+
+class DBItem : public Dbt
+{
+public:
+
+ virtual ~DBItem(){}
+
+ virtual bool isEmpty(){return empty;}
+//void fromDbt(Dbt *dbt);
+
+ void set();
+ void get();
+
+
+protected:
+ virtual void read(QDataStream *s) = 0;
+ virtual void write(QDataStream *s) = 0;
+ QByteArray mydata;
+ bool empty;
+
+};
+
+class DBItemMainKey : public DBItem
+{
+ public:
+ DBItemMainKey();
+ DBItemMainKey(QString searchstring);
+
+
+ QString getString(){ return sstr;}
+
+private:
+
+ virtual void read(QDataStream *s);
+ virtual void write(QDataStream *s);
+
+ QString sstr;
+
+};
+
+
+class DBItemMainData : public DBItem
+{
+ public:
+
+ typedef QMapIterator<QString,QValueList<unsigned int> > TranslationIterator;
+ typedef QMap<QString,QValueList<unsigned int> > TranslationMap;
+
+ DBItemMainData();
+
+ QStringList getTranslations();
+ QValueList<unsigned int> getReferences(QString str);
+
+ void clear();
+
+
+//Add a translation with reference ref, if translation exists append
+// ref to the list of references
+ void addTranslation(QString str,unsigned int ref);
+ void removeTranslation(QString str,unsigned int ref);
+
+//remove any reference to ref, if ref is the only reference of a translation
+// the translation is removed
+ void removeRef(unsigned int ref);
+
+ unsigned int getIndexnumber(){ return indexnumber; }
+ void setIndexnumber(int i){ indexnumber=i; }
+
+private:
+
+ virtual void read(QDataStream *s);
+ virtual void write(QDataStream *s);
+
+ unsigned int indexnumber;
+ TranslationMap translations;
+
+};
+
+
+class DBItemMultiIndex : public DBItem
+{
+ public:
+ typedef QValueList<unsigned int> IndexList;
+
+ DBItemMultiIndex();
+ // DBItemMultiIndex(IndexList l);
+
+ void addEntry(unsigned int index);
+ void removeEntry(unsigned int index);
+
+ IndexList getList(){ return list;}
+ void clear() {list.clear();}
+
+private:
+
+ virtual void read(QDataStream *s);
+ virtual void write(QDataStream *s);
+
+ IndexList list;
+
+};
+
+
+class DBItemNum : public Dbt
+{
+ public:
+ DBItemNum(){
+ set_data(&num);
+ set_size(4);
+ num=0;
+ }
+ DBItemNum(unsigned int i){
+ set_data(&num);
+ set_size(4);
+ num=i;
+ }
+
+ unsigned int getNum(){ num=*(unsigned int *)get_data(); return num;}
+
+private:
+
+ unsigned int num;
+
+};
+
+
+
+
+#endif
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/dbscan.cpp b/kbabel/kbabeldict/modules/dbsearchengine2/dbscan.cpp
new file mode 100644
index 00000000..b19b2db2
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbscan.cpp
@@ -0,0 +1,280 @@
+/***************************************************************************
+ dbscan.cpp - Scan for po files to add in the DB
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000 by Andrea Rizzi
+ email : rizzi@kde.org
+ ***************************************************************************/
+
+/*
+ Translation search engine
+
+
+ Copyright 2000
+ Andrea Rizzi rizzi@kde.org
+
+ License GPL v 2.0
+
+*/
+#include "dbscan.h"
+#include <kconfig.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <kapplication.h>
+#include <kurl.h>
+#include <kdebug.h>
+#include <klineedit.h>
+#include <kurlrequester.h>
+#include <kcombobox.h>
+
+using namespace KBabel;
+
+MessagesSource::MessagesSource()
+{
+ //FIXMR: check if we should put something in that constructor
+}
+void MessagesSource::writeConfig(KConfigBase *config)
+{
+ config->writeEntry("Location",location.url());
+ config->writeEntry("LocationType",type);
+ config->writeEntry("ProjectName",projectName);
+ config->writeEntry("ProjectKeywords",projectKeywords);
+ config->writeEntry("Status",status);
+}
+
+void MessagesSource::readConfig(KConfigBase *config)
+{
+ location=config->readEntry("Location");
+ type=config->readNumEntry("LocationType",0);
+ projectName=config->readEntry("ProjectName");
+ projectKeywords=config->readEntry("ProjectKeywords");
+ status=config->readEntry("Status");
+
+}
+
+void MessagesSource::setDialogValues(SourceDialog *sd)
+{
+ sd->projectName->setText(projectName);
+ sd->projectKeywords->setText(projectKeywords);
+ sd->sourceLocation->setURL(location.url());
+ sd->status->setCurrentText(status);
+ sd->type->setCurrentItem(type);
+}
+void MessagesSource::getDialogValues(SourceDialog *sd)
+{
+ projectName=sd->projectName->text();
+ projectKeywords=sd->projectKeywords->text();
+ location=sd->sourceLocation->url();
+ status=sd->status->currentText();
+ type=sd->type->currentItem();
+}
+
+QValueList<KURL> MessagesSource::urls()
+{
+ QValueList<KURL> urlList;
+ if(type==0)
+ urlList.append(location);
+ if(type==1|| type==2)
+ urlList=filesInDir(location,(type==2));
+
+ return urlList;
+
+}
+
+QValueList<KURL> MessagesSource::filesInDir(KURL url,bool recursive)
+{
+ QValueList<KURL> result;
+ QDir d(url.path());
+ d.setMatchAllDirs(true);
+ kdDebug(0) << d.count() << " files in dir "<< url.path()<<endl;
+ const QFileInfoList* files = d.entryInfoList();
+ kdDebug(0) << files << endl;
+
+ // QPtrListIterator<QFileInfo> it(*files);
+ if(files){
+ for (QPtrListIterator<QFileInfo> fileit(*files); !fileit.atLast(); ++fileit )
+ {
+ if ((*fileit)->isDir())
+ {
+ if(recursive)
+ {
+ if((*fileit)->fileName()!="." && (*fileit)->fileName() !="..")
+ {
+ result+=filesInDir(KURL((*fileit)->absFilePath()),recursive);
+ kdDebug(0) << "Recursion done for " << (*fileit)->fileName() << endl;
+ }
+ }
+
+ }
+ else
+ {
+ kdDebug(0) << (*fileit)->fileName() << endl;
+ result.append(KURL((*fileit)->absFilePath()));
+ }
+ }
+ }
+ kdDebug(0) << result.count() << endl;
+
+ return result;
+}
+
+//FIXME: clean this class
+PoScanner::PoScanner(DataBaseInterface *dbi,
+ QObject *parent,const char *name):QObject(parent,name)
+{
+ di=dbi;
+ removeOldCatalogTranslation=true;
+ count=0;
+}
+
+bool PoScanner::scanPattern(QString pathName,QString pattern,bool rec)
+{
+int tot;
+//Only one progress bar!!
+
+bool pb=false;
+static bool called=false;
+if (!called)
+{ pb=true; count=0;}
+called=true;
+
+kdDebug(0) << QString("Scanning: %1, %2").arg(pathName).arg(pattern) << endl;
+
+if(pb)
+{
+emit patternStarted();
+emit patternProgress(0);
+}
+ QDir d(pathName,pattern);
+ d.setMatchAllDirs(true);
+ const QFileInfoList* files = d.entryInfoList();
+ tot=files->count();
+ QPtrListIterator<QFileInfo> it(*files);
+kdDebug(0) << tot << endl;
+ for ( int i=0; i<tot; i++ )
+ {
+ if ((*it)->isDir())
+ {
+ if(rec)
+ {
+ kdDebug(0) << d[i] << endl;
+ if(d[i]!="." && d[i]!="..")
+ scanPattern(pathName+"/"+d[i],pattern,true);
+ }
+ } else
+ {
+ kdDebug(0) << d[i] << endl;
+ scanFile(pathName+"/"+d[i]);
+ }
+
+ if(pb)
+
+ emit patternProgress(100*i/tot);
+
+
+ ++it;
+ }
+
+
+
+if(pb)
+emit patternProgress(100);
+
+
+if(pb)
+emit patternFinished();
+if(pb){called=false;count=0;}
+
+return true;
+}
+
+bool PoScanner::scanFile(QString fileName)
+{
+ KURL u(fileName);
+ return scanURL(u);
+}
+
+bool PoScanner::scanURL(KURL u)
+{
+
+
+emit fileStarted();
+
+Catalog * catalog=new Catalog(this,"ScanPoCatalog");
+
+QString pretty=u.prettyURL();
+QString location=pretty.right(pretty.length()-pretty.findRev("/")-1);
+
+connect(catalog,SIGNAL(signalProgress(int)),this,SIGNAL(fileLoading(int)));
+emit filename(location);
+emit fileProgress(0);
+emit fileLoading(0);
+
+bool error;
+
+ConversionStatus rr=catalog->openURL(u);
+if(rr != OK && rr !=RECOVERED_PARSE_ERROR )
+{
+ delete catalog;
+ return false;
+}
+emit fileLoading(100);
+
+QString author;
+if(rr != HEADER_ERROR)
+ author=catalog->lastTranslator();
+else author=QString("");
+
+//int catnum=dm->catalogRef(location,author,fileName);
+InputInfo ii;
+
+
+uint i,tot;
+tot=catalog->numberOfEntries();
+
+bool fuzzy;
+bool untra;
+
+
+for (i=0;i<tot;i++) //Skip header = ????
+{
+
+ if(i % 10==0)
+ {
+ emit fileProgress(100*i/tot);
+ emit added(count);
+ kapp->processEvents(100);
+ }
+
+ fuzzy=catalog->isFuzzy(i);
+ untra=catalog->isUntranslated(i);
+
+
+ if(!fuzzy && !untra)
+ {
+ int res;
+ QString msgid,msgstr;
+ msgid=catalog->msgid(i,true).first();
+ msgstr=catalog->msgstr(i).first();
+ res=di->addEntry(msgid,msgstr,&ii);
+ count+=res;
+ }
+
+
+}
+
+
+// kdDebug(0) << QString("File finished") << endl;
+
+emit fileProgress(0);
+emit fileLoading(0);
+emit fileFinished();
+// dm->loadInfo(); // Sync the list of catalogs NOT NEEDED (?)
+
+delete catalog;
+
+//clear();
+return true;
+
+}
+#include "dbscan.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/dbscan.h b/kbabel/kbabeldict/modules/dbsearchengine2/dbscan.h
new file mode 100644
index 00000000..990d556c
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbscan.h
@@ -0,0 +1,120 @@
+/***************************************************************************
+ dbscan.h -
+ -------------------
+ begin : Fri Sep 8 2000
+ copyright : (C) 2000 by Andrea Rizzi
+ email : rizzi@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. *
+ * *
+ ***************************************************************************/
+/*
+ Translation search engine
+ Copyright 2000
+ Andrea Rizzi rizzi@kde.org
+
+*/
+
+
+#ifndef _DBSCAN_H_
+#define _DBSCAN_H_
+
+#include <catalog.h>
+#include <kurl.h>
+#include "database.h"
+
+#include "sourcedialog.h"
+
+class KConfigBase;
+
+class MessagesSource
+{
+ //FIXME Use KURL and add network support
+
+ public:
+ MessagesSource();
+ void writeConfig(KConfigBase *config);
+ void readConfig(KConfigBase *config);
+ void setDialogValues(SourceDialog *sd);
+ void getDialogValues(SourceDialog *sd);
+
+ /**
+ * It returns a list of urls to scan, the list contains single file if type is "SingleFile"
+ * or a list of files if type is "SingleDir" or "RecDir"
+ */
+ QValueList<KURL> urls();
+
+ private:
+ QValueList<KURL> filesInDir(KURL url,bool recursive);
+
+ KURL location;
+ // The source type "SingleFile" =0, "SingleDirectory"=1, "RecursiveDirectory"=2
+ uint type;
+
+ /**
+ * A filter to apply on source files
+*/
+
+ SearchFilter filter;
+
+ QString projectName;
+ QString projectKeywords;
+ QString status;
+};
+
+
+class PoScanner : public QObject
+{
+ Q_OBJECT;
+
+ public:
+
+ PoScanner(DataBaseInterface *dbi,QObject *parent=0,const char *name=0);
+
+ /*
+ Scan a single PO file.
+ */
+ bool scanFile(QString fileName);
+
+ /*
+ Scan a single URL file.
+ */
+ bool scanURL(KURL u);
+
+
+ /*
+ Scan a list of space separated files with possible MetaCharacters
+ */
+ bool scanPattern(QString pathName,QString pattern="*.po",bool rec=false);
+
+
+
+
+ signals:
+ void fileStarted();
+ void fileProgress(int);
+ void fileFinished();
+ void fileLoading(int);
+ void patternStarted();
+ void patternProgress(int);
+ void patternFinished();
+ void added(int);
+ void filename(QString);
+ private:
+
+ // If true when a translation is found in a CATALOG the old translation for this CATALOG
+ // will be removed
+ bool removeOldCatalogTranslation;
+ int count;
+ DataBaseInterface *di;
+ // InfoItem cinfo;
+};
+
+
+#endif
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/dbse2.ui b/kbabel/kbabeldict/modules/dbsearchengine2/dbse2.ui
new file mode 100644
index 00000000..327a9d9d
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbse2.ui
@@ -0,0 +1,732 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>DBSearchEnginePrefWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>447</width>
+ <height>483</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tabWidget2</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>General</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Database</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>DB folder:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>dbDirectory</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>autoUpdate</cstring>
+ </property>
+ <property name="text">
+ <string>Automatic update in kbabel</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>New Entries</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Author:</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="2">
+ <property name="name">
+ <cstring>checkBox2</cstring>
+ </property>
+ <property name="text">
+ <string>From kbabel</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>kLineEdit1</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Algorithm</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Minimum score:</string>
+ </property>
+ </widget>
+ <spacer row="4" column="1">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Algorithms to Use</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Score:</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="6" column="2">
+ <property name="name">
+ <cstring>scoreWordByWord</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="1" column="2">
+ <property name="name">
+ <cstring>scoreGlossary</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>textLabel3_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Score:</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="0">
+ <property name="name">
+ <cstring>useSentence</cstring>
+ </property>
+ <property name="text">
+ <string>Fuzzy sentence archive</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>useGlossary</cstring>
+ </property>
+ <property name="text">
+ <string>Glossary</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>useExact</cstring>
+ </property>
+ <property name="text">
+ <string>Exact </string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="4" column="2">
+ <property name="name">
+ <cstring>scoreDivide</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="0" column="2">
+ <property name="name">
+ <cstring>scoreExact</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="3" column="2">
+ <property name="name">
+ <cstring>scoreSentence</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="4" column="0">
+ <property name="name">
+ <cstring>useDivide</cstring>
+ </property>
+ <property name="text">
+ <string>Sentence by sentence</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>useAlpha</cstring>
+ </property>
+ <property name="text">
+ <string>Alphanumeric</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>textLabel3_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Score:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="1">
+ <property name="name">
+ <cstring>textLabel3_2_4</cstring>
+ </property>
+ <property name="text">
+ <string>Score:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Score:</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="2" column="2">
+ <property name="name">
+ <cstring>scoreAlpha</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="6" column="1">
+ <property name="name">
+ <cstring>textLabel3_2_6</cstring>
+ </property>
+ <property name="text">
+ <string>Score:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="1">
+ <property name="name">
+ <cstring>textLabel3_2_5</cstring>
+ </property>
+ <property name="text">
+ <string>Score:</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="6" column="0">
+ <property name="name">
+ <cstring>useWordByWord</cstring>
+ </property>
+ <property name="text">
+ <string>Word by word</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="5" column="0">
+ <property name="name">
+ <cstring>useDynamic</cstring>
+ </property>
+ <property name="text">
+ <string>Dynamic dictionary</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="5" column="2">
+ <property name="name">
+ <cstring>scoreDynamic</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Preferred number of results:</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="2" column="2">
+ <property name="name">
+ <cstring>numberOfResult</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="3" column="2">
+ <property name="name">
+ <cstring>minScore</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Output</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Output Processing</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>firstCapital</cstring>
+ </property>
+ <property name="text">
+ <string>First capital letter match</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>allCapital</cstring>
+ </property>
+ <property name="text">
+ <string>All capital letter match</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>accelerator</cstring>
+ </property>
+ <property name="text">
+ <string>Accelerator symbol (&amp;&amp;)</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="1">
+ <property name="name">
+ <cstring>sameLetter</cstring>
+ </property>
+ <property name="text">
+ <string>Try to use same letter</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="title">
+ <string>Custom Rules</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Original string regexp:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="0" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kLineEdit1_2</cstring>
+ </property>
+ </widget>
+ <widget class="QListView" row="3" column="0" rowspan="3" colspan="2">
+ <column>
+ <property name="text">
+ <string>Enabled</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string>New Item</string>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>customRules</cstring>
+ </property>
+ </widget>
+ <spacer row="5" column="2">
+ <property name="name">
+ <cstring>spacer7_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton" row="4" column="2">
+ <property name="name">
+ <cstring>deleteRule</cstring>
+ </property>
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="3" column="2">
+ <property name="name">
+ <cstring>addRule</cstring>
+ </property>
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel3_3</cstring>
+ </property>
+ <property name="text">
+ <string>Replace string:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kLineEdit3</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="1" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kLineEdit2</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Translated regexp(search):</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Import</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox6</cstring>
+ </property>
+ <property name="title">
+ <string>Options</string>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>checkLang</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>30</y>
+ <width>150</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Check language</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>useFilters</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>60</y>
+ <width>140</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Use current filters</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>dateToday</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>90</y>
+ <width>180</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Set date to today</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox7</cstring>
+ </property>
+ <property name="title">
+ <string>Sources</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>editSource</cstring>
+ </property>
+ <property name="text">
+ <string>Edit</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>removeSource</cstring>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>scanSource</cstring>
+ </property>
+ <property name="text">
+ <string>Scan Now</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="0" column="1">
+ <property name="name">
+ <cstring>addSource</cstring>
+ </property>
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ <spacer row="4" column="1">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton" row="5" column="1">
+ <property name="name">
+ <cstring>scanAll</cstring>
+ </property>
+ <property name="text">
+ <string>Scan All</string>
+ </property>
+ </widget>
+ <widget class="QListBox" row="0" column="0" rowspan="6" colspan="1">
+ <property name="name">
+ <cstring>sourceList</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Filters</string>
+ </attribute>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/dbse2_factory.cpp b/kbabel/kbabeldict/modules/dbsearchengine2/dbse2_factory.cpp
new file mode 100644
index 00000000..9c286052
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbse2_factory.cpp
@@ -0,0 +1,83 @@
+
+#include <klocale.h>
+#include <kinstance.h>
+#include <kaboutdata.h>
+#include <kdebug.h>
+
+#include "dbse2_factory.h"
+#include "KDBSearchEngine2.h"
+
+
+extern "C"
+{
+ KDE_EXPORT void *init_kbabeldict_dbsearchengine2()
+// void *init_libdbsearchengine2()
+ {
+ return new DbSe2Factory;
+ }
+};
+
+
+KInstance *DbSe2Factory::s_instance = 0;
+KAboutData *DbSe2Factory::s_about = 0;
+
+
+DbSe2Factory::DbSe2Factory( QObject *parent, const char *name)
+ : KLibFactory(parent,name)
+{
+}
+
+DbSe2Factory::~DbSe2Factory()
+{
+ if(s_instance)
+ {
+ delete s_instance;
+ s_instance=0;
+ }
+
+ if(s_about)
+ {
+ delete s_about;
+ s_about=0;
+ }
+}
+
+
+QObject *DbSe2Factory::createObject( QObject *parent, const char *name,
+ const char *classname, const QStringList &)
+{
+ if(QCString(classname) != "SearchEngine")
+ {
+ kdError() << "not a SearchEngine requested" << endl;
+ return 0;
+ }
+
+ KDBSearchEngine2 *se = new KDBSearchEngine2(parent,name);
+
+ emit objectCreated(se);
+ return se;
+}
+
+
+KInstance *DbSe2Factory::instance()
+{
+ if(!s_instance)
+ {
+
+ s_about = new KAboutData( "kdbsearchengine2",
+ I18N_NOOP("Translation Database")
+ , "1.99" ,
+I18N_NOOP("A fast translation search engine based on databases")
+ , KAboutData::License_GPL
+ , I18N_NOOP("Copyright 2000-2003 by Andrea Rizzi")
+ ,0,0, "rizzi@kde.org");
+
+ s_about->addAuthor("Andrea Rizzi",0,"rizzi@kde.org");
+
+ s_instance = new KInstance(s_about);
+ }
+
+ return s_instance;
+}
+
+#include "dbse2_factory.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/dbse2_factory.h b/kbabel/kbabeldict/modules/dbsearchengine2/dbse2_factory.h
new file mode 100644
index 00000000..4285d53c
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbse2_factory.h
@@ -0,0 +1,26 @@
+#ifndef DBSE2_FACTORY_H
+#define DBSE2_FACTORY_H
+
+#include <klibloader.h>
+class KInstance;
+class KAboutData;
+
+class DbSe2Factory : public KLibFactory
+{
+ Q_OBJECT
+public:
+ DbSe2Factory( QObject *parent=0, const char *name=0);
+ ~DbSe2Factory();
+
+ 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/dbsearchengine2/dbsearchengine2.desktop b/kbabel/kbabeldict/modules/dbsearchengine2/dbsearchengine2.desktop
new file mode 100644
index 00000000..a46bfff1
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbsearchengine2.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Type=Service
+Name=Translation Database v2 for KBabelDict
+Name[bg]=БД с преводи v2 за KBabelDict
+Name[br]=Stlennvon geriaoueg v2 evit KBabelDict
+Name[bs]=Baza prijevoda v2 za KBabelDict
+Name[ca]=Base de dades de traducció v2 per a KBabelDict
+Name[cs]=Databáze překladů v2 pro KBabelDict
+Name[cy]=Cronfa ddata Cyfieithiadau v2 i KBabelDict
+Name[da]=Oversættelsesdatabase v2 for KBabelDict
+Name[de]=Übersetzungsdatenbank Version 2 für KBabelDict
+Name[el]=Βάση δεδομένων μετάφρασης έκδοση 2 για το KBabelDict
+Name[es]=Base de datos de traducciones v2 para KBabelDict
+Name[et]=KBabelDicti tõlgete andmebaas (versioon 2)
+Name[eu]=v2 itzulpen datu-basea KBabelDict-entzat
+Name[fa]=دادگان ترجمۀ نسخه ۲ برای KBabelDict
+Name[fi]=KBabelDict-ohjelman käännöstietokanta v2
+Name[fr]=Base de données des traductions v2 pour KBabelDict
+Name[ga]=Cuimhne Aistriúcháin (v2) le haghaidh KBabelDict
+Name[gl]=Base de datos de traducións v2 de KBabelDict
+Name[hi]=के-बेबल-डिक्श के लिए अनुवाद डाटाबेस वी2
+Name[hu]=Fordítási adatbázis (v2) a KBabelDicthez
+Name[is]=Þýðingagagnagrunnur v2 fyrir KBabel orðabókina
+Name[it]=Banca dati delle traduzioni v2 per KBabelDict
+Name[ja]=KBabelDict トランザクションデータベース v2
+Name[ka]=თარგმნის მონაცემთა ბაზა ვ2 KBabelDict-სთვის
+Name[kk]=KBabelDict-тың аударма деректер қорының 2-нұсқасы
+Name[lt]=KBabelDict vertimų duomenų bazės 2 versija
+Name[ms]=Pangkalan Data Penterjemahan v2 KBabelDict
+Name[nb]=Oversettelsesdatabase versjon 2 for KBabelDict
+Name[nds]=Översettendatenbank V2 för KBabelDict
+Name[ne]=KBabelDict का लागि अनुबाद डाटाबेस v2
+Name[nl]=Vertalingendatabase versie2 voor KBabelDict
+Name[nn]=Omsetjingsdatabase versjon 2 for KBabelDict
+Name[pa]=ਕੇਬਬੇਲ-ਸ਼ਬਦ-ਕੋਸ਼ ਲਈ ਅਨੁਵਾਦ ਡਾਟਾਬੇਸ ਵਰਜਨ2
+Name[pl]=Baza tłumaczeń v2 dla KBabelDict
+Name[pt]=Base de Dados de Traduções v2 do KBabelDict
+Name[pt_BR]=Banco de Dados de Traduções v2 para o KBabelDict
+Name[ru]=Версия 2 базы данных перевода для KBabelDict
+Name[sk]=Databáza prekladov v2 pre KBabelDict
+Name[sl]=Zbirka prevodov različice 2 za KBabelDict
+Name[sr]=Преводилачка база података v2 за KBabelDict
+Name[sr@Latn]=Prevodilačka baza podataka v2 za KBabelDict
+Name[sv]=Översättningsdatabas version 2 för Kbabeldict
+Name[ta]= Kபாபேலுக்கான மொழிபெயர்ப்பு தரவுத்தளம் v2
+Name[tg]=Тафсири 2 базаи маълумоти тарҷумаҳо барои KBabelDict
+Name[tr]=KBabelDict için Çeviri Veritabanı v2
+Name[uk]=Версія 2 бази даних перекладів для KBabelDict
+Name[zh_CN]=KBabelDict 的翻译数据库 v2
+Name[zh_TW]=KBabelDict 翻譯資料庫 v2
+X-KDE-Library=kbabeldict_dbsearchengine2
+ServiceTypes=KBabelDictModule
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/dbseprefwidget.ui b/kbabel/kbabeldict/modules/dbsearchengine2/dbseprefwidget.ui
new file mode 100644
index 00000000..c233265f
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/dbseprefwidget.ui
@@ -0,0 +1,1039 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>DBSearchEnginePref</class>
+<author>Andrea Rizzi &lt;rizzi@kde.org&gt;</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>DBSEPrefWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>414</width>
+ <height>426</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>DBSEPrefWidget</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>TabWidget6</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string></string>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget4</cstring>
+ </property>
+ <attribute name="title">
+ <string>Generic</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>ButtonGroup2</cstring>
+ </property>
+ <property name="title">
+ <string>Search Mode</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>allRB</cstring>
+ </property>
+ <property name="text">
+ <string>Search in whole database (slow)</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Scroll the whole database and return everything that matches
+according to the rules defined in tabs &lt;strong&gt; Generic &lt;/strong&gt;
+and &lt;strong&gt;Match&lt;/strong&gt;</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>slistRB</cstring>
+ </property>
+ <property name="text">
+ <string>Search in list of "good keys" (best)</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Search in a list of &lt;em&gt;good keys&lt;/em&gt; (see &lt;strong&gt;Good keys&lt;/strong&gt; tab) with rules defined in &lt;strong&gt;Search&lt;/strong&gt; tab.
+This is the best way to search because the &lt;em&gt;good keys&lt;/em&gt; list probably contains all the keys that match with your query. However, it is smaller than the whole database.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="2" column="0">
+ <property name="name">
+ <cstring>rlistRB</cstring>
+ </property>
+ <property name="text">
+ <string>Return the list of "good keys" (fast)</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Returns the whole &lt;em&gt;good keys&lt;/em&gt; list. Rules defined in &lt;strong&gt;Search&lt;/strong&gt; tab are ignored.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>caseSensitiveCB</cstring>
+ </property>
+ <property name="text">
+ <string>Case sensitive</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;If it is checked the search will be case sensitive. It is ignored if you use &lt;em&gt;Return the list of "good keys"&lt;/em&gt; search mode.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>normalizeCB</cstring>
+ </property>
+ <property name="text">
+ <string>Normalize white space</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Remove white spaces at the beginning and at the end of the phrase.
+It also substitutes groups of more than one space character with only one space character.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>removeContextCB</cstring>
+ </property>
+ <property name="text">
+ <string>Remove context comment</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Remove, if exists, the _:comment</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout11</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Character to be ignored:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>ignoreLE</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget5</cstring>
+ </property>
+ <attribute name="title">
+ <string>Search</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>ButtonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Matching Method</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>Spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>Spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="2" column="1">
+ <property name="name">
+ <cstring>containedCB</cstring>
+ </property>
+ <property name="text">
+ <string>Query is contained</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Match if query is contained in database string</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="1">
+ <property name="name">
+ <cstring>containsCB</cstring>
+ </property>
+ <property name="text">
+ <string>Query contains</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Match if query contains the database string</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>normalTextRB</cstring>
+ </property>
+ <property name="text">
+ <string>Normal text</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Consider the search string as normal text.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>equalCB</cstring>
+ </property>
+ <property name="text">
+ <string>Equal</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="tristate">
+ <bool>false</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Match if query and database string are equal</string>
+ </property>
+ </widget>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>Spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QRadioButton" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>RegExpRB</cstring>
+ </property>
+ <property name="text">
+ <string>Regular expression</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Consider the search string as a regular expression</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>GroupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Word Substitution</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;If you use one or two &lt;em&gt;word substitution&lt;/em&gt; each time you search a phrase with less than the specified number of words, the search engine will also search for all phrases that differ from the original one in one or two words.&lt;p&gt;
+&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
+If you search for &lt;em&gt;My name is Andrea&lt;/em&gt; and you have activated &lt;em&gt;one word substitution&lt;/em&gt; you may also find phrases like &lt;em&gt;My name is Joe&lt;/em&gt; or &lt;em&gt;Your name is Andrea&lt;/em&gt;.</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>Spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>oneWordSubCB</cstring>
+ </property>
+ <property name="text">
+ <string>Use one word substitution</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="tristate">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>Spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Max number of words in the query:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="2">
+ <property name="name">
+ <cstring>twoWordSubSB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maxValue">
+ <number>14</number>
+ </property>
+ <property name="value">
+ <number>10</number>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>twoWordSubCB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Use two word substitution</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Max number of words in the query:</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="5" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Layout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel5_3</cstring>
+ </property>
+ <property name="text">
+ <string>[A-Za-z0-9_%</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>regExpLE</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel6_2</cstring>
+ </property>
+ <property name="text">
+ <string>]</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="4" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Local characters for regular expressions:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="2">
+ <property name="name">
+ <cstring>oneWordSubSB</cstring>
+ </property>
+ <property name="maxValue">
+ <number>200</number>
+ </property>
+ <property name="minValue">
+ <number>2</number>
+ </property>
+ <property name="value">
+ <number>40</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget6</cstring>
+ </property>
+ <attribute name="title">
+ <string>Database</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>TextLabel7_2</cstring>
+ </property>
+ <property name="text">
+ <string>Database folder:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>dirInput</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>autoAddCB_2</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Auto add entry to database</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Automatically add an entry to the database if a new translation is notified by someone (may be kbabel)</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1_4</cstring>
+ </property>
+ <property name="text">
+ <string>Auto added entry author:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>authorLE</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Put here the name and email address that you want to use as &lt;em&gt;last translator&lt;/em&gt; filed when you auto-add entry to the database (e.g. when you modify a translation with kbabel).&lt;p&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QPushButton" row="4" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>scanFilePB</cstring>
+ </property>
+ <property name="text">
+ <string>Scan Single PO File</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="5" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>scanPB_2</cstring>
+ </property>
+ <property name="text">
+ <string>Scan Folder</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="6" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>scanrecPB</cstring>
+ </property>
+ <property name="text">
+ <string>Scan Folder &amp;&amp; Subfolders</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="8" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Layout5</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>filenameLB</cstring>
+ </property>
+ <property name="text">
+ <string>Scanning file:</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>entriesLB</cstring>
+ </property>
+ <property name="text">
+ <string>Entries added:</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="9" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QProgressBar" row="2" column="1">
+ <property name="name">
+ <cstring>processPB</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="centerIndicator">
+ <bool>true</bool>
+ </property>
+ <property name="indicatorFollowsStyle">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Total progress:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>TextLabel3_3</cstring>
+ </property>
+ <property name="text">
+ <string>Processing file:</string>
+ </property>
+ </widget>
+ <widget class="QProgressBar" row="0" column="1">
+ <property name="name">
+ <cstring>totalPB</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="centerIndicator">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QProgressBar" row="1" column="1">
+ <property name="name">
+ <cstring>loadingPB</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="centerIndicator">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Loading file:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QPushButton" row="10" column="2">
+ <property name="name">
+ <cstring>exportPB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Export...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="10" column="0">
+ <property name="name">
+ <cstring>statPB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Statistics</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="10" column="1">
+ <property name="name">
+ <cstring>repeatPB</cstring>
+ </property>
+ <property name="text">
+ <string>Repeated Strings</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Good Keys</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>GroupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Generic</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qml&gt;Here you can define how to fill the &lt;em&gt;good keys list&lt;/em&gt;.&lt;p&gt;
+You can set the minimum number of words of the query that a key must have to be inserted in the &lt;em&gt;good keys list&lt;/em&gt;.&lt;p&gt;
+You can also set the minimum number of words of the key that the query must have to insert the key in the list.&lt;p&gt;
+These two numbers are the percentage of the total number of words. If the result of this percentage is less than one, the engine will set it to one.&lt;p&gt;
+Finally you can set the maximum number of entries in the list.</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Minimum number of words of the key also in the query (%):</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ <widget class="QSlider" row="1" column="0">
+ <property name="name">
+ <cstring>thresholdSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>SpinBox5</cstring>
+ </property>
+ <property name="suffix">
+ <string>%</string>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Minimum number of query words in the key (%):</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="4" column="1">
+ <property name="name">
+ <cstring>maxSB</cstring>
+ </property>
+ <property name="maxValue">
+ <number>5000</number>
+ </property>
+ <property name="value">
+ <number>30</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="1">
+ <property name="name">
+ <cstring>SpinBox6</cstring>
+ </property>
+ <property name="suffix">
+ <string>%</string>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>TextLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>Max list length:</string>
+ </property>
+ </widget>
+ <widget class="QSlider" row="3" column="0">
+ <property name="name">
+ <cstring>thresholdOrigSL</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>GroupBox3_2</cstring>
+ </property>
+ <property name="title">
+ <string>Frequent Words</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Discard words more frequent than:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>freqSB</cstring>
+ </property>
+ <property name="suffix">
+ <string>/10000</string>
+ </property>
+ <property name="maxValue">
+ <number>10000</number>
+ </property>
+ <property name="lineStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>nothingCB</cstring>
+ </property>
+ <property name="text">
+ <string>Frequent words are considered as in every key</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>thresholdSL</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>SpinBox5</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>thresholdOrigSL</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>SpinBox6</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>SpinBox5</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>thresholdSL</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>SpinBox6</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>thresholdOrigSL</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in declaration">klocale.h</include>
+ <include location="global" impldecl="in declaration">kseparator.h</include>
+</includes>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/preferenceswidget.cpp b/kbabel/kbabeldict/modules/dbsearchengine2/preferenceswidget.cpp
new file mode 100644
index 00000000..7634a799
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/preferenceswidget.cpp
@@ -0,0 +1,98 @@
+#include <qradiobutton.h>
+#include <qslider.h>
+#include <qspinbox.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <klocale.h>
+#include <kfiledialog.h>
+#include <kurlrequester.h>
+#include <qtoolbutton.h>
+#include <klineedit.h>
+#include <kstandarddirs.h>
+#include <knuminput.h>
+
+#include "dbse2.h"
+#include "preferenceswidget.h"
+
+KDB2PreferencesWidget::KDB2PreferencesWidget(QWidget *parent, const char* name)
+ : PrefWidget(parent,name)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+// QLabel *label = new QLabel(i18n("Settings for KDE Database Search Engine"),this);
+// layout->addWidget(label);
+
+ dbpw = new DBSearchEnginePrefWidget(this);
+ dbpw->dbDirectory->setMode(KFile::Directory | KFile::LocalOnly);
+ dbpw->show();
+ layout->addWidget(dbpw);
+ setMinimumSize(300,300);
+
+ standard();
+
+// connect(dbpw->browseTB_3,SIGNAL(clicked()),SLOT(browse1()));
+
+ emit restoreNow(); //Fill with actual params.
+
+}
+
+KDB2PreferencesWidget::~KDB2PreferencesWidget()
+{
+}
+
+void KDB2PreferencesWidget::apply()
+{
+emit applyNow();
+}
+
+void KDB2PreferencesWidget::cancel()
+{
+emit restoreNow();
+}
+
+void KDB2PreferencesWidget::standard()
+{
+QString defaultDir;
+ KStandardDirs * dirs = KGlobal::dirs();
+ if(dirs)
+ {
+ defaultDir = dirs->saveLocation("data");
+ if(defaultDir.right(1)!="/")
+ defaultDir+="/";
+ defaultDir += "kbabeldict/dbsearchengine2";
+ }
+dbpw->dbDirectory->setURL(defaultDir);
+
+dbpw->autoUpdate->setChecked(true);
+
+dbpw->useSentence->setChecked(true);
+dbpw->useGlossary->setChecked(true);
+dbpw->useExact->setChecked(true);
+dbpw->useDivide->setChecked(true);
+dbpw->useAlpha->setChecked(true);
+dbpw->useWordByWord->setChecked(true);
+dbpw->useDynamic->setChecked(true);
+dbpw->scoreDivide->setValue(90);
+dbpw->scoreExact->setValue(100);
+dbpw->scoreSentence->setValue(90);
+dbpw->scoreWordByWord->setValue(70);
+dbpw->scoreGlossary->setValue(98);
+dbpw->scoreAlpha->setValue(98);
+dbpw->scoreDynamic->setValue(80);
+
+dbpw->numberOfResult->setValue(5);
+dbpw->minScore->setValue(60);
+
+dbpw->firstCapital->setChecked(true);
+dbpw->allCapital->setChecked(false);
+dbpw->accelerator->setChecked(true);
+dbpw->sameLetter->setChecked(true);
+dbpw->checkLang->setChecked(true);
+dbpw->useFilters->setChecked(false);
+dbpw->dateToday->setChecked(false);
+/*
+ */
+ //dbpw->dirInput->setURL(defaultDir);
+}
+
+#include "preferenceswidget.moc"
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/preferenceswidget.h b/kbabel/kbabeldict/modules/dbsearchengine2/preferenceswidget.h
new file mode 100644
index 00000000..4714fd13
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/preferenceswidget.h
@@ -0,0 +1,26 @@
+#ifndef PREFERENCESWIDGET_H
+#define PREFERENCESWIDGET_H
+
+#include "searchengine.h"
+#include "dbse2.h"
+
+class KDB2PreferencesWidget : public PrefWidget
+{
+ Q_OBJECT
+
+public:
+ KDB2PreferencesWidget(QWidget *parent=0, const char* name=0);
+ virtual ~KDB2PreferencesWidget();
+
+ virtual void apply();
+ virtual void cancel();
+ virtual void standard();
+ DBSearchEnginePrefWidget *dbpw;
+
+signals:
+ void applyNow();
+ void restoreNow();
+
+};
+
+#endif
diff --git a/kbabel/kbabeldict/modules/dbsearchengine2/sourcedialog.ui b/kbabel/kbabeldict/modules/dbsearchengine2/sourcedialog.ui
new file mode 100644
index 00000000..3f4030a0
--- /dev/null
+++ b/kbabel/kbabeldict/modules/dbsearchengine2/sourcedialog.ui
@@ -0,0 +1,266 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>SourceDialog</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>SourceDialog</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>415</width>
+ <height>385</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Edit Source</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton" row="2" column="0">
+ <property name="name">
+ <cstring>ok</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="2" column="2">
+ <property name="name">
+ <cstring>cancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Additional Informations</string>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>76</y>
+ <width>108</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Status: </string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>projectName</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>125</x>
+ <y>22</y>
+ <width>182</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>projectKeywords</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>125</x>
+ <y>49</y>
+ <width>182</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <property name="name">
+ <cstring>status</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>125</x>
+ <y>76</y>
+ <width>182</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>22</y>
+ <width>108</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Project name:</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>49</y>
+ <width>108</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Project keywords:</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>General Info</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>sourceName</cstring>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>Single File</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Single Folder</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Recursive Folder</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>type</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Source name:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="2" column="1">
+ <property name="name">
+ <cstring>sourceLocation</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Type:</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>filterDialog</cstring>
+ </property>
+ <property name="text">
+ <string>Setup Filter...</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Location:</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="0">
+ <property name="name">
+ <cstring>useFilter</cstring>
+ </property>
+ <property name="text">
+ <string>Use filter</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>ok</sender>
+ <signal>clicked()</signal>
+ <receiver>SourceDialog</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>cancel</sender>
+ <signal>clicked()</signal>
+ <receiver>SourceDialog</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/kbabeldict/modules/poauxiliary/Makefile.am b/kbabel/kbabeldict/modules/poauxiliary/Makefile.am
new file mode 100644
index 00000000..75509337
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/Makefile.am
@@ -0,0 +1,36 @@
+## Makefile.am for poauxiliary
+
+# 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_poauxiliary.la
+
+# set the include path for X, qt and KDE
+INCLUDES = -I$(srcdir)/../.. -I../../../common -I$(srcdir)/../../../common $(all_includes)
+
+
+kbabeldict_poauxiliary_la_SOURCES = poauxiliary.cpp preferenceswidget.cpp\
+ pa_factory.cpp pwidget.ui
+kbabeldict_poauxiliary_la_LIBADD = ../../libkbabeldictplugin.la ../../../common/libkbabelcommon.la $(LIB_KDEUI) $(LIB_KIO)
+kbabeldict_poauxiliary_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+
+
+
+# these are the headers for your project
+noinst_HEADERS = poauxiliary.h preferenceswidget.h pa_factory.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 = poauxiliary.rc
+
+kde_services_DATA = poauxiliary.desktop
+EXTRA_DIST = $(kde_services_DATA)
diff --git a/kbabel/kbabeldict/modules/poauxiliary/pa_factory.cpp b/kbabel/kbabeldict/modules/poauxiliary/pa_factory.cpp
new file mode 100644
index 00000000..1448e2b0
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/pa_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 "pa_factory.h"
+#include "poauxiliary.h"
+
+
+extern "C"
+{
+ KDE_EXPORT void *init_kbabeldict_poauxiliary()
+ {
+ return new PaFactory;
+ }
+}
+
+
+KInstance *PaFactory::s_instance = 0;
+KAboutData *PaFactory::s_about = 0;
+
+
+PaFactory::PaFactory( QObject *parent, const char *name)
+ : KLibFactory(parent,name)
+{
+}
+
+PaFactory::~PaFactory()
+{
+ if(s_instance)
+ {
+ delete s_instance;
+ s_instance=0;
+ }
+
+ if(s_about)
+ {
+ delete s_about;
+ s_about=0;
+ }
+}
+
+
+QObject *PaFactory::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 PoAuxiliary(parent,name);
+}
+
+
+KInstance *PaFactory::instance()
+{
+ if(!s_instance)
+ {
+ s_about = new KAboutData( "poauxiliary", I18N_NOOP("PO Auxiliary")
+ , "1.0"
+ , I18N_NOOP("A simple module for exact searching in a PO file")
+ , KAboutData::License_GPL
+ , "Copyright 2000, 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 "pa_factory.moc"
diff --git a/kbabel/kbabeldict/modules/poauxiliary/pa_factory.h b/kbabel/kbabeldict/modules/poauxiliary/pa_factory.h
new file mode 100644
index 00000000..8871a538
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/pa_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 PA_FACTORY_H
+#define PA_FACTORY_H
+
+#include <klibloader.h>
+class KInstance;
+class KAboutData;
+
+class PaFactory : public KLibFactory
+{
+ Q_OBJECT
+public:
+ PaFactory( QObject *parent=0, const char *name=0);
+ ~PaFactory();
+
+ 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/poauxiliary/poauxiliary.cpp b/kbabel/kbabeldict/modules/poauxiliary/poauxiliary.cpp
new file mode 100644
index 00000000..373f123d
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/poauxiliary.cpp
@@ -0,0 +1,554 @@
+/* ****************************************************************************
+ 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 <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kinstance.h>
+
+#include <qregexp.h>
+#include <qtimer.h>
+#include <qstylesheet.h>
+
+#include "poauxiliary.h"
+#include "preferenceswidget.h"
+#include "pa_factory.h"
+
+#include <resources.h>
+#include <catalog.h>
+
+using namespace KBabel;
+
+PoAuxiliary::PoAuxiliary(QObject *parent, const char *name)
+ : SearchEngine(parent, name)
+{
+ catalog = new Catalog(this, "PoAuxiliary::catalog");
+ prefWidget=0;
+ error=false;
+ stop=false;
+ active=false;
+ loading=false;
+ initialized=false;
+
+ ignoreFuzzy=true;
+
+ loadTimer = new QTimer(this);
+ connect(loadTimer,SIGNAL(timeout()),this,SLOT(loadAuxiliary()));
+
+ msgidDict.setAutoDelete(true);
+}
+
+PoAuxiliary::~PoAuxiliary()
+{
+ results.clear();
+}
+
+bool PoAuxiliary::isReady() const
+{
+ return !error;
+}
+
+
+bool PoAuxiliary::isSearching() const
+{
+ return active;
+}
+
+
+void PoAuxiliary::saveSettings(KConfigBase *config)
+{
+ if(autoUpdate && prefWidget && prefWidget->settingsChanged())
+ {
+ applySettings();
+ }
+
+ config->writeEntry("Auxiliary", url);
+ config->writeEntry("IgnoreFuzzy",ignoreFuzzy);
+}
+
+void PoAuxiliary::readSettings(KConfigBase *config)
+{
+ bool needLoading=false;
+
+ QString newPath = config->readEntry("Auxiliary"
+ ,"../../../de/messages/@DIR1@/@PACKAGE@.po");
+ if(!initialized)
+ {
+ url = newPath;
+ }
+ else if(newPath != url)
+ {
+ url = newPath;
+ needLoading = true;
+ }
+
+ ignoreFuzzy = config->readBoolEntry("IgnoreFuzzy",true);
+
+ if(needLoading && !loadTimer->isActive())
+ {
+ kdDebug(KBABEL_SEARCH) << "readSettings" << endl;
+ loadTimer->start(100,true);
+ }
+
+ restoreSettings();
+}
+
+PrefWidget *PoAuxiliary::preferencesWidget(QWidget *parent)
+{
+ prefWidget = new AuxiliaryPreferencesWidget(parent,"pocompendium_prefwidget");
+ connect(prefWidget, SIGNAL(applySettings()), this, SLOT(applySettings()));
+ connect(prefWidget, SIGNAL(restoreSettings())
+ , this, SLOT(restoreSettings()));
+
+ restoreSettings();
+
+ return prefWidget;
+}
+
+const KAboutData *PoAuxiliary::about() const
+{
+ return PaFactory::instance()->aboutData();
+}
+
+
+QString PoAuxiliary::name() const
+{
+ return i18n("PO Auxiliary");
+}
+
+QString PoAuxiliary::id() const
+{
+ return "poauxiliary";
+}
+
+QString PoAuxiliary::lastError()
+{
+ return errorMsg;
+}
+
+bool PoAuxiliary::startSearch(const QString& t, uint pluralForm, const SearchFilter*filter)
+{
+ QString text(t);
+ if(autoUpdate && prefWidget && prefWidget->settingsChanged())
+ {
+ applySettings();
+ }
+
+ if(!initialized)
+ {
+ loadAuxiliary();
+ }
+
+ if(error)
+ return false;
+
+ if(isSearching())
+ return false;
+
+ stop=false;
+ active = true;
+ emit started();
+
+ clearResults();
+
+ kapp->processEvents(100);
+
+ text.replace("\n","");
+
+ Entry *entry = msgidDict[text];
+ if(entry)
+ {
+ if( !(entry->fuzzy && ignoreFuzzy) )
+ {
+ SearchResult *result = new SearchResult;
+ result->requested =QStyleSheet::convertFromPlainText(text);
+ result->found = QStyleSheet::convertFromPlainText(text);
+ result->translation =
+ QStyleSheet::convertFromPlainText(entry->translation);
+
+ result->plainRequested = text;
+ result->plainFound=text;
+ result->plainTranslation=entry->translation;
+ result->score=100;
+
+ if(entry->fuzzy)
+ {
+ result->translation="<qt><font color=\"red\">"+i18n("fuzzy")
+ +"</font><hr/>" + result->translation+"</qt>";
+ }
+
+ TranslationInfo *info = new TranslationInfo;
+ info->location = auxPackage;
+ info->translator = auxTranslator;
+ info->description = entry->comment;
+ info->filePath = auxURL;
+ result->descriptions.append(info);
+
+ results.append(result);
+
+ emit numberOfResultsChanged(1);
+ emit resultFound(result);
+ }
+ }
+
+
+ active = false;
+ stop = false;
+ emit finished();
+
+ return true;
+}
+
+
+bool PoAuxiliary::startSearchInTranslation(const QString& text)
+{
+ if(autoUpdate && prefWidget && prefWidget->settingsChanged())
+ {
+ applySettings();
+ }
+
+ if(!initialized)
+ {
+ loadAuxiliary();
+ }
+
+ if(error)
+ return false;
+
+ if(isSearching())
+ return false;
+
+ stop=false;
+ active = true;
+ emit started();
+
+ clearResults();
+
+ kapp->processEvents(100);
+
+ Entry *entry = msgstrDict[text];
+ if(entry)
+ {
+ if( !(entry->fuzzy && ignoreFuzzy) )
+ {
+ SearchResult *result = new SearchResult;
+ result->requested =QStyleSheet::convertFromPlainText(entry->orig);
+ result->found = QStyleSheet::convertFromPlainText(entry->orig);
+ result->translation =
+ QStyleSheet::convertFromPlainText(text);
+
+ result->plainRequested = entry->orig;
+ result->plainFound=entry->orig;
+ result->plainTranslation=text;
+ result->score=100;
+
+ if(entry->fuzzy)
+ {
+ result->translation="<qt><font color=\"red\">"+i18n("fuzzy")
+ +"</font><hr/>" + result->translation+"</qt>";
+ }
+
+ TranslationInfo *info = new TranslationInfo;
+ info->location = auxPackage;
+ info->translator = auxTranslator;
+ info->description = entry->comment;
+ info->filePath = auxURL;
+ result->descriptions.append(info);
+
+ results.append(result);
+
+ emit numberOfResultsChanged(1);
+ emit resultFound(result);
+ }
+ }
+
+
+ active = false;
+ stop = false;
+ emit finished();
+
+ return true;
+}
+
+void PoAuxiliary::stopSearch()
+{
+ stop=true;
+}
+
+
+void PoAuxiliary::applySettings()
+{
+ if(!prefWidget)
+ return;
+
+ bool needLoading=false;
+
+ if(isSearching())
+ stopSearch();
+
+ QString newPath = prefWidget->url();
+ if(!initialized)
+ {
+ url = newPath;
+ }
+ else if(newPath != url)
+ {
+ url = newPath;
+ needLoading=true;
+ }
+
+ ignoreFuzzy = prefWidget->ignoreFuzzy();
+
+ if(needLoading && !loadTimer->isActive())
+ {
+ loadTimer->start(100,true);
+ }
+}
+
+void PoAuxiliary::restoreSettings()
+{
+ if(!prefWidget)
+ return;
+
+ prefWidget->setURL(url);
+ prefWidget->setIgnoreFuzzy(ignoreFuzzy);
+}
+
+void PoAuxiliary::loadAuxiliary()
+{
+ if(loadTimer->isActive())
+ loadTimer->stop();
+
+ if(loading)
+ return;
+
+ loading=true;
+ error=false;
+
+ QString path=url;
+
+ if(path.contains("@LANG@"))
+ {
+ path.replace("@LANG@",langCode);
+ }
+ if(path.contains("@PACKAGE@"))
+ {
+ int pos=package.findRev("/");
+ if( pos<0 ) pos=0;
+ path.replace("@PACKAGE@",package.mid(pos));
+ }
+ if(path.contains("@PACKAGEDIR@"))
+ {
+ QString packagedir;
+ int pos=package.findRev("/");
+ if( pos > 0 ) packagedir=package.left(pos);
+ else packagedir="";
+ path.replace("@PACKAGEDIR@",packagedir);
+ kdDebug(KBABEL_SEARCH) << "Packagedir found " << packagedir << endl;
+ }
+ QRegExp reg("@DIR[0-9]+@");
+ if(path.contains(reg))
+ {
+ int pos=reg.search(path);
+ int len = reg.matchedLength();
+
+ while(pos>=0)
+ {
+ QString num=path.mid(pos+4,len-5);
+
+ bool ok;
+ int number=num.toInt(&ok);
+ if(ok)
+ {
+ QString dir=directory(editedFile,number);
+ QString s("@DIR%1@");
+ path.replace(s.arg(number),dir);
+
+ pos+=dir.length();
+ }
+
+ pos=reg.search(path);
+ len = reg.matchedLength();
+ }
+ }
+
+ KURL u;
+ QRegExp rel("^[a-zA-Z]+:");
+ if(rel.search(path) >= 0)
+ {
+ u=path;
+ }
+ else if(path[0] != '/') // relative path
+ {
+ KURL temp(editedFile);
+ QString dir = temp.directory();
+ kdDebug(KBABEL_SEARCH) << dir << endl;
+ u.setPath(dir+"/"+path);
+ u.cleanPath();
+ kdDebug(KBABEL_SEARCH) << u.prettyURL() << endl;
+ }
+ else
+ {
+ u.setPath(path);
+ }
+
+ emit progressStarts(i18n("Loading PO auxiliary"));
+ connect(catalog, SIGNAL(signalProgress(int))
+ , this, SIGNAL(progress(int)));
+
+ ConversionStatus stat = catalog->openURL(u);
+ if( stat != OK && stat != RECOVERED_PARSE_ERROR)
+ {
+ kdDebug(KBABEL_SEARCH) << "error while opening file " << u.prettyURL() << endl;
+
+ if( !error )
+ {
+ error = true;
+ errorMsg = i18n("Error while trying to open file for PO Auxiliary module:\n%1")
+ .arg(u.prettyURL());
+ emit hasError(errorMsg);
+ }
+ }
+ else
+ {
+ error = false;
+ // build index for fast search
+ msgidDict.clear();
+ msgstrDict.clear();
+
+ emit progressStarts(i18n("Building index"));
+
+ 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);
+ }
+
+ Entry *e = new Entry;
+ // FIXME: should care about plural forms
+ e->orig = catalog->msgid(i).first();
+ e->orig.replace("\n","");
+ kdWarning() << "PoAuxialiary does not support plural forms" << endl;
+ e->translation = catalog->msgstr(i).first();
+ e->comment = catalog->comment(i);
+ e->fuzzy = catalog->isFuzzy(i);
+
+ msgidDict.insert(catalog->msgid(i,true).first(),e);
+ msgstrDict.insert(e->translation,e);
+ }
+
+ auxPackage = catalog->packageName();
+ auxURL = catalog->currentURL().url();
+ auxTranslator = catalog->lastTranslator();
+ }
+
+ disconnect(catalog, SIGNAL(signalProgress(int))
+ , this, SIGNAL(progress(int)));
+
+ emit progressEnds();
+
+ initialized=true;
+
+ loading=false;
+
+ catalog->clear();
+}
+
+
+void PoAuxiliary::setEditedFile(const QString& file)
+{
+ if(initialized && (url.contains("@DIR") || KURL::isRelativeURL(url))
+ && file!=editedFile && !loadTimer->isActive() )
+ {
+ initialized=false;
+ }
+
+ editedFile=file;
+}
+
+
+void PoAuxiliary::setEditedPackage(const QString& pack)
+{
+ if(initialized && url.contains("@PACKAGE@") && pack!=package
+ && !loadTimer->isActive() )
+ {
+ initialized=false;
+ }
+
+ package=pack;
+}
+
+
+void PoAuxiliary::setLanguageCode(const QString& lang)
+{
+ if(initialized && url.contains("@LANG@") && lang!=langCode
+ && !loadTimer->isActive() )
+ {
+ initialized=false;
+ }
+
+ langCode=lang;
+}
+
+bool PoAuxiliary::usesRichTextResults()
+{
+ return true;
+}
+
+QString PoAuxiliary::translate(const QString& text, uint pluralForm)
+{
+ if(!initialized)
+ {
+ loadAuxiliary();
+ }
+
+ if(error)
+ {
+ return QString::null;
+ }
+
+ Entry *entry = msgidDict[text];
+ if(entry)
+ {
+ return entry->translation;
+ }
+
+ return QString::null;
+}
+
+
+#include "poauxiliary.moc"
diff --git a/kbabel/kbabeldict/modules/poauxiliary/poauxiliary.desktop b/kbabel/kbabeldict/modules/poauxiliary/poauxiliary.desktop
new file mode 100644
index 00000000..5629930e
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/poauxiliary.desktop
@@ -0,0 +1,51 @@
+[Desktop Entry]
+Type=Service
+Name=Auxiliary PO Module for KBabelDict
+Name[bg]=Помощен PO модул за KBabelDict
+Name[bs]=Pomoćni PO modul za KBabelDict
+Name[ca]=Mòdul PO auxiliar per a KBabelDict
+Name[cs]=Doplňkový PO modul pro KBabelDict
+Name[cy]=Modiwl PO Ategol i KBabelDict
+Name[da]=Auxiliary PO-module for KBabelDict
+Name[de]=PO-Hilfsdatei-Modul für KBabelDict
+Name[el]=Άρθρωμα βοηθητικού PO για το KBabelDict
+Name[es]=Módulo PO auxiliar para KBabelDict
+Name[et]=KBabelDicti PO liitlasfaili moodul
+Name[eu]=PO modulu laguntzailea KBabelDict-entzat
+Name[fa]=پیمانۀ کمکی PO برای KBabelDict
+Name[fi]=KBabelDict-ohjelman PO-apumoduuli
+Name[fr]=Module de PO auxiliaire pour KBabelDict
+Name[gl]=Módulo de PO auxiliar para KBabelDict
+Name[hi]=के-बेबल-डिक्श के लिए ऑक्जिलरी पीओ मॉड्यूल
+Name[hu]=Kiegészítő PO modul a KBabelDicthez
+Name[is]=Viðbótar PO eining fyrir KBabel orðabókina
+Name[it]=Modulo ausiliario PO per KBabelDict
+Name[ja]=KBabelDict 補助 PO モジュール
+Name[ka]=დამხმარე PO მოდული KBabelDict-სთვის
+Name[kk]=KBabelDict-тың қосымша PO модулі
+Name[lt]=KBabelDict papildomo PO žodyno modulis
+Name[ms]=Modul Auksillari PO untuk KBabelDict
+Name[nb]=Hjelpeordlistemodul for KBabelDict
+Name[nds]=PO-Hülpdateimoduul för KBabelDict
+Name[ne]=KBabelDict का लागि सहायक पीओ मोड्युल
+Name[nl]=Alternatieve PO-module voor KBabelDict
+Name[nn]=Jamføringsmodul for KBabelDict
+Name[pa]=ਕੇਬਬੇਲ-ਸ਼ਬਦਕੋਸ਼ ਲਈ ਸਹਾਇਕ PO ਸਹਾਇਕ
+Name[pl]=Moduł pomocniczego pliku PO dla KBabelDict
+Name[pt]=Módulo de PO Auxiliar para o KBabelDict
+Name[pt_BR]=Módulo Auxiliar PO para o KBabelDict
+Name[ru]=Вспомогательный модуль PO для KBabelDict
+Name[sk]=Iný PO súbore pre KBabelDict
+Name[sl]=Dodatni modul PO za KBabelDict
+Name[sr]=Помоћни PO модул за KBabelDict
+Name[sr@Latn]=Pomoćni PO modul za KBabelDict
+Name[sv]=Hjälp-PO modul för Kbabeldict
+Name[ta]=Kபாபேலுக்கான இரண்டாம் PO கூறு
+Name[tg]=Модули ёрирасони PO барои KBabelDict
+Name[tr]=KBabelDict için Yardımcı PO Modülü
+Name[uk]=Модуль допоміжного словника PO для KBabelDict
+Name[zh_CN]=KBabelDict 的 PO 辅助词典模块
+Name[zh_TW]=KBabelDict 輔助 PO 模組
+X-KDE-Library=kbabeldict_poauxiliary
+ServiceTypes=KBabelDictModule
+Applications=kbabel
diff --git a/kbabel/kbabeldict/modules/poauxiliary/poauxiliary.h b/kbabel/kbabeldict/modules/poauxiliary/poauxiliary.h
new file mode 100644
index 00000000..27fecba6
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/poauxiliary.h
@@ -0,0 +1,136 @@
+/* ****************************************************************************
+ 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 POAUXILIARY_H
+#define POAUXILIARY_H
+
+#include "searchengine.h"
+
+#include <qguardedptr.h>
+#include <qdict.h>
+class QTimer;
+
+namespace KBabel
+{
+ class Catalog;
+}
+
+class AuxiliaryPreferencesWidget;
+
+class PoAuxiliary : public SearchEngine
+{
+ Q_OBJECT
+
+public:
+ PoAuxiliary(QObject *parent=0, const char *name=0);
+ virtual ~PoAuxiliary();
+
+ virtual bool isReady() const;
+
+ virtual QString translate(const QString& text, 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();
+
+ virtual bool usesRichTextResults();
+
+public slots:
+ virtual bool startSearch(const QString& text, unsigned int pluralForm
+ , const SearchFilter*filter);
+ virtual bool startSearchInTranslation(const QString& text);
+
+ virtual void stopSearch();
+
+ virtual void setEditedFile(const QString&);
+ virtual void setEditedPackage(const QString&);
+ virtual void setLanguageCode(const QString&);
+
+
+protected slots:
+ /** reads the current settings from the preferences dialog */
+ void applySettings();
+
+ /** sets the current settings in the preferences dialog */
+ void restoreSettings();
+
+ void loadAuxiliary();
+
+private:
+ QGuardedPtr<AuxiliaryPreferencesWidget> prefWidget;
+ KBabel::Catalog *catalog;
+ QString auxPackage;
+ QString auxTranslator;
+ QString auxURL;
+
+ QString url;
+ bool ignoreFuzzy;
+
+ QString editedFile;
+ QString package;
+ QString langCode;
+
+ bool error;
+ QString errorMsg;
+
+ bool stop;
+ bool active;
+ bool loading;
+ bool initialized;
+
+ QTimer *loadTimer;
+
+ struct Entry
+ {
+ QString orig;
+ QString translation;
+ QString comment;
+ bool fuzzy;
+ };
+
+ QDict<Entry> msgidDict;
+ QDict<Entry> msgstrDict;
+};
+
+#endif
diff --git a/kbabel/kbabeldict/modules/poauxiliary/preferenceswidget.cpp b/kbabel/kbabeldict/modules/poauxiliary/preferenceswidget.cpp
new file mode 100644
index 00000000..e8d48032
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/preferenceswidget.cpp
@@ -0,0 +1,115 @@
+/* ****************************************************************************
+ 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 <klineedit.h>
+#include <klocale.h>
+#include <kurlrequester.h>
+
+#include "preferenceswidget.h"
+#include "pwidget.h"
+
+AuxiliaryPreferencesWidget::AuxiliaryPreferencesWidget(QWidget *parent, const char* name)
+ : PrefWidget(parent,name)
+ , changed(false)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ prefWidget = new PWidget(this);
+ layout->addWidget(prefWidget);
+
+
+ connect(prefWidget->urlInput->lineEdit(),SIGNAL(textChanged(const QString&))
+ , this, SLOT(setChanged()));
+}
+
+AuxiliaryPreferencesWidget::~AuxiliaryPreferencesWidget()
+{
+}
+
+
+void AuxiliaryPreferencesWidget::apply()
+{
+ emit applySettings();
+}
+
+void AuxiliaryPreferencesWidget::cancel()
+{
+ emit restoreSettings();
+}
+
+void AuxiliaryPreferencesWidget::standard()
+{
+ prefWidget->urlInput->setURL("@PACKAGE@.po");
+ changed=true;
+}
+
+void AuxiliaryPreferencesWidget::setURL(const QString url)
+{
+ prefWidget->urlInput->setURL(url);
+ changed=false;
+}
+
+QString AuxiliaryPreferencesWidget::url()
+{
+ changed = false;
+ return prefWidget->urlInput->url();
+}
+
+bool AuxiliaryPreferencesWidget::ignoreFuzzy()
+{
+ changed=false;
+ return prefWidget->fuzzyBtn->isChecked();
+}
+
+void AuxiliaryPreferencesWidget::setIgnoreFuzzy(bool flag)
+{
+ prefWidget->fuzzyBtn->setChecked(flag);
+}
+
+bool AuxiliaryPreferencesWidget::settingsChanged() const
+{
+ return changed;
+}
+
+void AuxiliaryPreferencesWidget::setChanged()
+{
+ changed=true;
+}
+
+
+#include "preferenceswidget.moc"
diff --git a/kbabel/kbabeldict/modules/poauxiliary/preferenceswidget.h b/kbabel/kbabeldict/modules/poauxiliary/preferenceswidget.h
new file mode 100644
index 00000000..45488158
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/preferenceswidget.h
@@ -0,0 +1,77 @@
+/* ****************************************************************************
+ 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 PWidget;
+
+class AuxiliaryPreferencesWidget : public PrefWidget
+{
+ Q_OBJECT
+
+public:
+ AuxiliaryPreferencesWidget(QWidget *parent=0, const char* name=0);
+ virtual ~AuxiliaryPreferencesWidget();
+
+ virtual void apply();
+ virtual void cancel();
+ virtual void standard();
+
+ void setURL(const QString url);
+ QString url();
+
+ void setIgnoreFuzzy(bool);
+ bool ignoreFuzzy();
+
+ bool settingsChanged() const;
+
+signals:
+ void restoreSettings();
+ void applySettings();
+
+public:
+ PWidget *prefWidget;
+
+protected slots:
+ void setChanged();
+
+private:
+ bool changed;
+
+};
+
+#endif
diff --git a/kbabel/kbabeldict/modules/poauxiliary/pwidget.ui b/kbabel/kbabeldict/modules/poauxiliary/pwidget.ui
new file mode 100644
index 00000000..8179caed
--- /dev/null
+++ b/kbabel/kbabeldict/modules/poauxiliary/pwidget.ui
@@ -0,0 +1,133 @@
+<!DOCTYPE UI><UI>
+<class>PWidget</class>
+<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>335</width>
+ <height>306</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>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Path to auxiliary file:</string>
+ </property>
+ <property>
+ <name>buddy</name>
+ <cstring>urlInput</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>KURLRequester</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>urlInput</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fuzzyBtn</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Ignore fuzzy entries</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;qt&gt;&lt;p&gt;
+The following variables will be replaced in the path if available:
+&lt;ul&gt;
+&lt;li&gt;&lt;b&gt;@PACKAGE@&lt;/b&gt;: the name of the currently translated application or package&lt;/li&gt;
+&lt;li&gt;&lt;b&gt;@LANG@&lt;/b&gt;: the language code&lt;/li&gt;
+&lt;li&gt;&lt;b&gt;@DIR&lt;em&gt;n&lt;/em&gt;@&lt;/b&gt;: where n is a positive integer. This expands to the nth folder counted from the filename&lt;/li&gt;
+&lt;/ul&gt;&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ </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>
+</UI>
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>&amp;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 &amp;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&amp;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&amp;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&amp;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 &amp;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&amp;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>&amp;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&amp;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>
diff --git a/kbabel/kbabeldict/modules/tmx/Makefile.am b/kbabel/kbabeldict/modules/tmx/Makefile.am
new file mode 100644
index 00000000..f0f54b01
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/Makefile.am
@@ -0,0 +1,34 @@
+## Makefile.am for tmxcompendium
+
+# 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_tmxcompendium.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_tmxcompendium_la_SOURCES = tmxcompendium.cpp preferenceswidget.cpp \
+ pc_factory.cpp pwidget.ui tmxcompendiumdata.cpp
+
+kbabeldict_tmxcompendium_la_LIBADD = ../../libkbabeldictplugin.la ../../../common/libkbabelcommon.la $(LIB_KDEUI) $(LIB_KIO)
+kbabeldict_tmxcompendium_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+
+
+
+# these are the headers for your project
+noinst_HEADERS = tmxcompendium.h preferenceswidget.h pc_factory.h \
+ tmxcompendiumdata.h
+
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+kde_services_DATA = tmxcompendium.desktop
+EXTRA_DIST = $(kde_services_DATA)
diff --git a/kbabel/kbabeldict/modules/tmx/pc_factory.cpp b/kbabel/kbabeldict/modules/tmx/pc_factory.cpp
new file mode 100644
index 00000000..a3dcfdf9
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/pc_factory.cpp
@@ -0,0 +1,111 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+ 2002 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 <kinstance.h>
+#include <kaboutdata.h>
+#include <kdebug.h>
+
+#include "pc_factory.h"
+#include "tmxcompendium.h"
+
+
+extern "C"
+{
+ KDE_EXPORT void *init_kbabeldict_tmxcompendium()
+ {
+ 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 TmxCompendium(parent,name);
+}
+
+
+KInstance *PcFactory::instance()
+{
+ if(!s_instance)
+ {
+ s_about = new KAboutData( "tmxcompendium", I18N_NOOP("TMX Compendium")
+ , "1.0"
+ , I18N_NOOP("A module for searching in a TMX file")
+ , KAboutData::License_GPL
+ , "Copyright 2002, Stanislav Visnovsky"
+ ,0,0, "visnovsky@kde.org");
+
+ s_about->addAuthor("Matthias Kiefer",0,"kiefer@kde.org");
+ s_about->addAuthor("Stanislav Visnovsky",0,"visnovsky@kde.org");
+
+ s_instance = new KInstance(s_about);
+ }
+
+ return s_instance;
+}
+
+#include "pc_factory.moc"
diff --git a/kbabel/kbabeldict/modules/tmx/pc_factory.h b/kbabel/kbabeldict/modules/tmx/pc_factory.h
new file mode 100644
index 00000000..5ef08277
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/pc_factory.h
@@ -0,0 +1,62 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002 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.
+
+**************************************************************************** */
+
+
+#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/tmx/preferenceswidget.cpp b/kbabel/kbabeldict/modules/tmx/preferenceswidget.cpp
new file mode 100644
index 00000000..1202496d
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/preferenceswidget.cpp
@@ -0,0 +1,334 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002 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 <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"
+
+TmxCompendiumPreferencesWidget::TmxCompendiumPreferencesWidget(QWidget *parent, const char* name)
+ : PrefWidget(parent,name)
+ , changed(false)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ prefWidget = new TmxCompendiumPWidget(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->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.</p></qt>" );
+ QWhatsThis::add(prefWidget->caseBtn,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);
+}
+
+TmxCompendiumPreferencesWidget::~TmxCompendiumPreferencesWidget()
+{
+}
+
+
+void TmxCompendiumPreferencesWidget::apply()
+{
+ emit applySettings();
+}
+
+void TmxCompendiumPreferencesWidget::cancel()
+{
+ emit restoreSettings();
+}
+
+void TmxCompendiumPreferencesWidget::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);
+
+ changed=true;
+}
+
+void TmxCompendiumPreferencesWidget::setURL(const QString url)
+{
+ prefWidget->urlInput->setURL(url);
+ changed=false;
+}
+
+void TmxCompendiumPreferencesWidget::setCaseSensitive(bool on)
+{
+ prefWidget->caseBtn->setChecked(on);
+ changed=false;
+}
+
+void TmxCompendiumPreferencesWidget::setMatchEqual(bool on)
+{
+ prefWidget->equalBtn->setChecked(on);
+ changed=false;
+}
+
+void TmxCompendiumPreferencesWidget::setMatchNGram(bool on)
+{
+ prefWidget->ngramBtn->setChecked(on);
+ changed=false;
+}
+
+void TmxCompendiumPreferencesWidget::setMatchIsContained(bool on)
+{
+ prefWidget->isContainedBtn->setChecked(on);
+ changed=false;
+}
+
+void TmxCompendiumPreferencesWidget::setMatchContains(bool on)
+{
+ prefWidget->containsBtn->setChecked(on);
+ changed=false;
+}
+
+void TmxCompendiumPreferencesWidget::setWholeWords(bool on)
+{
+ prefWidget->wholeBtn->setChecked(on);
+ changed=false;
+}
+
+
+void TmxCompendiumPreferencesWidget::setMatchWords(bool on)
+{
+ prefWidget->hasWordBtn->setChecked(on);
+ changed=false;
+}
+
+
+
+QString TmxCompendiumPreferencesWidget::url()
+{
+ changed=false;
+ return prefWidget->urlInput->url();
+}
+
+bool TmxCompendiumPreferencesWidget::caseSensitive()
+{
+ changed=false;
+
+ return prefWidget->caseBtn->isChecked();
+}
+
+bool TmxCompendiumPreferencesWidget::matchEqual()
+{
+ changed=false;
+
+ return prefWidget->equalBtn->isChecked();
+}
+
+bool TmxCompendiumPreferencesWidget::matchNGram()
+{
+ changed=false;
+
+ return prefWidget->ngramBtn->isChecked();
+}
+
+bool TmxCompendiumPreferencesWidget::matchIsContained()
+{
+ changed=false;
+
+ return prefWidget->isContainedBtn->isChecked();
+}
+
+bool TmxCompendiumPreferencesWidget::matchContains()
+{
+ changed=false;
+
+ return prefWidget->containsBtn->isChecked();
+}
+
+bool TmxCompendiumPreferencesWidget::wholeWords()
+{
+ changed=false;
+
+ return prefWidget->wholeBtn->isChecked();
+}
+
+
+bool TmxCompendiumPreferencesWidget::matchWords()
+{
+ changed=false;
+
+ return prefWidget->hasWordBtn->isChecked();
+}
+
+
+
+bool TmxCompendiumPreferencesWidget::settingsChanged() const
+{
+ return changed;
+}
+
+void TmxCompendiumPreferencesWidget::setChanged()
+{
+ changed=true;
+}
+
+
+void TmxCompendiumPreferencesWidget::equalBtnToggled(bool on)
+{
+ if(!on)
+ {
+ if(!prefWidget->isContainedBtn->isChecked()
+ && !prefWidget->ngramBtn->isChecked()
+ && !prefWidget->containsBtn->isChecked()
+ && !prefWidget->hasWordBtn->isChecked())
+ {
+ prefWidget->equalBtn->setChecked(true);
+ }
+ }
+}
+
+void TmxCompendiumPreferencesWidget::ngramBtnToggled(bool on)
+{
+ if(!on)
+ {
+ if(!prefWidget->isContainedBtn->isChecked()
+ && !prefWidget->equalBtn->isChecked()
+ && !prefWidget->containsBtn->isChecked()
+ && !prefWidget->hasWordBtn->isChecked())
+ {
+ prefWidget->equalBtn->setChecked(true);
+ }
+ }
+}
+
+void TmxCompendiumPreferencesWidget::isContainedBtnToggled(bool on)
+{
+ if(!on)
+ {
+ if(!prefWidget->equalBtn->isChecked()
+ && !prefWidget->ngramBtn->isChecked()
+ && !prefWidget->containsBtn->isChecked()
+ && !prefWidget->hasWordBtn->isChecked())
+ {
+ prefWidget->isContainedBtn->setChecked(true);
+ }
+ }
+}
+
+void TmxCompendiumPreferencesWidget::containsBtnToggled(bool on)
+{
+ if(!on)
+ {
+ if(!prefWidget->isContainedBtn->isChecked()
+ && !prefWidget->ngramBtn->isChecked()
+ && !prefWidget->equalBtn->isChecked()
+ && !prefWidget->hasWordBtn->isChecked())
+ {
+ prefWidget->containsBtn->setChecked(true);
+ }
+ }
+}
+
+void TmxCompendiumPreferencesWidget::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/tmx/preferenceswidget.h b/kbabel/kbabeldict/modules/tmx/preferenceswidget.h
new file mode 100644
index 00000000..c8356c3d
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/preferenceswidget.h
@@ -0,0 +1,97 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002 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.
+
+**************************************************************************** */
+
+
+#ifndef PREFERENCESWIDGET_H
+#define PREFERENCESWIDGET_H
+
+#include "searchengine.h"
+
+class TmxCompendiumPWidget;
+
+class TmxCompendiumPreferencesWidget : public PrefWidget
+{
+ Q_OBJECT
+
+public:
+ TmxCompendiumPreferencesWidget(QWidget *parent=0, const char* name=0);
+ virtual ~TmxCompendiumPreferencesWidget();
+
+ 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 setMatchWords(bool);
+ void setWholeWords(bool);
+ void setCaseSensitive(bool);
+
+ QString url();
+ bool matchEqual();
+ bool matchNGram();
+ bool matchIsContained();
+ bool matchContains();
+ bool matchWords();
+ bool wholeWords();
+ bool caseSensitive();
+
+
+ bool settingsChanged() const;
+
+signals:
+ void restoreSettings();
+ void applySettings();
+
+public:
+ TmxCompendiumPWidget *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/tmx/pwidget.ui b/kbabel/kbabeldict/modules/tmx/pwidget.ui
new file mode 100644
index 00000000..ef6c9967
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/pwidget.ui
@@ -0,0 +1,216 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>TmxCompendiumPWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>TMXPWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>452</width>
+ <height>291</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>GroupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>&amp;Path to Compendium File</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>urlInput</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>ButtonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Options</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout4</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QCheckBox" row="0" column="1">
+ <property name="name">
+ <cstring>wholeBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Onl&amp;y whole words</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>caseBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Case sensiti&amp;ve</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>A text matches if:</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout3</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>equalBtn</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;qual to searched text</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="1">
+ <property name="name">
+ <cstring>hasWordBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Contains a &amp;word of searched text</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>isContainedBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Co&amp;ntained in searched text</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>ngramBtn</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Similar to searched text</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="1">
+ <property name="name">
+ <cstring>containsBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Contains searched te&amp;xt</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <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>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+<tabstops>
+ <tabstop>caseBtn</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in declaration">kseparator.h</include>
+</includes>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+</includehints>
+</UI>
diff --git a/kbabel/kbabeldict/modules/tmx/tmxcompendium.cpp b/kbabel/kbabeldict/modules/tmx/tmxcompendium.cpp
new file mode 100644
index 00000000..152bc536
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/tmxcompendium.cpp
@@ -0,0 +1,1007 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002 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 <qtextstream.h>
+#include <qtimer.h>
+
+#include "tmxcompendiumdata.h"
+#include "tmxcompendium.h"
+#include "preferenceswidget.h"
+#include "pc_factory.h"
+
+#include <catalogitem.h>
+
+// ngram length and minimal matching for fuzzy search
+#define NGRAM_LEN 3
+#define LIM_NGRAM 50
+
+static KStaticDeleter< QDict<TmxCompendiumData> > compDataDeleter;
+QDict<TmxCompendiumData> *TmxCompendium::_compDict = 0;
+
+TmxCompendium::TmxCompendium(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;
+ wholeWords=true;
+
+ matchEqual = true;
+ matchNGram = true;
+ matchIsContained = false;
+ matchContains = true;
+ matchWords=true;
+
+
+ loadTimer = new QTimer(this);
+ connect(loadTimer,SIGNAL(timeout()),this,SLOT(slotLoadCompendium()));
+}
+
+TmxCompendium::~TmxCompendium()
+{
+ if(isSearching())
+ {
+ stopSearch();
+ }
+
+ unregisterData();
+}
+
+bool TmxCompendium::isReady() const
+{
+ return (isSearching() || !error);
+}
+
+
+bool TmxCompendium::isSearching() const
+{
+ return (active || loading);
+}
+
+
+void TmxCompendium::saveSettings(KConfigBase *config)
+{
+ if(autoUpdate && prefWidget && prefWidget->settingsChanged())
+ {
+ applySettings();
+ }
+
+ config->writeEntry("CaseSensitive",caseSensitive);
+ 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 TmxCompendium::readSettings(KConfigBase *config)
+{
+ caseSensitive = config->readBoolEntry("CaseSensitive", false);
+ 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 *TmxCompendium::preferencesWidget(QWidget *parent)
+{
+ prefWidget = new TmxCompendiumPreferencesWidget(parent,"tmxcompendium_prefwidget");
+ connect(prefWidget, SIGNAL(applySettings()), this, SLOT(applySettings()));
+ connect(prefWidget, SIGNAL(restoreSettings())
+ , this, SLOT(restoreSettings()));
+
+ restoreSettings();
+
+ return prefWidget;
+}
+
+const KAboutData *TmxCompendium::about() const
+{
+ return PcFactory::instance()->aboutData();
+}
+
+
+QString TmxCompendium::name() const
+{
+ return i18n("TMX Compendium");
+}
+
+QString TmxCompendium::id() const
+{
+ return "tmxcompendium";
+}
+
+QString TmxCompendium::lastError()
+{
+ return errorMsg;
+}
+
+
+bool TmxCompendium::startSearch(const QString& text, uint pluralForm, const SearchFilter*)
+{
+ 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;
+ uint checkCounter=0;
+
+ const int *index = data->exactDict(text);
+ if(index)
+ {
+ foundIndices.append(*index);
+
+ SearchResult *result = new SearchResult;
+ result->requested = text;
+ result->found = data->msgid(*index);
+ result->translation = data->msgstr(*index);
+ result->score = 100;
+
+ TranslationInfo *info = new TranslationInfo;
+ info->location = directory(realURL,0);
+ info->translator = QString::null;
+ info->description = QString::null;
+ result->descriptions.append(info);
+
+ results.append(result);
+
+ emit numberOfResultsChanged(results.count());
+ emit resultFound(result);
+ }
+
+ QString searchStr=TmxCompendiumData::simplify(text);
+
+
+ if(!caseSensitive)
+ {
+ searchStr = searchStr.lower();
+ }
+
+ QString temp = searchStr;
+ temp = temp.lower();
+
+ const QValueList<int> *indexList = data->allDict(temp);
+ if(indexList)
+ {
+ QValueList<int>::ConstIterator it;
+ for( it = indexList->begin(); it != indexList->end(); ++it )
+ {
+ if(foundIndices.contains(*it))
+ {
+ continue;
+ }
+
+ QString origStr = data->msgid(*it);
+ origStr = TmxCompendiumData::simplify(origStr);
+
+
+ if(!caseSensitive)
+ {
+ origStr = origStr.lower();
+ }
+
+ if(origStr==searchStr)
+ {
+ foundIndices.append(*it);
+
+ SearchResult *result = new SearchResult;
+ result->requested = text;
+ result->found = data->msgid(*it);
+ result->translation = data->msgstr(*it);
+ // FIXME: handle plural forms properly
+ result->score = score(result->requested,result->found.first());
+
+ TranslationInfo *info = new TranslationInfo;
+ info->location = directory(realURL,0);
+ info->translator = QString::null;
+ info->description = QString::null;
+ result->descriptions.append(info);
+
+ addResult(result);
+ }
+ }
+ }
+
+ QStringList wList = TmxCompendiumData::wordList(searchStr);
+ for ( QStringList::Iterator wit = wList.begin()
+ ; wit != wList.end(); ++wit )
+ {
+ if(stop)
+ break;
+
+ 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( (100*(checkCounter+1))%data->numberOfEntries() < 100)
+ {
+ emit progress( (100*(checkCounter+1))/data->numberOfEntries());
+ }
+
+ kapp->processEvents(100);
+
+ QString origStr = data->msgid(*it);
+ origStr = TmxCompendiumData::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 && text.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 = TmxCompendiumData::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 = text;
+ result->found = data->msgid(*it);
+ result->translation = data->msgstr(*it);
+ // FIXME: handle plural forms properly
+ result->score = score(result->requested,(result->found.first()));
+
+ TranslationInfo *info = new TranslationInfo;
+ info->location = directory(realURL,0);
+ info->translator = QString::null;
+ info->description = QString::null;
+ result->descriptions.append(info);
+
+ addResult(result);
+ }
+ }
+ }
+ }
+
+
+ if( matchNGram ||
+ (!wholeWords && (matchContains || matchIsContained || matchWords))
+ )
+ {
+ 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(checkedIndices.contains(i))
+ {
+ continue;
+ }
+
+ checkedIndices.append(i);
+ checkCounter++;
+
+ if(foundIndices.contains(i))
+ {
+ continue;
+ }
+
+ kapp->processEvents(100);
+
+ if(i >= data->numberOfEntries())
+ {
+ breakLoop = true;
+ break;
+ }
+
+ if( (100*(checkCounter+1))%data->numberOfEntries() < 100)
+ {
+ emit progress( (100*(checkCounter+1))/data->numberOfEntries());
+ }
+
+ QString origStr = data->msgid(i);
+ origStr = TmxCompendiumData::simplify(origStr);
+
+ if(!caseSensitive)
+ {
+ origStr = origStr.lower();
+ }
+
+
+ // if there is an string which just contains ignored characters,
+ // continue
+ if(origStr.isEmpty() ||
+ (origStr.length() == 1 && text.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 = TmxCompendiumData::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 = text;
+ result->found = data->msgid(i);
+ result->translation = data->msgstr(i);
+ // FIXME: handle plural forms properly
+ result->score = score(result->requested,(result->found.first()));
+
+ TranslationInfo *info = new TranslationInfo;
+ info->location = directory(realURL,0);
+ info->translator = QString::null;
+ info->description = QString::null;
+ result->descriptions.append(info);
+
+ addResult(result);
+ }
+ }
+ }
+
+ if( (100*(checkCounter+1))/data->numberOfEntries() < 100 && !stop)
+ {
+ for(int i=(100*(checkCounter+1))/data->numberOfEntries(); i<=100; i++)
+ {
+ emit progress(i);
+ }
+ }
+
+
+ active = false;
+ stop = false;
+ emit finished();
+
+ return true;
+}
+
+void TmxCompendium::stopSearch()
+{
+ stop=true;
+}
+
+
+void TmxCompendium::applySettings()
+{
+ if(!prefWidget)
+ return;
+
+ if(isSearching())
+ stopSearch();
+
+ caseSensitive = prefWidget->caseSensitive();
+ 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 TmxCompendium::restoreSettings()
+{
+ if(!prefWidget)
+ return;
+
+ prefWidget->setCaseSensitive(caseSensitive);
+ prefWidget->setWholeWords(wholeWords);
+ prefWidget->setURL(url);
+
+ prefWidget->setMatchEqual(matchEqual);
+ prefWidget->setMatchNGram(matchNGram);
+ prefWidget->setMatchIsContained(matchIsContained);
+ prefWidget->setMatchContains(matchContains);
+ prefWidget->setMatchWords(matchWords);
+}
+
+void TmxCompendium::loadCompendium()
+{
+ if(!loading && !loadTimer->isActive())
+ loadTimer->start(100,true);
+}
+
+void TmxCompendium::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 tmxcompendium?" << endl;
+
+ loading=false;
+ return;
+ }
+
+ if(!data->initialized())
+ {
+ if(!data->active())
+ {
+ data->load(u,langCode);
+ recheckData();
+ if(error)
+ {
+ emit hasError(errorMsg);
+ }
+ }
+ else
+ {
+ connect(data, SIGNAL(progressEnds()), this, SLOT(recheckData()));
+ }
+ }
+ else
+ {
+ recheckData();
+ if(error)
+ {
+ emit hasError(errorMsg);
+ }
+ }
+
+ initialized=true;
+}
+
+void TmxCompendium::recheckData()
+{
+ if(data)
+ {
+ disconnect(data, SIGNAL(progressEnds()), this, SLOT(recheckData()));
+
+ error = data->hasErrors();
+ errorMsg = data->errorMsg();
+ }
+
+ loading=false;
+}
+
+QString TmxCompendium::maskString(QString s) const
+{
+ 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 TmxCompendium::addResult(SearchResult *result)
+{
+ if(results.last() && results.last()->score >= result->score)
+ {
+ results.append(result);
+ }
+ else
+ {
+ SearchResult *sr;
+ for(sr = results.first(); sr != 0; sr=results.next())
+ {
+ if(sr->score < result->score)
+ {
+ results.insert(results.at(),result);
+ emit resultsReordered();
+ break;
+ }
+ }
+
+ if(!sr)
+ {
+ results.append(result);
+ }
+ }
+
+ emit numberOfResultsChanged(results.count());
+ emit resultFound(result);
+}
+
+
+void TmxCompendium::setLanguageCode(const QString& lang)
+{
+ if(initialized && url.contains("@LANG@") && lang!=langCode
+ && !loadTimer->isActive() )
+ {
+ initialized=false;
+ }
+
+ langCode=lang;
+}
+
+QString TmxCompendium::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)
+ {
+ return data->msgstr(*index);
+ }
+
+ return QString::null;
+}
+
+QString TmxCompendium::fuzzyTranslation(const QString& text, int &score, 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->numberOfEntries();
+
+ QString searchStr = TmxCompendiumData::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
+ QString origStr = data->msgid(i);
+ origStr = TmxCompendiumData::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;
+ return data->msgstr(best_matching);
+ }
+
+ return QString::null;
+}
+
+
+void TmxCompendium::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 TmxCompendium::registerData()
+{
+ data = compendiumDict()->find(realURL);
+ if(!data)
+ {
+ data = new TmxCompendiumData;
+ 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 TmxCompendium::removeData()
+{
+ const QObject *s=sender();
+ if(s && s->inherits("TmxCompendiumData"))
+ {
+ const TmxCompendiumData *d=static_cast<const TmxCompendiumData*>(s);
+ if(d)
+ {
+ QDictIterator<TmxCompendiumData> it(*compendiumDict());
+ while(it.current())
+ {
+ if(it.current() == d)
+ {
+ if(!d->hasObjects())
+ {
+ compendiumDict()->remove(it.currentKey());
+ }
+
+ break;
+ }
+
+ ++it;
+ }
+ }
+
+ }
+}
+
+QDict<TmxCompendiumData> *TmxCompendium::compendiumDict()
+{
+ if(!_compDict)
+ {
+ _compDict=compDataDeleter.setObject( new QDict<TmxCompendiumData> );
+ _compDict->setAutoDelete(true);
+ }
+
+ return _compDict;
+}
+
+
+
+#include "tmxcompendium.moc"
diff --git a/kbabel/kbabeldict/modules/tmx/tmxcompendium.desktop b/kbabel/kbabeldict/modules/tmx/tmxcompendium.desktop
new file mode 100644
index 00000000..cae7d333
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/tmxcompendium.desktop
@@ -0,0 +1,50 @@
+[Desktop Entry]
+Type=Service
+Name=TMX Compendium Module for KBabelDict
+Name[bg]=TMX компендиум за KBabelDict
+Name[bs]=Modul TMX kompendijuma za KBabelDict
+Name[ca]=Mòdul del Compendi TMX per a KBabelDict
+Name[cs]=Modul s TMX kompendiem pro KBabelDict
+Name[cy]=Modiwl Compendiwm TMX i KBabelDict
+Name[da]=TMX kompendium-module for KBabelDict
+Name[de]=TMX-Kompendium-Modul für KBabelDict
+Name[el]=Άρθρωμα επιτομής TMX για το KBabelDict
+Name[es]=Módulo de compendio TMX para KBabelDict
+Name[et]=KBabelDicti TMX kompendiumi moodul
+Name[eu]=TMX laburpen modulua KBabelDict-entzat
+Name[fa]=پیمانۀ مختصر TMX برای KBabelDict
+Name[fi]=KBabelDict-ohjelman TMX-kokoelmatiedostomoduuli
+Name[fr]=Module de fichier de référence des TMX pour KBabelDict
+Name[gl]=Módulo de compendio TMX para KBabelDict
+Name[hi]=के-बेबल-डिक्श के लिए टीएमएक्स कम्पेंडियम मॉड्यूल
+Name[hu]=TMX összefoglaló modul a KBabelDicthez
+Name[is]=TMX ágrips eining fyrir KBabel orðabókina
+Name[it]=Modulo TMX Compendium per KBabelDict
+Name[ja]=KBabelDict TMX 要約モジュール
+Name[ka]=TMX კონსპექტის მოდული KBabelDict-სთვის
+Name[kk]=KBabelDict-тың TMX аудармалар жиынтық модулі
+Name[lt]=KBabelDict TMX tekstyno modulis
+Name[ms]=Modul Kompendium TMX untuk KBabelDict
+Name[nb]=TMX-kompendium-modul for KBabelDict
+Name[nds]=TMX-Kompendiummoduul för KBabelDict
+Name[ne]=KBabelDict का लागि टीएमएक्स संक्षेप मोड्युल
+Name[nl]=TMX-samenvattingmodule voor KBabelDict
+Name[nn]=TMX-kompendiemodul for KBabelDict
+Name[pa]=ਕੇਬਬੇਲ-ਸ਼ਬਦਕੋਸ਼ ਲਈ TMX ਅਨੁਵਾਦ ਮੈਡੀਊਲ
+Name[pl]=Moduł Kompendium TMX dla KBabelDict
+Name[pt]=Módulo de Compêndio de TMX para o KBabelDict
+Name[pt_BR]=Módulo de Compêndio TMX para o KBabelDict
+Name[ru]=Модуль описания TMX для KBabelDict
+Name[sk]=TMX kompendium pre KBabelDict
+Name[sl]=Modul zbornika TMX za KBabelDict
+Name[sr]=Модул TMX зборника за KBabelDict
+Name[sr@Latn]=Modul TMX zbornika za KBabelDict
+Name[sv]=TMX-kompendiemodul för Kbabeldict
+Name[ta]=Kபாபேலுக்கான காம்பென்டியம் TMX கூறு
+Name[tg]=Модули тасвири TMX барои KBabelDict
+Name[tr]=KBabelDict için TMX Özet Modülü
+Name[uk]=Модуль збірки перекладів TMX для KBabelDict
+Name[zh_CN]=KBabelDict 的 TMX 概要词典模块
+Name[zh_TW]=KBabelDict TMX 摘要模組
+X-KDE-Library=kbabeldict_tmxcompendium
+ServiceTypes=KBabelDictModule
diff --git a/kbabel/kbabeldict/modules/tmx/tmxcompendium.h b/kbabel/kbabeldict/modules/tmx/tmxcompendium.h
new file mode 100644
index 00000000..9a2f8fba
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/tmxcompendium.h
@@ -0,0 +1,137 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2000 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002 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.
+
+**************************************************************************** */
+
+#ifndef TMXCOMPENDIUM_H
+#define TMXCOMPENDIUM_H
+
+#include "tmxcompendiumdata.h"
+#include "searchengine.h"
+
+#include <qdict.h>
+#include <qfile.h>
+#include <qguardedptr.h>
+
+class TmxCompendiumPreferencesWidget;
+class KConfigBase;
+class QTimer;
+
+class TmxCompendium : public SearchEngine
+{
+ Q_OBJECT
+
+public:
+ TmxCompendium(QObject *parent=0, const char *name=0);
+ virtual ~TmxCompendium();
+
+ virtual bool isReady() const;
+
+ virtual QString translate(const QString& text, uint pluralForm);
+ virtual QString fuzzyTranslation(const QString& text, int &score, 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& text, uint pluralForm, const SearchFilter* filter);
+ 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 *);
+ QString maskString(QString string) const;
+
+ void registerData();
+ void unregisterData();
+
+private:
+ QGuardedPtr<TmxCompendiumPreferencesWidget> prefWidget;
+ TmxCompendiumData *data;
+ QTimer *loadTimer;
+
+ QString url;
+ QString realURL;
+ QString langCode;
+
+ bool caseSensitive;
+ 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<TmxCompendiumData> *_compDict;
+ static QDict<TmxCompendiumData> *compendiumDict();
+};
+
+#endif
diff --git a/kbabel/kbabeldict/modules/tmx/tmxcompendiumdata.cpp b/kbabel/kbabeldict/modules/tmx/tmxcompendiumdata.cpp
new file mode 100644
index 00000000..3fa84aa4
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/tmxcompendiumdata.cpp
@@ -0,0 +1,308 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2001 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002 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 "tmxcompendiumdata.h"
+
+#include <qdom.h>
+#include <qfile.h>
+
+#include <tagextractor.h>
+#include <resources.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kio/netaccess.h>
+
+using namespace KBabel;
+
+TmxCompendiumData::TmxCompendiumData(QObject *parent)
+ : QObject(parent)
+ , _active(false)
+ , _error(false)
+ , _initialized(false)
+ , _exactDict(9887)
+ , _allDict(9887)
+ , _wordDict(9887)
+{
+ _exactDict.setAutoDelete(true);
+ _allDict.setAutoDelete(true);
+ _wordDict.setAutoDelete(true);
+}
+
+
+bool TmxCompendiumData::load(const KURL& url, const QString& language)
+{
+ kdDebug(KBABEL_SEARCH) << "Load " << url.url() << " in " << language << endl;
+ if(_active)
+ return false;
+
+
+ _error = false;
+ _active = true;
+
+ _exactDict.clear();
+ _allDict.clear();
+ _wordDict.clear();
+
+
+ emit progressStarts(i18n("Loading TMX compendium"));
+
+ QDomDocument doc( "mydocument" );
+
+ QString target;
+
+ if( KIO::NetAccess::download( url, target ) )
+ {
+ QFile f( target );
+ if ( !f.open( IO_ReadOnly ) )
+ {
+ _error = true;
+ _errorMsg = i18n( "Cannot open the file." );
+ }
+ else if ( !doc.setContent( &f ) ) {
+ _error = true;
+ _errorMsg = i18n( "Cannot parse XML data." );
+ }
+ f.close();
+ KIO::NetAccess::removeTempFile(target);
+ } else {
+ _error = true;
+ _errorMsg = i18n( "Cannot open the file." );
+ }
+
+ QDomElement docElem = doc.documentElement();
+
+ if( docElem.tagName() != "tmx" || !(docElem.hasAttribute("version")
+ && docElem.attribute("version") == "1.4" ) )
+ {
+ _error = true;
+ _errorMsg = i18n( "Unsupported format.");
+ }
+
+
+ if( _error )
+ {
+ _errorMsg = i18n("Error while trying to read file for TMX Compendium module:\n"
+ "%1\n"
+ "Reason: %2")
+ .arg(url.prettyURL()).arg(_errorMsg);
+
+ kdDebug(KBABEL_SEARCH) << "Error: " << _errorMsg << endl;
+
+ emit progressEnds();
+
+ _active = false;
+ _initialized=true;
+
+ return false;
+ }
+
+ emit progressStarts(i18n("Building indices"));
+
+ QDomNodeList tuTags = docElem.elementsByTagName("tu");
+ uint total = tuTags.count();
+
+ _originals.clear();
+ _originals.resize(total);
+ _translations.clear();
+ _translations.resize(total);
+
+ uint lastindex = 0;
+
+ for(uint i=0; i < total; i++)
+ {
+ if( (100*(i+1))%total < 100 )
+ {
+ emit progress((100*(i+1))/total);
+ kapp->processEvents(100);
+ }
+
+ QDomNodeList tuvTags = tuTags.item(i).toElement().elementsByTagName("tuv");
+ QString english, other;
+ for( uint j = 0 ; j < tuvTags.count() ; j++ )
+ {
+ QDomElement el = tuvTags.item(j).toElement();
+ if( el.attribute("xml:lang").upper() == "EN" ) english = el.text();
+ if( el.attribute("xml:lang").upper().startsWith(language.upper()) )
+ other = el.text();
+ }
+
+ if( !english.isEmpty() && !other.isEmpty() )
+ {
+ kdDebug(KBABEL_SEARCH) << english << " to " << lastindex << endl;
+ _originals[lastindex] = english;
+ _translations[lastindex] = other;
+
+ QString temp = english;
+
+ int *index = new int(lastindex);
+ _exactDict.insert(temp,index);
+
+ temp = simplify(temp);
+ temp = temp.lower();
+
+ if(!temp.isEmpty() && temp.length() > 1)
+ {
+ QValueList<int> *indexList=_allDict[temp];
+
+ if(!indexList)
+ {
+ indexList = new QValueList<int>;
+ _allDict.insert(temp,indexList);
+ }
+
+ indexList->append(lastindex);
+
+ 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(lastindex);
+ }
+ }
+ }
+ lastindex++;
+ }
+ }
+
+
+ // 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;
+ }
+ }
+
+ if( lastindex == 0)
+ {
+ _error = true;
+ _errorMsg = i18n("Empty database.");
+ }
+
+ kdDebug(KBABEL_SEARCH) << "load done" << endl;
+
+ _initialized=true;
+
+ emit progressEnds();
+
+ _active = false;
+
+ return true;
+}
+
+const int* TmxCompendiumData::exactDict(const QString& text) const
+{
+ return _exactDict[text];
+}
+
+const QValueList<int>* TmxCompendiumData::allDict(const QString& text) const
+{
+ return _allDict[text];
+}
+
+const QValueList<int>* TmxCompendiumData::wordDict(const QString& text) const
+{
+ return _wordDict[text];
+}
+
+const QString TmxCompendiumData::msgid(const int index) const
+{
+ return _originals[index];
+}
+
+const QString TmxCompendiumData::msgstr(const int index) const
+{
+ return _translations[index];
+}
+
+
+void TmxCompendiumData::registerObject(QObject *obj)
+{
+ if(!_registered.containsRef(obj))
+ _registered.append(obj);
+}
+
+bool TmxCompendiumData::unregisterObject(QObject *obj)
+{
+ _registered.removeRef(obj);
+
+ return _registered.count()==0;
+}
+
+bool TmxCompendiumData::hasObjects() const
+{
+ return _registered.count()==0;
+}
+
+QString TmxCompendiumData::simplify(const QString& string)
+{
+ QString result;
+
+ TagExtractor te;
+ te.setString(string);
+ result=te.plainString();
+
+ result=result.simplifyWhiteSpace();
+ result=result.stripWhiteSpace();
+
+ return result;
+}
+
+QStringList TmxCompendiumData::wordList(const QString& string)
+{
+ QString result=TmxCompendiumData::simplify(string);
+
+ return QStringList::split(' ',result);
+}
+
+#include "tmxcompendiumdata.moc"
diff --git a/kbabel/kbabeldict/modules/tmx/tmxcompendiumdata.h b/kbabel/kbabeldict/modules/tmx/tmxcompendiumdata.h
new file mode 100644
index 00000000..bc88a92e
--- /dev/null
+++ b/kbabel/kbabeldict/modules/tmx/tmxcompendiumdata.h
@@ -0,0 +1,106 @@
+/* ****************************************************************************
+ This file is part of KBabel
+
+ Copyright (C) 2001 by Matthias Kiefer
+ <matthias.kiefer@gmx.de>
+ 2002 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.
+
+**************************************************************************** */
+#ifndef TMXCOMPENDIUMDATA_H
+#define TMXCOMPENDIUMDATA_H
+
+
+#include <kurl.h>
+#include <qdict.h>
+#include <qobject.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+#include <qvaluevector.h>
+#include <qptrlist.h>
+
+class TmxCompendiumData : public QObject
+{
+ Q_OBJECT
+
+public:
+ TmxCompendiumData(QObject *parent=0);
+
+ bool load(const KURL& url, const QString& language);
+
+ const int *exactDict(const QString& text) const;
+ const QValueList<int> *allDict(const QString& text) const;
+ const QValueList<int> *wordDict(const QString& text) const;
+
+ const QString msgid(const int index) const;
+ const QString msgstr(const int index) const;
+ const int numberOfEntries() const { return _exactDict.count(); }
+
+ 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;
+
+ QDict<int> _exactDict;
+ QDict< QValueList<int> > _allDict;
+ QDict< QValueList<int> > _wordDict;
+
+ QValueVector<QString> _originals;
+ QValueVector<QString> _translations;
+
+ QPtrList<QObject> _registered;
+};
+
+#endif
diff --git a/kbabel/kbabeldict/searchengine.cpp b/kbabel/kbabeldict/searchengine.cpp
new file mode 100644
index 00000000..95ab5694
--- /dev/null
+++ b/kbabel/kbabeldict/searchengine.cpp
@@ -0,0 +1,283 @@
+/* ****************************************************************************
+ 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 "searchengine.h"
+
+#include <kdebug.h>
+
+SearchResult::SearchResult()
+{
+ score=0;
+ descriptions.setAutoDelete(true);
+}
+
+SearchResult::SearchResult(const SearchResult& r)
+{
+ requested=r.requested;
+ found=r.found;
+ translation=r.translation;
+ plainTranslation=r.plainTranslation;
+ plainFound=r.plainFound;
+ plainRequested=r.plainRequested;
+ descriptions.setAutoDelete(true);
+ score=r.score;
+
+ QPtrListIterator<TranslationInfo> it(r.descriptions);
+ for ( ; it.current(); ++it )
+ {
+ TranslationInfo *ti=new TranslationInfo(*(*it));
+ descriptions.append(ti);
+ }
+
+}
+
+PrefWidget::PrefWidget(QWidget *parent, const char *name)
+ : QWidget(parent,name)
+{
+}
+
+PrefWidget::~PrefWidget()
+{
+}
+
+
+SearchEngine::SearchEngine(QObject *parent, const char *name)
+ : QObject(parent, name)
+{
+ autoUpdate=false;
+ results.setAutoDelete(true);
+}
+
+SearchEngine::~SearchEngine()
+{
+}
+
+bool SearchEngine::startSearchInTranslation(const QString&, unsigned int, const SearchFilter*)
+{
+ return true;
+}
+
+bool SearchEngine::usesRichTextResults()
+{
+ return false;
+}
+
+bool SearchEngine::isEditable()
+{
+ return false;
+}
+
+void SearchEngine::edit()
+{
+}
+
+void SearchEngine::setAutoUpdateOptions(bool activate)
+{
+ autoUpdate=activate;
+}
+
+SearchResult *SearchEngine::result(int n)
+{
+ SearchResult *r=0;
+
+ if(n >= 0 && n < (int)results.count())
+ r = results.at(n);
+
+ return r;
+}
+
+int SearchEngine::numberOfResults() const
+{
+ return results.count();
+}
+
+SearchResult *SearchEngine::nextResult()
+{
+ SearchResult *r= results.next();
+ if(r)
+ return r;
+ else
+ {
+ return 0;
+ }
+}
+
+SearchResult *SearchEngine::prevResult()
+{
+ SearchResult *r= results.prev();
+ if(r)
+ return r;
+ else
+ {
+ return 0;
+ }
+}
+
+SearchResult *SearchEngine::firstResult()
+{
+ SearchResult *r= results.first();
+ if(r)
+ return r;
+ else
+ {
+ return 0;
+ }
+}
+
+
+SearchResult *SearchEngine::lastResult()
+{
+ SearchResult *r= results.last();
+ if(r)
+ return r;
+ else
+ {
+ return 0;
+ }
+}
+
+void SearchEngine::clearResults()
+{
+ results.clear();
+ emit numberOfResultsChanged(0);
+}
+
+
+
+void SearchEngine::setEditedFile(const QString&)
+{
+}
+
+
+void SearchEngine::setEditedPackage(const QString&)
+{
+}
+
+void SearchEngine::setLanguageCode(const QString&)
+{
+}
+
+void SearchEngine::setLanguage(const QString&,const QString&)
+{
+}
+
+
+
+void SearchEngine::stringChanged(const QStringList&,const QString&,unsigned int, const QString&)
+{
+}
+
+
+QString SearchEngine::directory(const QString& path, int n)
+{
+ if(n<0)
+ return QString::null;
+
+ int begin=path.findRev('/');
+ int end=path.length();
+
+ if(begin < 0)
+ {
+ kdDebug() << "not found" << endl;
+ if(n==0)
+ return path;
+ else
+ return QString::null;
+ }
+
+ for(int i=0; i < n; i++)
+ {
+ if(begin==0)
+ {
+ return QString::null;
+ }
+
+ end = begin;
+ begin = path.findRev('/', end-1);
+
+ if(begin < 0)
+ {
+ return QString::null;
+ }
+ }
+
+ begin++;
+ return path.mid(begin,end-begin);
+}
+
+
+uint SearchEngine::score(const QString& orig, const QString& found)
+{
+ if(orig == found)
+ return 100;
+
+ uint scoreA = ngramMatch(found, orig);
+ uint scoreB = ngramMatch(orig,found);
+ uint score = QMIN(scoreA, scoreB);
+
+ QString f = found.lower();
+ QString o = orig.lower();
+
+ scoreA = ngramMatch(f, o);
+ scoreB = ngramMatch(o, f);
+ score = (QMIN(scoreA, scoreB)+score)/2;
+
+ return score;
+}
+
+uint SearchEngine::ngramMatch (const QString& text1, const QString& text2,
+ uint ngram_len)
+{
+ if (text1.length() < ngram_len || text2.length() < ngram_len)
+ return 0;
+
+ uint cnt=0;
+ uint ngram_cnt = text1.length() - ngram_len + 1;
+
+ for (uint i = 0; i < ngram_cnt; i++) {
+ if (text2.find(text1.mid(i,ngram_len)) >= 0)
+ cnt++;
+ }
+
+ return (cnt*100) / ngram_cnt;
+}
+
+
+bool SearchFilter::match( const TranslationInfo& toCheck )
+{
+ // FIXME: not implemented yet
+ return true;
+}
+
+#include "searchengine.moc"
diff --git a/kbabel/kbabeldict/searchengine.h b/kbabel/kbabeldict/searchengine.h
new file mode 100644
index 00000000..db722362
--- /dev/null
+++ b/kbabel/kbabeldict/searchengine.h
@@ -0,0 +1,534 @@
+/* ****************************************************************************
+ 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 SEARCH_ENGINE_H
+#define SEARCH_ENGINE_H
+
+#include <qdatetime.h>
+#include <qptrlist.h>
+#include <qobject.h>
+#include <qstring.h>
+#include <qwidget.h>
+#include <kaboutdata.h>
+#include <kconfigbase.h>
+
+
+/*
+ * This class gives information about the translator, etc.
+ * Information, that is not available in a specific implementation of
+ * the SearchEngine, should be left empty.
+ */
+class KDE_EXPORT TranslationInfo
+{
+public:
+ /**
+ * Information about the location, where this entry was found.
+ * For example the PO-file it was found in, etc.
+ * */
+ QString location;
+
+ /**
+ * The complete path of the file, where this entry was found
+ */
+ QString filePath;
+
+
+ /** The date of the last change */
+ QDateTime lastChange;
+
+ /** The language, the translation belongs to */
+ QString languageCode;
+
+ /**
+ * The translator of this string
+ * For example the translator found in the header of the PO-file.
+ */
+ QString translator;
+
+ /**
+ * The name of a project this translation is a part of.
+ */
+ QString projectName;
+
+ /**
+ * Keywords defined for @ref projectName. For example KDE_3_1_BRANCH (project branch)
+ */
+ QStringList projectKeywords;
+
+ /**
+ * Part/context in a project, for example "multimedia", "admin", etc.
+ */
+ QString projectContext;
+
+ /**
+ * Status of the translation, for example "approved", "spellchecked", "unknown"
+ */
+ QString status;
+
+ /**
+ * Additional information to be presented to the user, for example a comment
+ */
+ QString description;
+};
+
+
+/**
+ * This class contains a result from the search
+ * plus additional information where it was found,
+ * the date and time of the last change, the translator, etc.
+ */
+class KDE_EXPORT SearchResult
+{
+public:
+ SearchResult();
+ SearchResult(const SearchResult&);
+
+ /** The requested string to search for */
+ QString requested;
+
+ /** The string that, was found (a list if it is a plural form) */
+ QStringList found;
+
+ /** The number of a plural form to search for */
+ uint requestedPluralForm;
+
+ /** The translation of the found string */
+ QString translation;
+
+ /** The number of a plural form of the translated string found */
+ uint translationPluralForm;
+
+ /**
+ * This string contains the plain translation if you are
+ * using rich text. If you don't use rich text, you can leave
+ * it empty
+ */
+ QString plainTranslation;
+
+ /**
+ * This string contains the plain string, that was found, if you are
+ * using rich text. If you don't use rich text, you can leave
+ * it empty
+ */
+ QString plainFound;
+
+ /**
+ * This string contains the plain requested string if you are
+ * using rich text. If you don't use rich text, you can leave
+ * it empty
+ */
+ QString plainRequested;
+
+ /**
+ * Constains a score for the found translation. 0 means exact matching.
+ * The higher the score is, the worse is the matching.
+ * How to compute the score is not yet really clear :-(
+ */
+ int score;
+
+ QPtrList<TranslationInfo> descriptions;
+};
+
+/**
+ *
+ */
+class KDE_EXPORT SearchFilter
+{
+public:
+ SearchFilter() :
+ _projects()
+ , _location( QString::null )
+ , _languageCode( QString::null )
+ , _origLanguageCode( QString::null )
+ , _translators()
+ , _projectKeywords()
+ , _projectContexts()
+ , _translationStatus()
+ {}
+
+ virtual ~SearchFilter() {}
+
+ void setProjectName( const QString& project ) { _projects = project; }
+ void setProjectName( const QStringList& projects ) { _projects = projects; }
+
+ /**
+ * Information about the location, where this entry was found.
+ * For example the PO-file it was found in, etc.
+ * */
+ void setLocation( const QString& location) { _location = location; }
+ QString location() const { return _location; }
+
+ /** The original language, the translation was made from */
+ void setOriginalLanguage( const QString& languageCode) { _origLanguageCode = languageCode; }
+
+ /** The language, the translation belongs to */
+ void setTranslationLanguage( const QString& languageCode) { _languageCode = languageCode; }
+
+ /**
+ * The translator of this string
+ * For example the translator found in the header of the PO-file.
+ */
+ void setTranslator( const QString& translator) { _translators = translator ; }
+ void setTranslator( const QStringList& translators) { _translators = translators ; }
+
+ /**
+ * Keywords defined for @ref projectName. For example KDE_3_1_BRANCH (project branch)
+ */
+ void setProjectKeywords( const QStringList& projectKeywords ) { _projectKeywords = projectKeywords; }
+
+ /**
+ * Part/context in a project, for example "multimedia", "admin", etc.
+ */
+ void setProjectContext( const QString& projectContext) { _projectContexts = projectContext; }
+ void setProjectContext( const QStringList& projectContexts) { _projectContexts = projectContexts; }
+
+ /**
+ * Status of the translation, for example "approved", "spellchecked", "unknown"
+ */
+ void setStatus( const QString& translationStatus) { _translationStatus = translationStatus; }
+ void setStatus( const QStringList& translationStati) { _translationStatus = translationStati; }
+
+ /**
+ * The key method of the class - check, if the argument
+ * matches this filter.
+ */
+ virtual bool match( const TranslationInfo& toCheck );
+
+private:
+ QStringList _projects;
+ QString _location;
+ QString _languageCode;
+ QString _origLanguageCode;
+ QStringList _translators;
+ QStringList _projectKeywords ;
+ QStringList _projectContexts;
+ QStringList _translationStatus;
+};
+
+/**
+ * This class is the base class for the preferences widget used to
+ * setup the search engines. Inherit from this and reimplement all
+ * necessary function. The widget should not be bigger than 400x400.
+ * If you need more space, you maybe want to use a tabbed widget.
+ */
+class KDE_EXPORT PrefWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ PrefWidget(QWidget *parent, const char* name=0);
+ virtual ~PrefWidget();
+
+public slots:
+ /**
+ * apply changes of the settings
+ */
+ virtual void apply()=0;
+ /**
+ * revert made changes
+ */
+ virtual void cancel()=0;
+ /**
+ * set settings to the standard options
+ */
+ virtual void standard()=0;
+};
+
+
+class KDE_EXPORT SearchEngine : public QObject
+{
+ Q_OBJECT
+
+public:
+ SearchEngine(QObject *parent=0, const char *name=0);
+ virtual ~SearchEngine();
+
+
+
+ /** @return the search result number n */
+ virtual SearchResult *result(int n);
+
+ /** @return the number of search results */
+ virtual int numberOfResults() const;
+
+ /** @return true, if a search is currently active */
+ virtual bool isSearching() const = 0;
+
+
+ /** save the settings in the given config object */
+ virtual void saveSettings(KConfigBase *config) = 0;
+ virtual void readSettings(KConfigBase *config) = 0;
+
+ /** @returns true, if it was initialized correctly */
+ virtual bool isReady() const =0;
+
+
+ /**
+ * @returns the exact translation of text or a empty string
+ * if no exact match was found.
+ */
+ virtual QString translate(const QString& text, const uint pluralForm = 0)=0;
+
+ /**
+ * @returns the translation of text according to the plugin settings or a empty string
+ * if no match was found.
+ */
+ virtual QString searchTranslation(const QString&, int &score, const uint pluralForm = 0) {
+ Q_UNUSED(pluralForm);
+
+ score = 0; return QString::null;
+ }
+
+ /**
+ * @returns a fuzzy translation of text or a empty string
+ * if no good match was found.
+ */
+ virtual QString fuzzyTranslation(const QString& /*text*/, int &score, const uint pluralForm = 0) {
+ Q_UNUSED(pluralForm);
+
+ score = 0; return QString::null; };
+
+
+ /**
+ * Finds all messages belonging to package package. If nothing is found,
+ * the list is empty.
+ * @param package The name of the file, something like "kbabel.po"
+ * @param resultList Will contain the found messages afterwards
+ * @param error If an error occured, this should contain a description
+ *
+ * @return true, if successfull
+ */
+ virtual bool messagesForFilter(const SearchFilter* filter
+ , QValueList<SearchResult>& resultList, QString& error)
+ {
+ Q_UNUSED(filter);
+ Q_UNUSED(resultList);
+
+ error = i18n("not implemented");
+ return false;
+ }
+
+ /**
+ * @returns true, if the searchresults are given as rich text
+ * the default implementation returns false
+ */
+ virtual bool usesRichTextResults();
+
+ /** @returns true, if the the entries in the database can be edited */
+ virtual bool isEditable();
+
+ /**
+ * @returns a widget which lets the user setup all preferences of this
+ * search engine. The returned widget should not be bigger than
+ * 400x400. If you need more space, you maybe want to use
+ * a tabbed widget.
+ * @param parent the parent of the returned widget
+ */
+ virtual PrefWidget* preferencesWidget(QWidget *parent)=0;
+
+ /** @returns information about this SearchEngine */
+ virtual const KAboutData *about() const= 0;
+
+ /** @returns the i18n name of this search engine */
+ virtual QString name() const= 0;
+
+ /** @returns a untranslated name of this engine */
+ virtual QString id() const= 0;
+
+ /** @returns the last error message */
+ virtual QString lastError() = 0;
+
+
+ /**
+ * sets the engine to always ask the preferences dialog for settings
+ * if is existing before starting the search.
+ */
+ virtual void setAutoUpdateOptions(bool activate);
+
+
+ /**
+ * @returns how good @param text1 matches @param text2
+ * comparing 3-grams .. n-grams, the returned value is
+ * a number between 0 and 100. @param ngram_len should be
+ * a value between 3 and 5.
+ */
+ static uint ngramMatch (const QString& text1, const QString& text2,
+ uint ngram_len=3);
+
+public slots:
+ /**
+ * starts a search for string s in the original text
+ * @returns false, if an error occured. Use @ref lastError
+ * to get the last error message
+ */
+ virtual bool startSearch(const QString& s, uint pluralForm = 0, const SearchFilter* filter = 0) = 0;
+
+ /**
+ * starts a search for string s in the translated text
+ * @returns false, if an error occured. Use @ref lastError
+ * to get the last error message
+ */
+ virtual bool startSearchInTranslation(const QString& s, uint pluralForm = 0, const SearchFilter* filter = 0);
+
+
+ /** stops a search */
+ virtual void stopSearch() = 0;
+
+ /** @return the next search result */
+ virtual SearchResult *nextResult();
+
+ /** @return the previous search result */
+ virtual SearchResult *prevResult();
+
+ /** @return the first search result */
+ virtual SearchResult *firstResult();
+
+ /** @return the last search result */
+ virtual SearchResult *lastResult();
+
+ /** clears the result list */
+ virtual void clearResults();
+
+
+ /**
+ * This method allows a search engine to use different settings depending
+ * on the edited file. The default implementation does nothing.
+ * @param file The edited file with path
+ */
+ virtual void setEditedFile(const QString& file);
+
+ /**
+ * This method allows a search engine to use different settings depending
+ * on the edited package. The default implementation does nothing.
+ * @param package The name of the package, that is currently translated.
+ */
+ virtual void setEditedPackage(const QString& package);
+
+ /**
+ * This method allows a search engine to use different settings depending
+ * on the language code. The default implementation does nothing.
+ * @param lang The current language code (e.g. de).
+ */
+ virtual void setLanguageCode(const QString& lang);
+ virtual void setLanguage(const QString& languageCode, const QString& languageName);
+
+
+
+ /**
+ * This method is called, if something has been changed in the
+ * current file. See @ref setEditedFile if you want to know the file
+ * name
+ * @param orig the original string (list of all plural forms)
+ * @param translation the translated string
+ * @param pluralForm the number of the plural form of the translation
+ * @param description the additional description, e.g., a PO comment
+ */
+ virtual void stringChanged( const QStringList& orig, const QString& translated
+ , const uint translationPluralForm, const QString& description);
+
+ /**
+ * If the database is editable this slot should open an dialog to let
+ * the user edit the contents of the database.
+ */
+ virtual void edit();
+
+ /************ convenience functions for distring normalization, etc.**********/
+
+ /**
+ * @returns the n-th directory name of path. Counting is started at
+ * end of path. Example: directory("/usr/local/src/foobar, 0")
+ * returns "foobar", while n=1 would return "src"
+ * FIXME: isn't it a code duplication?
+ */
+ static QString directory(const QString& path, int n);
+
+ /**
+ * computes a score to assess the match of the two strings:
+ * 0 means exact match, bigger means worse
+ */
+ static uint score(const QString& orig, const QString& found);
+
+signals:
+ /** signals, that a new search started */
+ void started();
+
+ /**
+ * signals progress in searching
+ * @param p should be between 0 and 100
+ * */
+ void progress(int p);
+
+ /**
+ * Use this, if you want to set your own message on the
+ * progressbar or if you do something else then searching,
+ * maybe loading a big file
+ */
+ void progressStarts(const QString&);
+
+ void progressEnds();
+
+ /**
+ * signals, that the number of search results has changed
+ * @param n the new number of results
+ * */
+ void numberOfResultsChanged(int n);
+
+ /**
+ * signals, that the order of the results in the list has changed.
+ * For example because a better matching string has been prepended.
+ */
+ void resultsReordered();
+
+ /**
+ * signals, that a new result was found
+ */
+ void resultFound(const SearchResult*);
+
+ /**
+ * signals, that search has finished
+ */
+ void finished();
+
+ /**
+ * signals, that an error occured, for example, that you wasn't
+ * able to open a database.
+ */
+ void hasError(const QString& error);
+
+protected:
+ QPtrList<SearchResult> results;
+ bool autoUpdate;
+};
+
+
+#endif // SEARCH_ENGINE_H