ProjectExplorer: Extend centralized state handling

Add some customization hooks to make tools aware of target errors
and vice versa.

Change-Id: I4d815087297a3fa1d1d6d52daeed7c4ae0f624bf
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2017-05-02 15:03:56 +02:00
parent 9ee0cec3bc
commit 5d8d3fbdc7
6 changed files with 187 additions and 30 deletions

View File

@@ -545,10 +545,18 @@ public:
void setState(State state);
void initiateStart();
void onTargetPrepared();
void onTargetPrepareFailed(const QString &msg);
void onToolPrepared();
void onToolPrepareFailed(const QString &msg);
void onTargetStarted();
void onTargetStartFailed(const QString &msg);
void onToolStarted();
void onToolStartFailed(const QString &msg);
void initiateStop();
void onToolStopped();
@@ -558,6 +566,8 @@ public:
void onTargetFailed(const QString &msg);
void handleFailure();
void showError(const QString &msg);
static bool isAllowedTransition(State from, State to);
RunControl *q;
@@ -619,7 +629,9 @@ RunControl::~RunControl()
#ifdef WITH_JOURNALD
JournaldWatcher::instance()->unsubscribe(this);
#endif
disconnect();
delete d;
d = nullptr;
}
void RunControl::initiateStart()
@@ -657,6 +669,14 @@ void RunControlPrivate::onTargetPrepared()
toolRunner->prepare();
}
void RunControlPrivate::onTargetPrepareFailed(const QString &msg)
{
checkState(State::TargetPreparing);
toolRunner->onTargetFailure();
showError(msg);
setState(State::Stopped);
}
void RunControlPrivate::onToolPrepared()
{
checkState(State::ToolPreparing);
@@ -664,6 +684,14 @@ void RunControlPrivate::onToolPrepared()
targetRunner->start();
}
void RunControlPrivate::onToolPrepareFailed(const QString &msg)
{
checkState(State::ToolPreparing);
targetRunner->onToolFailure();
showError(msg);
setState(State::Stopped);
}
void RunControlPrivate::onTargetStarted()
{
checkState(State::TargetStarting);
@@ -671,12 +699,28 @@ void RunControlPrivate::onTargetStarted()
toolRunner->start();
}
void RunControlPrivate::onTargetStartFailed(const QString &msg)
{
checkState(State::TargetStarting);
toolRunner->onTargetFailure();
showError(msg);
setState(State::Stopped);
}
void RunControlPrivate::onToolStarted()
{
checkState(State::ToolStarting);
setState(State::Running);
}
void RunControlPrivate::onToolStartFailed(const QString &msg)
{
checkState(State::ToolStarting);
targetRunner->onToolFailure();
showError(msg);
setState(State::Stopped);
}
void RunControlPrivate::initiateStop()
{
checkState(State::Running);
@@ -697,22 +741,34 @@ void RunControlPrivate::onTargetStopped()
setState(State::Stopped);
QTC_CHECK(applicationProcessHandle.isValid());
q->setApplicationProcessHandle(Utils::ProcessHandle());
targetRunner->onFinished();
}
void RunControlPrivate::onTargetFailed(const QString &msg)
{
if (!msg.isEmpty())
q->appendMessage(msg, ErrorMessageFormat);
handleFailure();
if (state == State::TargetPreparing) {
onTargetPrepareFailed(msg);
} else if (state == State::TargetStarting) {
onTargetStartFailed(msg);
} else {
showError(msg);
// showError(RunControl::tr("Unexpected state: %1").arg(int(state)));
setState(State::Stopped);
}
}
void RunControlPrivate::onToolFailed(const QString &msg)
{
if (!msg.isEmpty())
q->appendMessage(msg, ErrorMessageFormat);
handleFailure();
if (state == State::ToolPreparing) {
onToolPrepareFailed(msg);
} else if (state == State::ToolStarting) {
onToolStartFailed(msg);
} else {
showError(msg);
// showError(RunControl::tr("Unexpected state: %1").arg(int(state)));
setState(State::Stopped);
}
}
void RunControlPrivate::handleFailure()
@@ -732,6 +788,12 @@ void RunControlPrivate::handleFailure()
}
}
void RunControlPrivate::showError(const QString &msg)
{
if (!msg.isEmpty())
q->appendMessage(msg, ErrorMessageFormat);
}
Utils::OutputFormatter *RunControl::outputFormatter() const
{
return d->outputFormatter;
@@ -1081,10 +1143,10 @@ void SimpleTargetRunner::start()
QTC_ASSERT(r.is<StandardRunnable>(), return);
const QString executable = r.as<StandardRunnable>().executable;
if (executable.isEmpty()) {
reportFailure(RunControl::tr("No executable specified."));
reportStartFailed(RunControl::tr("No executable specified."));
} else if (!QFileInfo::exists(executable)) {
reportFailure(RunControl::tr("Executable %1 does not exist.")
.arg(QDir::toNativeSeparators(executable)));
reportStartFailed(RunControl::tr("Executable %1 does not exist.")
.arg(QDir::toNativeSeparators(executable)));
} else {
QString msg = RunControl::tr("Starting %1...").arg(QDir::toNativeSeparators(executable)) + '\n';
appendMessage(msg, Utils::NormalMessageFormat);
@@ -1170,12 +1232,37 @@ IDevice::ConstPtr TargetRunner::device() const
return m_runControl->device();
}
void TargetRunner::prepare()
{
reportPrepared(); // By default nothing to do, all is fine.
}
void TargetRunner::reportPrepareFailed(const QString &msg)
{
m_runControl->d->onTargetPrepareFailed(msg);
}
void TargetRunner::reportPrepared()
{
QTC_ASSERT(m_runControl, return);
m_runControl->d->onTargetPrepared();
}
void TargetRunner::start()
{
reportStarted();
}
void TargetRunner::reportStartFailed(const QString &msg)
{
m_runControl->d->onTargetStartFailed(msg);
}
void TargetRunner::stop()
{
reportStopped(); // By default all is fine.
}
void TargetRunner::reportStarted()
{
QTC_ASSERT(m_runControl, return);
@@ -1194,7 +1281,6 @@ void TargetRunner::reportFailure(const QString &msg)
m_runControl->d->onTargetFailed(msg);
}
// ToolRunner
ToolRunner::ToolRunner(RunControl *runControl)
@@ -1219,16 +1305,45 @@ IDevice::ConstPtr ToolRunner::device() const
return m_runControl->device();
}
void ToolRunner::prepare()
{
reportPrepared();
}
void ToolRunner::reportPrepared()
{
m_runControl->d->onToolPrepared();
}
void ToolRunner::start()
{
reportStarted();
}
void ToolRunner::reportStartFailed(const QString &msg)
{
QTC_CHECK(m_runControl->d->state == RunControlPrivate::State::ToolStarting);
m_runControl->d->targetRunner->onToolFailure();
reportFailure(msg);
}
void ToolRunner::reportStarted()
{
m_runControl->d->onToolStarted();
}
void ToolRunner::stop()
{
reportStopped();
}
void ToolRunner::reportStopFailed(const QString &msg)
{
QTC_CHECK(m_runControl->d->state == RunControlPrivate::State::ToolStopping);
m_runControl->d->targetRunner->onToolFailure();
reportFailure(msg);
}
void ToolRunner::reportStopped()
{
onStop();