diff options
Diffstat (limited to 'src/revisioncontrolplugin.cpp')
| -rw-r--r-- | src/revisioncontrolplugin.cpp | 177 |
1 files changed, 146 insertions, 31 deletions
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 <kaction.h> -#include <kicon.h> -#include <klocale.h> -#include <kfileitem.h> -#include <QDir> -#include <QString> -#include <QTextStream> - RevisionControlPlugin::RevisionControlPlugin() { } @@ -39,28 +31,59 @@ RevisionControlPlugin::~RevisionControlPlugin() // ---------------------------------------------------------------------------- +#include <kaction.h> +#include <kdialog.h> +#include <kicon.h> +#include <klocale.h> +#include <krun.h> +#include <kshell.h> +#include <kfileitem.h> +#include <kvbox.h> +#include <QDir> +#include <QLabel> +#include <QString> +#include <QTextEdit> +#include <QTextStream> + 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<QAction*> SubversionPlugin::contextMenuActions(const KFileItemList& items) const +QList<QAction*> 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<QAction*> actions; actions.append(m_updateAction); @@ -143,24 +193,90 @@ QList<QAction*> SubversionPlugin::contextMenuActions(const KFileItemList& items) return actions; } -QList<QAction*> SubversionPlugin::contextMenuActions(const QString& directory) const +QList<QAction*> SubversionPlugin::contextMenuActions(const QString& directory) { - Q_UNUSED(directory); + m_contextDir = directory; + m_contextItems.clear(); QList<QAction*> 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(); } - |
