#include "versioncontrolobserver.h"
#include <dolphinmodel.h>
+#include "dolphin_versioncontrolsettings.h"
#include <kdirlister.h>
#include <klocale.h>
#include <QMutexLocker>
#include <QTimer>
+/*
+ * 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<UpdateItemStatesThread*> list;
+};
+K_GLOBAL_STATIC(PendingThreadsSingleton, s_pendingThreads)
+
+
VersionControlObserver::VersionControlObserver(QAbstractItemView* view) :
QObject(view),
m_pendingItemStatesUpdate(false),
VersionControlObserver::~VersionControlObserver()
{
if (m_updateItemStatesThread != 0) {
- disconnect(m_updateItemStatesThread, SIGNAL(finished()),
- this, SLOT(applyUpdatedItemStates()));
- m_updateItemStatesThread->deleteWhenFinished();
- m_updateItemStatesThread = 0;
+ if (m_updateItemStatesThread->isFinished()) {
+ delete m_updateItemStatesThread;
+ m_updateItemStatesThread = 0;
+ } else {
+ // 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_plugin->disconnect();
+ m_plugin = 0;
}
QList<QAction*> VersionControlObserver::contextMenuActions(const KFileItemList& items) const
void VersionControlObserver::verifyDirectory()
{
+ if (!s_pendingThreads->list.isEmpty()) {
+ // Try to cleanup pending threads (see explanation in destructor)
+ QList<UpdateItemStatesThread*>::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;
}
}
-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."));
// operation has been completed because of the icon emblems.
emit operationCompletedMessage(QString());
}
-
+
if (m_pendingItemStatesUpdate) {
m_pendingItemStatesUpdate = false;
updateItemStates();
{
Q_ASSERT(m_plugin != 0);
if (m_updateItemStatesThread == 0) {
- m_updateItemStatesThread = new UpdateItemStatesThread(this);
+ 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;
}
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
}
}
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<KVersionControlPlugin>();
- Q_ASSERT(plugin != 0);
- plugins.append(plugin);
+ if (!disabledPluginsList.contains((*it)->name())) {
+ KVersionControlPlugin* plugin = (*it)->createInstance<KVersionControlPlugin>();
+ Q_ASSERT(plugin != 0);
+ plugins.append(plugin);
+ }
}
if (plugins.isEmpty()) {
pluginsAvailable = false;