File indexing completed on 2024-12-08 04:58:10
0001 /* 0002 SPDX-FileCopyrightText: 2017 Smith AR <audoban@openmailbox.org> 0003 SPDX-FileCopyrightText: 2017 Michail Vourlakos <mvourlakos@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "importer.h" 0009 0010 // local 0011 #include <coretypes.h> 0012 #include "manager.h" 0013 #include "../lattecorona.h" 0014 #include "../screenpool.h" 0015 #include "../layout/abstractlayout.h" 0016 #include "../settings/universalsettings.h" 0017 #include "../templates/templatesmanager.h" 0018 #include "../tools/commontools.h" 0019 0020 // Qt 0021 #include <QFile> 0022 #include <QLatin1String> 0023 0024 // KDE 0025 #include <KArchive/KTar> 0026 #include <KArchive/KArchiveEntry> 0027 #include <KArchive/KArchiveDirectory> 0028 #include <KConfigGroup> 0029 #include <KLocalizedString> 0030 #include <KNotification> 0031 0032 0033 enum SessionType 0034 { 0035 DefaultSession = 0, 0036 AlternativeSession 0037 }; 0038 0039 namespace Latte { 0040 namespace Layouts { 0041 0042 Importer::Importer(QObject *parent) 0043 : QObject(parent) 0044 { 0045 m_manager = qobject_cast<Layouts::Manager *>(parent); 0046 0047 qDebug() << " IMPORTER, STORAGE TEMP DIR ::: " << m_storageTmpDir.path(); 0048 } 0049 0050 Importer::~Importer() 0051 { 0052 } 0053 0054 bool Importer::updateOldConfiguration() 0055 { 0056 QFile oldAppletsFile(Latte::configPath() + "/lattedock-appletsrc"); 0057 0058 if (!oldAppletsFile.exists()) { 0059 return false; 0060 } 0061 0062 //! import standard old configuration and create the relevant layouts 0063 importOldLayout(Latte::configPath() + "/lattedock-appletsrc", i18n("My Layout")); 0064 importOldLayout(Latte::configPath() + "/lattedock-appletsrc", i18n("Alternative"), true); 0065 0066 QFile extFile(Latte::configPath() + "/lattedockextrc"); 0067 0068 //! import also the old user layouts into the new architecture 0069 if (extFile.exists()) { 0070 KSharedConfigPtr extFileConfig = KSharedConfig::openConfig(extFile.fileName()); 0071 KConfigGroup externalSettings = KConfigGroup(extFileConfig, "External"); 0072 QStringList userLayouts = externalSettings.readEntry("userLayouts", QStringList()); 0073 0074 for(const auto &userConfig : userLayouts) { 0075 qDebug() << "user layout : " << userConfig; 0076 importOldConfiguration(userConfig); 0077 } 0078 } 0079 0080 m_manager->corona()->universalSettings()->setVersion(2); 0081 m_manager->corona()->universalSettings()->setSingleModeLayoutName(i18n("My Layout")); 0082 0083 return true; 0084 } 0085 0086 bool Importer::importOldLayout(QString oldAppletsPath, QString newName, bool alternative, QString exportDirectory) 0087 { 0088 QString newLayoutPath = layoutCanBeImported(oldAppletsPath, newName, exportDirectory); 0089 qDebug() << "New Layout Should be created: " << newLayoutPath; 0090 0091 KSharedConfigPtr oldFile = KSharedConfig::openConfig(oldAppletsPath); 0092 KSharedConfigPtr newFile = KSharedConfig::openConfig(newLayoutPath); 0093 0094 KConfigGroup containments = KConfigGroup(oldFile, "Containments"); 0095 KConfigGroup copiedContainments = KConfigGroup(newFile, "Containments"); 0096 0097 QList<int> systrays; 0098 0099 bool atLeastOneContainmentWasFound{false}; 0100 0101 //! first copy the latte containments that correspond to the correct session 0102 //! and find also the systrays that should be copied also 0103 for(const auto &containmentId : containments.groupList()) { 0104 KConfigGroup containmentGroup = containments.group(containmentId); 0105 0106 QString plugin = containmentGroup.readEntry("plugin", QString()); 0107 SessionType session = (SessionType)containmentGroup.readEntry("session", (int)DefaultSession); 0108 0109 bool shouldImport = false; 0110 0111 if (plugin == QLatin1String("org.kde.latte.containment") && session == DefaultSession && !alternative) { 0112 qDebug() << containmentId << " - " << plugin << " - " << session; 0113 shouldImport = true; 0114 } else if (plugin == QLatin1String("org.kde.latte.containment") && session == AlternativeSession && alternative) { 0115 qDebug() << containmentId << " - " << plugin << " - " << session; 0116 shouldImport = true; 0117 } 0118 0119 // this latte containment should be imported 0120 if (shouldImport) { 0121 auto applets = containments.group(containmentId).group("Applets"); 0122 0123 for(const auto &applet : applets.groupList()) { 0124 KConfigGroup appletSettings = applets.group(applet).group("Configuration"); 0125 0126 int systrayId = appletSettings.readEntry("SystrayContainmentId", "-1").toInt(); 0127 0128 if (systrayId != -1) { 0129 systrays.append(systrayId); 0130 qDebug() << "systray was found in the containment..."; 0131 break; 0132 } 0133 } 0134 0135 KConfigGroup newContainment = copiedContainments.group(containmentId); 0136 containmentGroup.copyTo(&newContainment); 0137 atLeastOneContainmentWasFound = true; 0138 } 0139 } 0140 0141 //! not even one latte containment was found for that layout so we must break 0142 //! the code here 0143 if (!atLeastOneContainmentWasFound) { 0144 return false; 0145 } 0146 0147 //! copy also the systrays that were discovered 0148 for(const auto &containmentId : containments.groupList()) { 0149 int cId = containmentId.toInt(); 0150 0151 if (systrays.contains(cId)) { 0152 KConfigGroup containmentGroup = containments.group(containmentId); 0153 KConfigGroup newContainment = copiedContainments.group(containmentId); 0154 containmentGroup.copyTo(&newContainment); 0155 } 0156 } 0157 0158 copiedContainments.sync(); 0159 0160 KConfigGroup oldGeneralSettings = KConfigGroup(oldFile, "General"); 0161 0162 QStringList layoutLaunchers; 0163 0164 if (!alternative) { 0165 layoutLaunchers = oldGeneralSettings.readEntry("globalLaunchers_default", QStringList()); 0166 } else { 0167 layoutLaunchers = oldGeneralSettings.readEntry("globalLaunchers_alternative", QStringList()); 0168 } 0169 0170 //! update also the layout settings correctly 0171 Layout::AbstractLayout newLayout(this, newLayoutPath, newName); 0172 newLayout.setVersion(2); 0173 newLayout.setLaunchers(layoutLaunchers); 0174 0175 //newLayout.setShowInMenu(true); 0176 0177 if (alternative) { 0178 newLayout.setColor("purple"); 0179 } else { 0180 newLayout.setColor("blue"); 0181 } 0182 0183 return true; 0184 } 0185 0186 QStringList Importer::standardPaths(bool localfirst) 0187 { 0188 QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); 0189 0190 if (localfirst) { 0191 return paths; 0192 } else { 0193 QStringList reversed; 0194 0195 for (int i=paths.count()-1; i>=0; i--) { 0196 reversed << paths[i]; 0197 } 0198 0199 return reversed; 0200 } 0201 } 0202 0203 QStringList Importer::standardPathsFor(QString subPath, bool localfirst) 0204 { 0205 QStringList paths = standardPaths(localfirst); 0206 0207 QString separator = subPath.startsWith("/") ? "" : "/"; 0208 0209 for (int i=0; i<paths.count(); ++i) { 0210 paths[i] = paths[i] + separator + subPath; 0211 } 0212 0213 return paths; 0214 } 0215 0216 QString Importer::standardPath(QString subPath, bool localfirst) 0217 { 0218 QStringList paths = standardPaths(localfirst); 0219 0220 for(const auto &pt : paths) { 0221 QString ptF = pt + "/" +subPath; 0222 if (QFileInfo(ptF).exists()) { 0223 return ptF; 0224 } 0225 } 0226 0227 //! in any case that above fails 0228 if (QFileInfo("/usr/share/"+subPath).exists()) { 0229 return "/usr/share/"+subPath; 0230 } 0231 0232 return ""; 0233 } 0234 0235 QString Importer::storageTmpDir() const 0236 { 0237 return m_storageTmpDir.path(); 0238 } 0239 0240 QString Importer::layoutCanBeImported(QString oldAppletsPath, QString newName, QString exportDirectory) 0241 { 0242 QFile oldAppletsrc(oldAppletsPath); 0243 0244 //! old file doesn't exist 0245 if (!oldAppletsrc.exists()) { 0246 return QString(); 0247 } 0248 0249 KSharedConfigPtr lConfig = KSharedConfig::openConfig(oldAppletsPath); 0250 KConfigGroup m_layoutGroup = KConfigGroup(lConfig, "LayoutSettings"); 0251 int layoutVersion = m_layoutGroup.readEntry("version", 1); 0252 0253 //! old file layout appears to not be old as its version is >=2 0254 if (layoutVersion >= 2) { 0255 return QString(); 0256 } 0257 0258 QDir layoutDir(exportDirectory.isNull() ? layoutUserDir() : exportDirectory); 0259 0260 if (!layoutDir.exists() && exportDirectory.isNull()) { 0261 QDir(Latte::configPath()).mkdir("latte"); 0262 } 0263 0264 //! set up the new layout name 0265 if (newName.isEmpty()) { 0266 int extension = oldAppletsrc.fileName().lastIndexOf(".latterc"); 0267 0268 if (extension > 0) { 0269 //! remove the last 8 characters that contain the extension 0270 newName = oldAppletsrc.fileName().remove(extension, 8); 0271 } else { 0272 newName = oldAppletsrc.fileName(); 0273 } 0274 } 0275 0276 QString newLayoutPath = layoutDir.absolutePath() + "/" + newName + ".layout.latte"; 0277 QFile newLayoutFile(newLayoutPath); 0278 0279 QStringList filter; 0280 filter.append(QString(newName + "*.layout.latte")); 0281 QStringList files = layoutDir.entryList(filter, QDir::Files | QDir::NoSymLinks); 0282 0283 //! if the newLayout already exists provide a newName that doesn't 0284 if (files.count() >= 1) { 0285 int newCounter = files.count() + 1; 0286 0287 newLayoutPath = layoutDir.absolutePath() + "/" + newName + "-" + QString::number(newCounter) + ".layout.latte"; 0288 } 0289 0290 return newLayoutPath; 0291 } 0292 0293 bool Importer::importOldConfiguration(QString oldConfigPath, QString newName) 0294 { 0295 QFile oldConfigFile(oldConfigPath); 0296 0297 if (!oldConfigFile.exists()) { 0298 return false; 0299 } 0300 0301 KTar archive(oldConfigPath, QStringLiteral("application/x-tar")); 0302 archive.open(QIODevice::ReadOnly); 0303 0304 if (!archive.isOpen()) { 0305 return false; 0306 } 0307 0308 auto rootDir = archive.directory(); 0309 QTemporaryDir uniqueTempDir; 0310 QDir tempDir{uniqueTempDir.path()}; 0311 0312 qDebug() << "temp layout directory : " << tempDir.absolutePath(); 0313 0314 if (rootDir) { 0315 if (!tempDir.exists()) 0316 tempDir.mkpath(tempDir.absolutePath()); 0317 0318 for(const auto &name : rootDir->entries()) { 0319 auto fileEntry = rootDir->file(name); 0320 0321 if (fileEntry && (fileEntry->name() == QLatin1String("lattedockrc") 0322 || fileEntry->name() == QLatin1String("lattedock-appletsrc"))) { 0323 if (!fileEntry->copyTo(tempDir.absolutePath())) { 0324 qInfo() << i18nc("import/export config", "The extracted file could not be copied!!!"); 0325 archive.close(); 0326 return false; 0327 } 0328 } else { 0329 qInfo() << i18nc("import/export config", "The file has a wrong format!!!"); 0330 archive.close(); 0331 return false; 0332 } 0333 } 0334 } else { 0335 qInfo() << i18nc("import/export config", "The temp directory could not be created!!!"); 0336 archive.close(); 0337 return false; 0338 } 0339 0340 //! only if the above has passed we must process the files 0341 QString appletsPath(tempDir.absolutePath() + "/lattedock-appletsrc"); 0342 QString screensPath(tempDir.absolutePath() + "/lattedockrc"); 0343 0344 if (!QFile(appletsPath).exists() || !QFile(screensPath).exists()) { 0345 return false; 0346 } 0347 0348 0349 if (newName.isEmpty()) { 0350 int lastSlash = oldConfigPath.lastIndexOf("/"); 0351 newName = oldConfigPath.remove(0, lastSlash + 1); 0352 0353 int ext = newName.lastIndexOf(".latterc"); 0354 newName = newName.remove(ext, 8); 0355 } 0356 0357 if (!importOldLayout(appletsPath, newName)) { 0358 return false; 0359 } 0360 0361 //! the old configuration contains also screen values, these must be updated also 0362 /* 0363 * do not use any deprecated screen ids 0364 * KSharedConfigPtr oldScreensConfig = KSharedConfig::openConfig(screensPath); 0365 KConfigGroup m_screensGroup = KConfigGroup(oldScreensConfig, "ScreenConnectors"); 0366 0367 //restore the known ids to connector mappings 0368 for(const QString &key : m_screensGroup.keyList()) { 0369 QString connector = m_screensGroup.readEntry(key, QString()); 0370 int id = key.toInt(); 0371 0372 if (id >= 10 && !m_manager->corona()->screenPool()->hasScreenId(id)) { 0373 m_manager->corona()->screenPool()->insertScreenMapping(id, connector); 0374 } 0375 }*/ 0376 0377 return true; 0378 } 0379 0380 bool Importer::exportFullConfiguration(QString file) 0381 { 0382 if (QFile::exists(file) && !QFile::remove(file)) { 0383 return false; 0384 } 0385 0386 KTar archive(file, QStringLiteral("application/x-tar")); 0387 0388 if (!archive.open(QIODevice::WriteOnly)) { 0389 return false; 0390 } 0391 0392 archive.addLocalFile(QString(Latte::configPath() + "/lattedockrc"), QStringLiteral("lattedockrc")); 0393 0394 for(const auto &layoutName : availableLayouts()) { 0395 archive.addLocalFile(layoutUserFilePath(layoutName), QString("latte/" + layoutName + ".layout.latte")); 0396 } 0397 0398 //! custom templates 0399 QDir templatesDir(Latte::configPath() + "/latte/templates"); 0400 QStringList filters; 0401 filters.append(QString("*.layout.latte")); 0402 QStringList templates = templatesDir.entryList(filters, QDir::Files | QDir::Hidden | QDir::NoSymLinks); 0403 0404 for (int i=0; i<templates.count(); ++i) { 0405 QString templatePath = templatesDir.path() + "/" + templates[i]; 0406 archive.addLocalFile(templatePath, QString("latte/templates/" + templates[i])); 0407 } 0408 0409 filters.clear(); 0410 filters.append(QString("*.view.latte")); 0411 templates = templatesDir.entryList(filters, QDir::Files | QDir::Hidden | QDir::NoSymLinks); 0412 0413 for (int i=0; i<templates.count(); ++i) { 0414 QString templatePath = templatesDir.path() + "/" + templates[i]; 0415 archive.addLocalFile(templatePath, QString("latte/templates/" + templates[i])); 0416 } 0417 0418 archive.close(); 0419 0420 return true; 0421 } 0422 0423 Importer::LatteFileVersion Importer::fileVersion(QString file) 0424 { 0425 if (!QFile::exists(file)) 0426 return UnknownFileType; 0427 0428 if (file.endsWith(".layout.latte")) { 0429 KSharedConfigPtr lConfig = KSharedConfig::openConfig(QFileInfo(file).absoluteFilePath()); 0430 KConfigGroup layoutGroup = KConfigGroup(lConfig, "LayoutSettings"); 0431 int version = layoutGroup.readEntry("version", 1); 0432 0433 if (version == 2) 0434 return Importer::LayoutVersion2; 0435 else 0436 return Importer::UnknownFileType; 0437 } 0438 0439 if (!file.endsWith(".latterc")) { 0440 return Importer::UnknownFileType; 0441 } 0442 0443 KTar archive(file, QStringLiteral("application/x-tar")); 0444 archive.open(QIODevice::ReadOnly); 0445 0446 //! if the file isnt a tar archive 0447 if (!archive.isOpen()) { 0448 return Importer::UnknownFileType; 0449 } 0450 0451 QTemporaryDir archiveTempDir; 0452 0453 bool version1rc = false; 0454 bool version1applets = false; 0455 0456 bool version2rc = false; 0457 bool version2LatteDir = false; 0458 bool version2layout = false; 0459 0460 archive.directory()->copyTo(archiveTempDir.path()); 0461 0462 0463 //rc file 0464 QString rcFile(archiveTempDir.path() + "/lattedockrc"); 0465 0466 if (QFile(rcFile).exists()) { 0467 KSharedConfigPtr lConfig = KSharedConfig::openConfig(rcFile); 0468 KConfigGroup universalGroup = KConfigGroup(lConfig, "UniversalSettings"); 0469 int version = universalGroup.readEntry("version", 1); 0470 0471 if (version == 1) { 0472 version1rc = true; 0473 } else if (version == 2) { 0474 version2rc = true; 0475 } 0476 } 0477 0478 //applets file 0479 QString appletsFile(archiveTempDir.path() + "/lattedock-appletsrc"); 0480 0481 if (QFile(appletsFile).exists() && version1rc) { 0482 KSharedConfigPtr lConfig = KSharedConfig::openConfig(appletsFile); 0483 KConfigGroup generalGroup = KConfigGroup(lConfig, "LayoutSettings"); 0484 int version = generalGroup.readEntry("version", 1); 0485 0486 if (version == 1) { 0487 version1applets = true; 0488 } else if (version == 2) { 0489 version2layout = true; 0490 } 0491 } 0492 0493 //latte directory 0494 QString latteDir(archiveTempDir.path() + "/latte"); 0495 0496 if (QDir(latteDir).exists()) { 0497 version2LatteDir = true; 0498 } 0499 0500 if (version1applets) { 0501 return ConfigVersion1; 0502 } else if (version2rc && version2LatteDir) { 0503 return ConfigVersion2; 0504 } 0505 0506 return Importer::UnknownFileType; 0507 } 0508 0509 bool Importer::importHelper(QString fileName) 0510 { 0511 LatteFileVersion version = fileVersion(fileName); 0512 0513 if ((version != ConfigVersion1) && (version != ConfigVersion2)) { 0514 return false; 0515 } 0516 0517 KTar archive(fileName, QStringLiteral("application/x-tar")); 0518 archive.open(QIODevice::ReadOnly); 0519 0520 if (!archive.isOpen()) { 0521 return false; 0522 } 0523 0524 QDir latteDir(layoutUserDir()); 0525 0526 if (latteDir.exists()) { 0527 latteDir.removeRecursively(); 0528 } 0529 0530 archive.directory()->copyTo(Latte::configPath()); 0531 0532 return true; 0533 } 0534 0535 bool Importer::isAutostartEnabled() 0536 { 0537 QFile autostartFile(Latte::configPath() + "/autostart/org.kde.latte-dock.desktop"); 0538 return autostartFile.exists(); 0539 } 0540 0541 void Importer::enableAutostart() 0542 { 0543 //! deprecated old file 0544 QFile oldAutostartFile(Latte::configPath() + "/autostart/latte-dock.desktop"); 0545 0546 if (oldAutostartFile.exists()) { 0547 //! remove deprecated file 0548 oldAutostartFile.remove(); 0549 } 0550 0551 QFile autostartFile(Latte::configPath() + "/autostart/org.kde.latte-dock.desktop"); 0552 QFile metaFile(standardPath("applications/org.kde.latte-dock.desktop", false)); 0553 0554 if (autostartFile.exists()) { 0555 //! if autostart file already exists, do nothing 0556 return; 0557 } 0558 0559 if (metaFile.exists()) { 0560 //! check if autostart folder exists and create otherwise 0561 QDir autostartDir(Latte::configPath() + "/autostart"); 0562 if (!autostartDir.exists()) { 0563 QDir configDir(Latte::configPath()); 0564 configDir.mkdir("autostart"); 0565 } 0566 0567 metaFile.copy(autostartFile.fileName()); 0568 } 0569 } 0570 0571 void Importer::disableAutostart() 0572 { 0573 QFile oldAutostartFile(Latte::configPath() + "/autostart/latte-dock.desktop"); 0574 0575 if (oldAutostartFile.exists()) { 0576 //! remove deprecated file 0577 oldAutostartFile.remove(); 0578 } 0579 0580 QFile autostartFile(Latte::configPath() + "/autostart/org.kde.latte-dock.desktop"); 0581 0582 if (autostartFile.exists()) { 0583 autostartFile.remove(); 0584 } 0585 } 0586 0587 bool Importer::hasViewTemplate(const QString &name) 0588 { 0589 return availableViewTemplates().contains(name); 0590 } 0591 0592 QString Importer::importLayout(const QString &fileName, const QString &suggestedLayoutName) 0593 { 0594 QString newLayoutName = importLayoutHelper(fileName, suggestedLayoutName); 0595 0596 if (!newLayoutName.isEmpty()) { 0597 emit newLayoutAdded(layoutUserFilePath(newLayoutName)); 0598 } 0599 0600 return newLayoutName; 0601 } 0602 0603 QString Importer::importLayoutHelper(const QString &fileName, const QString &suggestedLayoutName) 0604 { 0605 LatteFileVersion version = fileVersion(fileName); 0606 0607 if (version != LayoutVersion2) { 0608 return QString(); 0609 } 0610 0611 QString newLayoutName = !suggestedLayoutName.isEmpty() ? suggestedLayoutName : Layout::AbstractLayout::layoutName(fileName); 0612 newLayoutName = uniqueLayoutName(newLayoutName); 0613 0614 QString newPath = layoutUserFilePath(newLayoutName); 0615 0616 QDir localLayoutsDir(layoutUserDir()); 0617 0618 if (!localLayoutsDir.exists()) { 0619 QDir(Latte::configPath()).mkdir("latte"); 0620 } 0621 0622 QFile(fileName).copy(newPath); 0623 0624 QFileInfo newFileInfo(newPath); 0625 0626 if (newFileInfo.exists() && !newFileInfo.isWritable()) { 0627 QFile(newPath).setPermissions(QFileDevice::ReadUser | QFileDevice::WriteUser | QFileDevice::ReadGroup | QFileDevice::ReadOther); 0628 } 0629 0630 return newLayoutName; 0631 } 0632 0633 QStringList Importer::availableLayouts() 0634 { 0635 QDir layoutDir(layoutUserDir()); 0636 QStringList filter; 0637 filter.append(QString("*.layout.latte")); 0638 QStringList files = layoutDir.entryList(filter, QDir::Files | QDir::NoSymLinks); 0639 0640 QStringList layoutNames; 0641 0642 for(const auto &file : files) { 0643 layoutNames.append(Layout::AbstractLayout::layoutName(file)); 0644 } 0645 0646 return layoutNames; 0647 } 0648 0649 QStringList Importer::availableViewTemplates() 0650 { 0651 QStringList templates; 0652 0653 QDir localDir(layoutUserDir() + "/templates"); 0654 QStringList filter; 0655 filter.append(QString("*.view.latte")); 0656 QStringList files = localDir.entryList(filter, QDir::Files | QDir::NoSymLinks); 0657 0658 for(const auto &file : files) { 0659 templates.append(Templates::Manager::templateName(file)); 0660 } 0661 0662 QDir systemDir(systemShellDataPath()+"/contents/templates"); 0663 QStringList sfiles = systemDir.entryList(filter, QDir::Files | QDir::NoSymLinks); 0664 0665 for(const auto &file : sfiles) { 0666 QString name = Templates::Manager::templateName(file); 0667 if (!templates.contains(name)) { 0668 templates.append(name); 0669 } 0670 } 0671 0672 return templates; 0673 } 0674 0675 QStringList Importer::availableLayoutTemplates() 0676 { 0677 QStringList templates; 0678 0679 QDir localDir(layoutUserDir() + "/templates"); 0680 QStringList filter; 0681 filter.append(QString("*.layout.latte")); 0682 QStringList files = localDir.entryList(filter, QDir::Files | QDir::NoSymLinks); 0683 0684 for(const auto &file : files) { 0685 templates.append(Templates::Manager::templateName(file)); 0686 } 0687 0688 QDir systemDir(systemShellDataPath()+"/contents/templates"); 0689 QStringList sfiles = systemDir.entryList(filter, QDir::Files | QDir::NoSymLinks); 0690 0691 for(const auto &file : sfiles) { 0692 QString name = Templates::Manager::templateName(file); 0693 if (!templates.contains(name)) { 0694 templates.append(name); 0695 } 0696 } 0697 0698 return templates; 0699 } 0700 0701 QString Importer::nameOfConfigFile(const QString &fileName) 0702 { 0703 int lastSlash = fileName.lastIndexOf("/"); 0704 QString tempLayoutFile = fileName; 0705 QString layoutName = tempLayoutFile.remove(0, lastSlash + 1); 0706 0707 int ext = layoutName.lastIndexOf(".latterc"); 0708 layoutName = layoutName.remove(ext, 8); 0709 0710 return layoutName; 0711 } 0712 0713 bool Importer::layoutExists(QString layoutName) 0714 { 0715 return QFile::exists(layoutUserFilePath(layoutName)); 0716 } 0717 0718 0719 QString Importer::layoutUserDir() 0720 { 0721 return QString(Latte::configPath() + "/latte"); 0722 } 0723 0724 QString Importer::layoutUserFilePath(QString layoutName) 0725 { 0726 return QString(layoutUserDir() + "/" + layoutName + ".layout.latte"); 0727 } 0728 0729 QString Importer::systemShellDataPath() 0730 { 0731 QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); 0732 QString rootpath = paths.count() > 0 ? paths[paths.count()-1] : "/usr/share"; 0733 return rootpath + "/plasma/shells/org.kde.latte.shell"; 0734 } 0735 0736 QString Importer::layoutTemplateSystemFilePath(const QString &name) 0737 { 0738 return systemShellDataPath() + "/contents/templates/" + name + ".layout.latte"; 0739 } 0740 0741 QString Importer::uniqueLayoutName(QString name) 0742 { 0743 int pos_ = name.lastIndexOf(QRegExp(QString(" - [0-9]+"))); 0744 0745 if (layoutExists(name) && pos_ > 0) { 0746 name = name.left(pos_); 0747 } 0748 0749 int i = 2; 0750 0751 QString namePart = name; 0752 0753 while (layoutExists(name)) { 0754 name = namePart + " - " + QString::number(i); 0755 i++; 0756 } 0757 0758 return name; 0759 } 0760 0761 Latte::MultipleLayouts::Status Importer::multipleLayoutsStatus() 0762 { 0763 QString linkedFilePath = layoutUserFilePath(Layout::MULTIPLELAYOUTSHIDDENNAME); 0764 if (!QFileInfo(linkedFilePath).exists()) { 0765 return Latte::MultipleLayouts::Uninitialized; 0766 } 0767 0768 KSharedConfigPtr filePtr = KSharedConfig::openConfig(linkedFilePath); 0769 KConfigGroup multipleSettings = KConfigGroup(filePtr, "MultipleLayoutsSettings"); 0770 return static_cast<Latte::MultipleLayouts::Status>(multipleSettings.readEntry("status", (int)Latte::MultipleLayouts::Uninitialized)); 0771 } 0772 0773 void Importer::setMultipleLayoutsStatus(const Latte::MultipleLayouts::Status &status) 0774 { 0775 QString linkedFilePath = layoutUserFilePath(Layout::MULTIPLELAYOUTSHIDDENNAME); 0776 0777 if (!QFileInfo(linkedFilePath).exists()) { 0778 return; 0779 } 0780 0781 if (multipleLayoutsStatus() == status) { 0782 return; 0783 } 0784 0785 qDebug() << " MULTIPLE LAYOUTS changed status:" << status; 0786 0787 KSharedConfigPtr filePtr = KSharedConfig::openConfig(linkedFilePath); 0788 KConfigGroup multipleSettings = KConfigGroup(filePtr, "MultipleLayoutsSettings"); 0789 multipleSettings.writeEntry("status", (int)(status)); 0790 multipleSettings.sync(); 0791 } 0792 0793 QStringList Importer::checkRepairMultipleLayoutsLinkedFile() 0794 { 0795 QString linkedFilePath = layoutUserFilePath(Layout::MULTIPLELAYOUTSHIDDENNAME); 0796 KSharedConfigPtr filePtr = KSharedConfig::openConfig(linkedFilePath); 0797 KConfigGroup linkedContainments = KConfigGroup(filePtr, "Containments"); 0798 0799 //! layoutName and its Containments 0800 QHash<QString, QStringList> linkedLayoutContainmentGroups; 0801 0802 for(const auto &cId : linkedContainments.groupList()) { 0803 QString layoutName = linkedContainments.group(cId).readEntry("layoutId", QString()); 0804 0805 if (!layoutName.isEmpty()) { 0806 qDebug() << layoutName; 0807 linkedLayoutContainmentGroups[layoutName].append(cId); 0808 linkedContainments.group(cId).writeEntry("layoutId", QString()); 0809 } 0810 } 0811 0812 QStringList updatedLayouts; 0813 0814 for(const auto &layoutName : linkedLayoutContainmentGroups.uniqueKeys()) { 0815 if (layoutName != Layout::MULTIPLELAYOUTSHIDDENNAME && layoutExists(layoutName)) { 0816 updatedLayouts << layoutName; 0817 KSharedConfigPtr layoutFilePtr = KSharedConfig::openConfig(layoutUserFilePath(layoutName)); 0818 KConfigGroup origLayoutContainments = KConfigGroup(layoutFilePtr, "Containments"); 0819 0820 //Clear old containments 0821 origLayoutContainments.deleteGroup(); 0822 0823 //Update containments 0824 for(const auto &cId : linkedLayoutContainmentGroups[layoutName]) { 0825 KConfigGroup newContainment = origLayoutContainments.group(cId); 0826 linkedContainments.group(cId).copyTo(&newContainment); 0827 linkedContainments.group(cId).deleteGroup(); 0828 } 0829 0830 origLayoutContainments.sync(); 0831 } 0832 } 0833 0834 //! clear all remaining ghost containments 0835 for(const auto &cId : linkedContainments.groupList()) { 0836 linkedContainments.group(cId).deleteGroup(); 0837 } 0838 0839 linkedContainments.sync(); 0840 0841 return updatedLayouts; 0842 } 0843 0844 } 0845 }