Commit de4e5c31 authored by Nikolai Krasheninnikov's avatar Nikolai Krasheninnikov Committed by Elvis Angelaccio
Browse files

[svn] Added SVN clean up dialog.

Dialog executes 'svn cleanup' command for a user picked directory.
This action is available only for directories.
Added functionality:
- delete unversioned files and folders;
- delete ignored files and folders;
- include externals;
- user can change a directory in a dialog itself by typing it or by
picking it;
- added checks if a directory is valid: for invalid paths "OK" button is
disabled.
parent f8ebbd42
......@@ -9,9 +9,10 @@ set(fileviewsvnplugin_SRCS
svnlogdialog.cpp
svncheckoutdialog.cpp
svnprogressdialog.cpp
svncleanupdialog.cpp
)
ki18n_wrap_ui(fileviewsvnplugin_SRCS svnlogdialog.ui svncheckoutdialog.ui svnprogressdialog.ui)
ki18n_wrap_ui(fileviewsvnplugin_SRCS svnlogdialog.ui svncheckoutdialog.ui svnprogressdialog.ui svncleanupdialog.ui)
kconfig_add_kcfg_files(fileviewsvnplugin_SRCS
fileviewsvnpluginsettings.kcfgc
......
......@@ -48,6 +48,7 @@
#include "svnlogdialog.h"
#include "svncheckoutdialog.h"
#include "svnprogressdialog.h"
#include "svncleanupdialog.h"
#include "svncommands.h"
......@@ -64,6 +65,8 @@ FileViewSvnPlugin::FileViewSvnPlugin(QObject* parent, const QList<QVariant>& arg
m_removeAction(nullptr),
m_showUpdatesAction(nullptr),
m_logAction(nullptr),
m_checkoutAction(nullptr),
m_cleanupAction(nullptr),
m_command(),
m_arguments(),
m_errorMsg(),
......@@ -130,6 +133,11 @@ FileViewSvnPlugin::FileViewSvnPlugin(QObject* parent, const QList<QVariant>& arg
connect(m_checkoutAction, &QAction::triggered,
this, &FileViewSvnPlugin::checkoutDialog);
m_cleanupAction = new QAction(this);
m_cleanupAction->setText(i18nc("@action:inmenu", "SVN Cleanup..."));
connect(m_cleanupAction, &QAction::triggered,
this, &FileViewSvnPlugin::cleanupDialog);
connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &FileViewSvnPlugin::slotOperationCompleted);
connect(&m_process, &QProcess::errorOccurred,
......@@ -489,6 +497,14 @@ void FileViewSvnPlugin::checkoutDialog()
svnCheckoutDialog->show();
}
void FileViewSvnPlugin::cleanupDialog()
{
SvnCleanupDialog *svnCleanupDialog = new SvnCleanupDialog(m_contextDir);
connect(svnCleanupDialog, &SvnCleanupDialog::errorMessage, this, &FileViewSvnPlugin::errorMessage);
connect(svnCleanupDialog, &SvnCleanupDialog::operationCompletedMessage, this, &FileViewSvnPlugin::operationCompletedMessage);
}
void FileViewSvnPlugin::slotOperationCompleted(int exitCode, QProcess::ExitStatus exitStatus)
{
m_pendingOperation = false;
......@@ -727,6 +743,7 @@ QList<QAction*> FileViewSvnPlugin::directoryActions(const KFileItem& directory)
actions.append(m_removeAction);
actions.append(m_revertAction);
actions.append(m_logAction);
actions.append(m_cleanupAction);
return actions;
}
......
......@@ -64,6 +64,7 @@ private slots:
void revertFiles();
void logDialog();
void checkoutDialog();
void cleanupDialog();
void slotOperationCompleted(int exitCode, QProcess::ExitStatus exitStatus);
void slotOperationError();
......@@ -118,6 +119,7 @@ private:
QAction* m_showUpdatesAction;
QAction* m_logAction;
QAction* m_checkoutAction;
QAction* m_cleanupAction;
QString m_command;
QStringList m_arguments;
......
/***************************************************************************
* Copyright (C) 2020 *
* by Nikolai Krasheninnikov <nkrasheninnikov@yandex.ru> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "svncleanupdialog.h"
#include <QFileDialog>
#include <QFileInfo>
#include <QDebug>
#include "svncommands.h"
SvnCleanupDialog::SvnCleanupDialog(const QString& workingDir, QWidget *parent) :
QDialog(parent)
{
m_ui.setupUi(this);
/*
* Add actions, establish connections.
*/
connect(m_ui.buttonCancel, &QPushButton::clicked, this, &QDialog::reject);
QAction *pickDirectory = m_ui.lineEditDirectory->addAction(QIcon::fromTheme("folder"), QLineEdit::TrailingPosition);
connect(pickDirectory, &QAction::triggered, this, [this] () {
const QString dir = QFileDialog::getExistingDirectory(this, i18nc("@title:window", "Choose a directory to clean up"),
m_ui.lineEditDirectory->text(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty()) {
m_ui.lineEditDirectory->setText(dir);
}
} );
/*
* Additional setup.
*/
m_ui.lineEditDirectory->setText(workingDir);
setAttribute(Qt::WA_DeleteOnClose);
show();
activateWindow();
}
SvnCleanupDialog::~SvnCleanupDialog() = default;
void SvnCleanupDialog::on_lineEditDirectory_textChanged(const QString &text)
{
m_ui.buttonOk->setEnabled(QFileInfo(text).isDir());
}
void SvnCleanupDialog::on_buttonOk_clicked()
{
const QString workDir = m_ui.lineEditDirectory->text();
const bool removeUnversioned = m_ui.checkBoxUnversioned->isChecked();
const bool removeIgnored = m_ui.checkBoxIgnored->isChecked();
const bool includeExternals = m_ui.checkBoxExternals->isChecked();
const CommandResult result = SvnCommands::cleanup(workDir, removeUnversioned, removeIgnored, includeExternals);
if (result.success) {
emit operationCompletedMessage(i18nc("@info:status", "SVN clean up completed successfully."));
} else {
emit errorMessage(i18nc("@info:status", "SVN clean up failed for %1", workDir));
qDebug() << result.stderr;
}
QDialog::accept();
}
/***************************************************************************
* Copyright (C) 2020 *
* by Nikolai Krasheninnikov <nkrasheninnikov@yandex.ru> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef SVNCLEANUPDIALOG_H
#define SVNCLEANUPDIALOG_H
#include <QDialog>
#include "ui_svncleanupdialog.h"
/**
* \brief Dialog for SVN cleanup operation.
*
* \note Dialog sets up a Qt::WA_DeleteOnClose attribute so it's delete itself on close.
*/
class SvnCleanupDialog : public QDialog {
Q_OBJECT
public:
/**
* \param[in] workingDir Directory to call 'svn cleanup' on.
* \param[in,out] parent Parent widget.
*/
SvnCleanupDialog(const QString& workingDir, QWidget *parent = nullptr);
virtual ~SvnCleanupDialog() override;
public slots:
void on_lineEditDirectory_textChanged(const QString &text);
void on_buttonOk_clicked();
signals:
/**
* Is emitted if an error occuers with a message \a msg.
*/
void errorMessage(const QString& msg);
/**
* Is emitted for successful operation with a message \a msg.
*/
void operationCompletedMessage(const QString& msg);
private:
Ui::SvnCleanupDialog m_ui;
};
#endif // SVNCLEANUPDIALOG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SvnCleanupDialog</class>
<widget class="QWidget" name="SvnCleanupDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>370</width>
<height>182</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>SVN Cleanup...</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Clean up directory:</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QLineEdit" name="lineEditDirectory">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QCheckBox" name="checkBoxUnversioned">
<property name="text">
<string>Delete unversioned files and directories</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="checkBoxIgnored">
<property name="text">
<string>Delete ignored files and directories</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkBoxExternals">
<property name="text">
<string>Include externals</string>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QPushButton" name="buttonOk">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>OK</string>
</property>
<property name="icon">
<iconset theme="dialog-ok">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QPushButton" name="buttonCancel">
<property name="text">
<string>Cancel</string>
</property>
<property name="icon">
<iconset theme="dialog-cancel">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
......@@ -285,7 +285,7 @@ bool SvnCommands::revertToRevision(const QString& filePath, ulong revision)
return true;
}
bool SvnCommands::cleanup(const QString& dir, bool removeUnversioned, bool removeIgnored, bool includeExternals)
CommandResult SvnCommands::cleanup(const QString& dir, bool removeUnversioned, bool removeIgnored, bool includeExternals)
{
QStringList arguments;
arguments << QStringLiteral("cleanup") << dir;
......@@ -305,11 +305,16 @@ bool SvnCommands::cleanup(const QString& dir, bool removeUnversioned, bool remov
arguments
);
CommandResult result;
if (!process.waitForFinished() || process.exitCode() != 0) {
return false;
result.success = false;
} else {
return true;
result.success = true;
}
result.stdout = process.readAllStandardOutput();
result.stderr = process.readAllStandardError();
return result;
}
bool SvnCommands::exportFile(const QUrl& path, ulong rev, QFileDevice *file)
......
......@@ -30,6 +30,15 @@
class QTemporaryFile;
class QFileDevice;
/**
* SVN commands execution results.
*/
struct CommandResult {
bool success; ///< True if return code is '0' (normal execution).
QString stdout; ///< Process stdout.
QString stderr; ///< Process stderr.
};
/**
* Path information for log entry.
*/
......@@ -153,9 +162,9 @@ public:
* restores directory state if Subversion client has crushed.
* Also this command could be used to remove unversioned or ignored files.
*
* \return True on success, false either.
* \return Filled up \p commandResult structure.
*/
static bool cleanup(const QString& dir, bool removeUnversioned = false, bool removeIgnored = false, bool includeExternals = false);
static CommandResult cleanup(const QString& dir, bool removeUnversioned = false, bool removeIgnored = false, bool includeExternals = false);
/**
* Export URL \p path at revision \p rev to a file \p file. URL could be a remote URL to a file
......
......@@ -112,8 +112,10 @@ void SvnProgressDialog::operationCompeleted()
disconnectFromProcess();
if (m_svnTerminated && !m_workingDir.isEmpty()) {
if (!SvnCommands::cleanup(m_workingDir)) {
qDebug() << QString("'svn cleanup' failed for %1").arg(m_workingDir);
const CommandResult result = SvnCommands::cleanup(m_workingDir);
if (!result.success) {
qWarning() << QString("'svn cleanup' failed for %1").arg(m_workingDir);
qWarning() << result.stderr;
}
m_svnTerminated = false;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment