File indexing completed on 2024-05-12 05:25:33
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 "abstractimportexportjob.h" 0008 #include "archivestorage.h" 0009 #include "backupresourcefilejobbase.h" 0010 #include "backupresourcefilejobimpl.h" 0011 #include "importexportprogressindicatorbase.h" 0012 #include "synchronizeresourcejob.h" 0013 0014 #include <Akonadi/AgentInstance> 0015 #include <PimCommonAkonadi/CreateResource> 0016 0017 #include <KLocalizedString> 0018 #include <KZip> 0019 #include <QTemporaryDir> 0020 0021 #include <Akonadi/ServerManager> 0022 0023 #include <KConfigGroup> 0024 #include <QCoreApplication> 0025 #include <QDir> 0026 #include <QFile> 0027 #include <QStandardPaths> 0028 0029 int AbstractImportExportJob::sArchiveVersion = -1; 0030 0031 AbstractImportExportJob::AbstractImportExportJob(QObject *parent, ArchiveStorage *archiveStorage, Utils::StoredTypes typeSelected, int numberOfStep) 0032 : QObject(parent) 0033 , mTypeSelected(typeSelected) 0034 , mArchiveStorage(archiveStorage) 0035 , mNumberOfStep(numberOfStep) 0036 , mImportExportProgressIndicator(new ImportExportProgressIndicatorBase(this)) 0037 { 0038 mImportExportProgressIndicator->setNumberOfStep(numberOfStep); 0039 connect(mImportExportProgressIndicator, &ImportExportProgressIndicatorBase::info, this, &AbstractImportExportJob::emitInfo); 0040 } 0041 0042 AbstractImportExportJob::~AbstractImportExportJob() 0043 { 0044 delete mCreateResource; 0045 delete mTempDir; 0046 } 0047 0048 void AbstractImportExportJob::createProgressDialog(const QString &title) 0049 { 0050 mImportExportProgressIndicator->createProgressDialog(title); 0051 connect(mImportExportProgressIndicator, &ImportExportProgressIndicatorBase::canceled, this, &AbstractImportExportJob::slotTaskCanceled); 0052 } 0053 0054 void AbstractImportExportJob::slotTaskCanceled() 0055 { 0056 Q_EMIT error(i18n("Task Canceled")); 0057 Q_EMIT jobFinished(); 0058 } 0059 0060 bool AbstractImportExportJob::wasCanceled() const 0061 { 0062 return mImportExportProgressIndicator->wasCanceled(); 0063 } 0064 0065 void AbstractImportExportJob::increaseProgressDialog() 0066 { 0067 mImportExportProgressIndicator->increaseProgressDialog(); 0068 } 0069 0070 void AbstractImportExportJob::setProgressDialogLabel(const QString &text) 0071 { 0072 mImportExportProgressIndicator->setProgressDialogLabel(text); 0073 } 0074 0075 ImportExportProgressIndicatorBase *AbstractImportExportJob::importExportProgressIndicator() const 0076 { 0077 return mImportExportProgressIndicator; 0078 } 0079 0080 void AbstractImportExportJob::setImportExportProgressIndicator(ImportExportProgressIndicatorBase *importExportProgressIndicator) 0081 { 0082 delete mImportExportProgressIndicator; 0083 mImportExportProgressIndicator = importExportProgressIndicator; 0084 mImportExportProgressIndicator->setNumberOfStep(mNumberOfStep); 0085 } 0086 0087 KZip *AbstractImportExportJob::archive() const 0088 { 0089 return mArchiveStorage->archive(); 0090 } 0091 0092 void AbstractImportExportJob::backupUiRcFile(const QString &configFileName, const QString &application) 0093 { 0094 const QString configrcStr(configFileName); 0095 const QString configrc = 0096 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("kxmlgui6") + application + QLatin1Char('/') + configrcStr; 0097 if (QFileInfo::exists(configrc)) { 0098 backupFile(configrc, Utils::configsPath(), configrcStr); 0099 } 0100 } 0101 0102 void AbstractImportExportJob::backupConfigFile(const QString &configFileName) 0103 { 0104 const QString configrcStr(configFileName); 0105 const QString configrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + configrcStr; 0106 if (QFileInfo::exists(configrc)) { 0107 backupFile(configrc, Utils::configsPath(), configrcStr); 0108 } 0109 } 0110 0111 void AbstractImportExportJob::backupFile(const QString &filename, const QString &path, const QString &storedName) 0112 { 0113 if (QFileInfo::exists(filename)) { 0114 const bool fileAdded = archive()->addLocalFile(filename, path + storedName); 0115 if (fileAdded) { 0116 emitInfo(i18n("\"%1\" backup done.", path + storedName)); 0117 } else { 0118 Q_EMIT error(i18n("\"%1\" cannot be exported.", path + storedName)); 0119 } 0120 } else { 0121 Q_EMIT error(i18n("\"%1\" does not exist.", filename)); 0122 } 0123 } 0124 0125 int AbstractImportExportJob::mergeConfigMessageBox(const QString &configName) const 0126 { 0127 return mImportExportProgressIndicator->mergeConfigMessageBox(configName); 0128 } 0129 0130 bool AbstractImportExportJob::overwriteConfigMessageBox(const QString &configName) const 0131 { 0132 return mImportExportProgressIndicator->overwriteConfigMessageBox(configName); 0133 } 0134 0135 void AbstractImportExportJob::overwriteDirectory(const QString &path, const KArchiveEntry *entry) 0136 { 0137 if (QDir(path).exists()) { 0138 if (overwriteDirectoryMessageBox(path)) { 0139 const auto dirEntry = static_cast<const KArchiveDirectory *>(entry); 0140 if (!dirEntry->copyTo(path)) { 0141 qCWarning(PIMDATAEXPORTERCORE_LOG) << "directory cannot overwrite to " << path; 0142 } 0143 } 0144 } else { 0145 const auto dirEntry = static_cast<const KArchiveDirectory *>(entry); 0146 if (dirEntry->copyTo(path)) { 0147 qCWarning(PIMDATAEXPORTERCORE_LOG) << "directory cannot overwrite to " << path; 0148 } 0149 } 0150 } 0151 0152 void AbstractImportExportJob::searchAllFiles(const KArchiveDirectory *dir, const QString &prefix, const QString &searchEntryName) 0153 { 0154 const QStringList lst = dir->entries(); 0155 for (const QString &entryName : lst) { 0156 const KArchiveEntry *entry = dir->entry(entryName); 0157 if (entry && entry->isDirectory()) { 0158 const QString newPrefix = (prefix.isEmpty() ? prefix : prefix + QLatin1Char('/')) + entryName; 0159 if (entryName == searchEntryName) { 0160 storeArchiveInfoResources(static_cast<const KArchiveDirectory *>(entry), entryName); 0161 } else { 0162 searchAllFiles(static_cast<const KArchiveDirectory *>(entry), newPrefix, searchEntryName); 0163 } 0164 } 0165 } 0166 } 0167 0168 void AbstractImportExportJob::storeArchiveInfoResources(const KArchiveDirectory *dir, const QString &prefix) 0169 { 0170 const QStringList lst = dir->entries(); 0171 for (const QString &entryName : lst) { 0172 const KArchiveEntry *entry = dir->entry(entryName); 0173 if (entry && entry->isDirectory()) { 0174 const auto resourceDir = static_cast<const KArchiveDirectory *>(entry); 0175 const QStringList lst = resourceDir->entries(); 0176 0177 if (lst.count() >= 2) { 0178 const QString archPath(prefix + QLatin1Char('/') + entryName + QLatin1Char('/')); 0179 ResourceFiles files; 0180 for (const QString &name : lst) { 0181 if (isAConfigFile(name)) { 0182 files.akonadiConfigFile = archPath + name; 0183 } else if (name.startsWith(Utils::prefixAkonadiConfigFile())) { 0184 files.akonadiAgentConfigFile = archPath + name; 0185 } else { 0186 files.akonadiResources = archPath + name; 0187 } 0188 } 0189 files.debug(); 0190 mListResourceFile.append(files); 0191 } else { 0192 qCWarning(PIMDATAEXPORTERCORE_LOG) << " Problem in archive. number of file " << lst.count(); 0193 } 0194 } 0195 } 0196 std::sort(mListResourceFile.begin(), mListResourceFile.end()); 0197 } 0198 0199 bool AbstractImportExportJob::isAConfigFile(const QString &name) const 0200 { 0201 Q_UNUSED(name) 0202 // Redefine in subclass 0203 return true; 0204 } 0205 0206 bool AbstractImportExportJob::overwriteDirectoryMessageBox(const QString &directory) const 0207 { 0208 return mImportExportProgressIndicator->overwriteDirectoryMessageBox(directory); 0209 } 0210 0211 qint64 AbstractImportExportJob::convertRealPathToCollection(KConfigGroup &group, const QString ¤tKey, bool addCollectionPrefix) 0212 { 0213 qint64 colId = -1; 0214 if (group.hasKey(currentKey)) { 0215 const QString path = group.readEntry(currentKey); 0216 if (!path.isEmpty()) { 0217 const Akonadi::Collection::Id id = convertPathToId(path); 0218 if (id != -1) { 0219 if (addCollectionPrefix) { 0220 group.writeEntry(currentKey, QStringLiteral("c%1").arg(id)); 0221 } else { 0222 group.writeEntry(currentKey, id); 0223 } 0224 } else { 0225 group.deleteEntry(currentKey); 0226 } 0227 colId = id; 0228 } 0229 } 0230 return colId; 0231 } 0232 0233 Akonadi::Collection::Id AbstractImportExportJob::convertPathToId(const QString &path) 0234 { 0235 if (path.isEmpty()) { 0236 return -1; 0237 } 0238 Akonadi::Collection::Id val = mHashConvertPathCollectionId.value(path, -1); 0239 if (val != -1) { 0240 return val; 0241 } 0242 const Akonadi::Collection::Id id = convertFolderPathToCollectionId(path); 0243 if (id != -1) { 0244 mHashConvertPathCollectionId.insert(path, id); 0245 } 0246 return id; 0247 } 0248 0249 void AbstractImportExportJob::initializeImportJob() 0250 { 0251 if (mTempDir) { 0252 qCDebug(PIMDATAEXPORTERCORE_LOG) << " initializeImportJob already called"; 0253 } else { 0254 mTempDir = new QTemporaryDir(); 0255 mTempDirName = mTempDir->path(); 0256 mCreateResource = new PimCommon::CreateResource(); 0257 connect(mCreateResource, &PimCommon::CreateResource::createResourceInfo, this, &AbstractImportExportJob::emitInfo); 0258 connect(mCreateResource, &PimCommon::CreateResource::createResourceError, this, &AbstractImportExportJob::emitError); 0259 } 0260 } 0261 0262 void AbstractImportExportJob::copyToDirectory(const KArchiveEntry *entry, const QString &dest) 0263 { 0264 const auto subfolderDir = static_cast<const KArchiveDirectory *>(entry); 0265 if (!subfolderDir->copyTo(dest)) { 0266 qCDebug(PIMDATAEXPORTERCORE_LOG) << "directory cannot copy to " << dest; 0267 } 0268 emitInfo(i18n("\"%1\" was copied.", dest)); 0269 } 0270 0271 void AbstractImportExportJob::copyToFile(const KArchiveFile *archivefile, const QString &dest, const QString &filename, const QString &prefix) 0272 { 0273 emitInfo(i18n("Restoring \"%1\"...", filename)); 0274 QDir dir(mTempDirName); 0275 const QString copyToDirName(mTempDirName + QLatin1Char('/') + prefix); 0276 const bool created = dir.mkpath(copyToDirName); 0277 if (!created) { 0278 qCWarning(PIMDATAEXPORTERCORE_LOG) << " directory :" << prefix << " not created"; 0279 } 0280 0281 if (!archivefile->copyTo(copyToDirName)) { 0282 qCWarning(PIMDATAEXPORTERCORE_LOG) << "copyToFile file " << filename << " can not copy to " << dest; 0283 } 0284 QFile file; 0285 file.setFileName(copyToDirName + QLatin1Char('/') + filename); 0286 0287 // QFile doesn't overwrite => remove old file before 0288 // qCDebug(PIMDATAEXPORTERCORE_LOG)<<" dest "<<dest; 0289 // qCDebug(PIMDATAEXPORTERCORE_LOG)<<" file "<<file.fileName(); 0290 QFile destination(dest); 0291 if (destination.exists()) { 0292 destination.remove(); 0293 } 0294 QFileInfo destFileInfo(dest); 0295 0296 QDir().mkpath(destFileInfo.path()); 0297 if (!file.copy(dest)) { 0298 mImportExportProgressIndicator->showErrorMessage(i18n("File \"%1\" cannot be copied to \"%2\".", filename, dest), i18n("Copy file")); 0299 } else { 0300 emitInfo(i18n("\"%1\" was restored.", filename)); 0301 } 0302 } 0303 0304 void AbstractImportExportJob::backupResourceFile(const QString &identifier, const QString &defaultPath) 0305 { 0306 auto job = new BackupResourceFileJobImpl(this); 0307 job->setDefaultPath(defaultPath); 0308 job->setIdentifier(identifier); 0309 job->setZip(archive()); 0310 connect(job, &BackupResourceFileJobImpl::error, this, &AbstractImportExportJob::emitError); 0311 connect(job, &BackupResourceFileJobImpl::info, this, &AbstractImportExportJob::emitInfo); 0312 job->start(); 0313 } 0314 0315 QStringList 0316 AbstractImportExportJob::restoreResourceFile(const QString &resourceBaseName, const QString &defaultPath, const QString &storePath, bool overwriteResources) 0317 { 0318 QStringList resourceToSync; 0319 // TODO fix sync config after created a resource 0320 if (!mListResourceFile.isEmpty()) { 0321 QDir dir(mTempDirName); 0322 dir.mkdir(defaultPath); 0323 const QString copyToDirName(mTempDirName + QLatin1Char('/') + defaultPath); 0324 if (!QDir().mkpath(copyToDirName)) { 0325 qCWarning(PIMDATAEXPORTERCORE_LOG) << " impossible to create :" << copyToDirName; 0326 } 0327 0328 for (int i = 0, total = mListResourceFile.size(); i < total; ++i) { 0329 ResourceFiles value = mListResourceFile.at(i); 0330 QMap<QString, QVariant> settings; 0331 if (value.akonadiConfigFile.contains(resourceBaseName + QLatin1Char('_'))) { 0332 const KArchiveEntry *fileResouceEntry = mArchiveDirectory->entry(value.akonadiConfigFile); 0333 if (fileResouceEntry && fileResouceEntry->isFile()) { 0334 const auto file = static_cast<const KArchiveFile *>(fileResouceEntry); 0335 if (!file->copyTo(copyToDirName)) { 0336 qCWarning(PIMDATAEXPORTERCORE_LOG) 0337 << "AbstractImportExportJob file " << value.akonadiConfigFile << " can not copy to " << copyToDirName; 0338 } 0339 QString resourceName(file->name()); 0340 0341 QString filename(file->name()); 0342 // TODO adapt filename otherwise it will use all the time the same filename. 0343 qCDebug(PIMDATAEXPORTERCORE_LOG) << " filename :" << filename; 0344 0345 KSharedConfig::Ptr resourceConfig = KSharedConfig::openConfig(copyToDirName + QLatin1Char('/') + resourceName); 0346 0347 QString newUrl = adaptNewResourceUrl(overwriteResources, resourceConfig, storePath); 0348 const QString dataFile = value.akonadiResources; 0349 const KArchiveEntry *dataResouceEntry = mArchiveDirectory->entry(dataFile); 0350 if (dataResouceEntry && dataResouceEntry->isFile()) { 0351 const auto file = static_cast<const KArchiveFile *>(dataResouceEntry); 0352 if (!file->copyTo(QFileInfo(newUrl).path())) { 0353 qCWarning(PIMDATAEXPORTERCORE_LOG) << "AbstractImportExportJob: file " << dataFile << " can not copy to " << newUrl; 0354 } 0355 } 0356 // setPath doesn't exist in groupware 0357 if (resourceBaseName != QStringLiteral("akonadi_davgroupware_resource") 0358 && resourceBaseName != QStringLiteral("akonadi_openxchange_resource") 0359 && resourceBaseName != QStringLiteral("akonadi_google_resource")) { 0360 if (!newUrl.isEmpty()) { 0361 settings.insert(QStringLiteral("Path"), newUrl); 0362 } 0363 } 0364 const QString agentConfigFile = value.akonadiAgentConfigFile; 0365 if (!agentConfigFile.isEmpty()) { 0366 const KArchiveEntry *akonadiAgentConfigEntry = mArchiveDirectory->entry(agentConfigFile); 0367 if (akonadiAgentConfigEntry->isFile()) { 0368 const auto file = static_cast<const KArchiveFile *>(akonadiAgentConfigEntry); 0369 file->copyTo(copyToDirName); 0370 resourceName = file->name(); 0371 const QString configPath = copyToDirName + QLatin1Char('/') + resourceName; 0372 filename = Utils::akonadiAgentName(configPath); 0373 } 0374 } 0375 0376 addSpecificResourceSettings(resourceConfig, resourceBaseName, settings); 0377 0378 const QString newResource = createResource(resourceBaseName, filename, settings, false); 0379 infoAboutNewResource(newResource); 0380 resourceToSync << newResource; 0381 qCDebug(PIMDATAEXPORTERCORE_LOG) << " newResource" << newResource; 0382 } 0383 } 0384 } 0385 emitInfo(i18n("Resources restored.")); 0386 } else { 0387 Q_EMIT error(i18n("No resources files found.")); 0388 qDebug() << " resourceBaseName " << resourceBaseName; 0389 } 0390 return resourceToSync; 0391 } 0392 0393 void AbstractImportExportJob::addSpecificResourceSettings(const KSharedConfig::Ptr /*resourceConfig*/ &, 0394 const QString & /*resourceName*/, 0395 QMap<QString, QVariant> & /*settings*/) 0396 { 0397 // Redefine it in subclass 0398 } 0399 0400 bool AbstractImportExportJob::copyArchiveFileTo(const KArchiveFile *file, const QString &destination) 0401 { 0402 const bool result = file->copyTo(destination); 0403 if (!result) { 0404 qCWarning(PIMDATAEXPORTERCORE_LOG) << "copyArchiveFileTo file " << file->name() << " can not copy to " << destination; 0405 } 0406 return result; 0407 } 0408 0409 void AbstractImportExportJob::extractZipFile(const KArchiveFile *file, const QString &source, const QString &destination, bool isStoredAsZippedArchive) 0410 { 0411 if (!file->copyTo(source)) { 0412 qCWarning(PIMDATAEXPORTERCORE_LOG) << "extractZipFile file " << file->name() << " can not copy to " << source; 0413 } 0414 QDir dest(destination); 0415 if (!dest.exists()) { 0416 dest.mkpath(destination); 0417 } 0418 if (isStoredAsZippedArchive) { 0419 QString errorMsg; 0420 KZip *zip = Utils::openZip(source + QLatin1Char('/') + file->name(), errorMsg); 0421 if (zip) { 0422 const KArchiveDirectory *zipDir = zip->directory(); 0423 const QStringList lst = zipDir->entries(); 0424 for (const QString &entryName : lst) { 0425 const KArchiveEntry *entry = zipDir->entry(entryName); 0426 if (entry) { 0427 if (entry->isDirectory()) { 0428 const auto dir = static_cast<const KArchiveDirectory *>(entry); 0429 if (!dir->copyTo(destination + QLatin1Char('/') + dir->name(), true)) { 0430 qCWarning(PIMDATAEXPORTERCORE_LOG) << " Error to copy directory" << destination + QLatin1Char('/') + dir->name(); 0431 } 0432 } else if (entry->isFile()) { 0433 const auto dir = static_cast<const KArchiveFile *>(entry); 0434 if (!dir->copyTo(destination)) { 0435 qCWarning(PIMDATAEXPORTERCORE_LOG) << " Error to copy file" << destination; 0436 } 0437 } 0438 } 0439 qApp->processEvents(); 0440 } 0441 delete zip; 0442 } else { 0443 Q_EMIT error(errorMsg); 0444 } 0445 } else { 0446 QFile archiveFile(source + QLatin1Char('/') + file->name()); 0447 if (!archiveFile.copy(destination + QLatin1Char('/') + file->name())) { 0448 Q_EMIT error(i18n("Unable to copy file %1", file->name())); 0449 } 0450 } 0451 } 0452 0453 void AbstractImportExportJob::restoreUiRcFile(const QString &configNameStr, const QString &applicationName) 0454 { 0455 const KArchiveEntry *configNameentry = mArchiveDirectory->entry(Utils::configsPath() + configNameStr); 0456 if (configNameentry && configNameentry->isFile()) { 0457 const auto configNameconfiguration = static_cast<const KArchiveFile *>(configNameentry); 0458 const QString configNamerc = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("kxmlgui6") + applicationName 0459 + QLatin1Char('/') + configNameStr; 0460 if (QFileInfo::exists(configNamerc)) { 0461 if (overwriteConfigMessageBox(configNameStr)) { 0462 copyToFile(configNameconfiguration, configNamerc, configNameStr, Utils::configsPath()); 0463 } 0464 } else { 0465 copyToFile(configNameconfiguration, configNamerc, configNameStr, Utils::configsPath()); 0466 } 0467 } 0468 } 0469 0470 void AbstractImportExportJob::restoreConfigFile(const QString &configNameStr) 0471 { 0472 const KArchiveEntry *configNameentry = mArchiveDirectory->entry(Utils::configsPath() + configNameStr); 0473 if (configNameentry && configNameentry->isFile()) { 0474 const auto configNameconfiguration = static_cast<const KArchiveFile *>(configNameentry); 0475 const QString configNamerc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + configNameStr; 0476 if (QFileInfo::exists(configNamerc)) { 0477 // TODO 4.12 allow to merge config. 0478 if (overwriteConfigMessageBox(configNameStr)) { 0479 copyToFile(configNameconfiguration, configNamerc, configNameStr, Utils::configsPath()); 0480 } 0481 } else { 0482 copyToFile(configNameconfiguration, configNamerc, configNameStr, Utils::configsPath()); 0483 } 0484 } 0485 } 0486 0487 void AbstractImportExportJob::infoAboutNewResource(const QString &resourceName) 0488 { 0489 emitInfo(i18n("Resource \'%1\' created.", resourceName)); 0490 } 0491 0492 int AbstractImportExportJob::archiveVersion() 0493 { 0494 return sArchiveVersion; 0495 } 0496 0497 void AbstractImportExportJob::setArchiveVersion(int version) 0498 { 0499 sArchiveVersion = version; 0500 } 0501 0502 void AbstractImportExportJob::slotSynchronizeInstanceFailed(const QString &instance) 0503 { 0504 Q_EMIT error(i18n("Failed to synchronize \'%1\'.", instance)); 0505 } 0506 0507 void AbstractImportExportJob::slotSynchronizeInstanceDone(const QString &name, const QString &identifier) 0508 { 0509 emitInfo(i18n("Resource \'%1\' synchronized.", name)); 0510 Q_EMIT needSynchronizeResource(name, identifier); 0511 } 0512 0513 void AbstractImportExportJob::slotAllResourceSynchronized() 0514 { 0515 emitInfo(i18n("All resources synchronized.")); 0516 slotNextStep(); 0517 } 0518 0519 void AbstractImportExportJob::slotNextStep() 0520 { 0521 // Implement in sub class. 0522 } 0523 0524 QString AbstractImportExportJob::generateInfo(const QString &info) 0525 { 0526 return applicationName() + QLatin1Char(' ') + info; 0527 } 0528 0529 void AbstractImportExportJob::emitInfo(const QString &str) 0530 { 0531 Q_EMIT info(generateInfo(str)); 0532 } 0533 0534 void AbstractImportExportJob::emitError(const QString &str) 0535 { 0536 Q_EMIT error(generateInfo(str)); 0537 } 0538 0539 void AbstractImportExportJob::startSynchronizeResources(const QStringList &listResourceToSync) 0540 { 0541 emitInfo(i18n("Start synchronizing...")); 0542 auto job = new SynchronizeResourceJob(this); 0543 job->setListResources(listResourceToSync); 0544 connect(job, &SynchronizeResourceJob::synchronizationFinished, this, &AbstractImportExportJob::slotAllResourceSynchronized); 0545 connect(job, &SynchronizeResourceJob::synchronizationInstanceDone, this, &AbstractImportExportJob::slotSynchronizeInstanceDone); 0546 connect(job, &SynchronizeResourceJob::synchronizationInstanceFailed, this, &AbstractImportExportJob::slotSynchronizeInstanceFailed); 0547 job->start(); 0548 } 0549 0550 void AbstractImportExportJob::initializeListStep() 0551 { 0552 if (mTypeSelected & Utils::MailTransport) { 0553 mListStep << Utils::MailTransport; 0554 } 0555 if (mTypeSelected & Utils::Mails) { 0556 mListStep << Utils::Mails; 0557 } 0558 if (mTypeSelected & Utils::Resources) { 0559 mListStep << Utils::Resources; 0560 } 0561 if (mTypeSelected & Utils::Identity) { 0562 mListStep << Utils::Identity; 0563 } 0564 if (mTypeSelected & Utils::Config) { 0565 mListStep << Utils::Config; 0566 } 0567 if (mTypeSelected & Utils::Data) { 0568 mListStep << Utils::Data; 0569 } 0570 } 0571 0572 void AbstractImportExportJob::storeDirectory(const QString &subDirectory) 0573 { 0574 const QDir directoryToStore(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + subDirectory); 0575 if (directoryToStore.exists()) { 0576 const bool templateDirAdded = archive()->addLocalDirectory(directoryToStore.path(), Utils::dataPath() + subDirectory); 0577 if (templateDirAdded) { 0578 emitInfo(i18n("Directory \"%1\" added to backup file.", directoryToStore.path())); 0579 } else { 0580 Q_EMIT error(i18n("Directory \"%1\" cannot be added to backup file.", directoryToStore.path())); 0581 } 0582 } 0583 } 0584 0585 void AbstractImportExportJob::importDataSubdirectory(const QString &subdirectoryRelativePath) 0586 { 0587 const KArchiveEntry *themeEntry = mArchiveDirectory->entry(Utils::dataPath() + subdirectoryRelativePath); 0588 if (themeEntry && themeEntry->isDirectory()) { 0589 const auto themeDir = static_cast<const KArchiveDirectory *>(themeEntry); 0590 const QStringList lst = themeDir->entries(); 0591 for (const QString &entryName : lst) { 0592 const KArchiveEntry *entry = themeDir->entry(entryName); 0593 if (entry && entry->isDirectory()) { 0594 QString subFolderName = entryName; 0595 const QString topLevelPath = 0596 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + subdirectoryRelativePath; 0597 QDir themeDirectory(topLevelPath + QStringLiteral("/%1").arg(entryName)); 0598 int i = 1; 0599 while (themeDirectory.exists()) { 0600 subFolderName = entryName + QStringLiteral("_%1").arg(i); 0601 themeDirectory = QDir(topLevelPath + QStringLiteral("/%1").arg(subFolderName)); 0602 ++i; 0603 } 0604 copyToDirectory(entry, topLevelPath + QStringLiteral("/%1").arg(subFolderName)); 0605 } 0606 } 0607 } 0608 } 0609 0610 void AbstractImportExportJob::convertCollectionListStrToAkonadiId(const KSharedConfig::Ptr &config, 0611 const QString &groupName, 0612 const QString &key, 0613 bool addCollectionPrefix) 0614 { 0615 if (config->hasGroup(groupName)) { 0616 KConfigGroup group = config->group(groupName); 0617 convertRealPathToCollectionList(group, key, addCollectionPrefix); 0618 } 0619 } 0620 0621 void AbstractImportExportJob::convertRealPathToCollectionList(KConfigGroup &group, const QString ¤tKey, bool addCollectionPrefix) 0622 { 0623 if (group.hasKey(currentKey)) { 0624 const QStringList listExpension = group.readEntry(currentKey, QStringList()); 0625 QStringList result; 0626 if (!listExpension.isEmpty()) { 0627 for (const QString &collection : listExpension) { 0628 const Akonadi::Collection::Id id = convertPathToId(collection); 0629 if (id != -1) { 0630 if (addCollectionPrefix) { 0631 result << QStringLiteral("c%1").arg(id); 0632 } else { 0633 result << QStringLiteral("%1").arg(id); 0634 } 0635 } 0636 } 0637 if (result.isEmpty()) { 0638 group.deleteEntry(currentKey); 0639 } else { 0640 group.writeEntry(currentKey, result); 0641 } 0642 } 0643 } 0644 } 0645 0646 void AbstractImportExportJob::setTempDirName(const QString &tempDirName) 0647 { 0648 mTempDirName = tempDirName; 0649 } 0650 0651 #include "moc_abstractimportexportjob.cpp"