Warning, file /education/parley/src/parleydocument.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 Frederik Gladhorn <frederik.gladhorn@kdemail.net> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "parleydocument.h" 0007 0008 #include "editor/editor.h" 0009 #include "parleymainwindow.h" 0010 #include "prefs.h" 0011 0012 #include "dashboard/dashboard.h" 0013 #include "settings/documentproperties.h" 0014 #include "vocabularyview.h" 0015 0016 #include <KEduVocExpression> 0017 #include <KEduVocLeitnerBox> 0018 #include <KEduVocLesson> 0019 #include <KEduVocWordtype> 0020 0021 #include <KRecentFilesAction> 0022 #include <QFileDialog> 0023 #include <QMimeDatabase> 0024 #include <QStandardPaths> 0025 #include <knewstuff_version.h> 0026 #include <KEMailSettings> 0027 #include <KMessageBox> 0028 #include <KProcess> 0029 #include <QTemporaryDir> 0030 0031 #include <QDialog> 0032 #include <QDialogButtonBox> 0033 #include <QTimer> 0034 0035 #ifdef HAVE_LIBXSLT 0036 #include "exportdialog.h" 0037 #include <libxml/parser.h> 0038 #include <libxml/tree.h> 0039 #include <libxslt/transform.h> 0040 #include <libxslt/xslt.h> 0041 #include <libxslt/xsltInternals.h> 0042 #include <libxslt/xsltutils.h> 0043 #endif 0044 0045 #include "settings/languageproperties.h" 0046 0047 namespace DocumentHelper 0048 { 0049 void fetchGrammar(KEduVocDocument *doc, int languageIndex) 0050 { 0051 QString locale = doc->identifier(languageIndex).locale(); 0052 0053 QUrl location(QUrl::fromUserInput(QStringLiteral("https://edu.kde.org/parley/locale/") + locale.split('_').at(0).toLower() + QStringLiteral(".kvtml"))); 0054 0055 KEduVocDocument grammarDoc; 0056 if (grammarDoc.open(location) == KEduVocDocument::NoError) { 0057 doc->identifier(languageIndex).setArticle(grammarDoc.identifier(0).article()); 0058 doc->identifier(languageIndex).setPersonalPronouns(grammarDoc.identifier(0).personalPronouns()); 0059 // @todo m_doc->identifier(index).setDeclension(grammarDoc.identifier(0).declension()); 0060 doc->identifier(languageIndex).setTenseList(grammarDoc.identifier(0).tenseList()); 0061 } else { 0062 qDebug() << "Download of " << location << " failed."; 0063 } 0064 } 0065 } // namespace DocumentHelper 0066 0067 ParleyDocument::ParleyDocument(ParleyMainWindow *parleyMainWindow) 0068 : QObject(parleyMainWindow) 0069 , m_parleyApp(parleyMainWindow) 0070 , m_doc(new KEduVocDocument) 0071 { 0072 } 0073 0074 ParleyDocument::~ParleyDocument() 0075 { 0076 close(); 0077 } 0078 0079 std::shared_ptr<KEduVocDocument> ParleyDocument::document() 0080 { 0081 // If there is no present vocabulary document, create an empty one. 0082 if (!m_doc) { 0083 m_doc.reset(new KEduVocDocument); 0084 } 0085 0086 return m_doc; 0087 } 0088 0089 void ParleyDocument::setTitle(const QString &title) 0090 { 0091 m_doc->setTitle(title); 0092 } 0093 0094 void ParleyDocument::slotFileNew() 0095 { 0096 if (queryClose()) { 0097 newDocument(true); 0098 } 0099 } 0100 0101 void ParleyDocument::newDocument(bool wizard) 0102 { 0103 std::shared_ptr<KEduVocDocument> newDoc(new KEduVocDocument); 0104 0105 initializeDefaultGrammar(newDoc.get()); 0106 setDefaultDocumentProperties(newDoc.get()); 0107 bool showGrammarDialog = false; 0108 bool fetchGrammarOnline = false; 0109 if (wizard) { 0110 DocumentProperties *titleAuthorWidget = new DocumentProperties(newDoc.get(), true, m_parleyApp); 0111 0112 QDialogButtonBox *button_dialog = new QDialogButtonBox; 0113 button_dialog->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 0114 0115 QVBoxLayout *layout = new QVBoxLayout; 0116 layout->addWidget(titleAuthorWidget); 0117 layout->addWidget(button_dialog); 0118 0119 QDialog *titleAuthorDialog = new QDialog; 0120 titleAuthorDialog->setLayout(layout); 0121 titleAuthorDialog->setWindowTitle(i18nc("@title:window document properties", "Properties for %1", newDoc->url().url())); 0122 0123 connect(titleAuthorDialog, &QDialog::accepted, titleAuthorWidget, &DocumentProperties::accept); 0124 connect(button_dialog, &QDialogButtonBox::accepted, titleAuthorDialog, &QDialog::accept); 0125 connect(button_dialog, &QDialogButtonBox::rejected, titleAuthorDialog, &QDialog::reject); 0126 0127 if (titleAuthorDialog->exec()) { 0128 showGrammarDialog = titleAuthorWidget->grammarCheckBox->isChecked(); 0129 fetchGrammarOnline = titleAuthorWidget->downloadGrammarCheckBox->isChecked(); 0130 delete titleAuthorDialog; 0131 } else { 0132 delete titleAuthorDialog; 0133 return; 0134 } 0135 } 0136 0137 close(); 0138 m_doc = std::move(newDoc); 0139 Q_EMIT documentChanged(m_doc); 0140 enableAutoBackup(Prefs::autoBackup()); 0141 0142 if (fetchGrammarOnline) { 0143 DocumentHelper::fetchGrammar(m_doc.get(), 0); 0144 DocumentHelper::fetchGrammar(m_doc.get(), 1); 0145 } 0146 if (showGrammarDialog) { 0147 languageProperties(); 0148 } 0149 0150 m_parleyApp->showEditor(); 0151 } 0152 0153 void ParleyDocument::slotFileOpen() 0154 { 0155 if (queryClose()) { 0156 ///@todo frameworks check filters are fixed in kvocdoc 0157 ///@todo frameworks check how to add child checkbox to this dialog 0158 QFileDialog dialog(m_parleyApp, i18nc("@title:window", "Open Vocabulary Collection"), QString(), KEduVocDocument::pattern(KEduVocDocument::Reading)); 0159 QCheckBox *practiceCheckBox = new QCheckBox(i18n("Open in practice &mode"), &dialog); 0160 practiceCheckBox->setChecked(m_parleyApp->currentComponent() != ParleyMainWindow::EditorComponent); 0161 dialog.setFileMode(QFileDialog::ExistingFile); 0162 if (dialog.exec() && !dialog.selectedFiles().isEmpty() && open(QUrl::fromLocalFile(dialog.selectedFiles().constFirst()))) { 0163 if (practiceCheckBox->isChecked()) { 0164 m_parleyApp->showPracticeConfiguration(); 0165 } else { 0166 m_parleyApp->showEditor(); 0167 } 0168 } 0169 } 0170 } 0171 0172 void ParleyDocument::slotFileOpenRecent(const QUrl &url) 0173 { 0174 if (queryClose() && open(url)) { 0175 m_parleyApp->showEditor(); ///@todo: start practice directly depending on current component 0176 } 0177 } 0178 0179 bool ParleyDocument::open(const QUrl &url) 0180 { 0181 if (url.path().isEmpty()) { 0182 return false; 0183 } 0184 0185 close(); 0186 0187 m_doc.reset(new KEduVocDocument); 0188 Q_EMIT documentChanged(m_doc); 0189 m_doc->setCsvDelimiter(Prefs::separator()); 0190 0191 bool isSuccess = false, isError = false; 0192 0193 KEduVocDocument::ErrorCode ret = m_doc->open(url, KEduVocDocument::FileDefaultHandling); 0194 switch (ret) { 0195 case KEduVocDocument::NoError: 0196 isSuccess = true; 0197 break; 0198 case KEduVocDocument::FileLocked: { 0199 int exit = KMessageBox::warningYesNo(m_parleyApp, 0200 i18n("The vocabulary collection is locked by another process. You can open the file if you take over the lock, " 0201 "but you will lose any changes from the other process.\n\nDo you want to take over the lock?\n"), 0202 i18n("Take Over Lock")); 0203 if (exit == KMessageBox::Yes) { // attempt to steal lock 0204 0205 ret = m_doc->open(url, KEduVocDocument::FileIgnoreLock); 0206 if (ret == KEduVocDocument::NoError) { 0207 qDebug() << "Lock stolen"; 0208 isSuccess = true; 0209 } else { 0210 isError = true; 0211 } 0212 } else { // Don't Steal continue work without saving !!! 0213 } 0214 0215 break; 0216 } 0217 default: 0218 isError = true; 0219 } 0220 0221 if (isSuccess) { 0222 qDebug() << "Open success."; 0223 // m_parleyApp->editor()->updateDocument(); 0224 m_parleyApp->addRecentFile(url, m_doc->title()); 0225 0226 enableAutoBackup(Prefs::autoBackup()); 0227 0228 } else { 0229 if (isError) { 0230 KMessageBox::error(m_parleyApp, 0231 i18n("Opening collection \"%1\" resulted in an error: %2", m_doc->url().url(), m_doc->errorDescription(ret)), 0232 i18nc("@title:window", "Open Collection")); 0233 } 0234 m_doc.reset(); 0235 Q_EMIT documentChanged(m_doc); 0236 } 0237 0238 return isSuccess; 0239 } 0240 0241 void ParleyDocument::close() 0242 { 0243 enableAutoBackup(false); 0244 if (m_doc) { 0245 m_doc.reset(); 0246 Q_EMIT documentChanged(m_doc); 0247 } 0248 } 0249 0250 bool ParleyDocument::queryClose() 0251 { 0252 if (!m_doc || !m_doc->isModified()) { 0253 return true; 0254 } 0255 0256 bool canSave = Prefs::autoSave(); // save without asking 0257 0258 if (!canSave) { 0259 int exit = KMessageBox::warningYesNoCancel(m_parleyApp, 0260 i18n("Vocabulary is modified.\n\nSave file before exit?\n"), 0261 QLatin1String(""), 0262 KStandardGuiItem::save(), 0263 KStandardGuiItem::discard()); 0264 switch (exit) { 0265 case KMessageBox::Yes: 0266 canSave = true; // save and exit 0267 break; 0268 case KMessageBox::No: 0269 canSave = false; // don't save but exit 0270 break; 0271 case KMessageBox::Continue: 0272 default: 0273 return false; // continue work without saving !!! 0274 } 0275 } 0276 0277 if (canSave) { 0278 save(); // save and exit 0279 } 0280 0281 close(); 0282 return true; 0283 } 0284 0285 void ParleyDocument::openGHNS() 0286 { 0287 if (m_parleyApp->queryClose()) { 0288 QDir downloadDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + '/' + "kvtml/"); 0289 0290 downloadDir.mkpath(downloadDir.absolutePath()); 0291 0292 QUrl url = QUrl::fromUserInput(QFileDialog::getOpenFileName(m_parleyApp, 0293 i18nc("@title:window", "Open Downloaded Vocabulary Collection"), 0294 downloadDir.path(), 0295 KEduVocDocument::pattern(KEduVocDocument::Reading))); 0296 0297 if (open(url)) { 0298 m_parleyApp->showPracticeConfiguration(); 0299 } 0300 } 0301 } 0302 0303 void ParleyDocument::save() 0304 { 0305 if (m_doc->url().fileName().isEmpty()) { 0306 saveAs(); 0307 return; 0308 } 0309 0310 // remove previous backup 0311 QFile::remove(m_doc->url().toLocalFile() + '~'); 0312 QFile::copy(QFile::encodeName(m_doc->url().toLocalFile()), QFile::encodeName(m_doc->url().toLocalFile() + '~')); 0313 0314 m_doc->setCsvDelimiter(Prefs::separator()); 0315 0316 Q_EMIT statesNeedSaving(); 0317 0318 QString newgenerator = QLatin1String("Parley ") + PARLEY_VERSION_STRING; 0319 m_doc->setGenerator(newgenerator); 0320 0321 bool isSuccess = false, isError = false; 0322 0323 KEduVocDocument::ErrorCode ret = m_doc->saveAs(m_doc->url(), KEduVocDocument::Automatic, KEduVocDocument::FileIgnoreLock); 0324 0325 switch (ret) { 0326 case KEduVocDocument::NoError: 0327 isSuccess = true; 0328 break; 0329 case KEduVocDocument::FileLocked: { 0330 int exit = KMessageBox::warningYesNo(m_parleyApp, 0331 i18n("File \"%1\" is locked by another process. You can save to the file if you take over the lock, but you will " 0332 "lose any changes from the other process.\n\nDo you want to take over the lock?\n", 0333 m_doc->url().url()), 0334 QLatin1String("")); 0335 if (exit == KMessageBox::Yes) { 0336 m_doc->setGenerator(newgenerator); 0337 ret = m_doc->saveAs(m_doc->url(), KEduVocDocument::Automatic, KEduVocDocument::FileIgnoreLock); 0338 0339 if (ret == KEduVocDocument::NoError) { 0340 isSuccess = true; 0341 qDebug() << "Lock stolen"; 0342 } else { 0343 isError = true; 0344 } 0345 } else { 0346 // Intentionally empty else. Try to saveAs another filename 0347 } 0348 break; 0349 } 0350 default: 0351 isError = true; 0352 } 0353 0354 if (isSuccess) { 0355 m_parleyApp->addRecentFile(m_doc->url(), m_doc->title()); 0356 enableAutoBackup(Prefs::autoBackup()); 0357 } else { 0358 if (isError) { 0359 KMessageBox::error(m_parleyApp, 0360 i18n("Writing file \"%1\" resulted in an error: %2", m_doc->url().url(), m_doc->errorDescription(ret)), 0361 i18nc("@title:window", "Save File")); 0362 } 0363 qDebug() << "Save failed trying save as for " << m_doc->url().url(); 0364 saveAs(); 0365 } 0366 } 0367 0368 void ParleyDocument::saveAs(QUrl url) 0369 { 0370 if (!m_doc) { 0371 return; 0372 } 0373 0374 if (url.isEmpty()) { 0375 url = QUrl::fromLocalFile(QFileDialog::getSaveFileName(m_parleyApp->parentWidget(), 0376 i18nc("@title:window", "Save Vocabulary As"), 0377 QString(), 0378 KEduVocDocument::pattern(KEduVocDocument::Writing))); 0379 0380 if (url.isEmpty()) { 0381 return; 0382 } 0383 } 0384 0385 QFileInfo fileinfo(url.toLocalFile()); 0386 if (fileinfo.exists()) { 0387 if (KMessageBox::warningContinueCancel(0, 0388 i18n("<qt>The file<p><b>%1</b></p>already exists. Do you want to overwrite it?</qt>", url.toLocalFile()), 0389 QString(), 0390 KStandardGuiItem::overwrite()) 0391 == KMessageBox::Cancel) { 0392 return; 0393 } 0394 } 0395 0396 QString msg = i18nc("@info:status saving a file", "Saving %1", url.toLocalFile()); 0397 0398 QFile::remove(url.toLocalFile() + '~'); // remove previous backup 0399 QFile::copy(QFile::encodeName(url.toLocalFile()), QFile::encodeName(QString(url.toLocalFile() + '~'))); 0400 0401 m_doc->setCsvDelimiter(Prefs::separator()); 0402 0403 if (!url.toLocalFile().contains('.')) { 0404 url.fromLocalFile(url.toLocalFile() + QLatin1String(".kvtml")); 0405 } 0406 0407 bool isSuccess = false, isError = false; 0408 m_doc->setGenerator(QStringLiteral("Parley")); 0409 int ret = m_doc->saveAs(url, KEduVocDocument::Automatic); 0410 switch (ret) { 0411 case KEduVocDocument::NoError: 0412 isSuccess = true; 0413 break; 0414 case KEduVocDocument::FileLocked: { 0415 int exit = KMessageBox::warningYesNo(m_parleyApp, 0416 i18n("File \"%1\" is locked by another process. You can save to the file if you take over the lock, but you will " 0417 "lose any changes from the other process.\n\nDo you want to take over the lock?\n", 0418 m_doc->url().url()), 0419 QLatin1String("")); 0420 if (exit == KMessageBox::Yes) { // attempt lock steal 0421 m_doc->setGenerator(QLatin1String("Parley ") + PARLEY_VERSION_STRING); 0422 ret = m_doc->saveAs(m_doc->url(), KEduVocDocument::Automatic, KEduVocDocument::FileIgnoreLock); 0423 0424 if (ret == KEduVocDocument::NoError) { 0425 isSuccess = true; 0426 qDebug() << "Lock stolen"; 0427 } else { 0428 isError = true; 0429 } 0430 break; 0431 } else { // don't steal the lock 0432 } 0433 0434 break; 0435 } 0436 default: 0437 isError = true; 0438 break; 0439 } 0440 0441 if (isSuccess) { 0442 qDebug() << "SaveAs success."; 0443 m_parleyApp->addRecentFile(m_doc->url(), m_doc->title()); 0444 Q_EMIT statesNeedSaving(); 0445 0446 } else { 0447 qDebug() << "SaveAs failed for " << m_doc->url().url() << " \nwhy " << m_doc->errorDescription(ret); 0448 if (isError) { 0449 KMessageBox::error(m_parleyApp, 0450 i18n("Writing file \"%1\" resulted in an error: %2", m_doc->url().url(), m_doc->errorDescription(ret)), 0451 i18nc("@title:window", "Save File")); 0452 } 0453 } 0454 } 0455 0456 void ParleyDocument::initializeDefaultGrammar(KEduVocDocument *doc) 0457 { 0458 KEduVocWordType *root = doc->wordTypeContainer(); 0459 KEduVocWordType *noun = new KEduVocWordType(i18n("Noun"), root); 0460 noun->setWordType(KEduVocWordFlag::Noun); 0461 root->appendChildContainer(noun); 0462 0463 KEduVocWordType *nounChild = new KEduVocWordType(i18n("Masculine"), noun); 0464 nounChild->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Masculine); 0465 noun->appendChildContainer(nounChild); 0466 nounChild = new KEduVocWordType(i18n("Feminine"), noun); 0467 nounChild->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Feminine); 0468 noun->appendChildContainer(nounChild); 0469 nounChild = new KEduVocWordType(i18n("Neuter"), noun); 0470 nounChild->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Neuter); 0471 noun->appendChildContainer(nounChild); 0472 0473 KEduVocWordType *verb = new KEduVocWordType(i18n("Verb"), root); 0474 verb->setWordType(KEduVocWordFlag::Verb); 0475 root->appendChildContainer(verb); 0476 0477 KEduVocWordType *adjective = new KEduVocWordType(i18n("Adjective"), root); 0478 adjective->setWordType(KEduVocWordFlag::Adjective); 0479 root->appendChildContainer(adjective); 0480 0481 KEduVocWordType *adverb = new KEduVocWordType(i18n("Adverb"), root); 0482 adverb->setWordType(KEduVocWordFlag::Adverb); 0483 root->appendChildContainer(adverb); 0484 0485 KEduVocWordType *conjunction = new KEduVocWordType(i18n("Conjunction"), root); 0486 conjunction->setWordType(KEduVocWordFlag::Conjunction); 0487 root->appendChildContainer(conjunction); 0488 } 0489 0490 void ParleyDocument::setDefaultDocumentProperties(KEduVocDocument *doc) 0491 { 0492 KEMailSettings emailSettings; 0493 emailSettings.setProfile(emailSettings.defaultProfileName()); 0494 doc->setAuthor(emailSettings.getSetting(KEMailSettings::RealName)); 0495 doc->setAuthorContact(emailSettings.getSetting(KEMailSettings::EmailAddress)); 0496 0497 doc->setLicense(i18n("Public Domain")); 0498 doc->setCategory(i18n("Languages")); 0499 0500 QString locale = QLocale().name(); 0501 0502 doc->appendIdentifier(); 0503 doc->appendIdentifier(); 0504 doc->identifier(0).setName(QLocale(locale).nativeLanguageName()); 0505 doc->identifier(0).setLocale(locale); 0506 doc->identifier(1).setName(i18n("A Second Language")); 0507 doc->identifier(1).setLocale(locale); 0508 0509 KEduVocLesson *lesson = new KEduVocLesson(i18n("Lesson 1"), doc->lesson()); 0510 doc->lesson()->appendChildContainer(lesson); 0511 0512 // add some entries 0513 for (int i = 0; i < 15; i++) { 0514 lesson->appendEntry(new KEduVocExpression()); 0515 } 0516 0517 doc->setModified(false); 0518 } 0519 0520 void ParleyDocument::slotGHNS(const QList<KNSCore::Entry> &entries) 0521 { 0522 QMimeDatabase db; 0523 QString fileName; 0524 int numberInstalled = 0; 0525 for (const auto &entry : entries) { 0526 if (entry.status() != KNS3::Entry::Installed) { 0527 continue; 0528 } 0529 ++numberInstalled; 0530 // check mime type and if kvtml, open it 0531 const QStringList installedFiles = entry.installedFiles(); 0532 for (const QString &file : installedFiles) { 0533 QMimeType mimeType = db.mimeTypeForFile(file); 0534 qDebug() << "KNS2 file of mime type:" << db.mimeTypeForFile(file).name(); 0535 if (mimeType.inherits(QStringLiteral("application/x-kvtml"))) { 0536 ParleyMainWindow::instance()->addRecentFile(QUrl::fromLocalFile(file), QString()); ///@todo: title! 0537 fileName = file; 0538 } 0539 } 0540 } 0541 0542 // to enable the display in the welcome screen 0543 Prefs::self()->save(); 0544 m_parleyApp->updateRecentFilesModel(); 0545 if (numberInstalled > 1) { 0546 openGHNS(); 0547 } else if (numberInstalled == 1) { 0548 if (open(QUrl::fromLocalFile(fileName))) 0549 m_parleyApp->showPracticeConfiguration(); 0550 else 0551 KMessageBox::error(m_parleyApp, i18n("Could not open vocabulary collection \"%1\"", entries.first().name())); 0552 } 0553 } 0554 0555 void ParleyDocument::documentProperties() 0556 { 0557 DocumentProperties *titleAuthorWidget = new DocumentProperties(m_doc.get(), false, m_parleyApp); 0558 0559 QDialogButtonBox *button_dialog = new QDialogButtonBox; 0560 button_dialog->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 0561 0562 QVBoxLayout *layout = new QVBoxLayout; 0563 layout->addWidget(titleAuthorWidget); 0564 layout->addWidget(button_dialog); 0565 0566 QDialog *titleAuthorDialog = new QDialog; 0567 titleAuthorDialog->setLayout(layout); 0568 titleAuthorDialog->setWindowTitle(i18nc("@title:window document properties", "Properties for %1", m_doc->url().url())); 0569 0570 // the language options are only shown, when this is used to create a new document. 0571 titleAuthorWidget->languageGroupBox->setVisible(false); 0572 0573 connect(titleAuthorDialog, &QDialog::accepted, titleAuthorWidget, &DocumentProperties::accept); 0574 connect(button_dialog, &QDialogButtonBox::accepted, titleAuthorDialog, &QDialog::accept); 0575 connect(button_dialog, &QDialogButtonBox::rejected, titleAuthorDialog, &QDialog::reject); 0576 0577 titleAuthorDialog->exec(); 0578 delete titleAuthorDialog; 0579 Q_EMIT documentChanged(m_doc); 0580 } 0581 0582 void ParleyDocument::languageProperties() 0583 { 0584 LanguageProperties properties(m_doc.get(), m_parleyApp); 0585 if (properties.exec() == QDialog::Accepted) { 0586 Q_EMIT languagesChanged(); 0587 } 0588 } 0589 0590 void ParleyDocument::exportDialog() 0591 { 0592 #ifdef HAVE_LIBXSLT 0593 ExportDialog dialog(this, m_parleyApp); 0594 dialog.exec(); 0595 #endif 0596 } 0597 0598 void ParleyDocument::slotFileMerge() 0599 { 0600 ///@todo as soon as some brave soul descends into the lib and implements merging this should be enabled 0601 // KUrl url = KFileDialog::getOpenUrl(QString(), KEduVocDocument::pattern(KEduVocDocument::Reading), parentWidget(), i18n("Merge Vocabulary File")); 0602 // 0603 // if (!url.isEmpty()) { 0604 // QString msg = i18n("Loading %1", url.path()); 0605 // slotStatusMsg(msg); 0606 // 0607 // KEduVocDocument *new_doc = new KEduVocDocument(this); 0608 // new_doc->setCsvDelimiter(Prefs::separator()); 0609 // new_doc->open(url); 0610 // 0611 // m_doc->merge(new_doc, true); 0612 // 0613 // KEduVocWordFlag::setTenseNames(m_doc->tenseDescriptions()); 0614 // KVTUsage::setUsageNames(m_doc->usageDescriptions()); 0615 // 0616 // delete(new_doc); 0617 // m_recentFilesAction->addUrl(url); 0618 // m_tableModel->reset(); 0619 // m_lessonModel->setDocument(m_doc); 0620 // m_tableView->adjustContent(); 0621 // } 0622 } 0623 0624 void ParleyDocument::enableAutoBackup(bool enable) 0625 { 0626 if (!enable) { 0627 if (m_backupTimer) { 0628 m_backupTimer->stop(); 0629 } 0630 } else { 0631 if (!m_backupTimer) { 0632 m_backupTimer = new QTimer(this); 0633 connect(m_backupTimer, &QTimer::timeout, this, &ParleyDocument::save); 0634 } 0635 m_backupTimer->start(Prefs::backupTime() * 60 * 1000); 0636 } 0637 }