X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/e164a139cff331663660513d42edd44976fa240c..78d4fffee8694281190ceab84f47bd2f2dfc8235:/src/versioncontrol/versioncontrolobserver.cpp diff --git a/src/versioncontrol/versioncontrolobserver.cpp b/src/versioncontrol/versioncontrolobserver.cpp index aa78e7e4f..744d81f4f 100644 --- a/src/versioncontrol/versioncontrolobserver.cpp +++ b/src/versioncontrol/versioncontrolobserver.cpp @@ -28,6 +28,7 @@ #include #include +#include "pendingthreadsmaintainer.h" #include "updateitemstatesthread.h" #include @@ -35,18 +36,6 @@ #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), @@ -69,7 +58,7 @@ VersionControlObserver::VersionControlObserver(QAbstractItemView* view) : m_dirLister = m_dolphinModel->dirLister(); connect(m_dirLister, SIGNAL(completed()), this, SLOT(delayedDirectoryVerification())); - + // The verification timer specifies the timeout until the shown directory // is checked whether it is versioned. Per default it is assumed that users // don't iterate through versioned directories and a high timeout is used @@ -92,14 +81,11 @@ VersionControlObserver::~VersionControlObserver() } 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. + // user interface, the thread will be forwarded to the + // PendingThreadsMaintainer, which will delete the thread later. disconnect(m_updateItemStatesThread, SIGNAL(finished()), this, SLOT(slotThreadFinished())); - s_pendingThreads->list.append(m_updateItemStatesThread); + PendingThreadsMaintainer::instance().append(m_updateItemStatesThread); m_updateItemStatesThread = 0; } } @@ -113,9 +99,9 @@ VersionControlObserver::~VersionControlObserver() 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; } @@ -123,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; @@ -145,20 +131,7 @@ 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(); + const KUrl versionControlUrl = m_dirLister->url(); if (!versionControlUrl.isLocalFile()) { return; } @@ -168,16 +141,16 @@ 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 (m_plugin != 0) { + connect(m_plugin, SIGNAL(versionStatesChanged()), + this, SLOT(silentDirectoryVerification())); + connect(m_plugin, SIGNAL(infoMessage(QString)), + this, SIGNAL(infoMessage(QString))); + connect(m_plugin, SIGNAL(errorMessage(QString)), + this, SIGNAL(errorMessage(QString))); + connect(m_plugin, SIGNAL(operationCompletedMessage(QString)), + this, SIGNAL(operationCompletedMessage(QString))); - if (foundVersionInfo) { if (!m_versionedDirectory) { m_versionedDirectory = true; @@ -188,14 +161,6 @@ void VersionControlObserver::verifyDirectory() this, SLOT(delayedDirectoryVerification())); connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)), this, SLOT(delayedDirectoryVerification())); - connect(m_plugin, SIGNAL(versionStatesChanged()), - this, SLOT(silentDirectoryVerification())); - connect(m_plugin, SIGNAL(infoMessage(const QString&)), - this, SIGNAL(infoMessage(const QString&))); - connect(m_plugin, SIGNAL(errorMessage(const QString&)), - this, SIGNAL(errorMessage(const QString&))); - connect(m_plugin, SIGNAL(operationCompletedMessage(const QString&)), - this, SIGNAL(operationCompletedMessage(const QString&))); } updateItemStates(); } else if (m_versionedDirectory) { @@ -268,7 +233,7 @@ void VersionControlObserver::updateItemStates() m_pendingItemStatesUpdate = true; return; } - + QList itemStates; addDirectory(QModelIndex(), itemStates); if (!itemStates.isEmpty()) { @@ -286,7 +251,7 @@ void VersionControlObserver::addDirectory(const QModelIndex& parentIndex, QList< for (int row = 0; row < rowCount; ++row) { const QModelIndex index = m_dolphinModel->index(row, DolphinModel::Version, parentIndex); addDirectory(index, itemStates); - + ItemState itemState; itemState.index = index; itemState.item = m_dolphinModel->itemForIndex(index); @@ -302,7 +267,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; } @@ -310,12 +275,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); @@ -327,15 +291,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;