From 66ad27aba14cdfea777b9ebe1beb161f80f26463 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Mon, 27 Jul 2009 05:31:48 +0000 Subject: Improved Subversion test plugin to allow committing, updating, diffing, adding and removing of files. As soon as the test plugin gets moved to kdesdk, the code should be improved to use the libsvn interface. svn path=/trunk/KDE/kdebase/apps/; revision=1002839 --- src/revisioncontrolplugin.cpp | 177 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 146 insertions(+), 31 deletions(-) (limited to 'src/revisioncontrolplugin.cpp') diff --git a/src/revisioncontrolplugin.cpp b/src/revisioncontrolplugin.cpp index b3b407c61..1e19ddcf0 100644 --- a/src/revisioncontrolplugin.cpp +++ b/src/revisioncontrolplugin.cpp @@ -19,14 +19,6 @@ #include "revisioncontrolplugin.h" -#include -#include -#include -#include -#include -#include -#include - RevisionControlPlugin::RevisionControlPlugin() { } @@ -39,28 +31,59 @@ RevisionControlPlugin::~RevisionControlPlugin() // ---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + SubversionPlugin::SubversionPlugin() : - m_directory(), + m_retrievalDir(), m_revisionInfoHash(), m_updateAction(0), + m_showLocalChangesAction(0), m_commitAction(0), m_addAction(0), - m_removeAction(0) + m_removeAction(0), + m_contextDir(), + m_contextItems() { m_updateAction = new KAction(this); m_updateAction->setIcon(KIcon("view-refresh")); m_updateAction->setText(i18nc("@item:inmenu", "SVN Update")); + connect(m_updateAction, SIGNAL(triggered()), + this, SLOT(updateFiles())); + + m_showLocalChangesAction = new KAction(this); + m_showLocalChangesAction->setIcon(KIcon("view-split-left-right")); + m_showLocalChangesAction->setText(i18nc("@item:inmenu", "Show Local SVN Changes")); + connect(m_showLocalChangesAction, SIGNAL(triggered()), + this, SLOT(showLocalChanges())); m_commitAction = new KAction(this); m_commitAction->setText(i18nc("@item:inmenu", "SVN Commit...")); + connect(m_commitAction, SIGNAL(triggered()), + this, SLOT(commitFiles())); m_addAction = new KAction(this); m_addAction->setIcon(KIcon("list-add")); m_addAction->setText(i18nc("@item:inmenu", "SVN Add")); + connect(m_addAction, SIGNAL(triggered()), + this, SLOT(addFiles())); m_removeAction = new KAction(this); m_removeAction->setIcon(KIcon("list-remove")); m_removeAction->setText(i18nc("@item:inmenu", "SVN Delete")); + connect(m_removeAction, SIGNAL(triggered()), + this, SLOT(removeFiles())); } SubversionPlugin::~SubversionPlugin() @@ -75,7 +98,7 @@ QString SubversionPlugin::fileName() const bool SubversionPlugin::beginRetrieval(const QString& directory) { Q_ASSERT(directory.endsWith('/')); - m_directory = directory; + m_retrievalDir = directory; const QString path = directory + ".svn/text-base/"; QDir dir(path); @@ -83,15 +106,16 @@ bool SubversionPlugin::beginRetrieval(const QString& directory) const int size = fileInfoList.size(); QString fileName; for (int i = 0; i < size; ++i) { - fileName = fileInfoList.at(i).fileName(); + const QFileInfo fileInfo = fileInfoList.at(i); + fileName = fileInfo.fileName(); // Remove the ".svn-base" postfix to be able to compare the filenames // in a fast way in SubversionPlugin::revisionState(). fileName.chop(sizeof(".svn-base") / sizeof(char) - 1); if (!fileName.isEmpty()) { RevisionInfo info; - info.size = fileInfoList.at(i).size(); - info.timeStamp = fileInfoList.at(i).lastModified(); - m_revisionInfoHash.insert(fileName, info); + info.size = fileInfo.size(); + info.timeStamp = fileInfo.lastModified(); + m_revisionInfoHash.insert(directory + fileName, info); } } return size > 0; @@ -103,37 +127,63 @@ void SubversionPlugin::endRetrieval() RevisionControlPlugin::RevisionState SubversionPlugin::revisionState(const KFileItem& item) { - const QString name = item.name(); + const QString itemUrl = item.localPath(); if (item.isDir()) { - QFile file(m_directory + name + "/.svn"); + QFile file(itemUrl + "/.svn"); if (file.open(QIODevice::ReadOnly)) { file.close(); - // TODO... - return RevisionControlPlugin::LatestRevision; + return RevisionControlPlugin::NormalRevision; } - } else if (m_revisionInfoHash.contains(name)) { - const RevisionInfo info = m_revisionInfoHash.value(item.name()); + } else if (m_revisionInfoHash.contains(itemUrl)) { + const RevisionInfo info = m_revisionInfoHash.value(itemUrl); const QDateTime localTimeStamp = item.time(KFileItem::ModificationTime).dateTime(); const QDateTime versionedTimeStamp = info.timeStamp; if (localTimeStamp > versionedTimeStamp) { if ((info.size != item.size()) || !equalRevisionContent(item.name())) { - return RevisionControlPlugin::EditingRevision; + return RevisionControlPlugin::LocallyModifiedRevision; } } else if (localTimeStamp < versionedTimeStamp) { if ((info.size != item.size()) || !equalRevisionContent(item.name())) { return RevisionControlPlugin::UpdateRequiredRevision; } } - return RevisionControlPlugin::LatestRevision; + return RevisionControlPlugin::NormalRevision; } - return RevisionControlPlugin::LocalRevision; + return RevisionControlPlugin::UnversionedRevision; } -QList SubversionPlugin::contextMenuActions(const KFileItemList& items) const +QList SubversionPlugin::contextMenuActions(const KFileItemList& items) { - Q_UNUSED(items); + Q_ASSERT(!items.isEmpty()); + + m_contextItems = items; + m_contextDir.clear(); + + // iterate all items and check the revision state to know which + // actions can be enabled + const int itemsCount = items.count(); + int revisionedCount = 0; + int editingCount = 0; + foreach (const KFileItem& item, items) { + const RevisionState state = revisionState(item); + if (state != UnversionedRevision) { + ++revisionedCount; + } + + switch (state) { + case LocallyModifiedRevision: + case ConflictingRevision: + ++editingCount; + break; + default: + break; + } + } + m_commitAction->setEnabled(editingCount > 0); + m_addAction->setEnabled(revisionedCount == 0); + m_removeAction->setEnabled(revisionedCount == itemsCount); QList actions; actions.append(m_updateAction); @@ -143,24 +193,90 @@ QList SubversionPlugin::contextMenuActions(const KFileItemList& items) return actions; } -QList SubversionPlugin::contextMenuActions(const QString& directory) const +QList SubversionPlugin::contextMenuActions(const QString& directory) { - Q_UNUSED(directory); + m_contextDir = directory; + m_contextItems.clear(); QList actions; actions.append(m_updateAction); + actions.append(m_showLocalChangesAction); actions.append(m_commitAction); return actions; } +void SubversionPlugin::updateFiles() +{ + execSvnCommand("update"); +} + +void SubversionPlugin::showLocalChanges() +{ + Q_ASSERT(!m_contextDir.isEmpty()); + Q_ASSERT(m_contextItems.isEmpty()); + + const QString command = "mkfifo /tmp/fifo; svn diff " + + KShell::quoteArg(m_contextDir) + + " > /tmp/fifo & kompare /tmp/fifo; rm /tmp/fifo"; + KRun::runCommand(command, 0); +} + +void SubversionPlugin::commitFiles() +{ + KDialog dialog(0, Qt::Dialog); + + KVBox* box = new KVBox(&dialog); + new QLabel(i18nc("@label", "Description:"), box); + QTextEdit* editor = new QTextEdit(box); + + dialog.setMainWidget(box); + dialog.setCaption(i18nc("@title:window", "SVN Commit")); + dialog.setButtons(KDialog::Ok | KDialog::Cancel); + dialog.setDefaultButton(KDialog::Ok); + dialog.setButtonText(KDialog::Ok, i18nc("@action:button", "Commit")); + + KConfigGroup dialogConfig(KSharedConfig::openConfig("dolphinrc"), + "SvnCommitDialog"); + dialog.restoreDialogSize(dialogConfig); + + if (dialog.exec() == QDialog::Accepted) { + const QString description = editor->toPlainText(); + execSvnCommand("commit -m " + KShell::quoteArg(description)); + } + + dialog.saveDialogSize(dialogConfig, KConfigBase::Persistent); +} + +void SubversionPlugin::addFiles() +{ + execSvnCommand("add"); +} + +void SubversionPlugin::removeFiles() +{ + execSvnCommand("remove"); +} + +void SubversionPlugin::execSvnCommand(const QString& svnCommand) +{ + const QString command = "svn " + svnCommand + ' '; + if (!m_contextDir.isEmpty()) { + KRun::runCommand(command + KShell::quoteArg(m_contextDir), 0); + } else { + foreach (const KFileItem& item, m_contextItems) { + KRun::runCommand(command + KShell::quoteArg(item.localPath()), 0); + } + } +} + bool SubversionPlugin::equalRevisionContent(const QString& name) const { - QFile localFile(m_directory + '/' + name); + QFile localFile(m_retrievalDir + '/' + name); if (!localFile.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } - QFile revisionedFile(m_directory + "/.svn/text-base/" + name + ".svn-base"); + QFile revisionedFile(m_retrievalDir + "/.svn/text-base/" + name + ".svn-base"); if (!revisionedFile.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } @@ -175,4 +291,3 @@ bool SubversionPlugin::equalRevisionContent(const QString& name) const return localText.atEnd() && revisionedText.atEnd(); } - -- cgit v1.3