#include "dolphin_versioncontrolsettings.h"
-#include <KDirLister>
#include <KLocale>
#include <KService>
#include <KServiceTypeTrader>
#include <kitemviews/kfileitemmodel.h>
-#include <kversioncontrolplugin.h>
+#include <kversioncontrolplugin2.h>
-#include "pendingthreadsmaintainer.h"
#include "updateitemstatesthread.h"
+#include <QFile>
#include <QMutexLocker>
#include <QTimer>
VersionControlObserver::~VersionControlObserver()
{
- if (m_updateItemStatesThread) {
- 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, 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;
- }
- }
-
if (m_plugin) {
- m_plugin->disconnect();
+ m_plugin->disconnect(this);
m_plugin = 0;
}
}
if (m_model) {
disconnect(m_model, SIGNAL(itemsInserted(KItemRangeList)),
this, SLOT(delayedDirectoryVerification()));
+ disconnect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
+ this, SLOT(delayedDirectoryVerification()));
}
m_model = model;
if (model) {
connect(m_model, SIGNAL(itemsInserted(KItemRangeList)),
this, SLOT(delayedDirectoryVerification()));
+ connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
+ this, SLOT(delayedDirectoryVerification()));
}
}
return m_model;
}
-QList<QAction*> VersionControlObserver::contextMenuActions(const KFileItemList& items) const
+QList<QAction*> VersionControlObserver::actions(const KFileItemList& items) const
{
QList<QAction*> actions;
- if (isVersioned() && m_updateItemStatesThread->lockPlugin()) {
- actions = m_plugin->contextMenuActions(items);
- m_updateItemStatesThread->unlockPlugin();
+
+ bool hasNullItems = false;
+ foreach (const KFileItem& item, items) {
+ if (item.isNull()) {
+ kWarning() << "Requesting version-control-actions for empty items";
+ hasNullItems = true;
+ break;
+ }
}
- return actions;
-}
-QList<QAction*> VersionControlObserver::contextMenuActions(const QString& directory) const
-{
- QList<QAction*> actions;
- if (isVersioned() && m_updateItemStatesThread->lockPlugin()) {
- actions = m_plugin->contextMenuActions(directory);
- m_updateItemStatesThread->unlockPlugin();
+ if (!m_model || hasNullItems) {
+ return actions;
+ }
+
+ KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin);
+ if (pluginV2) {
+ // Use version 2 of the KVersionControlPlugin which allows providing actions
+ // also for non-versioned directories.
+ actions = pluginV2->actions(items);
+ } else if (isVersioned()) {
+ // Support deprecated interfaces from KVersionControlPlugin version 1.
+ // Context menu actions where only available for versioned directories.
+ QString directory;
+ if (items.count() == 1) {
+ const KFileItem rootItem = m_model->rootItem();
+ if (!rootItem.isNull() && items.first().url() == rootItem.url()) {
+ directory = rootItem.url().path(KUrl::AddTrailingSlash);
+ }
+ }
+
+ actions = directory.isEmpty() ? m_plugin->contextMenuActions(items)
+ : m_plugin->contextMenuActions(directory);
}
return actions;
return;
}
- const KUrl versionControlUrl = m_model->rootDirectory();
- if (!versionControlUrl.isLocalFile()) {
+ const KFileItem rootItem = m_model->rootItem();
+ if (rootItem.isNull() || !rootItem.url().isLocalFile()) {
return;
}
if (m_plugin) {
- m_plugin->disconnect();
+ m_plugin->disconnect(this);
}
- m_plugin = searchPlugin(versionControlUrl);
+ m_plugin = searchPlugin(rootItem.url());
if (m_plugin) {
- connect(m_plugin, SIGNAL(versionStatesChanged()),
- this, SLOT(silentDirectoryVerification()));
+ KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin);
+ if (pluginV2) {
+ connect(pluginV2, SIGNAL(itemVersionsChanged()),
+ this, SLOT(silentDirectoryVerification()));
+ } else {
+ connect(m_plugin, SIGNAL(versionStatesChanged()),
+ this, SLOT(silentDirectoryVerification()));
+ }
connect(m_plugin, SIGNAL(infoMessage(QString)),
this, SIGNAL(infoMessage(QString)));
connect(m_plugin, SIGNAL(errorMessage(QString)),
void VersionControlObserver::slotThreadFinished()
{
- if (!m_plugin) {
+ UpdateItemStatesThread* thread = m_updateItemStatesThread;
+ m_updateItemStatesThread = 0; // The thread deletes itself automatically (see updateItemStates())
+
+ if (!m_plugin || !thread) {
return;
}
- if (!m_updateItemStatesThread->retrievedItems()) {
+ if (!thread->retrievedItems()) {
// Ignore m_silentUpdate for an error message
emit errorMessage(i18nc("@info:status", "Update of version information failed."));
return;
}
- const QList<ItemState> itemStates = m_updateItemStatesThread->itemStates();
+ const QList<ItemState> itemStates = thread->itemStates();
foreach (const ItemState& itemState, itemStates) {
QHash<QByteArray, QVariant> values;
values.insert("version", QVariant(itemState.version));
void VersionControlObserver::updateItemStates()
{
Q_ASSERT(m_plugin);
- if (!m_updateItemStatesThread) {
- m_updateItemStatesThread = new UpdateItemStatesThread();
- connect(m_updateItemStatesThread, SIGNAL(finished()),
- this, SLOT(slotThreadFinished()));
- }
- if (m_updateItemStatesThread->isRunning()) {
+ if (m_updateItemStatesThread) {
// An update is currently ongoing. Wait until the thread has finished
// the update (see slotThreadFinished()).
m_pendingItemStatesUpdate = true;
return;
}
-
QList<ItemState> itemStates;
const int itemCount = m_model->count();
itemStates.reserve(itemCount);
ItemState itemState;
itemState.index = i;
itemState.item = m_model->fileItem(i);
- itemState.version = KVersionControlPlugin::UnversionedVersion;
+ itemState.version = KVersionControlPlugin2::UnversionedVersion;
itemStates.append(itemState);
}
if (!m_silentUpdate) {
emit infoMessage(i18nc("@info:status", "Updating version information..."));
}
- m_updateItemStatesThread->setData(m_plugin, itemStates);
+ m_updateItemStatesThread = new UpdateItemStatesThread(m_plugin, itemStates);
+ connect(m_updateItemStatesThread, SIGNAL(finished()),
+ this, SLOT(slotThreadFinished()));
+ connect(m_updateItemStatesThread, SIGNAL(finished()),
+ m_updateItemStatesThread, SLOT(deleteLater()));
+
m_updateItemStatesThread->start(); // slotThreadFinished() is called when finished
}
}
// Verify whether the current directory contains revision information
// like .svn, .git, ...
- Q_UNUSED(directory);
foreach (KVersionControlPlugin* plugin, plugins) {
- // Use the KDirLister cache to check for .svn, .git, ... files
const QString fileName = directory.path(KUrl::AddTrailingSlash) + plugin->fileName();
if (QFile::exists(fileName)) {
return plugin;
bool VersionControlObserver::isVersioned() const
{
- return false; //m_dolphinModel->hasVersionData() && m_plugin;
+ return m_versionedDirectory && m_plugin;
}
#include "versioncontrolobserver.moc"