VCS: Simplify submit editor accept/close flow

* Replace message box with an error on the output pane.
* Separate logic for accept and close.

Change-Id: Ib9fa201a1a67ee195086f7a22bc6678a9642452a
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: André Hartmann <aha_1980@gmx.de>
This commit is contained in:
Orgad Shaneh
2022-10-22 22:16:44 +03:00
committed by Orgad Shaneh
parent aa33927651
commit d63bfa4a29
11 changed files with 61 additions and 89 deletions

View File

@@ -184,7 +184,7 @@ public:
// String -> repository, StringList -> files // String -> repository, StringList -> files
void changed(const QVariant &); void changed(const QVariant &);
void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) final; void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) final;
bool submitEditorAboutToClose() final; bool activateCommit() final;
// File menu action slots // File menu action slots
void addCurrentFile(); void addCurrentFile();
@@ -784,7 +784,7 @@ void BazaarPluginPrivate::uncommit()
m_client.synchronousUncommit(state.topLevel(), dialog.revision(), dialog.extraOptions()); m_client.synchronousUncommit(state.topLevel(), dialog.revision(), dialog.extraOptions());
} }
bool BazaarPluginPrivate::submitEditorAboutToClose() bool BazaarPluginPrivate::activateCommit()
{ {
auto commitEditor = qobject_cast<CommitEditor *>(submitEditor()); auto commitEditor = qobject_cast<CommitEditor *>(submitEditor());
QTC_ASSERT(commitEditor, return true); QTC_ASSERT(commitEditor, return true);

View File

@@ -218,7 +218,7 @@ public:
protected: protected:
void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) override; void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) override;
bool submitEditorAboutToClose() override; bool activateCommit() override;
void discardCommit() override { cleanCheckInMessageFile(); } void discardCommit() override { cleanCheckInMessageFile(); }
QString ccGet(const FilePath &workingDir, const QString &file, const QString &prefix = {}); QString ccGet(const FilePath &workingDir, const QString &file, const QString &prefix = {});
QList<QStringPair> ccGetActivities() const; QList<QStringPair> ccGetActivities() const;
@@ -734,7 +734,7 @@ ClearCasePluginPrivate::ClearCasePluginPrivate()
} }
// called before closing the submit editor // called before closing the submit editor
bool ClearCasePluginPrivate::submitEditorAboutToClose() bool ClearCasePluginPrivate::activateCommit()
{ {
if (!isCheckInEditorOpen()) if (!isCheckInEditorOpen())
return true; return true;

View File

@@ -238,7 +238,7 @@ public:
protected: protected:
void updateActions(ActionState) final; void updateActions(ActionState) final;
bool submitEditorAboutToClose() final; bool activateCommit() final;
void discardCommit() override { cleanCommitMessageFile(); } void discardCommit() override { cleanCommitMessageFile(); }
private: private:
@@ -706,7 +706,7 @@ void CvsPluginPrivate::vcsDescribe(const FilePath &source, const QString &change
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
}; };
bool CvsPluginPrivate::submitEditorAboutToClose() bool CvsPluginPrivate::activateCommit()
{ {
if (!isCommitEditorOpen()) if (!isCommitEditorOpen())
return true; return true;

View File

@@ -250,7 +250,7 @@ public:
void startRebaseFromCommit(const FilePath &workingDirectory, QString commit); void startRebaseFromCommit(const FilePath &workingDirectory, QString commit);
void updateActions(VcsBasePluginPrivate::ActionState) override; void updateActions(VcsBasePluginPrivate::ActionState) override;
bool submitEditorAboutToClose() override; bool activateCommit() override;
void discardCommit() override { cleanCommitMessageFile(); } void discardCommit() override { cleanCommitMessageFile(); }
void diffCurrentFile(); void diffCurrentFile();
@@ -1380,7 +1380,7 @@ IEditor *GitPluginPrivate::openSubmitEditor(const QString &fileName, const Commi
return editor; return editor;
} }
bool GitPluginPrivate::submitEditorAboutToClose() bool GitPluginPrivate::activateCommit()
{ {
if (!isCommitEditorOpen()) if (!isCommitEditorOpen())
return true; return true;

View File

@@ -136,7 +136,7 @@ public:
private: private:
void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) final; void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) final;
bool submitEditorAboutToClose() final; bool activateCommit() final;
// File menu action slots // File menu action slots
void addCurrentFile(); void addCurrentFile();
@@ -644,7 +644,7 @@ void MercurialPluginPrivate::diffFromEditorSelected(const QStringList &files)
m_client.diff(m_submitRepository, files); m_client.diff(m_submitRepository, files);
} }
bool MercurialPluginPrivate::submitEditorAboutToClose() bool MercurialPluginPrivate::activateCommit()
{ {
auto commitEditor = qobject_cast<CommitEditor *>(submitEditor()); auto commitEditor = qobject_cast<CommitEditor *>(submitEditor());
QTC_ASSERT(commitEditor, return true); QTC_ASSERT(commitEditor, return true);

View File

@@ -222,7 +222,7 @@ public:
void getTopLevel(const FilePath &workingDirectory = {}, bool isSync = false); void getTopLevel(const FilePath &workingDirectory = {}, bool isSync = false);
void updateActions(ActionState) override; void updateActions(ActionState) override;
bool submitEditorAboutToClose() override; bool activateCommit() override;
void discardCommit() override { cleanCommitMessageFile(); } void discardCommit() override { cleanCommitMessageFile(); }
QString commitDisplayName() const final; QString commitDisplayName() const final;
@@ -1526,7 +1526,7 @@ bool PerforcePluginPrivate::isCommitEditorOpen() const
return !m_commitMessageFileName.isEmpty(); return !m_commitMessageFileName.isEmpty();
} }
bool PerforcePluginPrivate::submitEditorAboutToClose() bool PerforcePluginPrivate::activateCommit()
{ {
if (!isCommitEditorOpen()) if (!isCommitEditorOpen())
return true; return true;

View File

@@ -222,7 +222,7 @@ public:
protected: protected:
void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) override; void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) override;
bool submitEditorAboutToClose() override; bool activateCommit() override;
void discardCommit() override { cleanCommitMessageFile(); } void discardCommit() override { cleanCommitMessageFile(); }
private: private:
@@ -543,7 +543,7 @@ SubversionClient *SubversionPluginPrivate::client()
return m_client; return m_client;
} }
bool SubversionPluginPrivate::submitEditorAboutToClose() bool SubversionPluginPrivate::activateCommit()
{ {
if (!isCommitEditorOpen()) if (!isCommitEditorOpen())
return true; return true;

View File

@@ -503,7 +503,13 @@ VcsBasePluginPrivate::VcsBasePluginPrivate(const Context &context)
{ {
Internal::VcsPlugin *plugin = Internal::VcsPlugin::instance(); Internal::VcsPlugin *plugin = Internal::VcsPlugin::instance();
connect(plugin, &Internal::VcsPlugin::submitEditorAboutToClose, connect(plugin, &Internal::VcsPlugin::submitEditorAboutToClose,
this, &VcsBasePluginPrivate::slotSubmitEditorAboutToClose); this, [this](VcsBaseSubmitEditor *submitEditor, bool *result) {
if (submitEditor == m_submitEditor) {
*result = submitEditor->promptSubmit(this);
if (*result)
discardCommit();
}
});
// First time: create new listener // First time: create new listener
if (!m_listener) if (!m_listener)
m_listener = new Internal::StateListener(plugin); m_listener = new Internal::StateListener(plugin);
@@ -522,31 +528,6 @@ void VcsBasePluginPrivate::extensionsInitialized()
m_listener->slotStateChanged(); m_listener->slotStateChanged();
} }
void VcsBasePluginPrivate::slotSubmitEditorAboutToClose(VcsBaseSubmitEditor *submitEditor, bool *result)
{
qCDebug(baseLog) << this << "plugin's submit editor" << m_submitEditor
<< (m_submitEditor ? m_submitEditor->document()->id().name() : QByteArray())
<< "closing submit editor" << submitEditor
<< (submitEditor ? submitEditor->document()->id().name() : QByteArray());
if (submitEditor == m_submitEditor) {
const VcsBaseSubmitEditor::PromptSubmitResult response = submitEditor->promptSubmit(this);
m_submitActionTriggered = false;
switch (response) {
case VcsBaseSubmitEditor::SubmitCanceled:
*result = false;
break;
case VcsBaseSubmitEditor::SubmitDiscarded:
discardCommit();
*result = true;
break;
default:
*result = submitEditorAboutToClose();
break;
}
}
}
void VcsBasePluginPrivate::slotStateChanged(const Internal::State &newInternalState, Core::IVersionControl *vc) void VcsBasePluginPrivate::slotStateChanged(const Internal::State &newInternalState, Core::IVersionControl *vc)
{ {
if (vc == this) { if (vc == this) {
@@ -614,10 +595,8 @@ QString VcsBasePluginPrivate::commitDisplayName() const
void VcsBasePluginPrivate::commitFromEditor() void VcsBasePluginPrivate::commitFromEditor()
{ {
// Close the submit editor
m_submitActionTriggered = true;
QTC_ASSERT(m_submitEditor, return); QTC_ASSERT(m_submitEditor, return);
EditorManager::closeDocuments({m_submitEditor->document()}); m_submitEditor->accept(this);
} }
bool VcsBasePluginPrivate::promptBeforeCommit() bool VcsBasePluginPrivate::promptBeforeCommit()

View File

@@ -137,7 +137,7 @@ public:
virtual QString commitDisplayName() const; virtual QString commitDisplayName() const;
void commitFromEditor(); void commitFromEditor();
bool submitActionTriggered() const { return m_submitActionTriggered; } virtual bool activateCommit() = 0;
protected: protected:
// Prompt to save all files before commit: // Prompt to save all files before commit:
@@ -164,8 +164,6 @@ protected:
// Implement to enable the plugin menu actions according to state. // Implement to enable the plugin menu actions according to state.
virtual void updateActions(ActionState as) = 0; virtual void updateActions(ActionState as) = 0;
// Implement to start the submit process, use submitEditor() to get the submit editor instance.
virtual bool submitEditorAboutToClose() = 0;
virtual void discardCommit(); virtual void discardCommit();
// A helper to enable the VCS menu action according to state: // A helper to enable the VCS menu action according to state:
@@ -176,7 +174,6 @@ protected:
bool enableMenuAction(ActionState as, QAction *in) const; bool enableMenuAction(ActionState as, QAction *in) const;
private: private:
void slotSubmitEditorAboutToClose(VcsBaseSubmitEditor *submitEditor, bool *result);
void slotStateChanged(const Internal::State &s, Core::IVersionControl *vc); void slotStateChanged(const Internal::State &s, Core::IVersionControl *vc);
bool supportsRepositoryCreation() const; bool supportsRepositoryCreation() const;
@@ -185,7 +182,6 @@ private:
Core::Context m_context; Core::Context m_context;
VcsBasePluginState m_state; VcsBasePluginState m_state;
int m_actionState = -1; int m_actionState = -1;
bool m_submitActionTriggered = false;
}; };
} // namespace VcsBase } // namespace VcsBase

View File

@@ -125,6 +125,7 @@ public:
QPointer<QAction> m_submitAction; QPointer<QAction> m_submitAction;
NickNameDialog *m_nickNameDialog = nullptr; NickNameDialog *m_nickNameDialog = nullptr;
bool m_disablePrompt = false;
}; };
VcsBaseSubmitEditorPrivate::VcsBaseSubmitEditorPrivate(SubmitEditorWidget *editorWidget, VcsBaseSubmitEditorPrivate::VcsBaseSubmitEditorPrivate(SubmitEditorWidget *editorWidget,
@@ -478,46 +479,47 @@ void VcsBaseSubmitEditor::setDescriptionMandatory(bool v)
enum { checkDialogMinimumWidth = 500 }; enum { checkDialogMinimumWidth = 500 };
VcsBaseSubmitEditor::PromptSubmitResult VcsBaseSubmitEditor::promptSubmit(VcsBasePluginPrivate *plugin) void VcsBaseSubmitEditor::accept(VcsBasePluginPrivate *plugin)
{ {
auto submitWidget = static_cast<SubmitEditorWidget *>(this->widget()); auto submitWidget = static_cast<SubmitEditorWidget *>(this->widget());
Core::EditorManager::activateEditor(this, Core::EditorManager::IgnoreNavigationHistory); Core::EditorManager::activateEditor(this, Core::EditorManager::IgnoreNavigationHistory);
if (!submitWidget->isEnabled() || !submitWidget->isEdited())
return SubmitDiscarded;
QString errorMessage; QString errorMessage;
const bool canCommit = checkSubmitMessage(&errorMessage) && submitWidget->canSubmit(&errorMessage);
// Pop up a message depending on whether the check succeeded and the if (!canCommit) {
// user wants to be prompted VcsOutputWindow::appendError(
bool canCommit = checkSubmitMessage(&errorMessage) && submitWidget->canSubmit(&errorMessage); tr("Cannot %1%2.",
const bool prompt = !plugin->submitActionTriggered(); "%2 is an optional error message with ': ' prefix. Don't add space in front.")
if (canCommit && !prompt) .arg(plugin->commitDisplayName().toLower(),
return SubmitConfirmed; errorMessage.isEmpty() ? errorMessage : ": " + errorMessage));
QMessageBox mb(Core::ICore::dialogParent()); } else if (plugin->activateCommit()) {
const QString commitName = plugin->commitDisplayName(); close();
mb.setWindowTitle(tr("Close %1 %2 Editor").arg(plugin->displayName(), commitName));
mb.setIcon(QMessageBox::Question);
QString message;
if (canCommit) {
message = tr("What do you want to do with these changes?");
} else {
message = tr("Cannot %1%2.\nWhat do you want to do?",
"%2 is an optional error message with ': ' prefix. Don't add space in front.")
.arg(commitName.toLower(),
errorMessage.isEmpty() ? errorMessage : ": " + errorMessage);
} }
mb.setText(message); }
mb.setStandardButtons(QMessageBox::Close | QMessageBox::Cancel);
// On Windows there is no mnemonic for Close. Set it explicitly. void VcsBaseSubmitEditor::close()
mb.button(QMessageBox::Close)->setText(tr("&Close")); {
mb.button(QMessageBox::Cancel)->setText(tr("&Keep Editing")); d->m_disablePrompt = true;
// prompt is true when the editor is closed, and false when triggered by the submit action Core::EditorManager::closeDocuments({document()});
if (prompt) }
mb.setDefaultButton(QMessageBox::Cancel);
mb.exec(); bool VcsBaseSubmitEditor::promptSubmit(VcsBasePluginPrivate *plugin)
return mb.result() == QMessageBox::Close ? SubmitDiscarded : SubmitCanceled; {
if (d->m_disablePrompt)
return true;
Core::EditorManager::activateEditor(this, Core::EditorManager::IgnoreNavigationHistory);
auto submitWidget = static_cast<SubmitEditorWidget *>(this->widget());
if (!submitWidget->isEnabled() || !submitWidget->isEdited())
return true;
const QString commitName = plugin->commitDisplayName();
return QMessageBox::question(Core::ICore::dialogParent(),
tr("Close %1 %2 Editor").arg(plugin->displayName(), commitName),
tr("Closing this editor will abort the %1. Are you sure?")
.arg(commitName.toLower())) == QMessageBox::Yes;
} }
QString VcsBaseSubmitEditor::promptForNickName() QString VcsBaseSubmitEditor::promptForNickName()

View File

@@ -47,14 +47,8 @@ public:
~VcsBaseSubmitEditor() override; ~VcsBaseSubmitEditor() override;
// A utility routine to be called when closing a submit editor. void accept(VcsBasePluginPrivate *plugin);
// Runs checks on the message and prompts according to configuration. bool promptSubmit(VcsBasePluginPrivate *plugin);
// Force prompt should be true if it is invoked by closing an editor
// as opposed to invoking the "Submit" button.
// 'promptSetting' points to a bool variable containing the plugin's
// prompt setting. The user can uncheck it from the message box.
enum PromptSubmitResult { SubmitConfirmed, SubmitCanceled, SubmitDiscarded };
PromptSubmitResult promptSubmit(VcsBasePluginPrivate *plugin);
QAbstractItemView::SelectionMode fileListSelectionMode() const; QAbstractItemView::SelectionMode fileListSelectionMode() const;
void setFileListSelectionMode(QAbstractItemView::SelectionMode sm); void setFileListSelectionMode(QAbstractItemView::SelectionMode sm);
@@ -123,6 +117,7 @@ private:
bool checkSubmitMessage(QString *errorMessage) const; bool checkSubmitMessage(QString *errorMessage) const;
bool runSubmitMessageCheckScript(const QString &script, QString *errorMessage) const; bool runSubmitMessageCheckScript(const QString &script, QString *errorMessage) const;
QString promptForNickName(); QString promptForNickName();
void close();
VcsBaseSubmitEditorPrivate *d = nullptr; VcsBaseSubmitEditorPrivate *d = nullptr;