From: Peter Penz Date: Wed, 29 Jul 2009 21:56:37 +0000 (+0000) Subject: Allow the revision control plugins to indicate information-, error- and operation... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/a70be712fd5b33071c4733c47f810948d86dd4d8 Allow the revision control plugins to indicate information-, error- and operation-completed messages. svn path=/trunk/KDE/kdebase/apps/; revision=1004346 --- diff --git a/src/dolphinpart.cpp b/src/dolphinpart.cpp index b8a39cffc..6452ba36a 100644 --- a/src/dolphinpart.cpp +++ b/src/dolphinpart.cpp @@ -92,7 +92,9 @@ DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantL setXMLFile("dolphinpart.rc"); connect(m_view, SIGNAL(infoMessage(QString)), - this, SLOT(slotInfoMessage(QString))); + this, SLOT(slotMessage(QString))); + connect(m_view, SIGNAL(operationCompletedMessage(QString)), + this, SLOT(slotMessage(QString))); connect(m_view, SIGNAL(errorMessage(QString)), this, SLOT(slotErrorMessage(QString))); connect(m_view, SIGNAL(itemTriggered(KFileItem)), @@ -306,7 +308,7 @@ void DolphinPart::slotCanceled(const KUrl& url) slotCompleted(url); } -void DolphinPart::slotInfoMessage(const QString& msg) +void DolphinPart::slotMessage(const QString& msg) { emit setStatusBarText(msg); } diff --git a/src/dolphinpart.h b/src/dolphinpart.h index 4a030af89..66f397589 100644 --- a/src/dolphinpart.h +++ b/src/dolphinpart.h @@ -113,7 +113,7 @@ Q_SIGNALS: private Q_SLOTS: void slotCompleted(const KUrl& url); void slotCanceled(const KUrl& url); - void slotInfoMessage(const QString& msg); + void slotMessage(const QString& msg); void slotErrorMessage(const QString& msg); /** * Shows the information for the item \a item inside the statusbar. If the diff --git a/src/dolphinstatusbar.cpp b/src/dolphinstatusbar.cpp index 7a9b5dc8a..591a45c03 100644 --- a/src/dolphinstatusbar.cpp +++ b/src/dolphinstatusbar.cpp @@ -124,7 +124,14 @@ DolphinStatusBar::~DolphinStatusBar() void DolphinStatusBar::setMessage(const QString& msg, Type type) { + if (msg.isEmpty()) { + // show the default text as fallback + clear(); + return; + } + if ((msg == m_messageLabel->text()) && (type == m_messageLabel->type())) { + // the message is already shown return; } diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index 2fc664f21..589940479 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -1474,6 +1474,12 @@ void DolphinView::createView() m_previewGenerator->setPreviewShown(m_showPreview); m_revisionControlObserver = new RevisionControlObserver(view); + connect(m_revisionControlObserver, SIGNAL(infoMessage(const QString&)), + this, SIGNAL(infoMessage(const QString&))); + connect(m_revisionControlObserver, SIGNAL(errorMessage(const QString&)), + this, SIGNAL(errorMessage(const QString&))); + connect(m_revisionControlObserver, SIGNAL(operationCompletedMessage(const QString&)), + this, SIGNAL(operationCompletedMessage(const QString&))); if (DolphinSettings::instance().generalSettings()->showToolTips()) { m_toolTipManager = new ToolTipManager(view, m_proxyModel); diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 3111925ff..475b002e2 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -335,7 +335,13 @@ void DolphinViewContainer::slotDirListerCompleted() void DolphinViewContainer::showItemInfo(const KFileItem& item) { if (item.isNull()) { - m_statusBar->clear(); + // Only clear the status bar if unimportant messages are shown. + // This prevents that information- or error-messages get hidden + // by moving the mouse above the viewport or when closing the + // context menu. + if (m_statusBar->type() == DolphinStatusBar::Default) { + m_statusBar->clear(); + } } else { m_statusBar->setMessage(item.getStatusBarInfo(), DolphinStatusBar::Default); } diff --git a/src/revisioncontrolobserver.cpp b/src/revisioncontrolobserver.cpp index 1e7347a9b..7745dbe43 100644 --- a/src/revisioncontrolobserver.cpp +++ b/src/revisioncontrolobserver.cpp @@ -23,6 +23,7 @@ #include "revisioncontrolplugin.h" #include +#include #include #include @@ -41,11 +42,13 @@ public: void setData(RevisionControlPlugin* plugin, const QList& itemStates); QList itemStates() const; - + bool retrievedItems() const; + protected: virtual void run(); private: + bool m_retrievedItems; RevisionControlPlugin* m_plugin; QMutex* m_pluginMutex; QList m_itemStates; @@ -53,7 +56,9 @@ private: UpdateItemStatesThread::UpdateItemStatesThread(QObject* parent, QMutex* pluginMutex) : QThread(parent), - m_pluginMutex(pluginMutex) + m_retrievedItems(false), + m_pluginMutex(pluginMutex), + m_itemStates() { } @@ -73,12 +78,14 @@ void UpdateItemStatesThread::run() const QString directory = m_itemStates.first().item.url().directory(KUrl::AppendTrailingSlash); QMutexLocker locker(m_pluginMutex); + m_retrievedItems = false; if (m_plugin->beginRetrieval(directory)) { const int count = m_itemStates.count(); for (int i = 0; i < count; ++i) { m_itemStates[i].revision = m_plugin->revisionState(m_itemStates[i].item); } m_plugin->endRetrieval(); + m_retrievedItems = true; } } @@ -87,6 +94,11 @@ QList UpdateItemStatesThread::itemStates() c return m_itemStates; } +bool UpdateItemStatesThread::retrievedItems() const +{ + return m_retrievedItems; +} + // ------------------------------------------------------------------------------------------------ RevisionControlObserver::RevisionControlObserver(QAbstractItemView* view) : @@ -165,6 +177,12 @@ void RevisionControlObserver::verifyDirectory() if (m_plugin == 0) { // TODO: just for testing purposes. A plugin approach will be used later. m_plugin = new SubversionPlugin(); + connect(m_plugin, SIGNAL(infoMessage(const QString&)), + this, SIGNAL(infoMessage(const QString&))); + connect(m_plugin, SIGNAL(errorMessage(const QString&)), + this, SIGNAL(errorMessage(const QString&))); + connect(m_plugin, SIGNAL(operationCompletedMessage(const QString&)), + this, SIGNAL(operationCompletedMessage(const QString&))); } revisionControlUrl.addPath(m_plugin->fileName()); @@ -212,6 +230,11 @@ void RevisionControlObserver::verifyDirectory() void RevisionControlObserver::applyUpdatedItemStates() { + if (!m_updateItemStatesThread->retrievedItems()) { + emit errorMessage(i18nc("@info:status", "Update of revision information failed.")); + return; + } + // QAbstractItemModel::setData() triggers a bottleneck in combination with QListView // (a detailed description of the root cause is given in the class KFilePreviewGenerator // from kdelibs). To bypass this bottleneck, the signals of the model are temporary blocked. @@ -228,6 +251,11 @@ void RevisionControlObserver::applyUpdatedItemStates() m_dolphinModel->blockSignals(signalsBlocked); m_view->viewport()->repaint(); + + // Using an empty message results in clearing the previously shown information message and showing + // the default status bar information. This is useful as the user already gets feedback that the + // operation has been completed because of the icon emblems. + emit operationCompletedMessage(QString()); if (m_pendingItemStatesUpdate) { m_pendingItemStatesUpdate = false; @@ -266,6 +294,7 @@ void RevisionControlObserver::updateItemStates() itemStates.append(itemState); } + emit infoMessage(i18nc("@info:status", "Updating revision information...")); m_updateItemStatesThread->setData(m_plugin, itemStates); m_updateItemStatesThread->start(); // applyUpdatedItemStates() is called when finished } diff --git a/src/revisioncontrolobserver.h b/src/revisioncontrolobserver.h index ae19e219f..4decbda7f 100644 --- a/src/revisioncontrolobserver.h +++ b/src/revisioncontrolobserver.h @@ -57,7 +57,26 @@ public: QList contextMenuActions(const KFileItemList& items) const; QList contextMenuActions(const QString& directory) const; + +signals: + /** + * Is emitted if an information message with the content \a msg + * should be shown. + */ + void infoMessage(const QString& msg); + + /** + * Is emitted if an error message with the content \a msg + * should be shown. + */ + void errorMessage(const QString& msg); + /** + * Is emitted if an "operation completed" message with the content \a msg + * should be shown. + */ + void operationCompletedMessage(const QString& msg); + private slots: void delayedDirectoryVerification(); void verifyDirectory(); diff --git a/src/revisioncontrolplugin.cpp b/src/revisioncontrolplugin.cpp index ff2425aab..bc50d28c7 100644 --- a/src/revisioncontrolplugin.cpp +++ b/src/revisioncontrolplugin.cpp @@ -55,6 +55,9 @@ SubversionPlugin::SubversionPlugin() : m_commitAction(0), m_addAction(0), m_removeAction(0), + m_command(), + m_errorMsg(), + m_operationCompletedMsg(), m_contextDir(), m_contextItems() { @@ -173,8 +176,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 @@ -211,8 +215,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); @@ -223,7 +236,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() @@ -257,7 +273,10 @@ void SubversionPlugin::commitFiles() if (dialog.exec() == QDialog::Accepted) { const QString description = editor->toPlainText(); - execSvnCommand("commit -m " + KShell::quoteArg(description)); + execSvnCommand("commit -m " + KShell::quoteArg(description), + 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); @@ -265,22 +284,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::slotOperationCompleted() +{ + if (m_contextItems.isEmpty()) { + emit operationCompletedMessage(m_operationCompletedMsg); + } 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::execSvnCommand(const QString& svnCommand) +void SubversionPlugin::startSvnCommandProcess() { - const QString command = "svn " + svnCommand + ' '; + QProcess* process = new QProcess(this); + connect(process, SIGNAL(finished(int)), + this, SLOT(slotOperationCompleted())); + connect(process, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(slotOperationError())); + + QStringList arguments; + arguments << m_command; if (!m_contextDir.isEmpty()) { - KRun::runCommand(command + KShell::quoteArg(m_contextDir), 0); + process->start("svn", arguments << 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("svn", arguments << KShell::quoteArg(item.localPath())); + // the remaining items of m_contextItems will be executed + // after the process has finished (see slotOperationFinished()) } } diff --git a/src/revisioncontrolplugin.h b/src/revisioncontrolplugin.h index 718e5c17d..939fa6f57 100644 --- a/src/revisioncontrolplugin.h +++ b/src/revisioncontrolplugin.h @@ -137,6 +137,24 @@ signals: * RevisionControlPlugin::endRetrieval(). */ void revisionStatesChanged(const QString& directory); + + /** + * Is emitted if an information message with the content \a msg + * should be shown. + */ + void infoMessage(const QString& msg); + + /** + * Is emitted if an error message with the content \a msg + * should be shown. + */ + void errorMessage(const QString& msg); + + /** + * Is emitted if an "operation completed" message with the content \a msg + * should be shown. + */ + void operationCompletedMessage(const QString& msg); }; @@ -169,12 +187,26 @@ private slots: void addFiles(); void removeFiles(); + void slotOperationCompleted(); + void slotOperationError(); + private: /** * Executes the command "svn {svnCommand}" for the files that have been * set by getting the context menu actions (see contextMenuActions()). + * @param infoMsg Message that should be shown before the command is executed. + * @param errorMsg Message that should be shown if the execution of the command + * has been failed. + * @param operationCompletedMsg + * Message that should be shown if the execution of the command + * has been completed successfully. */ - void execSvnCommand(const QString& svnCommand); + void execSvnCommand(const QString& svnCommand, + const QString& infoMsg, + const QString& errorMsg, + const QString& operationCompletedMsg); + + void startSvnCommandProcess(); private: QHash m_revisionInfoHash; @@ -185,8 +217,13 @@ private: QAction* m_commitAction; QAction* m_addAction; QAction* m_removeAction; - mutable QString m_contextDir; - mutable KFileItemList m_contextItems; + + QString m_command; + QString m_errorMsg; + QString m_operationCompletedMsg; + + QString m_contextDir; + KFileItemList m_contextItems; }; #endif // REVISIONCONTROLPLUGIN_H