Commit edd7224c authored by con's avatar con
Browse files

Add "never ask again" option to dialog asking about killing applications

The option is used for the stop button in the application output.
Closing tabs will still ask unconditionally, also if applications would
be killed as a side-effect, e.g. of closing Qt Creator.
The Symbian controls also always ask, with a more descriptive text,
because killing applications might have negative effect on the device in
some cases.

Reviewed-by: Friedemann Kleint
Task-number: QTCREATORBUG-3119
parent daafa533
......@@ -124,6 +124,16 @@ void CheckableMessageBox::setCheckBoxText(const QString &t)
m_d->ui.checkBox->setText(t);
}
bool CheckableMessageBox::isCheckBoxVisible() const
{
return m_d->ui.checkBox->isVisible();
}
void CheckableMessageBox::setCheckBoxVisible(bool v)
{
m_d->ui.checkBox->setVisible(v);
}
QDialogButtonBox::StandardButtons CheckableMessageBox::standardButtons() const
{
return m_d->ui.buttonBox->standardButtons();
......@@ -134,6 +144,16 @@ void CheckableMessageBox::setStandardButtons(QDialogButtonBox::StandardButtons s
m_d->ui.buttonBox->setStandardButtons(s);
}
QPushButton *CheckableMessageBox::button(QDialogButtonBox::StandardButton b) const
{
return m_d->ui.buttonBox->button(b);
}
QPushButton *CheckableMessageBox::addButton(const QString &text, QDialogButtonBox::ButtonRole role)
{
return m_d->ui.buttonBox->addButton(text, role);
}
QDialogButtonBox::StandardButton CheckableMessageBox::defaultButton() const
{
foreach (QAbstractButton *b, m_d->ui.buttonBox->buttons())
......
......@@ -79,8 +79,13 @@ public:
QString checkBoxText() const;
void setCheckBoxText(const QString &);
bool isCheckBoxVisible() const;
void setCheckBoxVisible(bool);
QDialogButtonBox::StandardButtons standardButtons() const;
void setStandardButtons(QDialogButtonBox::StandardButtons s);
QPushButton *button(QDialogButtonBox::StandardButton b) const;
QPushButton *addButton(const QString &text, QDialogButtonBox::ButtonRole role);
QDialogButtonBox::StandardButton defaultButton() const;
void setDefaultButton(QDialogButtonBox::StandardButton s);
......
......@@ -469,20 +469,19 @@ void DebuggerRunControl::showMessage(const QString &msg, int channel)
}
}
bool DebuggerRunControl::aboutToStop() const
bool DebuggerRunControl::promptToStop(bool *optionalPrompt) const
{
QTC_ASSERT(isRunning(), return true;)
if (optionalPrompt && !*optionalPrompt)
return true;
const QString question = tr("A debugging session is still in progress. "
"Terminating the session in the current"
" state can leave the target in an inconsistent state."
" Would you still like to terminate it?");
const QMessageBox::StandardButton answer =
QMessageBox::question(debuggerCore()->mainWindow(),
tr("Close Debugging Session"), question,
QMessageBox::Yes|QMessageBox::No);
return answer == QMessageBox::Yes;
return showPromptToStopDialog(tr("Close Debugging Session"), question,
QString(), QString(), optionalPrompt);
}
RunControl::StopResult DebuggerRunControl::stop()
......
......@@ -85,7 +85,7 @@ public:
// ProjectExplorer::RunControl
void start();
bool aboutToStop() const;
bool promptToStop(bool *prompt = 0) const;
StopResult stop(); // Called from SnapshotWindow.
bool isRunning() const;
QString displayName() const;
......
......@@ -183,14 +183,14 @@ int OutputPane::tabWidgetIndexOf(int runControlIndex) const
bool OutputPane::aboutToClose() const
{
foreach(const RunControlTab &rt, m_runControlTabs)
if (rt.runControl->isRunning() && !rt.runControl->aboutToStop())
if (rt.runControl->isRunning() && !rt.runControl->promptToStop())
return false;
return true;
}
void OutputPane::aboutToUnloadSession()
{
closeTabs(true);
closeTabs(CloseTabWithPrompt);
}
QWidget *OutputPane::outputWidget(QWidget *)
......@@ -309,18 +309,18 @@ void OutputPane::stopRunControl()
QTC_ASSERT(index != -1 && m_runControlTabs.at(index).runControl->isRunning(), return;)
RunControl *rc = m_runControlTabs.at(index).runControl;
if (rc->isRunning() && rc->aboutToStop())
if (rc->isRunning() && optionallyPromptToStop(rc))
rc->stop();
if (debug)
qDebug() << "OutputPane::stopRunControl " << rc;
}
bool OutputPane::closeTabs(bool prompt)
bool OutputPane::closeTabs(CloseTabMode mode)
{
bool allClosed = true;
for (int t = m_tabWidget->count() - 1; t >= 0; t--)
if (!closeTab(t, prompt))
if (!closeTab(t, mode))
allClosed = false;
if (debug)
qDebug() << "OutputPane::closeTabs() returns " << allClosed;
......@@ -329,10 +329,10 @@ bool OutputPane::closeTabs(bool prompt)
bool OutputPane::closeTab(int index)
{
return closeTab(index, true);
return closeTab(index, CloseTabWithPrompt);
}
bool OutputPane::closeTab(int tabIndex, bool prompt)
bool OutputPane::closeTab(int tabIndex, CloseTabMode closeTabMode)
{
const int index = indexOf(m_tabWidget->widget(tabIndex));
QTC_ASSERT(index != -1, return true;)
......@@ -344,8 +344,14 @@ bool OutputPane::closeTab(int tabIndex, bool prompt)
<< tab.window << tab.asyncClosing;
// Prompt user to stop
if (tab.runControl->isRunning()) {
if (prompt && !tab.runControl->aboutToStop())
return false;
switch (closeTabMode) {
case CloseTabNoPrompt:
break;
case CloseTabWithPrompt:
if (!tab.runControl->promptToStop())
return false;
break;
}
if (tab.runControl->stop() == RunControl::AsynchronousStop) {
tab.asyncClosing = true;
return false;
......@@ -363,6 +369,16 @@ bool OutputPane::closeTab(int tabIndex, bool prompt)
return true;
}
bool OutputPane::optionallyPromptToStop(RunControl *runControl)
{
ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
ProjectExplorerSettings settings = pe->projectExplorerSettings();
if (!runControl->promptToStop(&settings.prompToStopRunControl))
return false;
pe->setProjectExplorerSettings(settings);
return true;
}
void OutputPane::projectRemoved()
{
tabChanged(m_tabWidget->currentIndex());
......@@ -415,7 +431,7 @@ void OutputPane::runControlFinished()
}
// Check for asynchronous close. Close the tab.
if (m_runControlTabs.at(senderIndex).asyncClosing)
closeTab(tabWidgetIndexOf(senderIndex), false);
closeTab(tabWidgetIndexOf(senderIndex), CloseTabNoPrompt);
if (!isRunning())
emit allRunControlsFinished();
......
......@@ -70,6 +70,11 @@ class OutputPane : public Core::IOutputPane
Q_OBJECT
public:
enum CloseTabMode {
CloseTabNoPrompt,
CloseTabWithPrompt
};
OutputPane();
virtual ~OutputPane();
......@@ -93,7 +98,7 @@ public:
void showTabFor(RunControl *rc);
bool aboutToClose() const;
bool closeTabs(bool prompt);
bool closeTabs(CloseTabMode mode);
signals:
void allRunControlsFinished();
......@@ -126,7 +131,8 @@ private:
};
bool isRunning() const;
bool closeTab(int index, bool prompt);
bool closeTab(int index, CloseTabMode cm);
bool optionallyPromptToStop(RunControl *runControl);
int indexOf(const RunControl *) const;
int indexOf(const QWidget *outputWindow) const;
......
......@@ -832,6 +832,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
d->m_projectExplorerSettings.wrapAppOutput = s->value("ProjectExplorer/Settings/WrapAppOutput", true).toBool();
d->m_projectExplorerSettings.useJom = s->value("ProjectExplorer/Settings/UseJom", true).toBool();
d->m_projectExplorerSettings.autorestoreLastSession = s->value("ProjectExplorer/Settings/AutoRestoreLastSession", false).toBool();
d->m_projectExplorerSettings.prompToStopRunControl = s->value("ProjectExplorer/Settings/PromptToStopRunControl", false).toBool();
d->m_projectExplorerSettings.environmentId = QUuid(s->value("ProjectExplorer/Settings/EnvironmentId").toString());
if (d->m_projectExplorerSettings.environmentId.isNull())
d->m_projectExplorerSettings.environmentId = QUuid::createUuid();
......@@ -988,7 +989,7 @@ ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown()
// Attempt to synchronously shutdown all run controls.
// If that fails, fall back to asynchronous shutdown (Debugger run controls
// might shutdown asynchronously).
if (d->m_outputPane->closeTabs(false /* No prompt any more */))
if (d->m_outputPane->closeTabs(OutputPane::CloseTabNoPrompt /* No prompt any more */))
return SynchronousShutdown;
connect(d->m_outputPane, SIGNAL(allRunControlsFinished()),
this, SIGNAL(asynchronousShutdownFinished()));
......@@ -1092,6 +1093,7 @@ void ProjectExplorerPlugin::savePersistentSettings()
s->setValue("ProjectExplorer/Settings/WrapAppOutput", d->m_projectExplorerSettings.wrapAppOutput);
s->setValue("ProjectExplorer/Settings/UseJom", d->m_projectExplorerSettings.useJom);
s->setValue("ProjectExplorer/Settings/AutoRestoreLastSession", d->m_projectExplorerSettings.autorestoreLastSession);
s->setValue("ProjectExplorer/Settings/PromptToStopRunControl", d->m_projectExplorerSettings.prompToStopRunControl);
s->setValue("ProjectExplorer/Settings/EnvironmentId", d->m_projectExplorerSettings.environmentId.toString());
}
}
......
......@@ -46,7 +46,7 @@ struct ProjectExplorerSettings
saveBeforeBuild(false), showCompilerOutput(false),
showRunOutput(true), cleanOldAppOutput(false),
wrapAppOutput(true), useJom(true),
autorestoreLastSession(false)
autorestoreLastSession(false), prompToStopRunControl(false)
{ }
bool buildBeforeDeploy;
......@@ -58,6 +58,7 @@ struct ProjectExplorerSettings
bool wrapAppOutput;
bool useJom;
bool autorestoreLastSession; // This option is set in the Session Manager!
bool prompToStopRunControl;
// Add a UUid which is used to identify the development environment.
// This is used to warn the user when he is trying to open a .user file that was created
......@@ -75,10 +76,10 @@ inline bool operator==(const ProjectExplorerSettings &p1, const ProjectExplorerS
&& p1.cleanOldAppOutput == p2.cleanOldAppOutput
&& p1.wrapAppOutput == p2.wrapAppOutput
&& p1.useJom == p2.useJom
&& p1.autorestoreLastSession == p2.autorestoreLastSession;
&& p1.autorestoreLastSession == p2.autorestoreLastSession
&& p1.prompToStopRunControl == p2.prompToStopRunControl;
}
} // namespace ProjectExplorer
} // namespace Internal
......
......@@ -77,6 +77,7 @@ ProjectExplorerSettings ProjectExplorerSettingsWidget::settings() const
pes.cleanOldAppOutput = m_ui.cleanOldAppOutputCheckBox->isChecked();
pes.wrapAppOutput = m_ui.wrapAppOutputCheckBox->isChecked();
pes.useJom = m_ui.jomCheckbox->isChecked();
pes.prompToStopRunControl = m_ui.promptToStopRunControlCheckBox->isChecked();
return pes;
}
......@@ -90,6 +91,7 @@ void ProjectExplorerSettingsWidget::setSettings(const ProjectExplorerSettings &
m_ui.cleanOldAppOutputCheckBox->setChecked(pes.cleanOldAppOutput);
m_ui.wrapAppOutputCheckBox->setChecked(pes.wrapAppOutput);
m_ui.jomCheckbox->setChecked(pes.useJom);
m_ui.promptToStopRunControlCheckBox->setChecked(pes.prompToStopRunControl);
}
QString ProjectExplorerSettingsWidget::projectsDirectory() const
......
......@@ -2,14 +2,6 @@
<ui version="4.0">
<class>ProjectExplorer::Internal::ProjectExplorerSettingsPageUi</class>
<widget class="QWidget" name="ProjectExplorer::Internal::ProjectExplorerSettingsPageUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>437</width>
<height>389</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="directoryGroupBox">
......@@ -104,6 +96,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="promptToStopRunControlCheckBox">
<property name="text">
<string>Prompt to stop applications</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
......
......@@ -38,15 +38,18 @@
#include "target.h"
#include "buildconfiguration.h"
#include "projectexplorerconstants.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <utils/checkablemessagebox.h>
#include <coreplugin/icore.h>
#include <QtCore/QTimer>
#include <QtCore/QSettings>
#include <QtGui/QMainWindow>
#include <QtGui/QMessageBox>
#include <QtGui/QAbstractButton>
#include <QtGui/QPushButton>
#ifdef Q_OS_MAC
#include <Carbon/Carbon.h>
......@@ -320,20 +323,50 @@ QString RunControl::displayName() const
return m_displayName;
}
bool RunControl::aboutToStop() const
bool RunControl::promptToStop(bool *optionalPrompt) const
{
QTC_ASSERT(isRunning(), return true;)
QMessageBox messageBox(QMessageBox::Warning,
tr("Application Still Running"),
tr("%1 is still running.").arg(displayName()),
QMessageBox::Cancel | QMessageBox::Yes,
Core::ICore::instance()->mainWindow());
messageBox.setInformativeText(tr("Force it to quit?"));
messageBox.setDefaultButton(QMessageBox::Yes);
messageBox.button(QMessageBox::Yes)->setText(tr("Force Quit"));
messageBox.button(QMessageBox::Cancel)->setText(tr("Keep Running"));
return messageBox.exec() == QMessageBox::Yes;
if (optionalPrompt && !*optionalPrompt)
return true;
const QString msg = tr("<html><head/><body><center><i>%1</i> is still running.<center/>"
"<center>Force it to quit?</center></body></html>").arg(displayName());
return showPromptToStopDialog(tr("Application Still Running"), msg,
tr("Force Quit"), tr("Keep Running"),
optionalPrompt);
}
// Utility to prompt to terminate application with checkable box.
bool RunControl::showPromptToStopDialog(const QString &title,
const QString &text,
const QString &stopButtonText,
const QString &cancelButtonText,
bool *prompt) const
{
QTC_ASSERT(isRunning(), return true;)
// Show a question message box where user can uncheck this
// question for this class.
Utils::CheckableMessageBox messageBox(Core::ICore::instance()->mainWindow());
messageBox.setWindowTitle(title);
messageBox.setText(text);
messageBox.setStandardButtons(QDialogButtonBox::Yes|QDialogButtonBox::Cancel);
if (!stopButtonText.isEmpty())
messageBox.button(QDialogButtonBox::Yes)->setText(stopButtonText);
if (!cancelButtonText.isEmpty())
messageBox.button(QDialogButtonBox::Cancel)->setText(cancelButtonText);
messageBox.setDefaultButton(QDialogButtonBox::Yes);
if (prompt) {
messageBox.setCheckBoxText(tr("Do not ask again"));
messageBox.setChecked(false);
} else {
messageBox.setCheckBoxVisible(false);
}
messageBox.exec();
const bool close = messageBox.clickedStandardButton() == QDialogButtonBox::Yes;
if (close && prompt && messageBox.isChecked())
*prompt = false;
return close;
}
bool RunControl::sameRunConfiguration(const RunControl *other) const
......
......@@ -191,7 +191,10 @@ public:
explicit RunControl(RunConfiguration *runConfiguration, QString mode);
virtual ~RunControl();
virtual void start() = 0;
virtual bool aboutToStop() const;
// Prompt to stop. If 'optionalPrompt' is passed, a "Do not ask again"-
// checkbox will show and the result will be returned in '*optionalPrompt'.
virtual bool promptToStop(bool *optionalPrompt = 0) const;
virtual StopResult stop() = 0;
virtual bool isRunning() const = 0;
virtual QString displayName() const;
......@@ -214,6 +217,13 @@ signals:
private slots:
void bringApplicationToForegroundInternal();
protected:
// Utility to prompt to terminate application with checkable box.
bool showPromptToStopDialog(const QString &title, const QString &text,
const QString &stopButtonText = QString(),
const QString &cancelButtonText = QString(),
bool *prompt = 0) const;
private:
QString m_displayName;
QString m_runMode;
......
......@@ -625,6 +625,18 @@ bool S60DeviceRunControl::isRunning() const
}
}
bool S60DeviceRunControl::promptToStop(bool *) const
{
// We override the settings prompt
QTC_ASSERT(isRunning(), return true;)
const QString question = tr("<html><head/><body><center><i>%1</i> is still running on the device.<center/>"
"<center>Terminating it can leave the target in an inconsistent state.</center>"
"<center>Would you still like to terminate it?</center></body></html>").arg(displayName());
return showPromptToStopDialog(tr("Application Still Running"), question,
tr("Force Quit"), tr("Keep Running"));
}
void S60DeviceRunControl::startLaunching()
{
QString errorMessage;
......@@ -1085,3 +1097,9 @@ void S60DeviceDebugRunControl::start()
appendMessage(tr("Launching debugger..."), NormalMessageFormat);
Debugger::DebuggerRunControl::start();
}
bool S60DeviceDebugRunControl::promptToStop(bool *) const
{
// We override the settings prompt
return Debugger::DebuggerRunControl::promptToStop(0);
}
......@@ -158,6 +158,7 @@ public:
virtual void start();
virtual StopResult stop();
virtual bool isRunning() const;
virtual bool promptToStop(bool *optionalPrompt = 0) const;
static QMessageBox *createTrkWaitingMessageBox(const QString &port, QWidget *parent = 0);
......@@ -251,6 +252,7 @@ public:
explicit S60DeviceDebugRunControl(S60DeviceRunConfiguration *runConfiguration,
const QString &mode);
virtual void start();
virtual bool promptToStop(bool *optionalPrompt = 0) const;
};
} // namespace Internal
......
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