X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/8fbb88475517cb055617ba375c8f0747f6f646e7..ee0eb84df4d3169b49d877ef850c4702963ce90f:/src/versioncontrol/versioncontrolobserver.cpp diff --git a/src/versioncontrol/versioncontrolobserver.cpp b/src/versioncontrol/versioncontrolobserver.cpp index 9e52d1f51..f47f47484 100644 --- a/src/versioncontrol/versioncontrolobserver.cpp +++ b/src/versioncontrol/versioncontrolobserver.cpp @@ -20,6 +20,7 @@ #include "versioncontrolobserver.h" #include +#include "dolphin_versioncontrolsettings.h" #include #include @@ -34,6 +35,18 @@ #include #include +/* + * Maintains a list of pending threads, that get regulary checked + * whether they are finished and hence can get deleted. QThread::wait() + * is never used to prevent any blocking of the user interface. + */ +struct PendingThreadsSingleton +{ + QList list; +}; +K_GLOBAL_STATIC(PendingThreadsSingleton, s_pendingThreads) + + VersionControlObserver::VersionControlObserver(QAbstractItemView* view) : QObject(view), m_pendingItemStatesUpdate(false), @@ -73,14 +86,22 @@ VersionControlObserver::VersionControlObserver(QAbstractItemView* view) : VersionControlObserver::~VersionControlObserver() { if (m_updateItemStatesThread != 0) { - disconnect(m_updateItemStatesThread, SIGNAL(finished()), - this, SLOT(applyUpdatedItemStates())); if (m_updateItemStatesThread->isFinished()) { delete m_updateItemStatesThread; + m_updateItemStatesThread = 0; } else { - m_updateItemStatesThread->deleteWhenFinished(); + // The version controller gets deleted, while a thread still + // is working to get the version information. To avoid a blocking + // user interface, no waiting for the finished() signal of the thread is + // done. Instead the thread will be remembered inside the global + // list s_pendingThreads, which will checked regulary. The thread does + // not work on shared data that is part of the VersionController instance, + // so skipping the waiting is save. + disconnect(m_updateItemStatesThread, SIGNAL(finished()), + this, SLOT(slotThreadFinished())); + s_pendingThreads->list.append(m_updateItemStatesThread); + m_updateItemStatesThread = 0; } - m_updateItemStatesThread = 0; } m_plugin->disconnect(); @@ -122,6 +143,19 @@ void VersionControlObserver::silentDirectoryVerification() void VersionControlObserver::verifyDirectory() { + if (!s_pendingThreads->list.isEmpty()) { + // Try to cleanup pending threads (see explanation in destructor) + QList::iterator it = s_pendingThreads->list.begin(); + while (it != s_pendingThreads->list.end()) { + if ((*it)->isFinished()) { + (*it)->deleteLater(); + it = s_pendingThreads->list.erase(it); + } else { + ++it; + } + } + } + KUrl versionControlUrl = m_dirLister->url(); if (!versionControlUrl.isLocalFile()) { return; @@ -176,8 +210,12 @@ void VersionControlObserver::verifyDirectory() } } -void VersionControlObserver::applyUpdatedItemStates() +void VersionControlObserver::slotThreadFinished() { + if (m_plugin == 0) { + return; + } + if (!m_updateItemStatesThread->retrievedItems()) { // ignore m_silentUpdate for an error message emit errorMessage(i18nc("@info:status", "Update of version information failed.")); @@ -207,7 +245,7 @@ void VersionControlObserver::applyUpdatedItemStates() // operation has been completed because of the icon emblems. emit operationCompletedMessage(QString()); } - + if (m_pendingItemStatesUpdate) { m_pendingItemStatesUpdate = false; updateItemStates(); @@ -220,11 +258,11 @@ void VersionControlObserver::updateItemStates() if (m_updateItemStatesThread == 0) { m_updateItemStatesThread = new UpdateItemStatesThread(); connect(m_updateItemStatesThread, SIGNAL(finished()), - this, SLOT(applyUpdatedItemStates())); + this, SLOT(slotThreadFinished())); } if (m_updateItemStatesThread->isRunning()) { // An update is currently ongoing. Wait until the thread has finished - // the update (see applyUpdatedItemStates()). + // the update (see slotThreadFinished()). m_pendingItemStatesUpdate = true; return; } @@ -236,7 +274,7 @@ void VersionControlObserver::updateItemStates() emit infoMessage(i18nc("@info:status", "Updating version information...")); } m_updateItemStatesThread->setData(m_plugin, itemStates); - m_updateItemStatesThread->start(); // applyUpdatedItemStates() is called when finished + m_updateItemStatesThread->start(); // slotThreadFinished() is called when finished } } @@ -270,11 +308,16 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director if (plugins.isEmpty()) { // No searching for plugins has been done yet. Query the KServiceTypeTrader for // all fileview version control plugins and remember them in 'plugins'. + const QString disabledPlugins = VersionControlSettings::disabledPlugins(); + const QStringList disabledPluginsList = disabledPlugins.split(','); + const KService::List pluginServices = KServiceTypeTrader::self()->query("FileViewVersionControlPlugin"); for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) { - KVersionControlPlugin* plugin = (*it)->createInstance(); - Q_ASSERT(plugin != 0); - plugins.append(plugin); + if (!disabledPluginsList.contains((*it)->name())) { + KVersionControlPlugin* plugin = (*it)->createInstance(); + Q_ASSERT(plugin != 0); + plugins.append(plugin); + } } if (plugins.isEmpty()) { pluginsAvailable = false;