File indexing completed on 2024-03-24 17:24:32

0001 /**
0002  * SPDX-FileCopyrightText: (C) 2015 Gleb Baryshev <gleb.baryshev@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef KDE4_MIGRATION_H
0008 #define KDE4_MIGRATION_H
0009 
0010 #include <KAboutData>
0011 #include <KConfigGroup>
0012 #include <KIO/CopyJob>
0013 #include <KLocalizedString>
0014 #include <KSharedConfig>
0015 #include <Kdelibs4ConfigMigrator>
0016 #include <Kdelibs4Migration>
0017 #include <QDebug>
0018 #include <QDir>
0019 #include <QEventLoop>
0020 #include <QMessageBox>
0021 #include <QScopedPointer>
0022 #include <QStandardPaths>
0023 
0024 /** Use Kdelibs4ConfigMigrator to detect KDE4 config and then migrate both config and data.
0025     Suggest deleting the files from the old location
0026 
0027     Prerequisite: existing QApplication in order to run KIO Jobs and QEventLoop
0028  */
0029 class Kde4Migrator
0030 {
0031 public:
0032     //! @returns True if both config and data have been migrated
0033     bool migrateKde4Data()
0034     {
0035         Kdelibs4ConfigMigrator rcMigrator(KAboutData::applicationData().componentName());
0036         rcMigrator.setConfigFiles({BASKET_RC});
0037         rcMigrator.setUiFiles({"basketui.rc", "basket_part.rc"});
0038         if (rcMigrator.migrate())
0039             qDebug() << "Kdelibs4ConfigMigrator migrate=true";
0040         else
0041             return false;
0042 
0043         // Safety check
0044         // ~/.local/share/basket
0045         if (QDir(getNewDataDir()).exists()) {
0046             qDebug() << "Directory" << getNewDataDir() << "already exists, not trying to overwrite";
0047             return false;
0048         }
0049 
0050         QString customDataFolder = getCustomDataFolder();
0051         if (customDataFolder.length() > 0) {
0052             qDebug() << "Keeping basket data in" << customDataFolder;
0053             return false; // Do not delete the data folder. Note: old basketrc will not be deleted either
0054         }
0055 
0056         m_dataMigrator.reset(new Kdelibs4Migration());
0057         if (m_dataMigrator->kdeHomeFound()) {
0058             bool copySucceeded = false;
0059             QEventLoop waitLoop;
0060 
0061             auto onCopyFinished = [&](KJob *job) {
0062                 int error = job->error();
0063                 qDebug() << "KIO::CopyJob finished with result" << error;
0064                 if (error != 0) {
0065                     qDebug() << job->errorString();
0066                     QMessageBox::critical(nullptr,
0067                                           QGuiApplication::applicationDisplayName(),
0068                                           i18n("Failed to migrate Basket data from KDE4. You will need to close Basket and copy the basket folder manually.\n"
0069                                                "Source: %1\nDestination: %2\nReason: %3",
0070                                                getOldDataDir(),
0071                                                getNewDataDir(),
0072                                                job->errorString()));
0073                 }
0074                 copySucceeded = (error == 0);
0075                 waitLoop.quit();
0076             };
0077 
0078             qDebug() << "Kdelibs4Migration: start copying basket data";
0079             KIO::CopyJob *copyJob = KIO::copyAs(QUrl::fromLocalFile(getOldDataDir()), QUrl::fromLocalFile(getNewDataDir()));
0080             QObject::connect(copyJob, &KIO::CopyJob::result, onCopyFinished);
0081             waitLoop.exec();
0082 
0083             if (copySucceeded)
0084                 return true;
0085         }
0086 
0087         return false;
0088     }
0089 
0090     void showPostMigrationDialog()
0091     {
0092         QMessageBox msgBox;
0093         msgBox.setWindowTitle(i18n("Choose action"));
0094         msgBox.setText(
0095             i18n("Basket data from KDE4 have been successfully migrated to %1.\n"
0096                  "Unless you are planning to run KDE4 version again, you can delete the old folder %2",
0097                  getNewDataDir(),
0098                  getOldDataDir()));
0099         msgBox.addButton(i18n("Delete (to Trash)"), QMessageBox::YesRole);
0100         msgBox.addButton(i18n("Keep"), QMessageBox::NoRole);
0101         msgBox.setIcon(QMessageBox::Information);
0102         int dialogCode = msgBox.exec();
0103 
0104         if (dialogCode == 0) {
0105             // ~/.kde/share/config/basketrc
0106             QString basketrc = m_dataMigrator->locateLocal("config", BASKET_RC);
0107 
0108             QList<QUrl> trashList = {QUrl::fromLocalFile(getOldDataDir())};
0109             if (QFile(basketrc).exists())
0110                 trashList.prepend(QUrl::fromLocalFile(basketrc));
0111 
0112             qDebug() << "Move to trash:" << trashList;
0113             KIO::trash(trashList);
0114         }
0115     }
0116 
0117 private:
0118     const QString BASKET_RC = "basketrc";
0119 
0120     QScopedPointer<Kdelibs4Migration> m_dataMigrator;
0121 
0122     QString getOldConfig()
0123     {
0124         return m_dataMigrator->locateLocal("config", BASKET_RC);
0125     }
0126 
0127     QString getOldDataDir()
0128     {
0129         return m_dataMigrator->saveLocation("data", "basket");
0130     }
0131 
0132     QString getNewDataDir()
0133     {
0134         return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/basket";
0135     }
0136 
0137     QString getCustomDataFolder()
0138     {
0139         KSharedConfig::Ptr basketConfig = KSharedConfig::openConfig(BASKET_RC);
0140         KConfigGroup config = basketConfig->group("Main window");
0141         return config.readEntry("dataFolder", QString());
0142     }
0143 };
0144 
0145 #endif // KDE4_MIGRATION_H