summaryrefslogtreecommitdiffstats
path: root/kvoctrain/kvoctrain/kva_io.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kvoctrain/kvoctrain/kva_io.cpp')
-rw-r--r--kvoctrain/kvoctrain/kva_io.cpp697
1 files changed, 697 insertions, 0 deletions
diff --git a/kvoctrain/kvoctrain/kva_io.cpp b/kvoctrain/kvoctrain/kva_io.cpp
new file mode 100644
index 00000000..22df3874
--- /dev/null
+++ b/kvoctrain/kvoctrain/kva_io.cpp
@@ -0,0 +1,697 @@
+/***************************************************************************
+
+ i/o part of kvoctrain
+
+ -----------------------------------------------------------------------
+
+ begin : Thu Mar 11 20:50:53 MET 1999
+
+ copyright : (C) 1999-2001 Ewald Arnold <kvoctrain@ewald-arnold.de>
+ (C) 2001 The KDE-EDU team
+ (C) 2004-2005 Peter Hedlund <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 <unistd.h>
+
+#include <qtimer.h>
+
+#include <kfiledialog.h>
+#include <kcombobox.h>
+#include <kprogress.h>
+#include <krecentdocument.h>
+#include <kstatusbar.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <knewstuff/downloaddialog.h>
+
+#include "kvoctrain.h"
+#include "UsageManager.h"
+#include "common-dialogs/ProgressDlg.h"
+#include <prefs.h>
+
+static const char *PATTERN_ALL = I18N_NOOP("*|All Files (*)\n");
+static const char *PATTERN_ML = I18N_NOOP("*.kvtml|KVocTrain Markup (*.kvtml)\n");
+static const char *PATTERN_LEX = I18N_NOOP("*.lex|Vocabulary Trainer 5.0 (*.lex)\n");
+static const char *PATTERN_VL = I18N_NOOP("*.vl|KVoclearn (*.vl)\n");
+static const char *PATTERN_QVO = I18N_NOOP("*.qvo|QVocab (*.qvo)\n");
+static const char *PATTERN_VOC = I18N_NOOP("*.voc|Vokabeltrainer (*.voc)\n");
+static const char *PATTERN_CSV = I18N_NOOP("*.csv|Text (*.csv)\n");
+static const char *PATTERN_VCB = I18N_NOOP("*.vocab|Vocabbox (*.vocab)\n");
+
+// we can read these
+#define FILTER_RPATTERN i18n(PATTERN_ML)+i18n(PATTERN_VCB)+i18n(PATTERN_VOC)+i18n(PATTERN_CSV)+i18n(PATTERN_LEX)+i18n(PATTERN_ALL)
+
+// we can write these
+#define FILTER_WPATTERN i18n(PATTERN_ML)+i18n(PATTERN_VCB)+i18n(PATTERN_CSV)+i18n(PATTERN_LEX)+i18n(PATTERN_ALL)
+
+
+void kvoctrainApp::slotTimeOutBackup()
+{
+ if (Prefs::autoBackup() && doc && doc->isModified() ) {
+ slotStatusMsg(i18n("Autobackup in progress"));
+ slotFileSave();
+ }
+ if (Prefs::backupTime() > 0)
+ btimer->start(Prefs::backupTime() * 60 * 1000, TRUE);
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+bool kvoctrainApp::queryClose()
+{
+ bool erg = queryExit();
+ if (erg)
+ doc->setModified(false); // avoid double query on exit via system menu
+ return erg;
+}
+
+
+bool kvoctrainApp::queryExit()
+{
+ saveOptions();
+ if (!doc || !doc->isModified() ) return true;
+
+ bool save = (Prefs::autoSave()); //save without asking
+
+ if (!save)
+ {
+ int exit = KMessageBox::warningYesNoCancel(this,
+ i18n("Vocabulary is modified.\n\nSave file before exit?\n"),
+ kapp->makeStdCaption(""),
+ KStdGuiItem::save(), KStdGuiItem::discard());
+ if (exit==KMessageBox::Yes) {
+ save = true; // save and exit
+ }
+ else if (exit == KMessageBox::No) {
+ save = false; // dont save but exit
+ }
+ else {
+ return false; // continue work
+ }
+ }
+
+ if (save) {
+ if (!doc->URL().isEmpty())
+ slotFileSave(); // save and exit
+ if (doc->isModified())
+ {
+ // Error while saving or no name
+ slotFileSaveAs();
+ }
+ }
+ return true;
+}
+
+
+void kvoctrainApp::slotFileQuit()
+{
+ ///////////////////////////////////////////////////////////////////
+ // exits the Application
+ if(queryExit())
+ {
+ doc->setModified(false); // Make sure not to bother about saving again.
+ kapp->quit();
+ }
+ else
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::slotProgress(kvoctrainDoc *curr_doc, int percent)
+{
+ if (pdlg != 0)
+ pdlg->setValue (curr_doc, percent);
+ else if (pbar != 0)
+ pbar->setValue (percent);
+ kapp->processEvents();
+}
+
+
+void kvoctrainApp::slotFileOpenRecent(const KURL& url)
+{
+ slotStatusMsg(i18n("Opening file..."));
+ if (queryExit() && fileOpenRecent->items().count() > 0)
+ {
+ fileOpenRecent->setCurrentItem(-1);
+ loadfileFromPath(url);
+ }
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::slotFileNew()
+{
+ slotStatusMsg(i18n("Creating new file..."));
+
+ if (queryExit() ) {
+ view->setView (0, langset);
+ delete doc;
+ QString name = "";
+ doc = new kvoctrainDoc (this, 0 /*KURL(name)*/);
+ loadDocProps(doc);
+ if (doc->numLangs() == 0) {
+ QString l = "en";
+ doc->appendLang(l);
+ }
+ view->setView(doc, langset);
+ view->getTable()->setFont(Prefs::tableFont());
+ view->adjustContent();
+ connect (doc, SIGNAL (docModified(bool)), this, SLOT(slotModifiedDoc(bool)));
+ doc->setModified(false);
+ }
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::slotFileOpen()
+{
+ slotStatusMsg(i18n("Opening file..."));
+
+ if (queryExit() ) {
+ QString s;
+ KURL url = KFileDialog::getOpenURL(QString::null, FILTER_RPATTERN, parentWidget(), i18n("Open Vocabulary File"));
+ loadfileFromPath(url, true);
+ }
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::loadfileFromPath(const KURL & url, bool addRecent)
+{
+ if (!url.path().isEmpty())
+ {
+ view->setView(0, langset);
+ delete doc;
+ doc = 0;
+
+ QString format = i18n("Loading %1");
+ QString msg = format.arg(url.path());
+
+ slotStatusMsg(msg);
+ prepareProgressBar();
+ doc = new kvoctrainDoc (this, url);
+ removeProgressBar();
+ loadDocProps(doc);
+ view->setView(doc, langset);
+ view->getTable()->setFont(Prefs::tableFont());
+ view->adjustContent();
+ if (addRecent)
+ fileOpenRecent->addURL(url) /*addRecentFile (url.path())*/;
+ connect (doc, SIGNAL (docModified(bool)), this, SLOT(slotModifiedDoc(bool)));
+ doc->setModified(false);
+ }
+}
+
+void kvoctrainApp::slotFileOpenExample()
+{
+ slotStatusMsg(i18n("Opening example file..."));
+
+ if (queryExit() ) {
+ QString s;
+ s = locate("data", "kvoctrain/examples/");
+ KURL url = KFileDialog::getOpenURL(s, FILTER_RPATTERN, parentWidget(), i18n("Open Example Vocabulary File"));
+ loadfileFromPath(url, false);
+ if (doc)
+ doc->URL().setFileName(QString::null);
+ }
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::slotGHNS()
+{
+ if (!m_newStuff)
+ m_newStuff = new KVTNewStuff(this);
+ m_newStuff->download();
+}
+
+
+void kvoctrainApp::slotFileMerge()
+{
+ slotStatusMsg(i18n("Merging file..."));
+
+ QString s;
+ KURL url = KFileDialog::getOpenURL(QString::null, FILTER_RPATTERN, parentWidget(), i18n("Merge Vocabulary File"));
+
+ if (!url.isEmpty() ) {
+
+ QString format = i18n("Loading %1");
+ QString msg = format.arg(url.path());
+
+ slotStatusMsg(msg);
+ prepareProgressBar();
+ kvoctrainDoc *new_doc = new kvoctrainDoc (this, url);
+ connect (new_doc, SIGNAL (docModified(bool)), this, SLOT(slotModifiedDoc(bool)));
+ doc->setModified(false);
+ removeProgressBar();
+
+ vector<QString> old_names = doc->getLessonDescr();
+ vector<QString> new_names = new_doc->getLessonDescr();
+
+ vector<QString> old_types = doc->getTypeDescr();
+ vector<QString> new_types = new_doc->getTypeDescr();
+
+ vector<QString> old_tenses = doc->getTenseDescr();
+ vector<QString> new_tenses = new_doc->getTenseDescr();
+
+ vector<int> old_in_query = doc->getLessonsInQuery();
+ vector<int> new_in_query = new_doc->getLessonsInQuery();
+
+ vector<QString> old_usages = doc->getUsageDescr();
+ vector<QString> new_usages = new_doc->getUsageDescr();
+
+ format = i18n("Merging %1");
+ msg = format.arg(url.path());
+ slotStatusMsg(msg);
+
+ QApplication::setOverrideCursor( waitCursor );
+
+ int lesson_offset = lessons->count()-1;
+ for (int i = 0; i < (int) new_names.size(); i++) {
+ lessons->insertItem (new_names[i]);
+ old_names.push_back(new_names[i]);
+ }
+ doc->setLessonDescr(old_names);
+
+ for (int i = 0; i < (int) new_in_query.size(); i++)
+ old_in_query.push_back(new_in_query[i]+lesson_offset);
+ doc->setLessonsInQuery(old_in_query);
+ querymanager.setLessonItems(old_in_query);
+
+ int types_offset = old_types.size();
+ for (int i = 0; i < (int) new_types.size(); i++) {
+ old_types.push_back(new_types[i]);
+ }
+ doc->setTypeDescr(old_types);
+ QueryManager::setTypeNames(old_types);
+
+
+ int tenses_offset = old_tenses.size();
+ for (int i = 0; i < (int) new_tenses.size(); i++) {
+ old_tenses.push_back(new_tenses[i]);
+ }
+ doc->setTenseDescr(old_tenses);
+ Conjugation::setTenseNames(old_tenses);
+
+
+ int usages_offset = old_usages.size();
+ for (int i = 0; i < (int) new_usages.size(); i++) {
+ old_usages.push_back(new_usages[i]);
+ }
+ doc->setUsageDescr(old_usages);
+ UsageManager::setUsageNames(old_usages);
+
+
+ bool equal = true;
+ if (doc->getOriginalIdent() != new_doc->getOriginalIdent())
+ equal = false;
+ for (int i = 1; i < doc->numLangs(); i++)
+ if (doc->getIdent(i) != new_doc->getIdent(i))
+ equal = false;
+
+ if (equal) { // easy way: same language codes, just append
+
+ for (int i = 0; i < new_doc->numEntries(); i++) {
+ kvoctrainExpr *expr = new_doc->getEntry(i);
+
+ expr->setLesson(expr->getLesson()+lesson_offset);
+
+ for (int lang = 0; lang <= (int) expr->numTranslations(); lang++) {
+ QString t = expr->getType (lang);
+ // adjust type offset
+ if (!t.isEmpty() && t.left(1) == QM_USER_TYPE) {
+ QString t2;
+ t.remove (0, 1);
+ t2.setNum (t.toInt()+types_offset);
+ t2.insert (0, QM_USER_TYPE);
+ expr->setType (lang, t2);
+ }
+
+ t = expr->getUsageLabel (lang);
+ // adjust usage offset
+ QString tg;
+ if (!t.isEmpty() ) {
+ QString t2;
+ while (t.left(strlen(UL_USER_USAGE)) == UL_USER_USAGE) {
+ QString n;
+ t.remove (0, 1);
+ int next;
+ if ((next = t.find(UL_USAGE_DIV)) >= 0) {
+ n = t.left(next);
+ t.remove (0, next+1);
+ }
+ else {
+ n = t;
+ t = "";
+ }
+
+ t2.setNum (n.toInt()+usages_offset);
+ t2.insert (0, UL_USER_USAGE);
+ if (tg.length() == 0)
+ tg = t2;
+ else
+ tg += UL_USAGE_DIV + t2;
+ }
+
+ if (tg.length() == 0)
+ tg = t;
+ else if (t.length() != 0)
+ tg += UL_USAGE_DIV + t;
+
+ expr->setUsageLabel (lang, tg);
+ }
+
+ Conjugation conj = expr->getConjugation(lang);
+ bool condirty = false;
+ for (int ci = 0; ci < conj.numEntries(); ci++) {
+ t = conj.getType(ci);
+ if (!t.isEmpty() && t.left(1) == UL_USER_TENSE) {
+ t.remove (0, strlen(UL_USER_TENSE));
+ QString t2;
+ t2.setNum (t.toInt()+tenses_offset);
+ t2.insert (0, UL_USER_TENSE);
+ conj.setType(ci, t2);
+ condirty = true;
+ }
+ if (condirty)
+ expr->setConjugation(lang, conj);
+ }
+ }
+
+ doc->appendEntry (expr);
+ }
+ doc->setModified();
+ }
+ else { // hard way: move entries around, most attributes get lost
+ vector<int> move_matrix;
+
+ vector <bool> cs_equal;
+ for (int i = 0; i < QMAX (doc->numLangs(), new_doc->numLangs()); i++)
+ cs_equal.push_back (false);
+
+ move_matrix.push_back(new_doc->findIdent(doc->getOriginalIdent()));
+ for (int i = 1; i < doc->numLangs(); i++)
+ move_matrix.push_back(new_doc->findIdent(doc->getIdent(i)));
+
+ for (int j = 0; j < new_doc->numEntries(); j++) {
+ kvoctrainExpr new_expr;
+ kvoctrainExpr *expr = new_doc->getEntry(j);
+ new_expr.setLesson(expr->getLesson()+lesson_offset);
+
+ for (int i = 0; i < (int) move_matrix.size(); i++) {
+ int lpos = move_matrix[i];
+ if (lpos >= 0) {
+
+ if (lpos == 0)
+ s = expr->getOriginal();
+ else
+ s = expr->getTranslation(lpos);
+
+ if (!cs_equal[lpos]) {
+ cs_equal[lpos] = true;
+ QString id = lpos == 0 ? doc->getOriginalIdent()
+ : doc->getIdent(lpos);
+ }
+
+ if (i == 0)
+ new_expr.setOriginal(s);
+ else
+ new_expr.setTranslation(i, s);
+ QString r = expr->getRemark(lpos);
+ new_expr.setRemark (i, r);
+
+ QString t = expr->getType(lpos);
+ if (!t.isEmpty() && t.left(1) == QM_USER_TYPE) {
+ QString t2;
+ t.remove (0, 1);
+ t2.setNum (t.toInt()+types_offset);
+ t2.insert (0, QM_USER_TYPE);
+ new_expr.setType (i, t2);
+ }
+
+ t = expr->getUsageLabel(lpos);
+ if (!t.isEmpty() && t.left(1) == QM_USER_TYPE) {
+ QString t2;
+ t.remove (0, 1);
+ t2.setNum (t.toInt()+usages_offset);
+ t2.insert (0, QM_USER_TYPE);
+ new_expr.setUsageLabel (i, t2);
+ }
+
+ Conjugation conj = expr->getConjugation(lpos);
+ for (int ci = 0; ci < conj.numEntries(); ci++) {
+ t = conj.getType(ci);
+ if (!t.isEmpty() && t.left(1) == QM_USER_TYPE) {
+ t.remove (0, strlen(QM_USER_TYPE));
+ QString t2;
+ t2.setNum (t.toInt()+tenses_offset);
+ t2.insert (0, QM_USER_TYPE);
+ conj.setType(ci, t2);
+ }
+ }
+
+ }
+ }
+ // only append if entries are used
+ bool used = !new_expr.getOriginal().isEmpty();
+ for (int i = 1; i < (int) doc->numLangs(); i++)
+ if (!new_expr.getTranslation(i).isEmpty())
+ used = true;
+
+ if (used) {
+ doc->appendEntry(&new_expr);
+ doc->setModified();
+ }
+ }
+ }
+ delete (new_doc);
+ fileOpenRecent->addURL(url); // addRecentFile (url.path());
+ }
+
+ view->setView(doc, langset);
+ view->getTable()->setFont(Prefs::tableFont());
+ view->adjustContent();
+ QApplication::restoreOverrideCursor();
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::slotFileSave()
+{
+ if (entryDlg != 0)
+ commitEntryDlg(false);
+
+ if (doc->URL().fileName() == i18n("Untitled") ) {
+ slotFileSaveAs();
+ return;
+ }
+
+ QString format = i18n("Saving %1");
+ QString msg = format.arg(doc->URL().path());
+ slotStatusMsg(msg);
+
+ // remove previous backup
+ QFile::remove(QFile::encodeName(doc->URL().path()+"~"));
+ ::rename (QFile::encodeName(doc->URL().path()),
+ QFile::encodeName(doc->URL().path()+"~"));
+
+ prepareProgressBar();
+ saveDocProps(doc);
+ doc->saveAs(this, doc->URL(), doc->getTitle(), kvoctrainDoc::automatic);
+ fileOpenRecent->addURL(doc->URL());
+ removeProgressBar();
+
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::fillLessonBox(kvoctrainDoc *the_doc)
+{
+ lessons->clear();
+ lessons->insertItem (the_doc->getLessonDescr(0));
+ vector<QString> names = the_doc->getLessonDescr();
+ for (int i = 0; i < (int) names.size(); i++)
+ lessons->insertItem (names[i]);
+ act_lesson = the_doc->getCurrentLesson();
+ if (act_lesson > lessons->count() ) {
+ act_lesson = 0;
+ the_doc->setCurrentLesson(act_lesson);
+ }
+ lessons->setCurrentItem (act_lesson);
+}
+
+
+void kvoctrainApp::loadDocProps(kvoctrainDoc *the_doc)
+{
+ fillLessonBox(the_doc);
+
+ random_expr1.clear();
+ random_expr2.clear();
+ queryList.clear();
+ the_doc->getQueryLang (act_query_org, act_query_trans);
+ if (!act_query_org.isEmpty() && !act_query_trans.isEmpty() ) {
+ for (int i = 0; i < the_doc->numEntries(); i++)
+ {
+ kvoctrainExpr *entry = the_doc->getEntry(i);
+ if (entry->isInQuery())
+ {
+ int less = entry->getLesson();
+ for (int l = (int) queryList.size(); l <= less; l++) {
+ vector<QueryEntryRef> ref_vec;
+ queryList.push_back(ref_vec);
+ }
+ QueryEntryRef ref(entry, i);
+ queryList[less].push_back(ref);
+ }
+ }
+ }
+
+ QueryManager::setTypeNames (doc->getTypeDescr() );
+ UsageManager::setUsageNames (doc->getUsageDescr() );
+ Conjugation::setTenseNames (doc->getTenseDescr() );
+
+ querymanager.setLessonItems(doc->getLessonsInQuery() );
+
+ // remove empty elements
+ for (int i = (int) queryList.size()-1; i >= 0; i--)
+ if (queryList[i].size() == 0) {
+ queryList.erase(queryList.begin() + i);
+ }
+
+ query_cycle = 1;
+ query_startnum = 0;
+ for (int i = 0; i < (int) queryList.size(); i++)
+ query_startnum += queryList[i].size();
+ query_num = query_startnum;
+}
+
+
+void kvoctrainApp::saveDocProps(kvoctrainDoc *the_doc)
+{
+ the_doc->setQueryLang (act_query_org, act_query_trans);
+}
+
+
+void kvoctrainApp::slotFileSaveAs()
+{
+ slotStatusMsg(i18n("Saving file under new filename..."));
+
+ if (entryDlg != 0)
+ commitEntryDlg(false);
+
+ KURL url = KFileDialog::getSaveURL(QString::null, FILTER_WPATTERN, parentWidget(), i18n("Save Vocabulary As"));
+
+ if (!url.isEmpty() ) {
+ QFileInfo fileinfo(url.path());
+ if (fileinfo.exists() && KMessageBox::warningContinueCancel(0,
+ i18n("<qt>The file<br><b>%1</b><br>already exists. Do you want to overwrite it?</qt>")
+ .arg(url.path()),QString::null,i18n("Overwrite")) == KMessageBox::Cancel)
+ {
+ // do nothing
+ }
+ else
+
+ if (doc) {
+ QString format = i18n("Saving %1");
+ QString msg = format.arg(url.path());
+ slotStatusMsg(msg);
+
+ QFile::remove(QFile::encodeName(url.path()+"~")); // remove previous backup
+ ::rename (QFile::encodeName(url.path()), QFile::encodeName(QString(url.path()+"~")));
+ saveDocProps(doc);
+
+ prepareProgressBar();
+ doc->saveAs(this, url, doc->getTitle(), kvoctrainDoc::automatic);
+ fileOpenRecent->addURL(doc->URL());
+ removeProgressBar();
+ }
+ }
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::slotSaveSelection ()
+{
+ if (entryDlg != 0)
+ commitEntryDlg(false);
+
+ slotStatusMsg(i18n("Saving selected area under new filename..."));
+ QString save_separator = Prefs::separator();
+ Prefs::setSeparator("\t");
+ kvoctrainDoc seldoc(this, "");
+ // transfer most important parts
+ seldoc.appendLang(doc->getOriginalIdent());
+ for (int i = 1; i < doc->numLangs(); i++)
+ seldoc.appendLang(doc->getIdent(i));
+ seldoc.setAuthor(doc->getAuthor());
+ seldoc.setLessonDescr(doc->getLessonDescr());
+ seldoc.setTypeDescr(doc->getTypeDescr());
+
+ for (int i = doc->numEntries()-1; i >= 0; i--)
+ if (doc->getEntry(i)->isInQuery() )
+ seldoc.appendEntry(doc->getEntry(i));
+
+ KURL url = KFileDialog::getSaveURL(QString::null, FILTER_WPATTERN, parentWidget(), i18n("Save Vocabulary As"));
+
+ if (!url.isEmpty() )
+ {
+ QFileInfo fileinfo(url.path());
+ if (fileinfo.exists() && KMessageBox::warningContinueCancel(0,
+ i18n("<qt>The file<br><b>%1</b><br>already exists. Do you want to overwrite it?</qt>")
+ .arg(url.path()),QString::null,i18n("Overwrite")) == KMessageBox::Cancel)
+ {
+ // do nothing
+ }
+ else
+ {
+ QString format = i18n("Saving %1");
+ QString msg = format.arg(url.path());
+ slotStatusMsg(msg);
+
+ QFile::remove(url.path()+"~"); // remove previous backup
+ // FIXME: check error
+ ::rename (QFile::encodeName(url.path()), QFile::encodeName(url.path()+"~"));
+ saveDocProps(&seldoc);
+
+ prepareProgressBar();
+ seldoc.saveAs(this, url, i18n ("Part of: ") + doc->getTitle(), kvoctrainDoc::automatic);
+ removeProgressBar();
+ }
+ }
+ Prefs::setSeparator(save_separator);
+ slotStatusMsg(IDS_DEFAULT);
+}
+
+
+void kvoctrainApp::prepareProgressBar ()
+{
+ statusBar()->clear ();
+ pbar = new KProgress (statusBar());
+ pbar->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ statusBar()->addWidget(pbar, 150, true);
+ pbar->show();
+}
+
+
+void kvoctrainApp::removeProgressBar ()
+{
+ statusBar()->clear ();
+ statusBar()->removeWidget(pbar);
+ delete pbar;
+ pbar = 0;
+ delete pdlg;
+ pdlg = 0;
+}