You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1112 lines
25 KiB
1112 lines
25 KiB
/***************************************************************************
|
|
Vocabulary Document for KDE Edu
|
|
-----------------------------------------------------------------------
|
|
copyright : (C) 1999-2001 Ewald Arnold
|
|
(C) 2001 The KDE-EDU team
|
|
(C) 2005 Peter Hedlung
|
|
email : peter.hedlund@kdemail.net
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "keduvocdocument.h"
|
|
|
|
#include <tdeapplication.h>
|
|
#include <tdelocale.h>
|
|
#include <kdebug.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tdeio/netaccess.h>
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <algorithm>
|
|
#include <functional>
|
|
#include <vector>
|
|
using namespace std;
|
|
|
|
#include <iostream>
|
|
|
|
#include <float.h>
|
|
|
|
#include "keduvockvtmlwriter.h"
|
|
#include "keduvockvtmlreader.h"
|
|
#include "leitnersystem.h"
|
|
//#include "prefs.h"
|
|
|
|
//********************************************************
|
|
// KEduVocDocument
|
|
//********************************************************
|
|
|
|
KEduVocDocument::KEduVocDocument(TQObject * /*parent*/)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
|
|
KEduVocDocument::~KEduVocDocument()
|
|
{
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setVersion (const TQString & vers)
|
|
{
|
|
doc_version = vers;
|
|
}
|
|
|
|
|
|
void KEduVocDocument::getVersion(int &, int &, int &)
|
|
{
|
|
}
|
|
|
|
|
|
void KEduVocDocument::Init ()
|
|
{
|
|
lesson_descr.clear();
|
|
type_descr.clear();
|
|
tense_descr.clear();
|
|
langs.clear();
|
|
sort_lang.clear();
|
|
extraSizehints.clear();
|
|
sizehints.clear();
|
|
vocabulary.clear();
|
|
dirty = false;
|
|
sort_allowed = true;
|
|
unknown_attr = false;
|
|
unknown_elem = false;
|
|
sort_lesson = false;
|
|
setCurrentLesson (0);
|
|
queryorg = "";
|
|
querytrans = "";
|
|
doc_url.setFileName(i18n("Untitled"));
|
|
doctitle = "";
|
|
author = "";
|
|
|
|
activeLeitnerSystem = false;
|
|
leitnerSystem = 0;
|
|
}
|
|
|
|
|
|
bool KEduVocDocument::open(const KURL& url, bool /*append*/)
|
|
{
|
|
Init();
|
|
if (!url.isEmpty())
|
|
doc_url = url;
|
|
|
|
// TODO EPT connect( this, TQT_SIGNAL(progressChanged(KEduVocDocument*,int)), parent, TQT_SLOT(slotProgress(KEduVocDocument*,int)) );
|
|
|
|
TQString tmpfile;
|
|
if (TDEIO::NetAccess::download( url, tmpfile, 0 ))
|
|
{
|
|
TQFile f(tmpfile);
|
|
if (!f.open(IO_ReadOnly))
|
|
{
|
|
KMessageBox::error(0, i18n("<qt>Cannot open file<br><b>%1</b></qt>").arg(url.path()));
|
|
return false;
|
|
}
|
|
|
|
FileType ft = detectFT(url.path());
|
|
|
|
bool read = false;
|
|
while (!read) {
|
|
|
|
TQApplication::setOverrideCursor( waitCursor );
|
|
switch (ft) {
|
|
case kvtml:
|
|
{
|
|
KEduVocKvtmlReader kvtmlReader(&f);
|
|
read = kvtmlReader.readDoc(this);
|
|
}
|
|
break;
|
|
|
|
case vt_lex:
|
|
{
|
|
TQTextStream is (&f);
|
|
//TODO read = loadFromLex (is);
|
|
}
|
|
break;
|
|
|
|
case vt_vcb:
|
|
{
|
|
TQTextStream is (&f);
|
|
//TODO read = loadFromVcb (is);
|
|
}
|
|
break;
|
|
|
|
case csv:
|
|
{
|
|
TQTextStream is(&f);
|
|
//TODO read = loadFromCsv(is);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
KEduVocKvtmlReader kvtmlReader(&f);
|
|
read = kvtmlReader.readDoc(this);
|
|
}
|
|
}
|
|
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
if (!read) {
|
|
if (unknown_attr || unknown_elem ) {
|
|
Init();
|
|
return false;
|
|
}
|
|
// TODO new readers provide an explicite error message
|
|
// the two messages should be merged
|
|
TQString format = i18n("Could not load \"%1\"\nDo you want to try again?");
|
|
TQString msg = format.arg(url.path());
|
|
int result = KMessageBox::warningContinueCancel(0, msg,
|
|
kapp->makeStdCaption(i18n("I/O Failure")),
|
|
i18n("&Retry"));
|
|
if ( result == KMessageBox::Cancel ) {
|
|
Init();
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
f.close();
|
|
TDEIO::NetAccess::removeTempFile( tmpfile );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
bool KEduVocDocument::saveAs(TQObject * /*parent*/, const KURL & url, FileType ft, const TQString & generator)
|
|
{
|
|
// connect( this, TQT_SIGNAL(progressChanged(KEduVocDocument*,int)), parent, TQT_SLOT(slotProgress(KEduVocDocument*,int)) );
|
|
|
|
KURL tmp (url);
|
|
|
|
if (ft == automatic)
|
|
{
|
|
if (tmp.path().right(strlen("." KVTML_EXT)) == "." KVTML_EXT)
|
|
ft = kvtml;
|
|
else if (tmp.path().right(strlen("." VT5_LEX_EXT)) == "." VT5_LEX_EXT)
|
|
ft = vt_lex;
|
|
else if (tmp.path().right(strlen("." VCB_EXT)) == "." VCB_EXT)
|
|
ft = vt_vcb;
|
|
else if (tmp.path().right(strlen("." CSV_EXT)) == "." CSV_EXT)
|
|
ft = csv;
|
|
else
|
|
{
|
|
tmp.setFileName(tmp.path() + "." KVTML_EXT);
|
|
ft = kvtml;
|
|
}
|
|
}
|
|
|
|
bool saved = false;
|
|
while (!saved)
|
|
{
|
|
|
|
TQFile f(tmp.path());
|
|
|
|
if (!f.open(IO_WriteOnly))
|
|
{
|
|
KMessageBox::error(0, i18n("<qt>Cannot write to file<br><b>%1</b></qt>").arg(tmp.path()));
|
|
return false;
|
|
}
|
|
|
|
TQApplication::setOverrideCursor( waitCursor );
|
|
switch (ft) {
|
|
case kvtml: {
|
|
KEduVocKvtmlWriter kvtmlWriter(&f);
|
|
saved = kvtmlWriter.writeDoc(this, generator);
|
|
}
|
|
break;
|
|
|
|
case vt_lex: {
|
|
TQTextStream os( &f ); // serialize using f
|
|
//TODO saved = saveToLex(os, title);
|
|
}
|
|
break;
|
|
|
|
case vt_vcb: {
|
|
TQTextStream os( &f ); // serialize using f
|
|
//TODO saved = saveToVcb(os, title);
|
|
}
|
|
break;
|
|
|
|
case csv: {
|
|
TQTextStream os( &f ); // serialize using f
|
|
//TODO saved = saveToCsv(os, title);
|
|
}
|
|
break;
|
|
|
|
default: {
|
|
kdError() << "kvcotrainDoc::saveAs(): unknown filetype" << endl;
|
|
}
|
|
break;
|
|
}
|
|
f.close();
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
if (!saved) {
|
|
// TODO new writers provide an explicite error message
|
|
// the two messages should be merged
|
|
TQString format = i18n("Could not save \"%1\"\nDo you want to try again?");
|
|
TQString msg = format.arg(tmp.path());
|
|
int result = KMessageBox::warningContinueCancel(0, msg,
|
|
kapp->makeStdCaption(i18n("I/O Failure")),
|
|
i18n("&Retry"));
|
|
if ( result == KMessageBox::Cancel ) return false;
|
|
}
|
|
}
|
|
doc_url = tmp;
|
|
dirty = false;
|
|
emit docModified(false);
|
|
return true;
|
|
}
|
|
|
|
|
|
KEduVocExpression *KEduVocDocument::getEntry(int index)
|
|
{
|
|
if (index < 0 || index >= (int)vocabulary.size() )
|
|
return 0;
|
|
else
|
|
return &vocabulary[index];
|
|
}
|
|
|
|
|
|
void KEduVocDocument::removeEntry(int index)
|
|
{
|
|
if (index >= 0 && index < (int)vocabulary.size() )
|
|
vocabulary.erase (vocabulary.begin() + index);
|
|
}
|
|
|
|
|
|
int KEduVocDocument::findIdent (const TQString &lang) const
|
|
{
|
|
vector<TQString>::const_iterator first = langs.begin();
|
|
int count = 0;
|
|
while (first != langs.end()) {
|
|
if ( *first == lang)
|
|
return count;
|
|
first++;
|
|
count++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getIdent (int index) const
|
|
{
|
|
if (index >= (int)langs.size() || index < 1 )
|
|
return "";
|
|
else
|
|
return langs[index];
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setIdent (int idx, const TQString &id)
|
|
{
|
|
if (idx < (int)langs.size() && idx >= 1 ) {
|
|
langs[idx] = id;
|
|
}
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getTypeName (int index) const
|
|
{
|
|
if (index >= (int)type_descr.size())
|
|
return "";
|
|
else
|
|
return type_descr[index];
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setTypeName (int idx, TQString &id)
|
|
{
|
|
if (idx >= (int)type_descr.size())
|
|
for (int i = (int)type_descr.size(); i <= idx; i++)
|
|
type_descr.push_back ("");
|
|
|
|
type_descr[idx] = id;
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getTenseName (int index) const
|
|
{
|
|
if (index >= (int)tense_descr.size())
|
|
return "";
|
|
else
|
|
return tense_descr[index];
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setTenseName (int idx, TQString &id)
|
|
{
|
|
if (idx >= (int)tense_descr.size())
|
|
for (int i = (int)tense_descr.size(); i <= idx; i++)
|
|
tense_descr.push_back ("");
|
|
|
|
tense_descr[idx] = id;
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getUsageName (int index) const
|
|
{
|
|
if (index >= (int)usage_descr.size())
|
|
return "";
|
|
else
|
|
return usage_descr[index];
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setUsageName (int idx, TQString &id)
|
|
{
|
|
if (idx >= (int)usage_descr.size())
|
|
for (int i = (int)usage_descr.size(); i <= idx; i++)
|
|
usage_descr.push_back ("");
|
|
|
|
usage_descr[idx] = id;
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setConjugation (int idx, const Conjugation &con)
|
|
{
|
|
if ( idx < 0) return;
|
|
|
|
// extend conjugation with empty elements
|
|
if ((int)conjugations.size() <= idx )
|
|
for (int i = conjugations.size(); i < idx+1; i++)
|
|
conjugations.push_back (Conjugation());
|
|
|
|
conjugations[idx] = con;
|
|
}
|
|
|
|
|
|
Conjugation KEduVocDocument::getConjugation (int idx) const
|
|
{
|
|
if (idx >= (int)conjugations.size() || idx < 0) {
|
|
return Conjugation();
|
|
}
|
|
else {
|
|
return conjugations[idx];
|
|
}
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setArticle (int idx, const Article &art)
|
|
{
|
|
if ( idx < 0) return;
|
|
|
|
// extend conjugation with empty elements
|
|
if ((int)articles.size() <= idx )
|
|
for (int i = articles.size(); i < idx+1; i++)
|
|
articles.push_back (Article());
|
|
|
|
articles[idx] = art;
|
|
}
|
|
|
|
|
|
Article KEduVocDocument::getArticle (int idx) const
|
|
{
|
|
if (idx >= (int)articles.size() || idx < 0) {
|
|
return Article();
|
|
}
|
|
else {
|
|
return articles[idx];
|
|
}
|
|
}
|
|
|
|
|
|
int KEduVocDocument::getSizeHint (int idx) const
|
|
{
|
|
if (idx < 0) {
|
|
idx = -idx;
|
|
if (idx >= (int)extraSizehints.size() )
|
|
return 80; // make a good guess about column size
|
|
else {
|
|
// cout << "gsh " << idx << " " << extraSizehints[idx] << endl;
|
|
return extraSizehints[idx];
|
|
}
|
|
}
|
|
else {
|
|
if (idx >= (int)sizehints.size() )
|
|
return 150; // make a good guess about column size
|
|
else {
|
|
// cout << "gsh " << idx << " " << sizehints[idx] << endl;
|
|
return sizehints[idx];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setSizeHint (int idx, const int width)
|
|
{
|
|
// cout << "ssh " << idx << " " << width << endl;
|
|
if (idx < 0) {
|
|
idx = -idx;
|
|
if (idx >= (int)extraSizehints.size()) {
|
|
for (int i = (int)extraSizehints.size(); i <= idx; i++)
|
|
extraSizehints.push_back (80);
|
|
}
|
|
extraSizehints[idx] = width;
|
|
|
|
}
|
|
else {
|
|
if (idx >= (int)sizehints.size()) {
|
|
for (int i = (int)sizehints.size(); i <= idx; i++)
|
|
sizehints.push_back (150);
|
|
}
|
|
sizehints[idx] = width;
|
|
}
|
|
}
|
|
|
|
|
|
class eraseTrans : public unary_function<KEduVocExpression, void>
|
|
{
|
|
|
|
public:
|
|
|
|
eraseTrans (int idx)
|
|
: index (idx) {}
|
|
|
|
void operator() (KEduVocExpression& x) const
|
|
{
|
|
x.removeTranslation(index);
|
|
}
|
|
|
|
private:
|
|
int index;
|
|
};
|
|
|
|
|
|
void KEduVocDocument::removeIdent (int index)
|
|
{
|
|
if (index < (int)langs.size() && index >= 1 ) {
|
|
langs.erase(langs.begin() + index);
|
|
for_each (vocabulary.begin(), vocabulary.end(), eraseTrans(index));
|
|
}
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getOriginalIdent () const
|
|
{
|
|
if (langs.size() > 0)
|
|
return langs[0];
|
|
else
|
|
return "";
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setOriginalIdent (const TQString &id)
|
|
{
|
|
if (langs.size() > 0) {
|
|
langs[0] = id;
|
|
}
|
|
}
|
|
|
|
|
|
class sortByOrg : public binary_function<KEduVocExpression, KEduVocExpression, bool>
|
|
{
|
|
|
|
public:
|
|
|
|
sortByOrg (bool _dir)
|
|
: dir (_dir) {}
|
|
|
|
bool operator() (const KEduVocExpression& x, const KEduVocExpression& y) const
|
|
{
|
|
return
|
|
!dir
|
|
? (TQString::compare(x.getOriginal().upper(),
|
|
y.getOriginal().upper() ) < 0)
|
|
: (TQString::compare(x.getOriginal().upper(),
|
|
y.getOriginal().upper() ) > 0);
|
|
}
|
|
|
|
private:
|
|
bool dir;
|
|
};
|
|
|
|
|
|
class sortByLessonAndOrg_alpha
|
|
: public binary_function<KEduVocExpression, KEduVocExpression, bool>
|
|
{
|
|
|
|
public:
|
|
|
|
sortByLessonAndOrg_alpha (bool _dir, KEduVocDocument &_doc)
|
|
: dir (_dir), doc(_doc) {}
|
|
|
|
bool operator() (const KEduVocExpression& x, const KEduVocExpression& y) const
|
|
{
|
|
if (x.getLesson() != y.getLesson() )
|
|
return
|
|
!dir
|
|
? (TQString::compare(doc.getLessonDescr(x.getLesson()).upper(),
|
|
doc.getLessonDescr(y.getLesson()).upper() ) < 0)
|
|
: (TQString::compare(doc.getLessonDescr(x.getLesson()).upper(),
|
|
doc.getLessonDescr(y.getLesson()).upper() ) > 0);
|
|
else
|
|
return
|
|
!dir
|
|
? (TQString::compare(x.getOriginal().upper(),
|
|
y.getOriginal().upper() ) < 0)
|
|
: (TQString::compare(x.getOriginal().upper(),
|
|
y.getOriginal().upper() ) > 0);
|
|
}
|
|
|
|
private:
|
|
bool dir;
|
|
KEduVocDocument &doc;
|
|
};
|
|
|
|
|
|
class sortByLessonAndOrg_index
|
|
: public binary_function<KEduVocExpression, KEduVocExpression, bool>
|
|
{
|
|
|
|
public:
|
|
|
|
sortByLessonAndOrg_index (bool _dir, KEduVocDocument &_doc)
|
|
: dir (_dir), doc(_doc) {}
|
|
|
|
bool operator() (const KEduVocExpression& x, const KEduVocExpression& y) const
|
|
{
|
|
if (x.getLesson() != y.getLesson() )
|
|
return
|
|
!dir
|
|
? x.getLesson() < y.getLesson()
|
|
: y.getLesson() < x.getLesson();
|
|
else
|
|
return
|
|
!dir
|
|
? (TQString::compare(x.getOriginal().upper(),
|
|
y.getOriginal().upper() ) < 0)
|
|
: (TQString::compare(x.getOriginal().upper(),
|
|
y.getOriginal().upper() ) > 0);
|
|
}
|
|
|
|
private:
|
|
bool dir;
|
|
KEduVocDocument &doc;
|
|
};
|
|
|
|
|
|
class sortByTrans : public binary_function<KEduVocExpression, KEduVocExpression, bool>
|
|
{
|
|
|
|
public:
|
|
|
|
sortByTrans (int i, bool _dir)
|
|
: index(i), dir (_dir) {}
|
|
|
|
bool operator() (const KEduVocExpression& x, const KEduVocExpression& y) const
|
|
{
|
|
return
|
|
!dir
|
|
? (TQString::compare(x.getTranslation(index).upper(),
|
|
y.getTranslation(index).upper() ) < 0)
|
|
: (TQString::compare(x.getTranslation(index).upper(),
|
|
y.getTranslation(index).upper() ) > 0);
|
|
}
|
|
|
|
private:
|
|
int index;
|
|
bool dir;
|
|
};
|
|
|
|
|
|
bool KEduVocDocument::sort (int index)
|
|
{
|
|
if (!sort_allowed)
|
|
return false;
|
|
|
|
if (index >= numLangs())
|
|
return false;
|
|
|
|
if (sort_lang.size() < langs.size())
|
|
for (int i = sort_lang.size(); i < (int) langs.size(); i++)
|
|
sort_lang.push_back(false);
|
|
|
|
if (index == 0)
|
|
std::sort (vocabulary.begin(), vocabulary.end(), sortByOrg(sort_lang[0]));
|
|
else
|
|
std::sort (vocabulary.begin(), vocabulary.end(), sortByTrans(index, sort_lang[index]));
|
|
sort_lang[index] = !sort_lang[index];
|
|
return sort_lang[index];
|
|
}
|
|
|
|
|
|
bool KEduVocDocument::sortByLesson_alpha ()
|
|
{
|
|
if (!sort_allowed)
|
|
return false;
|
|
|
|
std::sort (vocabulary.begin(), vocabulary.end(), sortByLessonAndOrg_alpha(sort_lesson, *this ));
|
|
sort_lesson = !sort_lesson;
|
|
return sort_lesson;
|
|
}
|
|
|
|
|
|
bool KEduVocDocument::sortByLesson_index ()
|
|
{
|
|
if (!sort_allowed)
|
|
return false;
|
|
|
|
if (sort_lang.size() < langs.size())
|
|
for (int i = sort_lang.size(); i < (int) langs.size(); i++)
|
|
sort_lang.push_back(false);
|
|
|
|
std::sort (vocabulary.begin(), vocabulary.end(), sortByLessonAndOrg_index(sort_lesson, *this ));
|
|
sort_lesson = !sort_lesson;
|
|
sort_lang[0] = sort_lesson;
|
|
return sort_lesson;
|
|
}
|
|
|
|
bool KEduVocDocument::leitnerSystemActive()
|
|
{
|
|
return activeLeitnerSystem;
|
|
}
|
|
|
|
void KEduVocDocument::setLeitnerSystemActive( bool yes )
|
|
{
|
|
if( yes )
|
|
{
|
|
if( leitnerSystem == 0 )
|
|
createStandardLeitnerSystem(); //if nothing is loaded yet
|
|
|
|
activeLeitnerSystem = true;
|
|
}
|
|
else if( !yes )
|
|
activeLeitnerSystem = false;
|
|
}
|
|
|
|
void KEduVocDocument::createStandardLeitnerSystem()
|
|
{
|
|
LeitnerSystem* tmpSystem = new LeitnerSystem();
|
|
TQString name = "Standard";
|
|
|
|
tmpSystem->setSystemName( name );
|
|
tmpSystem->insertBox( "Box 1" );
|
|
tmpSystem->insertBox( "Box 2" );
|
|
tmpSystem->insertBox( "Box 3" );
|
|
tmpSystem->insertBox( "Box 4" );
|
|
tmpSystem->insertBox( "Box 5" );
|
|
|
|
tmpSystem->setCorrectBox( "Box 1", "Box 2" );
|
|
tmpSystem->setWrongBox( "Box 1", "Box 1" );
|
|
|
|
tmpSystem->setCorrectBox( "Box 2", "Box 3" );
|
|
tmpSystem->setWrongBox( "Box 2", "Box 1" );
|
|
|
|
tmpSystem->setCorrectBox( "Box 3", "Box 4" );
|
|
tmpSystem->setWrongBox( "Box 3", "Box 1" );
|
|
|
|
tmpSystem->setCorrectBox( "Box 4", "Box 5" );
|
|
tmpSystem->setWrongBox( "Box 4", "Box 1" );
|
|
|
|
tmpSystem->setCorrectBox( "Box 5", "Box 1" );
|
|
tmpSystem->setWrongBox( "Box 5", "Box 1" );
|
|
|
|
leitnerSystem = tmpSystem;
|
|
}
|
|
|
|
void KEduVocDocument::setLeitnerSystem( LeitnerSystem* system )
|
|
{
|
|
leitnerSystem = system;
|
|
|
|
/*KWordQuizApp* app = (KWordQuizApp*) parent();
|
|
app->slotLeitnerSystem();*/
|
|
}
|
|
|
|
LeitnerSystem* KEduVocDocument::getLeitnerSystem()
|
|
{
|
|
return leitnerSystem;
|
|
}
|
|
|
|
|
|
class resetAll : public unary_function<KEduVocExpression, void>
|
|
{
|
|
|
|
public:
|
|
|
|
resetAll (int less)
|
|
: lesson(less) {}
|
|
|
|
void operator() (KEduVocExpression& x)
|
|
{
|
|
for (int i = 0; i <= x.numTranslations(); i++) {
|
|
if (lesson == 0 || lesson == x.getLesson() ) {
|
|
x.setGrade(i, KV_NORM_GRADE, false);
|
|
x.setGrade(i, KV_NORM_GRADE, true);
|
|
x.setQueryCount (i, 0, true);
|
|
x.setQueryCount (i, 0, false);
|
|
x.setBadCount (i, 0, true);
|
|
x.setBadCount (i, 0, false);
|
|
x.setQueryDate (i, 0, true);
|
|
x.setQueryDate (i, 0, false);
|
|
}
|
|
}
|
|
}
|
|
private:
|
|
int lesson;
|
|
};
|
|
|
|
|
|
class resetOne : public unary_function<KEduVocExpression, void>
|
|
{
|
|
|
|
public:
|
|
|
|
resetOne (int idx, int less)
|
|
: index (idx), lesson(less) {}
|
|
|
|
void operator() (KEduVocExpression& x)
|
|
{
|
|
if (lesson == 0 || lesson == x.getLesson() ) {
|
|
x.setGrade(index, KV_NORM_GRADE, false);
|
|
x.setGrade(index, KV_NORM_GRADE, true);
|
|
x.setQueryCount (index, 0, true);
|
|
x.setQueryCount (index, 0, false);
|
|
x.setBadCount (index, 0, true);
|
|
x.setBadCount (index, 0, false);
|
|
x.setQueryDate (index, 0, true);
|
|
x.setQueryDate (index, 0, false);
|
|
}
|
|
}
|
|
|
|
private:
|
|
int index;
|
|
int lesson;
|
|
};
|
|
|
|
|
|
void KEduVocDocument::resetEntry (int index, int lesson)
|
|
{
|
|
if (index < 0)
|
|
for_each (vocabulary.begin(), vocabulary.end(), resetAll(lesson) );
|
|
else
|
|
for_each (vocabulary.begin(), vocabulary.end(), resetOne(index, lesson) );
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getLessonDescr(int idx) const
|
|
{
|
|
if (idx == 0)
|
|
return i18n("<no lesson>");
|
|
|
|
if (idx <= 0 || idx > (int) lesson_descr.size() )
|
|
return "";
|
|
|
|
return lesson_descr[idx-1];
|
|
}
|
|
|
|
|
|
vector<int> KEduVocDocument::getLessonsInQuery() const
|
|
{
|
|
vector<int> iqvec;
|
|
for (unsigned i = 0; i < lessons_in_query.size(); i++)
|
|
if (lessons_in_query[i]) {
|
|
iqvec.push_back(i+1); // Offset <no lesson>
|
|
// cout << "getliq: " << i+1 << endl;
|
|
}
|
|
return iqvec;
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setLessonsInQuery(vector<int> lesson_iq)
|
|
{
|
|
lessons_in_query.clear();
|
|
for (unsigned i = 0; i < lesson_descr.size(); i++)
|
|
lessons_in_query.push_back(false);
|
|
|
|
for (unsigned i = 0; i < lesson_iq.size(); i++)
|
|
if (lesson_iq[i] <= (int) lessons_in_query.size() ) {
|
|
lessons_in_query[lesson_iq[i]-1] = true; // Offset <no lesson>
|
|
// cout << "setliq: " << lesson_iq[i] << " " << i << endl;
|
|
}
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getTitle() const
|
|
{
|
|
if (doctitle.isEmpty())
|
|
return doc_url.fileName();
|
|
else
|
|
return doctitle;
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getAuthor() const
|
|
{
|
|
return author;
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getLicense() const
|
|
{
|
|
return license;
|
|
}
|
|
|
|
|
|
TQString KEduVocDocument::getDocRemark() const
|
|
{
|
|
return doc_remark;
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setTitle(const TQString & title)
|
|
{
|
|
doctitle = title.stripWhiteSpace();
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setAuthor(const TQString & s)
|
|
{
|
|
author = s.stripWhiteSpace();
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setLicense(const TQString & s)
|
|
{
|
|
license = s.stripWhiteSpace();
|
|
}
|
|
|
|
|
|
void KEduVocDocument::setDocRemark(const TQString & s)
|
|
{
|
|
doc_remark = s.stripWhiteSpace();
|
|
}
|
|
|
|
|
|
int KEduVocDocument::search(TQString substr, int id,
|
|
int first, int last,
|
|
bool word_start,
|
|
bool)
|
|
{
|
|
if (last >= numEntries()
|
|
|| last < 0 )
|
|
last = numEntries();
|
|
|
|
if (first < 0)
|
|
first = 0;
|
|
|
|
if (id >= numLangs()
|
|
|| last < first
|
|
)
|
|
return -1;
|
|
|
|
if (id == 0) {
|
|
for (int i = first; i < last; i++) {
|
|
if (word_start) {
|
|
if (getEntry(i)->getOriginal().find (substr, 0, false) == 0) // case insensitive
|
|
return i;
|
|
}
|
|
else {
|
|
if (getEntry(i)->getOriginal().find (substr, 0, false) > -1) // case insensitive
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (int i = first; i < last; i++) {
|
|
if (word_start) {
|
|
if (getEntry(i)->getTranslation(id).find (substr, 0, false) == 0) // case insensitive
|
|
return i;
|
|
}
|
|
else {
|
|
if (getEntry(i)->getTranslation(id).find (substr, 0, false) > -1) // case insensitive
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
#define _OFFSET 0x40
|
|
#define _BITMASK 0x3F
|
|
#define _BITUSED 6
|
|
|
|
TQString KEduVocDocument::compressDate(unsigned long l) const
|
|
{
|
|
if (l == 0)
|
|
return "";
|
|
|
|
TQString res;
|
|
if (l <= KVD_ZERO_TIME)
|
|
l = 1;
|
|
else
|
|
l -= KVD_ZERO_TIME;
|
|
while (l != 0) {
|
|
char c = _OFFSET + (l & _BITMASK);
|
|
res.insert (0, c);
|
|
l >>= _BITUSED;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
unsigned long KEduVocDocument::decompressDate(TQString s) const
|
|
{
|
|
if (s.isEmpty())
|
|
return 0;
|
|
|
|
long res = 0;
|
|
unsigned incr = 0;
|
|
for (int i = s.length()-1; i >= 0; i--) {
|
|
char c = s.local8Bit()[i];
|
|
res += ((c - _OFFSET) & _BITMASK) << incr ;
|
|
incr += _BITUSED;
|
|
}
|
|
return res > 48 ? res+KVD_ZERO_TIME : 0; // early bug with "0"
|
|
}
|
|
|
|
|
|
KEduVocDocument::FileType KEduVocDocument::detectFT(const TQString &filename)
|
|
{
|
|
TQFile f( filename );
|
|
if (!f.open( IO_ReadOnly ))
|
|
return csv;
|
|
|
|
TQDataStream is( &f );
|
|
|
|
TQ_INT8 c1, c2, c3, c4, c5;
|
|
is >> c1
|
|
>> c2
|
|
>> c3
|
|
>> c4
|
|
>> c5; // guess filetype by first x bytes
|
|
|
|
TQTextStream ts (&f);
|
|
TQString line;
|
|
line = ts.readLine();
|
|
line.insert (0, c5);
|
|
line.insert (0, c4);
|
|
line.insert (0, c3);
|
|
line.insert (0, c2);
|
|
line.insert (0, c1);
|
|
f.close();
|
|
|
|
bool stat = is.device()->status();
|
|
if (stat != IO_Ok)
|
|
return kvd_none;
|
|
if (c1 == '<' && c2 == '?' && c3 == 'x' && c4 == 'm' && c5 == 'l')
|
|
return kvtml;
|
|
|
|
if (line.find (VCB_SEPARATOR) >= 0)
|
|
return vt_vcb;
|
|
|
|
if (line == LEX_IDENT_50)
|
|
return vt_lex;
|
|
|
|
return csv;
|
|
}
|
|
|
|
|
|
class expRef {
|
|
|
|
public:
|
|
|
|
expRef (KEduVocExpression *_exp, int _idx)
|
|
{
|
|
idx = _idx;
|
|
exp = _exp;
|
|
}
|
|
|
|
bool operator< (const expRef& y) const
|
|
{
|
|
TQString s1 = exp->getOriginal();
|
|
TQString s2 = y.exp->getOriginal();
|
|
int cmp = TQString::compare(s1.upper(), s2.upper());
|
|
if (cmp != 0)
|
|
return cmp < 0;
|
|
|
|
for (int i = 1; i < (int) exp->numTranslations(); i++) {
|
|
|
|
s1 = exp->getTranslation(i);
|
|
s2 = y.exp->getTranslation(i);
|
|
cmp = TQString::compare(s1.upper(), s2.upper() );
|
|
if (cmp != 0)
|
|
return cmp < 0;
|
|
}
|
|
return cmp < 0;
|
|
}
|
|
|
|
int idx;
|
|
KEduVocExpression *exp;
|
|
};
|
|
|
|
|
|
int KEduVocDocument::cleanUp()
|
|
{
|
|
int count = 0;
|
|
KEduVocExpression *kve1, *kve2;
|
|
vector<expRef> shadow;
|
|
vector<int> to_delete;
|
|
|
|
for (int i = 0; i < (int) vocabulary.size(); i++)
|
|
shadow.push_back (expRef (getEntry(i), i));
|
|
std::sort(shadow.begin(), shadow.end());
|
|
|
|
#ifdef CLEAN_BUG
|
|
ofstream sso ("shadow.out");
|
|
for (int i = shadow.size()-1; i > 0; i--) {
|
|
kve1 = shadow[i].exp;
|
|
sso << kve1->getOriginal() << " ";
|
|
for (int l = 1; l < (int) numLangs(); l++ )
|
|
sso << kve1->getTranslation(l) << " ";
|
|
sso << endl;
|
|
}
|
|
#endif
|
|
|
|
int ent_no = 0;
|
|
int ent_percent = vocabulary.size () / 100;
|
|
float f_ent_percent = vocabulary.size () / 100.0;
|
|
emit progressChanged(this, 0);
|
|
|
|
for (int i = shadow.size()-1; i > 0; i--) {
|
|
kve1 = shadow[i].exp;
|
|
kve2 = shadow[i-1].exp;
|
|
|
|
ent_no++;
|
|
if (ent_percent != 0 && (ent_no % ent_percent) == 0 )
|
|
emit progressChanged(this, (int)((ent_no / f_ent_percent) / 2.0));
|
|
|
|
bool equal = true;
|
|
if (kve1->getOriginal() == kve2->getOriginal() ) {
|
|
for (int l = 1; equal && l < (int) numLangs(); l++ )
|
|
if (kve1->getTranslation(l) != kve2->getTranslation(l))
|
|
equal = false;
|
|
|
|
if (equal) {
|
|
to_delete.push_back(shadow[i-1].idx);
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// removing might take very long
|
|
ent_no = 0;
|
|
ent_percent = to_delete.size () / 100;
|
|
f_ent_percent = to_delete.size () / 100.0;
|
|
emit progressChanged(this, 0);
|
|
|
|
std::sort (to_delete.begin(), to_delete.end() );
|
|
for (int i = (int) to_delete.size()-1; i >= 0; i--) {
|
|
ent_no++;
|
|
if (ent_percent != 0 && (ent_no % ent_percent) == 0 )
|
|
emit progressChanged(this, (int)(50 + ent_no / f_ent_percent / 2.0));
|
|
#ifdef CLEAN_BUG
|
|
sso << getEntry(to_delete[i])->getOriginal() << endl;
|
|
#endif
|
|
removeEntry (to_delete[i]);
|
|
setModified();
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
#include "keduvocdocument.moc"
|