]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/views/versioncontrol/versioncontrolobserver.cpp
Switch to C++20
[dolphin.git] / src / views / versioncontrol / versioncontrolobserver.cpp
index 6766aa479a0b57dd2c7454ec40d6ddc2d0dedc88..3101c772793958178eace04248e58a9b54fa74e8 100644 (file)
@@ -8,27 +8,26 @@
 
 #include "dolphin_versioncontrolsettings.h"
 #include "dolphindebug.h"
-#include "views/dolphinview.h"
 #include "kitemviews/kfileitemmodel.h"
 #include "updateitemstatesthread.h"
+#include "views/dolphinview.h"
 
 #include <KLocalizedString>
 #include <KPluginFactory>
-#include <KPluginLoader>
 #include <KPluginMetaData>
 
 #include <QTimer>
 
-VersionControlObserver::VersionControlObserver(QObject* parent) :
-    QObject(parent),
-    m_pendingItemStatesUpdate(false),
-    m_silentUpdate(false),
-    m_view(nullptr),
-    m_model(nullptr),
-    m_dirVerificationTimer(nullptr),
-    m_pluginsInitialized(false),
-    m_plugin(nullptr),
-    m_updateItemStatesThread(nullptr)
+VersionControlObserver::VersionControlObserver(QObject *parent)
+    : QObject(parent)
+    , m_pendingItemStatesUpdate(false)
+    , m_silentUpdate(false)
+    , m_view(nullptr)
+    , m_model(nullptr)
+    , m_dirVerificationTimer(nullptr)
+    , m_pluginsInitialized(false)
+    , m_currentPlugin(nullptr)
+    m_updateItemStatesThread(nullptr)
 {
     // The verification timer specifies the timeout until the shown directory
     // is checked whether it is versioned. Per default it is assumed that users
@@ -38,66 +37,69 @@ VersionControlObserver::VersionControlObserver(QObject* parent) :
     m_dirVerificationTimer = new QTimer(this);
     m_dirVerificationTimer->setSingleShot(true);
     m_dirVerificationTimer->setInterval(500);
-    connect(m_dirVerificationTimer, &QTimer::timeout,
-            this, &VersionControlObserver::verifyDirectory);
+    connect(m_dirVerificationTimer, &QTimer::timeout, this, &VersionControlObserver::verifyDirectory);
 }
 
 VersionControlObserver::~VersionControlObserver()
 {
-    if (m_plugin) {
-        m_plugin->disconnect(this);
-        m_plugin = nullptr;
+    if (m_currentPlugin) {
+        m_currentPlugin->disconnect(this);
     }
+    if (m_updateItemStatesThread) {
+        m_updateItemStatesThread->requestInterruption();
+        m_updateItemStatesThread->wait();
+        m_updateItemStatesThread->deleteLater();
+    }
+
+    if (m_currentPlugin) {
+        delete m_currentPlugin;
+        m_currentPlugin = nullptr;
+    }
+    m_plugins.clear();
 }
 
-void VersionControlObserver::setModel(KFileItemModelmodel)
+void VersionControlObserver::setModel(KFileItemModel *model)
 {
     if (m_model) {
-        disconnect(m_model, &KFileItemModel::itemsInserted,
-                   this, &VersionControlObserver::delayedDirectoryVerification);
-        disconnect(m_model, &KFileItemModel::itemsChanged,
-                   this, &VersionControlObserver::slotItemsChanged);
+        disconnect(m_model, &KFileItemModel::itemsInserted, this, &VersionControlObserver::delayedDirectoryVerification);
+        disconnect(m_model, &KFileItemModel::itemsChanged, this, &VersionControlObserver::slotItemsChanged);
     }
 
     m_model = model;
 
     if (model) {
-        connect(m_model, &KFileItemModel::itemsInserted,
-                this, &VersionControlObserver::delayedDirectoryVerification);
-        connect(m_model, &KFileItemModel::itemsChanged,
-                this, &VersionControlObserver::slotItemsChanged);
+        connect(m_model, &KFileItemModel::itemsInserted, this, &VersionControlObserver::delayedDirectoryVerification);
+        connect(m_model, &KFileItemModel::itemsChanged, this, &VersionControlObserver::slotItemsChanged);
     }
 }
 
-KFileItemModelVersionControlObserver::model() const
+KFileItemModel *VersionControlObserver::model() const
 {
     return m_model;
 }
 
-void VersionControlObserver::setView(DolphinViewview)
+void VersionControlObserver::setView(DolphinView *view)
 {
     if (m_view) {
-        disconnect(m_view, &DolphinView::activated,
-                   this, &VersionControlObserver::delayedDirectoryVerification);
+        disconnect(m_view, &DolphinView::activated, this, &VersionControlObserver::delayedDirectoryVerification);
     }
 
     m_view = view;
 
     if (m_view) {
-        connect(m_view, &DolphinView::activated,
-                this, &VersionControlObserver::delayedDirectoryVerification);
+        connect(m_view, &DolphinView::activated, this, &VersionControlObserver::delayedDirectoryVerification);
     }
 }
 
-DolphinViewVersionControlObserver::view() const
+DolphinView *VersionControlObserver::view() const
 {
     return m_view;
 }
 
-QList<QAction*> VersionControlObserver::actions(const KFileItemList& items) const
+QList<QAction *> VersionControlObserver::actions(const KFileItemList &items) const
 {
     bool hasNullItems = false;
-    for (const KFileItemitem : items) {
+    for (const KFileItem &item : items) {
         if (item.isNull()) {
             qCWarning(DolphinDebug) << "Requesting version-control-actions for empty items";
             hasNullItems = true;
@@ -110,10 +112,10 @@ QList<QAction*> VersionControlObserver::actions(const KFileItemList& items) cons
     }
 
     if (isVersionControlled()) {
-        return m_plugin->versionControlActions(items);
+        return m_currentPlugin->versionControlActions(items);
     } else {
-        QList<QAction*> actions;
-        for (const QPointer<KVersionControlPlugin> &plugin : qAsConst(m_plugins)) {
+        QList<QAction *> actions;
+        for (const KVersionControlPlugin *plugin : std::as_const(m_plugins)) {
             actions << plugin->outOfVersionControlActions(items);
         }
         return actions;
@@ -132,14 +134,14 @@ void VersionControlObserver::silentDirectoryVerification()
     m_dirVerificationTimer->start();
 }
 
-void VersionControlObserver::slotItemsChanged(const KItemRangeList& itemRanges, const QSet<QByteArray>& roles)
+void VersionControlObserver::slotItemsChanged(const KItemRangeList &itemRanges, const QSet<QByteArray> &roles)
 {
     Q_UNUSED(itemRanges)
 
-    // Because "version" role is emitted by VCS plugin (ourselfs) we don't need to
+    // Because "version" role is emitted by VCS plugin (ourselves) we don't need to
     // analyze it and update directory item states information. So lets check if
     // there is only "version".
-    if ( !(roles.count() == 1 && roles.contains("version")) ) {
+    if (!(roles.count() == 1 && roles.contains("version"))) {
         delayedDirectoryVerification();
     }
 }
@@ -155,42 +157,42 @@ void VersionControlObserver::verifyDirectory()
         return;
     }
 
-    if (m_plugin != nullptr) {
-        if (!rootItem.url().path().startsWith(m_localRepoRoot) || !QFile::exists(m_localRepoRoot + '/' + m_plugin->fileName())) {
-            m_plugin = nullptr;
+    if (m_currentPlugin && rootItem.url().path().startsWith(m_localRepoRoot) && QFile::exists(m_localRepoRoot + '/' + m_currentPlugin->fileName())) {
+        // current directory is still versionned
+        updateItemStates();
+        return;
+    }
 
-            // The directory is not versioned. Reset the verification timer to a higher
-            // value, so that browsing through non-versioned directories is not slown down
-            // by an immediate verification.
-            m_dirVerificationTimer->setInterval(500);
-        } else {
-            // View was versionned but should not be anymore
-            updateItemStates();
-        }
-    } else if ((m_plugin = searchPlugin(rootItem.url()))) {
+    if ((m_currentPlugin = searchPlugin(rootItem.url()))) {
         // The directory is versioned. Assume that the user will further browse through
         // versioned directories and decrease the verification timer.
         m_dirVerificationTimer->setInterval(100);
         updateItemStates();
+        return;
     }
+
+    // The directory is not versioned. Reset the verification timer to a higher
+    // value, so that browsing through non-versioned directories is not slown down
+    // by an immediate verification.
+    m_dirVerificationTimer->setInterval(500);
 }
 
 void VersionControlObserver::slotThreadFinished()
 {
-    UpdateItemStatesThreadthread = m_updateItemStatesThread;
+    UpdateItemStatesThread *thread = m_updateItemStatesThread;
     m_updateItemStatesThread = nullptr; // The thread deletes itself automatically (see updateItemStates())
 
-    if (!m_plugin || !thread) {
+    if (!m_currentPlugin || !thread) {
         return;
     }
 
-    const QMap<QString, QVector<ItemState> >& itemStates = thread->itemStates();
-    QMap<QString, QVector<ItemState> >::const_iterator it = itemStates.constBegin();
+    const QMap<QString, QVector<ItemState>> &itemStates = thread->itemStates();
+    QMap<QString, QVector<ItemState>>::const_iterator it = itemStates.constBegin();
     for (; it != itemStates.constEnd(); ++it) {
-        const QVector<ItemState>items = it.value();
+        const QVector<ItemState> &items = it.value();
 
-        for (const ItemStateitem : items) {
-            const KFileItemfileItem = item.first;
+        for (const ItemState &item : items) {
+            const KFileItem &fileItem = item.first;
             const KVersionControlPlugin::ItemVersion version = item.second;
             QHash<QByteArray, QVariant> values;
             values.insert("version", QVariant(version));
@@ -213,7 +215,7 @@ void VersionControlObserver::slotThreadFinished()
 
 void VersionControlObserver::updateItemStates()
 {
-    Q_ASSERT(m_plugin);
+    Q_ASSERT(m_currentPlugin);
     if (m_updateItemStatesThread) {
         // An update is currently ongoing. Wait until the thread has finished
         // the update (see slotThreadFinished()).
@@ -221,25 +223,22 @@ void VersionControlObserver::updateItemStates()
         return;
     }
 
-    QMap<QString, QVector<ItemState> > itemStates;
+    QMap<QString, QVector<ItemState>> itemStates;
     createItemStatesList(itemStates);
 
     if (!itemStates.isEmpty()) {
         if (!m_silentUpdate) {
-            Q_EMIT infoMessage(i18nc("@info:status", "Updating version information..."));
+            Q_EMIT infoMessage(i18nc("@info:status", "Updating version information"));
         }
-        m_updateItemStatesThread = new UpdateItemStatesThread(m_plugin, itemStates);
-        connect(m_updateItemStatesThread, &UpdateItemStatesThread::finished,
-                this, &VersionControlObserver::slotThreadFinished);
-        connect(m_updateItemStatesThread, &UpdateItemStatesThread::finished,
-                m_updateItemStatesThread, &UpdateItemStatesThread::deleteLater);
+        m_updateItemStatesThread = new UpdateItemStatesThread(m_currentPlugin, itemStates);
+        connect(m_updateItemStatesThread, &UpdateItemStatesThread::finished, this, &VersionControlObserver::slotThreadFinished);
+        connect(m_updateItemStatesThread, &UpdateItemStatesThread::finished, m_updateItemStatesThread, &UpdateItemStatesThread::deleteLater);
 
         m_updateItemStatesThread->start(); // slotThreadFinished() is called when finished
     }
 }
 
-int VersionControlObserver::createItemStatesList(QMap<QString, QVector<ItemState> >& itemStates,
-                                                 const int firstIndex)
+int VersionControlObserver::createItemStatesList(QMap<QString, QVector<ItemState>> &itemStates, const int firstIndex)
 {
     const int itemCount = m_model->count();
     const int currentExpansionLevel = m_model->expandedParentsCount(firstIndex);
@@ -266,7 +265,7 @@ int VersionControlObserver::createItemStatesList(QMap<QString, QVector<ItemState
     }
 
     if (!items.isEmpty()) {
-        const QUrlurl = items.first().first.url();
+        const QUrl &url = items.first().first.url();
         itemStates.insert(url.adjusted(QUrl::RemoveFilename).path(), items);
     }
 
@@ -276,57 +275,45 @@ int VersionControlObserver::createItemStatesList(QMap<QString, QVector<ItemState
 void VersionControlObserver::initPlugins()
 {
     if (!m_pluginsInitialized) {
-        // No searching for plugins has been done yet. Query the KServiceTypeTrader for
-        // all fileview version control plugins and remember them in 'plugins'.
+        // No searching for plugins has been done yet. Query all fileview version control
+        // plugins and remember them in 'plugins'.
         const QStringList enabledPlugins = VersionControlSettings::enabledPlugins();
 
-        const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral("dolphin/vcs"));
-
-        QSet<QString> loadedPlugins;
+        const QVector<KPluginMetaData> plugins = KPluginMetaData::findPlugins(QStringLiteral("dolphin/vcs"));
 
         for (const auto &p : plugins) {
             if (enabledPlugins.contains(p.name())) {
-                KPluginLoader loader(p.fileName());
-                KPluginFactory *factory = loader.factory();
-                KVersionControlPlugin *plugin = factory->create<KVersionControlPlugin>();
+                auto plugin = KPluginFactory::instantiatePlugin<KVersionControlPlugin>(p, parent()).plugin;
                 if (plugin) {
                     m_plugins.append(plugin);
-                    loadedPlugins += p.name();
                 }
             }
         }
 
-        for (auto &plugin : qAsConst(m_plugins)) {
-            connect(plugin, &KVersionControlPlugin::itemVersionsChanged,
-                this, &VersionControlObserver::silentDirectoryVerification);
-            connect(plugin, &KVersionControlPlugin::infoMessage,
-                this, &VersionControlObserver::infoMessage);
-            connect(plugin, &KVersionControlPlugin::errorMessage,
-                this, &VersionControlObserver::errorMessage);
-            connect(plugin, &KVersionControlPlugin::operationCompletedMessage,
-                this, &VersionControlObserver::operationCompletedMessage);
+        for (const auto *plugin : std::as_const(m_plugins)) {
+            connect(plugin, &KVersionControlPlugin::itemVersionsChanged, this, &VersionControlObserver::silentDirectoryVerification);
+            connect(plugin, &KVersionControlPlugin::infoMessage, this, &VersionControlObserver::infoMessage);
+            connect(plugin, &KVersionControlPlugin::errorMessage, this, &VersionControlObserver::errorMessage);
+            connect(plugin, &KVersionControlPlugin::operationCompletedMessage, this, &VersionControlObserver::operationCompletedMessage);
         }
 
         m_pluginsInitialized = true;
     }
 }
 
-KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& directory)
+KVersionControlPlugin *VersionControlObserver::searchPlugin(const QUrl &directory)
 {
     initPlugins();
 
     // Verify whether the current directory is under a version system
-    for (const QPointer<KVersionControlPlugin> &plugin : qAsConst(m_plugins)) {
-        if (!plugin) {
-            continue;
-        }
-
+    for (KVersionControlPlugin *plugin : std::as_const(m_plugins)) {
         // first naively check if we are at working copy root
         const QString fileName = directory.path() + '/' + plugin->fileName();
         if (QFile::exists(fileName)) {
             m_localRepoRoot = directory.path();
             return plugin;
         }
+
         const QString root = plugin->localRepositoryRoot(directory.path());
         if (!root.isEmpty()) {
             m_localRepoRoot = root;
@@ -338,6 +325,7 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& director
 
 bool VersionControlObserver::isVersionControlled() const
 {
-    return m_plugin != nullptr;
+    return m_currentPlugin != nullptr;
 }
 
+#include "moc_versioncontrolobserver.cpp"