X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/a2913a020520d9a461be9c9d596f9ae4f2454947..79a6e75b6567e8cf2ef677cea6bb2c34075d07c7:/src/revisioncontrolplugin.cpp diff --git a/src/revisioncontrolplugin.cpp b/src/revisioncontrolplugin.cpp index a5cfba5b9..683398879 100644 --- a/src/revisioncontrolplugin.cpp +++ b/src/revisioncontrolplugin.cpp @@ -19,8 +19,6 @@ #include "revisioncontrolplugin.h" -#include - RevisionControlPlugin::RevisionControlPlugin() { } @@ -35,15 +33,17 @@ RevisionControlPlugin::~RevisionControlPlugin() #include #include +#include #include #include #include #include -#include #include #include #include +#include #include +#include #include #include @@ -55,8 +55,12 @@ SubversionPlugin::SubversionPlugin() : m_commitAction(0), m_addAction(0), m_removeAction(0), + m_command(), + m_errorMsg(), + m_operationCompletedMsg(), m_contextDir(), - m_contextItems() + m_contextItems(), + m_tempFile() { m_updateAction = new KAction(this); m_updateAction->setIcon(KIcon("view-refresh")); @@ -101,33 +105,39 @@ bool SubversionPlugin::beginRetrieval(const QString& directory) { Q_ASSERT(directory.endsWith('/')); - const QString statusCommand = "svn status " + directory; - FILE* in = popen(statusCommand.toAscii().data(), "r"); - if (in == 0) { - return false; - } - - char buffer[1024]; - while (fgets(buffer, sizeof(buffer), in) != 0) { - RevisionState state = NormalRevision; - - switch (buffer[0]) { - case '?': state = UnversionedRevision; break; - case 'M': state = LocallyModifiedRevision; break; - case 'A': state = AddedRevision; break; - case 'D': state = RemovedRevision; break; - case 'C': state = ConflictingRevision; break; - default: break; - } + QStringList arguments; + arguments << "status" << "--show-updates" << directory; + + QProcess process; + process.start("svn", arguments); + while (process.waitForReadyRead()) { + char buffer[1024]; + while (process.readLine(buffer, sizeof(buffer)) > 0) { + RevisionState state = NormalRevision; + QString filePath(buffer); + + switch (buffer[0]) { + case '?': state = UnversionedRevision; break; + case 'M': state = LocallyModifiedRevision; break; + case 'A': state = AddedRevision; break; + case 'D': state = RemovedRevision; break; + case 'C': state = ConflictingRevision; break; + default: + if (filePath.contains('*')) { + state = UpdateRequiredRevision; + } + break; + } - QString filePath(buffer); - int pos = filePath.indexOf('/'); - const int length = filePath.length() - pos - 1; - filePath = filePath.mid(pos, length); - if (!filePath.isEmpty()) { - m_revisionInfoHash.insert(filePath, state); + int pos = filePath.indexOf('/'); + const int length = filePath.length() - pos - 1; + filePath = filePath.mid(pos, length); + if (!filePath.isEmpty()) { + m_revisionInfoHash.insert(filePath, state); + } } } + m_revisionInfoKeys = m_revisionInfoHash.keys(); return true; } @@ -167,8 +177,9 @@ RevisionControlPlugin::RevisionState SubversionPlugin::revisionState(const KFile QList SubversionPlugin::contextMenuActions(const KFileItemList& items) { Q_ASSERT(!items.isEmpty()); - - m_contextItems = items; + foreach (const KFileItem& item, items) { + m_contextItems.append(item); + } m_contextDir.clear(); // iterate all items and check the revision state to know which @@ -205,8 +216,17 @@ QList SubversionPlugin::contextMenuActions(const KFileItemList& items) QList SubversionPlugin::contextMenuActions(const QString& directory) { - m_contextDir = directory; - m_contextItems.clear(); + const bool enabled = m_contextItems.isEmpty(); + if (enabled) { + m_contextDir = directory; + } + + // Only enable the SVN actions if no SVN commands are + // executed currently (see slotOperationCompleted() and + // startSvnCommandProcess()). + m_updateAction->setEnabled(enabled); + m_showLocalChangesAction->setEnabled(enabled); + m_commitAction->setEnabled(enabled); QList actions; actions.append(m_updateAction); @@ -217,7 +237,10 @@ QList SubversionPlugin::contextMenuActions(const QString& directory) void SubversionPlugin::updateFiles() { - execSvnCommand("update"); + execSvnCommand("update", + i18nc("@info:status", "Updating SVN repository..."), + i18nc("@info:status", "Update of SVN repository failed."), + i18nc("@info:status", "Updated SVN repository.")); } void SubversionPlugin::showLocalChanges() @@ -250,8 +273,24 @@ void SubversionPlugin::commitFiles() dialog.restoreDialogSize(dialogConfig); if (dialog.exec() == QDialog::Accepted) { - const QString description = editor->toPlainText(); - execSvnCommand("commit -m " + KShell::quoteArg(description)); + // Write the commit description into a temporary file, so + // that it can be read by the command "svn commit -F". The temporary + // file must stay alive until slotOperationCompleted() is invoked and will + // be destroyed when the revision plugin is destructed. + if (!m_tempFile.open()) { + emit errorMessage(i18nc("@info:status", "Commit of SVN changes failed.")); + return; + } + + QTextStream out(&m_tempFile); + const QString fileName = m_tempFile.fileName(); + out << editor->toPlainText(); + m_tempFile.close(); + + execSvnCommand("commit -F " + KShell::quoteArg(fileName), + i18nc("@info:status", "Committing SVN changes..."), + i18nc("@info:status", "Commit of SVN changes failed."), + i18nc("@info:status", "Committed SVN changes.")); } dialog.saveDialogSize(dialogConfig, KConfigBase::Persistent); @@ -259,22 +298,68 @@ void SubversionPlugin::commitFiles() void SubversionPlugin::addFiles() { - execSvnCommand("add"); + execSvnCommand("add", + i18nc("@info:status", "Adding files to SVN repository..."), + i18nc("@info:status", "Adding of files to SVN repository failed."), + i18nc("@info:status", "Added files to SVN repository.")); } void SubversionPlugin::removeFiles() { - execSvnCommand("remove"); + execSvnCommand("remove", + i18nc("@info:status", "Removing files from SVN repository..."), + i18nc("@info:status", "Removing of files from SVN repository failed."), + i18nc("@info:status", "Removed files from SVN repository.")); } -void SubversionPlugin::execSvnCommand(const QString& svnCommand) +void SubversionPlugin::slotOperationCompleted() { - const QString command = "svn " + svnCommand + ' '; + if (m_contextItems.isEmpty()) { + emit operationCompletedMessage(m_operationCompletedMsg); + emit revisionStatesChanged(); + } else { + startSvnCommandProcess(); + } +} + +void SubversionPlugin::slotOperationError() +{ + emit errorMessage(m_errorMsg); + + // don't do any operation on other items anymore + m_contextItems.clear(); +} + +void SubversionPlugin::execSvnCommand(const QString& svnCommand, + const QString& infoMsg, + const QString& errorMsg, + const QString& operationCompletedMsg) +{ + emit infoMessage(infoMsg); + + m_command = svnCommand; + m_errorMsg = errorMsg; + m_operationCompletedMsg = operationCompletedMsg; + + startSvnCommandProcess(); +} + +void SubversionPlugin::startSvnCommandProcess() +{ + QProcess* process = new QProcess(this); + connect(process, SIGNAL(finished(int)), + this, SLOT(slotOperationCompleted())); + connect(process, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(slotOperationError())); + + const QString program = "svn " + m_command + ' '; if (!m_contextDir.isEmpty()) { - KRun::runCommand(command + KShell::quoteArg(m_contextDir), 0); + process->start(program + KShell::quoteArg(m_contextDir)); + m_contextDir.clear(); } else { - foreach (const KFileItem& item, m_contextItems) { - KRun::runCommand(command + KShell::quoteArg(item.localPath()), 0); - } + const KFileItem item = m_contextItems.takeLast(); + process->start(program + KShell::quoteArg(item.localPath())); + // the remaining items of m_contextItems will be executed + // after the process has finished (see slotOperationFinished()) } }