X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/af7ced90477abfc96ee8e3fe0f3c8b2c5a8bcb84..dc0236254abc9f11210e101a3089b8d9afff262b:/src/versioncontrol/versioncontrolobserver.cpp diff --git a/src/versioncontrol/versioncontrolobserver.cpp b/src/versioncontrol/versioncontrolobserver.cpp index ebe59e049..c5a0b982f 100644 --- a/src/versioncontrol/versioncontrolobserver.cpp +++ b/src/versioncontrol/versioncontrolobserver.cpp @@ -28,6 +28,7 @@ #include #include +#include "pendingthreadsmaintainer.h" #include "updateitemstatesthread.h" #include @@ -74,26 +75,33 @@ 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, the thread will be forwarded to the + // PendingThreadsMaintainer, which will delete the thread later. + disconnect(m_updateItemStatesThread, SIGNAL(finished()), + this, SLOT(slotThreadFinished())); + PendingThreadsMaintainer::instance().append(m_updateItemStatesThread); + m_updateItemStatesThread = 0; } - m_updateItemStatesThread = 0; } - m_plugin->disconnect(); - m_plugin = 0; + if (m_plugin != 0) { + m_plugin->disconnect(); + m_plugin = 0; + } } QList VersionControlObserver::contextMenuActions(const KFileItemList& items) const { QList actions; - if (isVersioned() && m_updateItemStatesThread->beginReadItemStates()) { + if (isVersioned() && m_updateItemStatesThread->lockPlugin()) { actions = m_plugin->contextMenuActions(items); - m_updateItemStatesThread->endReadItemStates(); + m_updateItemStatesThread->unlockPlugin(); } return actions; } @@ -101,9 +109,9 @@ QList VersionControlObserver::contextMenuActions(const KFileItemList& QList VersionControlObserver::contextMenuActions(const QString& directory) const { QList actions; - if (isVersioned() && m_updateItemStatesThread->beginReadItemStates()) { + if (isVersioned() && m_updateItemStatesThread->lockPlugin()) { actions = m_plugin->contextMenuActions(directory); - m_updateItemStatesThread->endReadItemStates(); + m_updateItemStatesThread->unlockPlugin(); } return actions; @@ -133,16 +141,7 @@ void VersionControlObserver::verifyDirectory() } m_plugin = searchPlugin(versionControlUrl); - const bool foundVersionInfo = (m_plugin != 0); - if (!foundVersionInfo && m_versionedDirectory) { - // Version control systems like Git provide the version information - // file only in the root directory. Check whether the version information file can - // be found in one of the parent directories. - - // TODO... - } - - if (foundVersionInfo) { + if (m_plugin != 0) { if (!m_versionedDirectory) { m_versionedDirectory = true; @@ -177,11 +176,9 @@ void VersionControlObserver::verifyDirectory() } } -void VersionControlObserver::applyUpdatedItemStates() +void VersionControlObserver::slotThreadFinished() { if (m_plugin == 0) { - // The signal finished() has been emitted, but the thread has been marked - // as invalid in the meantime. Just ignore the signal in this case. return; } @@ -214,7 +211,7 @@ void VersionControlObserver::applyUpdatedItemStates() // operation has been completed because of the icon emblems. emit operationCompletedMessage(QString()); } - + if (m_pendingItemStatesUpdate) { m_pendingItemStatesUpdate = false; updateItemStates(); @@ -227,11 +224,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; } @@ -243,7 +240,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 } } @@ -269,7 +266,7 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director static QList plugins; if (!pluginsAvailable) { - // a searching for plugins has already been done, but no + // A searching for plugins has already been done, but no // plugins are installed return 0; } @@ -277,12 +274,11 @@ 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 QStringList enabledPlugins = VersionControlSettings::enabledPlugins(); const KService::List pluginServices = KServiceTypeTrader::self()->query("FileViewVersionControlPlugin"); for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) { - if (!disabledPluginsList.contains((*it)->name())) { + if (enabledPlugins.contains((*it)->name())) { KVersionControlPlugin* plugin = (*it)->createInstance(); Q_ASSERT(plugin != 0); plugins.append(plugin); @@ -294,15 +290,36 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director } } - // verify whether the current directory contains revision information + // Verify whether the current directory contains revision information // like .svn, .git, ... foreach (KVersionControlPlugin* plugin, plugins) { - KUrl fileUrl = directory; + // Use the KDirLister cache to check for .svn, .git, ... files + KUrl dirUrl(directory); + KUrl fileUrl = dirUrl; fileUrl.addPath(plugin->fileName()); const KFileItem item = m_dirLister->findByUrl(fileUrl); if (!item.isNull()) { return plugin; } + + // Version control systems like Git provide the version information + // file only in the root directory. Check whether the version information file can + // be found in one of the parent directories. For performance reasons this + // step is only done, if the previous directory was marked as versioned by + // m_versionedDirectory. Drawback: Until e. g. Git is recognized, the root directory + // must be shown at least once. + if (m_versionedDirectory) { + KUrl upUrl = dirUrl.upUrl(); + while (upUrl != dirUrl) { + const QString filePath = dirUrl.pathOrUrl(KUrl::AddTrailingSlash) + plugin->fileName(); + QFileInfo file(filePath); + if (file.exists()) { + return plugin; + } + dirUrl = upUrl; + upUrl = dirUrl.upUrl(); + } + } } return 0;