summaryrefslogtreecommitdiffstats
path: root/kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.cpp')
-rw-r--r--kbabel/kbabeldict/modules/dbsearchengine/KDBSearchEngine.cpp1899
1 files changed, 1899 insertions, 0 deletions
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"