File indexing completed on 2024-12-22 04:28:07

0001 /*
0002   SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org>
0003 
0004   SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "importlibreofficeautocorrection.h"
0008 #include "textautocorrection_debug.h"
0009 #include <KLocalizedString>
0010 #include <KZip>
0011 #include <QDomDocument>
0012 #include <QFile>
0013 #include <QTemporaryDir>
0014 
0015 using namespace TextAutoCorrectionCore;
0016 
0017 ImportLibreOfficeAutocorrection::ImportLibreOfficeAutocorrection() = default;
0018 
0019 ImportLibreOfficeAutocorrection::~ImportLibreOfficeAutocorrection()
0020 {
0021     closeArchive();
0022 }
0023 
0024 void ImportLibreOfficeAutocorrection::closeArchive()
0025 {
0026     if (mArchive) {
0027         if (mArchive->isOpen()) {
0028             mArchive->close();
0029         }
0030         delete mArchive;
0031         mArchive = nullptr;
0032     }
0033 
0034     delete mTempDir;
0035     mTempDir = nullptr;
0036 }
0037 
0038 bool ImportLibreOfficeAutocorrection::import(const QString &fileName, QString &errorMessage, LoadAttribute loadAttribute)
0039 {
0040     // We Don't have it in LibreOffice
0041     if (loadAttribute == SuperScript) {
0042         return false;
0043     }
0044     closeArchive();
0045     mArchive = new KZip(fileName);
0046     const bool result = mArchive->open(QIODevice::ReadOnly);
0047     if (result) {
0048         importAutoCorrectionFile();
0049         return true;
0050     } else {
0051         qCWarning(TEXTAUTOCORRECTION_LOG) << "Impossible to open archive file";
0052         errorMessage = i18n("Archive cannot be opened in read mode.");
0053         return false;
0054     }
0055 }
0056 
0057 void ImportLibreOfficeAutocorrection::importAutoCorrectionFile()
0058 {
0059     mTempDir = new QTemporaryDir();
0060     const KArchiveDirectory *archiveDirectory = mArchive->directory();
0061     // Replace word
0062     if (!importFile(DOCUMENT, archiveDirectory)) {
0063         qCWarning(TEXTAUTOCORRECTION_LOG) << " Impossible to import DOCUMENT";
0064         return;
0065     }
0066 
0067     // No tread as end of line
0068     if (!importFile(SENTENCE, archiveDirectory)) {
0069         qCWarning(TEXTAUTOCORRECTION_LOG) << " Impossible to import SENTENCE";
0070         return;
0071     }
0072 
0073     // Two upper letter
0074     if (!importFile(WORD, archiveDirectory)) {
0075         qCWarning(TEXTAUTOCORRECTION_LOG) << " Impossible to import WORD";
0076         return;
0077     }
0078 }
0079 
0080 bool ImportLibreOfficeAutocorrection::importFile(Type type, const KArchiveDirectory *archiveDirectory)
0081 {
0082     const KArchiveEntry *documentList = nullptr;
0083 
0084     QString archiveFileName;
0085     switch (type) {
0086     case DOCUMENT:
0087         archiveFileName = QStringLiteral("DocumentList.xml");
0088         break;
0089     case SENTENCE:
0090         archiveFileName = QStringLiteral("SentenceExceptList.xml");
0091         break;
0092     case WORD:
0093         archiveFileName = QStringLiteral("WordExceptList.xml");
0094         break;
0095     default:
0096         return false;
0097     }
0098     documentList = archiveDirectory->entry(archiveFileName);
0099     if (documentList && documentList->isFile()) {
0100         const auto archiveFile = static_cast<const KArchiveFile *>(documentList);
0101         archiveFile->copyTo(mTempDir->path());
0102         QFile file(mTempDir->path() + QLatin1Char('/') + archiveFileName);
0103         if (!file.open(QIODevice::ReadOnly)) {
0104             qCWarning(TEXTAUTOCORRECTION_LOG) << "Impossible to open " << file.fileName();
0105         }
0106         QDomDocument doc;
0107         if (loadDomElement(doc, &file)) {
0108             QDomElement list = doc.documentElement();
0109             if (list.isNull()) {
0110                 qCDebug(TEXTAUTOCORRECTION_LOG) << "No list defined in " << type;
0111             } else {
0112                 for (QDomElement e = list.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
0113                     const QString tag = e.tagName();
0114                     if (tag == QLatin1String("block-list:block")) {
0115                         switch (type) {
0116                         case DOCUMENT:
0117                             if (e.hasAttribute(QStringLiteral("block-list:abbreviated-name")) && e.hasAttribute(QStringLiteral("block-list:name"))) {
0118                                 const QString find = e.attribute(QStringLiteral("block-list:abbreviated-name"));
0119                                 const QString replace = e.attribute(QStringLiteral("block-list:name"));
0120                                 mAutocorrectEntries.insert(find, replace);
0121                                 const int findLenght(find.length());
0122                                 mMaxFindStringLength = qMax(findLenght, mMaxFindStringLength);
0123                                 mMinFindStringLength = qMin(findLenght, mMinFindStringLength);
0124                             }
0125                             break;
0126                         case SENTENCE:
0127                             if (e.hasAttribute(QStringLiteral("block-list:abbreviated-name"))) {
0128                                 mUpperCaseExceptions.insert(e.attribute(QStringLiteral("block-list:abbreviated-name")));
0129                             }
0130 
0131                             break;
0132                         case WORD:
0133                             if (e.hasAttribute(QStringLiteral("block-list:abbreviated-name"))) {
0134                                 mTwoUpperLetterExceptions.insert(e.attribute(QStringLiteral("block-list:abbreviated-name")));
0135                             }
0136                             break;
0137                         }
0138                     } else {
0139                         qCDebug(TEXTAUTOCORRECTION_LOG) << " unknown tag " << tag;
0140                     }
0141                 }
0142             }
0143         }
0144     } else {
0145         return false;
0146     }
0147     return true;
0148 }
0149 
0150 bool ImportLibreOfficeAutocorrection::loadDomElement(QDomDocument &doc, QFile *file)
0151 {
0152     QString errorMsg;
0153     int errorRow;
0154     int errorCol;
0155     if (!doc.setContent(file, &errorMsg, &errorRow, &errorCol)) {
0156         qCDebug(TEXTAUTOCORRECTION_LOG) << "Unable to load document.Parse error in line " << errorRow << ", col " << errorCol << ": " << errorMsg;
0157         return false;
0158     }
0159     return true;
0160 }