VCS: Improve dialog on submit prompt

The dialog appears when closing the commit dialog without committing,
or when "prompt to submit" setting is enabled.

Fixes: QTCREATORBUG-18799
Change-Id: I8eb20becbcee7281b9f673a35ec698c6f8e04a40
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Robert Loehning <robert.loehning@qt.io>
Reviewed-by: André Hartmann <aha_1980@gmx.de>
This commit is contained in:
Orgad Shaneh
2018-11-09 09:59:40 +02:00
committed by Orgad Shaneh
parent 7d56d89f25
commit 15b176e30c
9 changed files with 71 additions and 89 deletions
+1 -4
View File
@@ -635,11 +635,8 @@ bool BazaarPlugin::submitEditorAboutToClose()
IDocument *editorDocument = commitEditor->document(); IDocument *editorDocument = commitEditor->document();
QTC_ASSERT(editorDocument, return true); QTC_ASSERT(editorDocument, return true);
bool dummyPrompt = false;
const VcsBaseSubmitEditor::PromptSubmitResult response = const VcsBaseSubmitEditor::PromptSubmitResult response =
commitEditor->promptSubmit(tr("Close Commit Editor"), tr("Do you want to commit the changes?"), commitEditor->promptSubmit(this, nullptr, !m_submitActionTriggered);
tr("Message check failed. Do you want to proceed?"),
&dummyPrompt, !m_submitActionTriggered);
m_submitActionTriggered = false; m_submitActionTriggered = false;
switch (response) { switch (response) {
+1 -4
View File
@@ -593,10 +593,7 @@ bool ClearCasePlugin::submitEditorAboutToClose()
// is, the editor was closed or shutdown). // is, the editor was closed or shutdown).
bool prompt = m_settings.promptToCheckIn; bool prompt = m_settings.promptToCheckIn;
const VcsBaseSubmitEditor::PromptSubmitResult answer = const VcsBaseSubmitEditor::PromptSubmitResult answer =
editor->promptSubmit(tr("Closing ClearCase Editor"), editor->promptSubmit(this, &prompt, !m_submitActionTriggered);
tr("Do you want to check in the files?"),
tr("The comment check failed. Do you want to check in the files?"),
&prompt, !m_submitActionTriggered);
m_submitActionTriggered = false; m_submitActionTriggered = false;
switch (answer) { switch (answer) {
case VcsBaseSubmitEditor::SubmitCanceled: case VcsBaseSubmitEditor::SubmitCanceled:
+3 -6
View File
@@ -431,12 +431,9 @@ bool CvsPlugin::submitEditorAboutToClose()
// Prompt user. Force a prompt unless submit was actually invoked (that // Prompt user. Force a prompt unless submit was actually invoked (that
// is, the editor was closed or shutdown). // is, the editor was closed or shutdown).
const VcsBaseSubmitEditor::PromptSubmitResult answer = const VcsBaseSubmitEditor::PromptSubmitResult answer = editor->promptSubmit(
editor->promptSubmit(tr("Closing CVS Editor"), this, client()->settings().boolPointer(CvsSettings::promptOnSubmitKey),
tr("Do you want to commit the change?"), !m_submitActionTriggered);
tr("The commit message check failed. Do you want to commit the change?"),
client()->settings().boolPointer(CvsSettings::promptOnSubmitKey),
!m_submitActionTriggered);
m_submitActionTriggered = false; m_submitActionTriggered = false;
switch (answer) { switch (answer) {
case VcsBaseSubmitEditor::SubmitCanceled: case VcsBaseSubmitEditor::SubmitCanceled:
+1 -5
View File
@@ -1034,12 +1034,8 @@ bool GitPlugin::submitEditorAboutToClose()
return true; return true;
// Prompt user. Force a prompt unless submit was actually invoked (that // Prompt user. Force a prompt unless submit was actually invoked (that
// is, the editor was closed or shutdown). // is, the editor was closed or shutdown).
bool promptData = false;
const VcsBaseSubmitEditor::PromptSubmitResult answer const VcsBaseSubmitEditor::PromptSubmitResult answer
= editor->promptSubmit(tr("Closing Git Editor"), = editor->promptSubmit(this, nullptr, !m_submitActionTriggered, false);
tr("Do you want to commit the change?"),
tr("Git will not accept this commit. Do you want to continue to edit it?"),
&promptData, !m_submitActionTriggered, false);
m_submitActionTriggered = false; m_submitActionTriggered = false;
switch (answer) { switch (answer) {
case VcsBaseSubmitEditor::SubmitCanceled: case VcsBaseSubmitEditor::SubmitCanceled:
+1 -4
View File
@@ -551,11 +551,8 @@ bool MercurialPlugin::submitEditorAboutToClose()
Core::IDocument *editorFile = commitEditor->document(); Core::IDocument *editorFile = commitEditor->document();
QTC_ASSERT(editorFile, return true); QTC_ASSERT(editorFile, return true);
bool dummyPrompt = false;
const VcsBaseSubmitEditor::PromptSubmitResult response = const VcsBaseSubmitEditor::PromptSubmitResult response =
commitEditor->promptSubmit(tr("Close Commit Editor"), tr("Do you want to commit the changes?"), commitEditor->promptSubmit(this, nullptr, !m_submitActionTriggered);
tr("Message check failed. Do you want to proceed?"),
&dummyPrompt, !m_submitActionTriggered);
m_submitActionTriggered = false; m_submitActionTriggered = false;
switch (response) { switch (response) {
+1 -4
View File
@@ -1310,10 +1310,7 @@ bool PerforcePlugin::submitEditorAboutToClose()
// is, the editor was closed or shutdown). // is, the editor was closed or shutdown).
bool wantsPrompt = m_settings.promptToSubmit(); bool wantsPrompt = m_settings.promptToSubmit();
const VcsBaseSubmitEditor::PromptSubmitResult answer = const VcsBaseSubmitEditor::PromptSubmitResult answer =
perforceEditor->promptSubmit(tr("Closing p4 Editor"), perforceEditor->promptSubmit(this, &wantsPrompt, !m_submitActionTriggered);
tr("Do you want to submit this change list?"),
tr("The commit message check failed. Do you want to submit this change list?"),
&wantsPrompt, !m_submitActionTriggered);
m_submitActionTriggered = false; m_submitActionTriggered = false;
if (answer == VcsBaseSubmitEditor::SubmitCanceled) if (answer == VcsBaseSubmitEditor::SubmitCanceled)
+3 -6
View File
@@ -425,12 +425,9 @@ bool SubversionPlugin::submitEditorAboutToClose()
// Prompt user. Force a prompt unless submit was actually invoked (that // Prompt user. Force a prompt unless submit was actually invoked (that
// is, the editor was closed or shutdown). // is, the editor was closed or shutdown).
VcsBaseClientSettings &newSettings = client()->settings(); VcsBaseClientSettings &newSettings = client()->settings();
const VcsBaseSubmitEditor::PromptSubmitResult answer = const VcsBaseSubmitEditor::PromptSubmitResult answer = editor->promptSubmit(
editor->promptSubmit(tr("Closing Subversion Editor"), this, newSettings.boolPointer(SubversionSettings::promptOnSubmitKey),
tr("Do you want to commit the change?"), !m_submitActionTriggered);
tr("The commit message check failed. Do you want to commit the change?"),
newSettings.boolPointer(SubversionSettings::promptOnSubmitKey),
!m_submitActionTriggered);
m_submitActionTriggered = false; m_submitActionTriggered = false;
switch (answer) { switch (answer) {
case VcsBaseSubmitEditor::SubmitCanceled: case VcsBaseSubmitEditor::SubmitCanceled:
+58 -54
View File
@@ -31,6 +31,7 @@
#include "submiteditorwidget.h" #include "submiteditorwidget.h"
#include "submitfieldwidget.h" #include "submitfieldwidget.h"
#include "submitfilemodel.h" #include "submitfilemodel.h"
#include "vcsbaseplugin.h"
#include "vcsoutputwindow.h" #include "vcsoutputwindow.h"
#include "vcsplugin.h" #include "vcsplugin.h"
#include "vcsprojectcache.h" #include "vcsprojectcache.h"
@@ -58,6 +59,7 @@
#include <QFileInfo> #include <QFileInfo>
#include <QPointer> #include <QPointer>
#include <QProcess> #include <QProcess>
#include <QPushButton>
#include <QSet> #include <QSet>
#include <QStringListModel> #include <QStringListModel>
#include <QStyle> #include <QStyle>
@@ -523,14 +525,31 @@ void VcsBaseSubmitEditor::setDescriptionMandatory(bool v)
enum { checkDialogMinimumWidth = 500 }; enum { checkDialogMinimumWidth = 500 };
static QString withUnusedMnemonic(QString string, const QList<QPushButton *> &otherButtons)
{
QSet<QChar> mnemonics;
for (QPushButton *button : otherButtons) {
const QString text = button->text();
const int ampersandPos = text.indexOf('&');
if (ampersandPos >= 0 && ampersandPos < text.size() - 1)
mnemonics.insert(text.at(ampersandPos + 1));
}
for (int i = 0, total = string.length(); i < total; ++i) {
if (!mnemonics.contains(string.at(i)))
return string.insert(i, '&');
}
return string;
}
VcsBaseSubmitEditor::PromptSubmitResult VcsBaseSubmitEditor::PromptSubmitResult
VcsBaseSubmitEditor::promptSubmit(const QString &title, VcsBaseSubmitEditor::promptSubmit(VcsBasePlugin *plugin,
const QString &question,
const QString &checkFailureQuestion,
bool *promptSetting, bool *promptSetting,
bool forcePrompt, bool forcePrompt,
bool canCommitOnFailure) bool canCommitOnFailure)
{ {
bool dummySetting = false;
if (!promptSetting)
promptSetting = &dummySetting;
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);
@@ -539,67 +558,52 @@ VcsBaseSubmitEditor::PromptSubmitResult
return SubmitDiscarded; return SubmitDiscarded;
QString errorMessage; QString errorMessage;
QMessageBox::StandardButton answer = QMessageBox::Yes;
const bool prompt = forcePrompt || *promptSetting; const bool prompt = forcePrompt || *promptSetting;
QWidget *parent = Core::ICore::mainWindow();
// Pop up a message depending on whether the check succeeded and the // Pop up a message depending on whether the check succeeded and the
// user wants to be prompted // user wants to be prompted
bool canCommit = checkSubmitMessage(&errorMessage) && submitWidget->canSubmit(&errorMessage); bool canCommit = checkSubmitMessage(&errorMessage) && submitWidget->canSubmit(&errorMessage);
if (canCommit && !prompt)
return SubmitConfirmed;
CheckableMessageBox mb(Core::ICore::dialogParent());
const QString commitName = plugin->commitDisplayName();
mb.setWindowTitle(tr("Close %1 %2 Editor")
.arg(plugin->versionControl()->displayName(), commitName));
mb.setIconPixmap(QMessageBox::standardIcon(QMessageBox::Question));
QString message;
if (canCommit) { if (canCommit) {
// Check ok, do prompt? message = tr("What do you want to do with these changes?");
if (prompt) {
// Provide check box to turn off prompt ONLY if it was not forced
if (*promptSetting && !forcePrompt) {
const QDialogButtonBox::StandardButton danswer =
CheckableMessageBox::question(parent, title, question,
tr("Prompt to submit"), promptSetting,
QDialogButtonBox::Yes|QDialogButtonBox::No|
QDialogButtonBox::Cancel,
QDialogButtonBox::Yes);
answer = CheckableMessageBox::dialogButtonBoxToMessageBoxButton(danswer);
} else {
answer = QMessageBox::question(parent, title, question,
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
QMessageBox::Yes);
}
}
} else { } else {
// Check failed. message = tr("Cannot %1%2.\nWhat do you want to do?",
QMessageBox::StandardButtons buttons; "%2 is an optional error message with ': ' prefix. Do not separate it from %1.")
if (canCommitOnFailure) .arg(commitName.toLower(),
buttons = QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel; errorMessage.isEmpty() ? errorMessage : ": " + errorMessage);
else
buttons = QMessageBox::Yes|QMessageBox::No;
QMessageBox msgBox(QMessageBox::Question, title, checkFailureQuestion,
buttons, parent);
msgBox.setDefaultButton(QMessageBox::Cancel);
msgBox.setInformativeText(errorMessage);
msgBox.setMinimumWidth(checkDialogMinimumWidth);
answer = static_cast<QMessageBox::StandardButton>(msgBox.exec());
} }
if (!canCommit && !canCommitOnFailure) { mb.setText(message);
switch (answer) { mb.setCheckBoxText(tr("Prompt to %1").arg(commitName.toLower()));
case QMessageBox::No: mb.setChecked(*promptSetting);
return SubmitDiscarded; // Provide check box to turn off prompt ONLY if it was not forced
case QMessageBox::Yes: mb.setCheckBoxVisible(*promptSetting && !forcePrompt);
return SubmitCanceled; QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Close | QDialogButtonBox::Cancel;
default: if (canCommit || canCommitOnFailure)
break; buttons |= QDialogButtonBox::Ok;
} mb.setStandardButtons(buttons);
} else { QPushButton *cancelButton = mb.button(QDialogButtonBox::Cancel);
switch (answer) { cancelButton->setText(tr("&Keep Editing"));
case QMessageBox::No: cancelButton->setDefault(true);
return SubmitDiscarded; if (QPushButton *commitButton = mb.button(QDialogButtonBox::Ok)) {
case QMessageBox::Yes: commitButton->setText(withUnusedMnemonic(commitName,
return SubmitConfirmed; {cancelButton, mb.button(QDialogButtonBox::Close)}));
default:
break;
}
} }
if (mb.exec() == QDialog::Accepted)
return SubmitCanceled; *promptSetting = mb.isChecked();
QAbstractButton *chosen = mb.clickedButton();
if (!chosen || chosen == cancelButton)
return SubmitCanceled;
if (chosen == mb.button(QDialogButtonBox::Close))
return SubmitDiscarded;
return SubmitConfirmed;
} }
QString VcsBaseSubmitEditor::promptForNickName() QString VcsBaseSubmitEditor::promptForNickName()
+2 -2
View File
@@ -46,6 +46,7 @@ namespace Internal {
class SubmitEditorWidget; class SubmitEditorWidget;
class SubmitFileModel; class SubmitFileModel;
class VcsBasePlugin;
class VcsBaseSubmitEditorPrivate; class VcsBaseSubmitEditorPrivate;
class VCSBASE_EXPORT VcsBaseSubmitEditorParameters class VCSBASE_EXPORT VcsBaseSubmitEditorParameters
@@ -84,8 +85,7 @@ public:
// 'promptSetting' points to a bool variable containing the plugin's // 'promptSetting' points to a bool variable containing the plugin's
// prompt setting. The user can uncheck it from the message box. // prompt setting. The user can uncheck it from the message box.
enum PromptSubmitResult { SubmitConfirmed, SubmitCanceled, SubmitDiscarded }; enum PromptSubmitResult { SubmitConfirmed, SubmitCanceled, SubmitDiscarded };
PromptSubmitResult promptSubmit(const QString &title, const QString &question, PromptSubmitResult promptSubmit(VcsBasePlugin *plugin,
const QString &checkFailureQuestion,
bool *promptSetting, bool *promptSetting,
bool forcePrompt = false, bool forcePrompt = false,
bool canCommitOnFailure = true); bool canCommitOnFailure = true);