00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "parley.h"
00026
00027 #include "practice/testentrymanager.h"
00028 #include "kvttablemodel.h"
00029 #include "kvtsortfiltermodel.h"
00030 #include "kvttableview.h"
00031 #include "kvtlessonmodel.h"
00032 #include "kvtlessonview.h"
00033
00034 #include "entry-dialogs/EntryDlg.h"
00035 #include "statistics-dialogs/StatisticsDialog.h"
00036 #include "settings/parleyprefs.h"
00037 #include "language-dialogs/languagedialog.h"
00038 #include "language-dialogs/grammardialog.h"
00039 #include "docprop-dialogs/TitlePage.h"
00040 #include "configure-practice/configurepracticedialog.h"
00041 #include "prefs.h"
00042
00043 #include <keduvoclesson.h>
00044
00045 #include <kstatusbar.h>
00046 #include <klineedit.h>
00047 #include <kcombobox.h>
00048 #include <kconfig.h>
00049 #include <kselectaction.h>
00050 #include <kstandarddirs.h>
00051 #include <klocale.h>
00052 #include <kdebug.h>
00053 #include <kiconloader.h>
00054 #include <krecentfilesaction.h>
00055 #include <kinputdialog.h>
00056 #include <kapplication.h>
00057 #include <KActionCollection>
00058 #include <KMessageBox>
00059
00060 #include <QFile>
00061 #include <QTimer>
00062 #include <QPixmap>
00063 #include <QKeyEvent>
00064 #include <QApplication>
00065 #include <QClipboard>
00066 #include <QProgressBar>
00067 #include <QSplitter>
00068 #include <QtGui/QPrinter>
00069 #include <QtGui/QPrintDialog>
00070
00071
00072
00073
00074
00075 void ParleyApp::saveOptions()
00076 {
00077 fileOpenRecent->saveEntries(KGlobal::config()->group("Recent Files"));
00078
00079 if (m_tableView) {
00080
00081 QModelIndex sourceIndex = m_sortFilterModel->mapToSource(m_tableView->currentIndex());
00082 Prefs::setCurrentRow(sourceIndex.row());
00083 Prefs::setCurrentCol(sourceIndex.column());
00084 }
00085
00086 if (m_lessonSelectionCombo)
00087 Prefs::setLessonEditingSelection(m_lessonSelectionCombo->currentIndex());
00088
00089 if (m_mainSplitter)
00090 Prefs::setMainWindowSplitter(m_mainSplitter->sizes());
00091
00092 Prefs::self()->writeConfig();
00093 }
00094
00095
00096 void ParleyApp::saveProperties(KConfigGroup &config)
00097 {
00098 saveOptions();
00099 if (m_doc) {
00100 config.writeEntry("Filename", m_doc->url().path());
00101 config.writeEntry("Title", m_doc->title());
00102 config.writeEntry("Modified", m_doc->isModified());
00103
00104 QString filename=m_doc->url().path();
00105 QString tempname = kapp->tempSaveName(filename);
00106 m_doc->saveAs(KUrl(tempname), KEduVocDocument::Automatic, "Parley");
00107 }
00108 }
00109
00110
00111 void ParleyApp::readProperties(const KConfigGroup &config)
00112 {
00113 QString filename = config.readEntry("Filename");
00114 QString title = config.readEntry("Title");
00115 bool modified = config.readEntry("Modified", false);
00116 if (modified) {
00117 bool b_canRecover;
00118 QString tempname = kapp->checkRecoverFile(filename,b_canRecover);
00119
00120 if (b_canRecover) {
00121 m_doc = new KEduVocDocument(this);
00122 m_doc->setUrl(KUrl(tempname));
00123 removeProgressBar();
00124 m_doc->setModified();
00125 m_doc->setTitle(title);
00126 m_doc->setUrl(KUrl(filename));
00127 setCaption(m_doc->title(), m_doc->isModified());
00128 QFile::remove(tempname);
00129 }
00130 } else if (!filename.isEmpty()) {
00131 m_doc = new KEduVocDocument(this);
00132 m_doc->setUrl(KUrl(filename));
00133 removeProgressBar();
00134 setCaption(m_doc->title(), m_doc->isModified());
00135 }
00136
00137 show();
00138 }
00139
00140
00141 ParleyApp::~ParleyApp()
00142 {
00143 removeEntryDlg();
00144 delete m_doc;
00145 }
00146
00147
00148 void ParleyApp::slotCancelSelection()
00149 {
00150 m_tableView->clearSelection();
00151 }
00152
00153
00154 void ParleyApp::slotSelectAll()
00155 {
00156 m_tableView->selectAll();
00157 }
00158
00159
00164 void ParleyApp::slotEditEntry()
00165 {
00166
00167 if (entryDlg == 0) {
00168 entryDlg = new EntryDlg(this, m_doc);
00169 connect(entryDlg, SIGNAL(closeEntryDialog()), this, SLOT(removeEntryDlg()));
00170 connect(entryDlg, SIGNAL(dataChanged(const QModelIndex& , const QModelIndex&)), m_tableModel, SLOT(dataChangedFromOutside(const QModelIndex& , const QModelIndex&)));
00171 }
00172
00173 if (entryDlg != 0) {
00174 entryDlg->commitData(false);
00175 }
00176 entryDlg->show();
00177
00178 if (entryDlg == 0) {
00179 kError() << "ParleyApp::setDataEntryDlg: entryDlg == 0\n";
00180 return;
00181 }
00182
00183
00184
00185
00186 QModelIndexList modelIndexList;
00187 modelIndexList = m_tableView->selectionModel()->selectedRows();
00188
00189 QList<int> entryList;
00190 foreach (QModelIndex modelIndex, modelIndexList) {
00191 entryList.append(m_sortFilterModel->mapToSource(modelIndex).row());
00192 }
00193
00194 QModelIndex currentIndex = m_tableView->currentIndex();
00195 if (currentIndex.isValid()) {
00196 currentIndex = m_sortFilterModel->mapToSource(currentIndex);
00197 }
00198
00199 if (entryList.isEmpty() ) {
00200 entryList.append( currentIndex.row() );
00201 }
00202
00203 entryDlg->setData(entryList, currentIndex.column() - KV_COL_TRANS);
00204 m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
00205 }
00206
00207
00208 void ParleyApp::removeEntryDlg()
00209 {
00210 if (entryDlg != 0) {
00211 entryDlg->deleteLater();
00212 entryDlg = 0;
00213 }
00214
00215 m_tableView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::EditKeyPressed | QAbstractItemView::DoubleClicked);
00216 }
00217
00218
00219 void ParleyApp::slotLanguageProperties()
00220 {
00221 GrammarDialog ddlg(m_doc, this);
00222
00223 if (ddlg.exec() == KDialog::Accepted) {
00224 m_doc->setModified();
00225 m_tableModel->reset();
00226 setCaption(m_doc->title(), m_doc->isModified());
00227
00228 }
00229 }
00230
00231
00232 void ParleyApp::slotUpdateWindowCaption()
00233 {
00234 setCaption(m_doc->title(), m_doc->isModified());
00235
00236 }
00237
00238
00239 void ParleyApp::slotCutEntry()
00240 {
00241
00242 slotEditCopy();
00243
00244
00245 if (m_tableView->selectionModel()->selectedRows().count() == 1) {
00246 int currentRow = m_tableView->currentIndex().row();
00247 int currentColumn = m_tableView->currentIndex().column();
00248 m_sortFilterModel->removeRows(m_tableView->currentIndex().row(), 1, QModelIndex());
00249 m_tableView->selectionModel()->setCurrentIndex(m_sortFilterModel->index(currentRow, currentColumn), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
00250 } else {
00251 int currentRow = m_tableView->currentIndex().row();
00252 int currentColumn = m_tableView->currentIndex().column();
00253 int rowCount = m_sortFilterModel->rowCount(QModelIndex());
00254
00255
00256 for (int i = rowCount - 1; i >= 0; i--)
00257 if (m_tableView->selectionModel()->isRowSelected(i, QModelIndex()))
00258 m_sortFilterModel->removeRows(i, 1, QModelIndex());
00259 m_tableView->selectionModel()->setCurrentIndex(m_sortFilterModel->index(currentRow, currentColumn), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
00260 }
00261 editDelete->setEnabled(m_sortFilterModel->rowCount(QModelIndex()) > 0);
00262 }
00263
00264
00265 void ParleyApp::slotDeleteEntry()
00266 {
00267 if (m_tableView->selectionModel()->selectedRows().count() == 1) {
00268 if (KMessageBox::Continue == KMessageBox::warningContinueCancel(this, i18n("Do you really want to delete the selected entry?"), "", KStandardGuiItem::del())) {
00269 int currentRow = m_tableView->currentIndex().row();
00270 int currentColumn = m_tableView->currentIndex().column();
00271 m_sortFilterModel->removeRows(m_tableView->currentIndex().row(), 1, QModelIndex());
00272 m_tableView->selectionModel()->setCurrentIndex(m_sortFilterModel->index(currentRow, currentColumn), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
00273 }
00274 } else {
00275 if (KMessageBox::Continue == KMessageBox::warningContinueCancel(this, i18n("Do you really want to delete the selected entries?"), "", KStandardGuiItem::del())) {
00276 int currentRow = m_tableView->currentIndex().row();
00277 int currentColumn = m_tableView->currentIndex().column();
00278 int rowCount = m_sortFilterModel->rowCount(QModelIndex());
00279
00280
00281 for (int i = rowCount - 1; i >= 0; i--)
00282 if (m_tableView->selectionModel()->isRowSelected(i, QModelIndex()))
00283 m_sortFilterModel->removeRows(i, 1, QModelIndex());
00284 m_tableView->selectionModel()->setCurrentIndex(m_sortFilterModel->index(currentRow, currentColumn), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
00285 }
00286 }
00287 editDelete->setEnabled(m_sortFilterModel->rowCount(QModelIndex()) > 0);
00288 }
00289
00290
00291 void ParleyApp::slotNewEntry()
00292 {
00293 m_tableModel->appendEntry();
00294
00295
00296 makeLessonVisibleInTable(m_doc->currentLesson());
00297
00298
00299 editDelete->setEnabled(m_sortFilterModel->rowCount(QModelIndex()) > 0);
00300
00301 QModelIndex currentIndex = m_sortFilterModel->index(
00302 m_sortFilterModel->rowCount(QModelIndex()) - 1, KV_COL_TRANS);
00303
00304 m_tableView->selectionModel()->setCurrentIndex(
00305 currentIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
00306
00307 m_tableView->edit(currentIndex);
00308 }
00309
00310
00311 void ParleyApp::makeLessonVisibleInTable(int lessonIndex)
00312 {
00313 switch (m_lessonSelectionCombo->currentIndex()) {
00314 case Prefs::EnumLessonEditingSelection::CurrentLesson:
00315 m_doc->setCurrentLesson(lessonIndex);
00316 m_sortFilterModel->clear();
00317 break;
00318 case Prefs::EnumLessonEditingSelection::LessonsInQuery:
00319 m_doc->setCurrentLesson(lessonIndex);
00320 if ( !m_doc->lesson(lessonIndex).inPractice() ) {
00321 m_lessonSelectionCombo->setCurrentIndex(Prefs::EnumLessonEditingSelection::CurrentLesson);
00322 }
00323 m_sortFilterModel->clear();
00324 break;
00325 case Prefs::EnumLessonEditingSelection::AllLessons:
00326 break;
00327 }
00328 }
00329
00330
00331 void ParleyApp::slotShowStatistics()
00332 {
00333 KVTStatisticsDialog sdlg(m_tableModel, this);
00334 sdlg.exec();
00335 }
00336
00337
00338 void ParleyApp::slotCleanVocabulary()
00339 {
00340 prepareProgressBar();
00341 QApplication::setOverrideCursor(Qt::WaitCursor);
00342 int num = m_doc->cleanUp();
00343 QApplication::restoreOverrideCursor();
00344 removeProgressBar();
00345
00346
00347
00348 if (num != 0) {
00349 m_tableModel->reset();
00350 QString s = i18np("1 entry with the same content was found and removed.",
00351 "%1 entries with the same content were found and removed.", num);
00352
00353 KMessageBox::information(this, s, i18n("Remove Duplicates"));
00354 }
00355 }
00356
00357
00358 void ParleyApp::slotGeneralOptions()
00359 {
00360 ParleyPrefs* dialog = new ParleyPrefs(m_doc, this, "settings", Prefs::self());
00361 connect(dialog, SIGNAL(settingsChanged(const QString &)), this, SLOT(slotApplyPreferences()));
00362 dialog->show();
00363 }
00364
00365
00366 void ParleyApp::slotApplyPreferences()
00367 {
00368 if (Prefs::autoBackup()) {
00369 QTimer::singleShot(Prefs::backupTime() * 60 * 1000, this, SLOT(slotTimeOutBackup()));
00370 }
00371
00372 if (m_pronunciationStatusBarLabel) {
00373 m_pronunciationStatusBarLabel->setFont(Prefs::iPAFont());
00374 }
00375
00376 m_tableView->setFont(Prefs::tableFont());
00377 m_tableView->reset();
00378
00379 m_tableModel->reset();
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 void ParleyApp::slotFilePrint()
00393 {
00394 QPrinter printer;
00395 printer.setFullPage(true);
00396 QPrintDialog printDialog(&printer, this);
00397
00398 if (printDialog.exec()) {
00399 m_tableView->print(&printer);
00400 }
00401 }
00402
00403
00404 void ParleyApp::slotEditCopy()
00405 {
00406
00407
00408 QApplication::setOverrideCursor(Qt::WaitCursor);
00409
00410 QString textToCopy;
00411 QModelIndexList selectedRows = m_tableView->selectionModel()->selectedRows(0);
00412
00413 foreach(const QModelIndex &idx, selectedRows) {
00414 bool sep = false;
00415 for (int i = KV_COL_TRANS; i < m_tableModel->columnCount(QModelIndex()); i++) {
00416 if (!sep)
00417 sep = true;
00418 else
00419 textToCopy += '\t';
00420
00421 QModelIndex mappedIndex = m_sortFilterModel->mapToSource(m_sortFilterModel->index(idx.row(), i));
00422 textToCopy += m_tableModel->data(mappedIndex, Qt::DisplayRole).toString();
00423 }
00424 if (!textToCopy.isEmpty())
00425 textToCopy += '\n';
00426 }
00427
00428 if (!textToCopy.isEmpty())
00429 QApplication::clipboard()->setText(textToCopy);
00430
00431 QApplication::restoreOverrideCursor();
00432
00433 }
00434
00435
00436 void ParleyApp::slotEditPaste()
00437 {
00439
00440
00441 QApplication::setOverrideCursor(Qt::WaitCursor);
00442 QString s;
00443 QString textToPaste = QApplication::clipboard()->text();
00444
00445 QTextStream ts;
00446 ts.setString(&textToPaste, QIODevice::Text);
00447
00448 QString num;
00449
00450 QModelIndexList selectedRows = m_tableView->selectionModel()->selectedRows();
00451 int lastSelectedRow;
00452 if(!selectedRows.isEmpty())
00453 lastSelectedRow = m_sortFilterModel->mapToSource(selectedRows.back()).row() + 1;
00454 else
00455 lastSelectedRow = m_tableModel->rowCount(QModelIndex());
00456
00457 int count = 0;
00458 while (!ts.atEnd()) {
00459 s = ts.readLine();
00460 if (!s.isEmpty()) {
00461 m_tableModel->insertRows(lastSelectedRow + count, 1);
00462 QStringList sl = s.split('\t', QString::KeepEmptyParts);
00463
00464 for (int i = 0; i < sl.count(); ++i) {
00465 m_tableModel->setData(m_tableModel->index(lastSelectedRow + count, i + KV_COL_TRANS), sl[i], Qt::EditRole);
00466 m_tableModel->setData(m_tableModel->index(lastSelectedRow + count, i + KV_COL_TRANS), m_doc->currentLesson(), KVTTableModel::LessonRole);
00467 }
00468 }
00469 count++;
00470 }
00471
00472 QApplication::restoreOverrideCursor();
00473
00474
00475 editDelete->setEnabled(m_sortFilterModel->rowCount(QModelIndex()) > 0);
00476 }
00477
00478
00479 void ParleyApp::slotSelectionChanged(const QItemSelection &, const QItemSelection &)
00480 {
00481
00482 if (entryDlg != 0) {
00483 slotEditEntry();
00484 }
00485 }
00486
00487
00488 void ParleyApp::slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous)
00489 {
00490
00491 Q_UNUSED(previous);
00492 if (!current.isValid()) {
00493 return;
00494 }
00495
00496 int translationId = current.column() - KV_COL_TRANS;
00497 if ( translationId < 0 ) {
00498 translationId = 0;
00499 }
00500
00501 QModelIndex index = current;
00502 index = m_sortFilterModel->mapToSource(current);
00503
00504 KEduVocExpression * currentExpression = m_doc->entry(index.row());
00505 statusBar()->clearMessage();
00506
00507 if (m_remarkStatusBarLabel != 0) {
00508 m_remarkStatusBarLabel->setText(i18n("Comment: %1", currentExpression->translation(translationId).comment()));
00509 }
00510 if (m_pronunciationStatusBarLabel != 0) {
00511 m_pronunciationStatusBarLabel->setText(i18n("Pronunciation: %1", currentExpression->translation(translationId).pronunciation()));
00512 }
00513 QString typeText = currentExpression->translation(translationId).type();
00514 if ( !currentExpression->translation(translationId).subType().isEmpty() ){
00515 typeText.append(i18n(" (%1)", currentExpression->translation(translationId).subType()));
00516 }
00517 if (m_typeStatusBarLabel != 0) {
00518 m_typeStatusBarLabel->setText(i18n("Type: %1", typeText));
00519 }
00520
00521 if (entryDlg != 0) {
00522 slotEditEntry();
00523 }
00524 }
00525
00526
00527 void ParleyApp::slotCurrentLessonChanged()
00528 {
00529 editDelete->setEnabled(m_sortFilterModel->rowCount(QModelIndex()) > 0);
00530 }
00531
00532 void ParleyApp::slotConfigShowSearch()
00533 {
00534 if (m_searchWidget) {
00535 m_searchWidget->setVisible(m_searchWidget->isHidden());
00536 Prefs::setShowSearch(m_searchWidget->isVisible());
00537 }
00538 }
00539
00540 void ParleyApp::slotEditLanguages()
00541 {
00542 LanguageDialog* languageDialog = new LanguageDialog(m_doc, this);
00544
00545 if ( languageDialog->exec() == KDialog::Accepted ) {
00546 m_tableModel->loadLanguageSettings();
00547 }
00548 }
00549
00550 void ParleyApp::slotDocumentProperties()
00551 {
00552 TitlePage* titleAuthorWidget = new TitlePage(m_doc, this);
00553 KDialog* titleAuthorDialog;
00554 titleAuthorDialog = new KDialog(this);
00555 titleAuthorDialog->setMainWidget( titleAuthorWidget );
00556 titleAuthorDialog->setCaption(i18nc("@title:window document properties", "Properties for %1", m_doc->url().url()));
00557 if ( titleAuthorDialog->exec() == KDialog::Accepted ) {
00558 titleAuthorWidget->commitData();
00559 }
00560 slotUpdateWindowCaption();
00561 delete titleAuthorDialog;
00562 }
00563
00564 void ParleyApp::configurePractice()
00565 {
00566 ConfigurePracticeDialog* configurePracticeDialog;
00567 configurePracticeDialog = new ConfigurePracticeDialog(m_doc, this, "practice settings", Prefs::self());
00568
00569 if ( configurePracticeDialog->exec() == ConfigurePracticeDialog::StartPractice ) {
00570 startPractice();
00571 }
00572 }
00573
00574 void ParleyApp::startPractice()
00575 {
00576 removeEntryDlg();
00577 hide();
00578
00579 TestEntryManager testManager(m_doc, this);
00580 testManager.startPractice();
00581
00582 show();
00583 }
00584
00585
00586 #include "parley.moc"