Debugger: De-pimpl AttachCoreDialog

Change-Id: Ic2835ead1c707a8264549c361415b410218051f5
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2024-12-20 16:34:03 +01:00
parent 0f0ceeabe7
commit 5ec8021ffe

View File

@@ -36,31 +36,51 @@ using namespace Utils;
namespace Debugger::Internal { namespace Debugger::Internal {
/////////////////////////////////////////////////////////////////////// class AttachCoreDialog final : public QDialog
//
// AttachCoreDialog
//
///////////////////////////////////////////////////////////////////////
class AttachCoreDialogPrivate
{ {
public: public:
KitChooser *kitChooser; AttachCoreDialog();
PathChooser *symbolFileName; int exec() final;
PathChooser *coreFileName;
PathChooser *overrideStartScriptFileName;
PathChooser *sysRootDirectory;
FilePath debuggerPath; FilePath symbolFile() const { return m_symbolFileName->filePath(); }
FilePath coreFile() const { return m_coreFileName->filePath(); }
FilePath overrideStartScript() const { return m_overrideStartScript->filePath(); }
FilePath sysRoot() const { return m_sysRootDirectory->filePath(); }
QDialogButtonBox *buttonBox; // For persistance.
ProgressIndicator *progressIndicator; ProjectExplorer::Kit *kit() const { return m_kitChooser->currentKit(); }
QLabel *progressLabel;
TaskTree taskTree; void setSymbolFile(const FilePath &filePath) { m_symbolFileName->setFilePath(filePath); }
expected_str<FilePath> coreFileResult; void setCoreFile(const FilePath &filePath) { m_coreFileName->setFilePath(filePath); }
expected_str<FilePath> symbolFileResult; void setOverrideStartScript(const FilePath &filePath) { m_overrideStartScript->setFilePath(filePath); }
void setSysRoot(const FilePath &sysRoot) { m_sysRootDirectory->setFilePath(sysRoot); }
void setKitId(Id id) { m_kitChooser->setCurrentKitId(id); }
FilePath coreFileCopy() const;
FilePath symbolFileCopy() const;
private:
void accepted();
void changed();
void coreFileChanged(const FilePath &core);
KitChooser *m_kitChooser;
PathChooser *m_symbolFileName;
PathChooser *m_coreFileName;
PathChooser *m_overrideStartScript;
PathChooser *m_sysRootDirectory;
FilePath m_debuggerPath;
QDialogButtonBox *m_buttonBox;
ProgressIndicator *m_progressIndicator;
QLabel *m_progressLabel;
TaskTree m_taskTree;
expected_str<FilePath> m_coreFileResult;
expected_str<FilePath> m_symbolFileResult;
struct State struct State
{ {
@@ -77,170 +97,132 @@ public:
State getDialogState() const State getDialogState() const
{ {
State st; State st;
st.validKit = (kitChooser->currentKit() != nullptr); st.validKit = (m_kitChooser->currentKit() != nullptr);
st.validSymbolFilename = symbolFileName->isValid(); st.validSymbolFilename = m_symbolFileName->isValid();
st.validCoreFilename = coreFileName->isValid(); st.validCoreFilename = m_coreFileName->isValid();
return st; return st;
} }
}; };
class AttachCoreDialog : public QDialog AttachCoreDialog::AttachCoreDialog()
{ : QDialog(ICore::dialogParent())
public:
explicit AttachCoreDialog(QWidget *parent);
~AttachCoreDialog() override;
int exec() override;
FilePath symbolFile() const;
FilePath coreFile() const;
FilePath overrideStartScript() const;
FilePath sysRoot() const;
// For persistance.
ProjectExplorer::Kit *kit() const;
void setSymbolFile(const FilePath &symbolFilePath);
void setCoreFile(const FilePath &coreFilePath);
void setOverrideStartScript(const FilePath &scriptName);
void setSysRoot(const FilePath &sysRoot);
void setKitId(Id id);
FilePath coreFileCopy() const;
FilePath symbolFileCopy() const;
void accepted();
private:
void changed();
void coreFileChanged(const FilePath &core);
class AttachCoreDialogPrivate *d;
};
AttachCoreDialog::AttachCoreDialog(QWidget *parent)
: QDialog(parent), d(new AttachCoreDialogPrivate)
{ {
setWindowTitle(Tr::tr("Load Core File")); setWindowTitle(Tr::tr("Load Core File"));
d->buttonBox = new QDialogButtonBox(this); m_buttonBox = new QDialogButtonBox(this);
d->buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
d->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); m_buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
d->kitChooser = new KitChooser(this); m_kitChooser = new KitChooser(this);
d->kitChooser->setShowIcons(true); m_kitChooser->setShowIcons(true);
d->kitChooser->populate(); m_kitChooser->populate();
d->coreFileName = new PathChooser(this); m_coreFileName = new PathChooser(this);
d->coreFileName->setHistoryCompleter("Debugger.CoreFile.History"); m_coreFileName->setHistoryCompleter("Debugger.CoreFile.History");
d->coreFileName->setExpectedKind(PathChooser::File); m_coreFileName->setExpectedKind(PathChooser::File);
d->coreFileName->setPromptDialogTitle(Tr::tr("Select Core File")); m_coreFileName->setPromptDialogTitle(Tr::tr("Select Core File"));
d->coreFileName->setAllowPathFromDevice(true); m_coreFileName->setAllowPathFromDevice(true);
d->symbolFileName = new PathChooser(this); m_symbolFileName = new PathChooser(this);
d->symbolFileName->setHistoryCompleter("Executable"); m_symbolFileName->setHistoryCompleter("Executable");
d->symbolFileName->setExpectedKind(PathChooser::File); m_symbolFileName->setExpectedKind(PathChooser::File);
d->symbolFileName->setPromptDialogTitle(Tr::tr("Select Executable or Symbol File")); m_symbolFileName->setPromptDialogTitle(Tr::tr("Select Executable or Symbol File"));
d->symbolFileName->setAllowPathFromDevice(true); m_symbolFileName->setAllowPathFromDevice(true);
d->symbolFileName->setToolTip( m_symbolFileName->setToolTip(
Tr::tr("Select a file containing debug information corresponding to the core file. " Tr::tr("Select a file containing debug information corresponding to the core file. "
"Typically, this is the executable or a *.debug file if the debug " "Typically, this is the executable or a *.debug file if the debug "
"information is stored separately from the executable.")); "information is stored separately from the executable."));
d->overrideStartScriptFileName = new PathChooser(this); m_overrideStartScript = new PathChooser(this);
d->overrideStartScriptFileName->setHistoryCompleter("Debugger.StartupScript.History"); m_overrideStartScript->setHistoryCompleter("Debugger.StartupScript.History");
d->overrideStartScriptFileName->setExpectedKind(PathChooser::File); m_overrideStartScript->setExpectedKind(PathChooser::File);
d->overrideStartScriptFileName->setPromptDialogTitle(Tr::tr("Select Startup Script")); m_overrideStartScript->setPromptDialogTitle(Tr::tr("Select Startup Script"));
d->sysRootDirectory = new PathChooser(this); m_sysRootDirectory = new PathChooser(this);
d->sysRootDirectory->setHistoryCompleter("Debugger.SysRoot.History"); m_sysRootDirectory->setHistoryCompleter("Debugger.SysRoot.History");
d->sysRootDirectory->setExpectedKind(PathChooser::Directory); m_sysRootDirectory->setExpectedKind(PathChooser::Directory);
d->sysRootDirectory->setPromptDialogTitle(Tr::tr("Select SysRoot Directory")); m_sysRootDirectory->setPromptDialogTitle(Tr::tr("Select SysRoot Directory"));
d->sysRootDirectory->setToolTip(Tr::tr( m_sysRootDirectory->setToolTip(Tr::tr(
"This option can be used to override the kit's SysRoot setting")); "This option can be used to override the kit's SysRoot setting"));
d->progressIndicator = new ProgressIndicator(ProgressIndicatorSize::Small, this); m_progressIndicator = new ProgressIndicator(ProgressIndicatorSize::Small, this);
d->progressIndicator->setVisible(false); m_progressIndicator->setVisible(false);
d->progressLabel = new QLabel(); m_progressLabel = new QLabel();
d->progressLabel->setVisible(false); m_progressLabel->setVisible(false);
// clang-format off // clang-format off
using namespace Layouting; using namespace Layouting;
Column { Column {
Form { Form {
Tr::tr("Kit:"), d->kitChooser, br, Tr::tr("Kit:"), m_kitChooser, br,
Tr::tr("Core file:"), d->coreFileName, br, Tr::tr("Core file:"), m_coreFileName, br,
Tr::tr("&Executable or symbol file:"), d->symbolFileName, br, Tr::tr("&Executable or symbol file:"), m_symbolFileName, br,
Tr::tr("Override &start script:"), d->overrideStartScriptFileName, br, Tr::tr("Override &start script:"), m_overrideStartScript, br,
Tr::tr("Override S&ysRoot:"), d->sysRootDirectory, br, Tr::tr("Override S&ysRoot:"), m_sysRootDirectory, br,
}, },
st, st,
hr, hr,
Row { Row {
d->progressIndicator, d->progressLabel, d->buttonBox m_progressIndicator, m_progressLabel, m_buttonBox
} }
}.attachTo(this); }.attachTo(this);
// clang-format on // clang-format on
} }
AttachCoreDialog::~AttachCoreDialog()
{
delete d;
}
int AttachCoreDialog::exec() int AttachCoreDialog::exec()
{ {
connect(d->symbolFileName, &PathChooser::validChanged, this, &AttachCoreDialog::changed); connect(m_symbolFileName, &PathChooser::validChanged, this, &AttachCoreDialog::changed);
connect(d->coreFileName, &PathChooser::validChanged, this, [this] { connect(m_coreFileName, &PathChooser::validChanged, this, [this] {
coreFileChanged(d->coreFileName->unexpandedFilePath()); coreFileChanged(m_coreFileName->unexpandedFilePath());
}); });
connect(d->coreFileName, &PathChooser::textChanged, this, [this] { connect(m_coreFileName, &PathChooser::textChanged, this, [this] {
coreFileChanged(d->coreFileName->unexpandedFilePath()); coreFileChanged(m_coreFileName->unexpandedFilePath());
}); });
connect(d->kitChooser, &KitChooser::currentIndexChanged, this, &AttachCoreDialog::changed); connect(m_kitChooser, &KitChooser::currentIndexChanged, this, &AttachCoreDialog::changed);
connect(d->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(d->buttonBox, &QDialogButtonBox::accepted, this, &AttachCoreDialog::accepted); connect(m_buttonBox, &QDialogButtonBox::accepted, this, &AttachCoreDialog::accepted);
changed(); changed();
connect(&d->taskTree, &TaskTree::done, this, [this] { connect(&m_taskTree, &TaskTree::done, this, [this] {
setEnabled(true); setEnabled(true);
d->progressIndicator->setVisible(false); m_progressIndicator->setVisible(false);
d->progressLabel->setVisible(false); m_progressLabel->setVisible(false);
if (!d->coreFileResult) { if (!m_coreFileResult) {
QMessageBox::critical(this, QMessageBox::critical(this,
Tr::tr("Error"), Tr::tr("Error"),
Tr::tr("Failed to copy core file to device: %1") Tr::tr("Failed to copy core file to device: %1")
.arg(d->coreFileResult.error())); .arg(m_coreFileResult.error()));
return; return;
} }
if (!d->symbolFileResult) { if (!m_symbolFileResult) {
QMessageBox::critical(this, QMessageBox::critical(this,
Tr::tr("Error"), Tr::tr("Error"),
Tr::tr("Failed to copy symbol file to device: %1") Tr::tr("Failed to copy symbol file to device: %1")
.arg(d->coreFileResult.error())); .arg(m_coreFileResult.error()));
return; return;
} }
accept(); accept();
}); });
connect(&d->taskTree, &TaskTree::progressValueChanged, this, [this](int value) { connect(&m_taskTree, &TaskTree::progressValueChanged, this, [this](int value) {
const QString text = Tr::tr("Copying files to device... %1/%2") const QString text = Tr::tr("Copying files to device... %1/%2")
.arg(value) .arg(value)
.arg(d->taskTree.progressMaximum()); .arg(m_taskTree.progressMaximum());
d->progressLabel->setText(text); m_progressLabel->setText(text);
}); });
AttachCoreDialogPrivate::State st = d->getDialogState(); State st = getDialogState();
if (!st.validKit) { if (!st.validKit) {
d->kitChooser->setFocus(); m_kitChooser->setFocus();
} else if (!st.validCoreFilename) { } else if (!st.validCoreFilename) {
d->coreFileName->setFocus(); m_coreFileName->setFocus();
} else if (!st.validSymbolFilename) { } else if (!st.validSymbolFilename) {
d->symbolFileName->setFocus(); m_symbolFileName->setFocus();
} }
return QDialog::exec(); return QDialog::exec();
@@ -284,109 +266,59 @@ void AttachCoreDialog::accepted()
AsyncTask<ResultType>{[this, copyFileAsync](auto &task) { AsyncTask<ResultType>{[this, copyFileAsync](auto &task) {
task.setConcurrentCallData(copyFileAsync, coreFile()); task.setConcurrentCallData(copyFileAsync, coreFile());
}, },
[this](const Async<ResultType> &task) { d->coreFileResult = task.result(); }, [this](const Async<ResultType> &task) { m_coreFileResult = task.result(); },
CallDoneIf::Success}, CallDoneIf::Success},
AsyncTask<ResultType>{[this, copyFileAsync](auto &task) { AsyncTask<ResultType>{[this, copyFileAsync](auto &task) {
task.setConcurrentCallData(copyFileAsync, symbolFile()); task.setConcurrentCallData(copyFileAsync, symbolFile());
}, },
[this](const Async<ResultType> &task) { d->symbolFileResult = task.result(); }, [this](const Async<ResultType> &task) { m_symbolFileResult = task.result(); },
CallDoneIf::Success} CallDoneIf::Success}
}; };
d->taskTree.setRecipe(root); m_taskTree.setRecipe(root);
d->taskTree.start(); m_taskTree.start();
d->progressLabel->setText(Tr::tr("Copying files to device...")); m_progressLabel->setText(Tr::tr("Copying files to device..."));
setEnabled(false); setEnabled(false);
d->progressIndicator->setVisible(true); m_progressIndicator->setVisible(true);
d->progressLabel->setVisible(true); m_progressLabel->setVisible(true);
} }
void AttachCoreDialog::coreFileChanged(const FilePath &coreFile) void AttachCoreDialog::coreFileChanged(const FilePath &coreFile)
{ {
if (coreFile.osType() != OsType::OsTypeWindows && coreFile.exists()) { if (coreFile.osType() != OsType::OsTypeWindows && coreFile.exists()) {
Kit *k = d->kitChooser->currentKit(); Kit *k = m_kitChooser->currentKit();
QTC_ASSERT(k, return); QTC_ASSERT(k, return);
ProcessRunData debugger = DebuggerKitAspect::runnable(k); ProcessRunData debugger = DebuggerKitAspect::runnable(k);
CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(debugger, coreFile); CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(debugger, coreFile);
if (!cinfo.foundExecutableName.isEmpty()) if (!cinfo.foundExecutableName.isEmpty())
d->symbolFileName->setFilePath(cinfo.foundExecutableName); m_symbolFileName->setFilePath(cinfo.foundExecutableName);
else if (!d->symbolFileName->isValid() && !cinfo.rawStringFromCore.isEmpty()) else if (!m_symbolFileName->isValid() && !cinfo.rawStringFromCore.isEmpty())
d->symbolFileName->setFilePath(FilePath::fromString(cinfo.rawStringFromCore)); m_symbolFileName->setFilePath(FilePath::fromString(cinfo.rawStringFromCore));
} }
changed(); changed();
} }
void AttachCoreDialog::changed() void AttachCoreDialog::changed()
{ {
AttachCoreDialogPrivate::State st = d->getDialogState(); State st = getDialogState();
d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(st.isValid()); m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(st.isValid());
}
FilePath AttachCoreDialog::coreFile() const
{
return d->coreFileName->filePath();
}
FilePath AttachCoreDialog::symbolFile() const
{
return d->symbolFileName->filePath();
} }
FilePath AttachCoreDialog::coreFileCopy() const FilePath AttachCoreDialog::coreFileCopy() const
{ {
return d->coreFileResult.value_or(d->symbolFileName->filePath()); return m_coreFileResult.value_or(m_symbolFileName->filePath());
} }
FilePath AttachCoreDialog::symbolFileCopy() const FilePath AttachCoreDialog::symbolFileCopy() const
{ {
return d->symbolFileResult.value_or(d->symbolFileName->filePath()); return m_symbolFileResult.value_or(m_symbolFileName->filePath());
}
void AttachCoreDialog::setSymbolFile(const FilePath &symbolFilePath)
{
d->symbolFileName->setFilePath(symbolFilePath);
}
void AttachCoreDialog::setCoreFile(const FilePath &coreFilePath)
{
d->coreFileName->setFilePath(coreFilePath);
}
void AttachCoreDialog::setKitId(Id id)
{
d->kitChooser->setCurrentKitId(id);
}
Kit *AttachCoreDialog::kit() const
{
return d->kitChooser->currentKit();
}
FilePath AttachCoreDialog::overrideStartScript() const
{
return d->overrideStartScriptFileName->filePath();
}
void AttachCoreDialog::setOverrideStartScript(const FilePath &scriptName)
{
d->overrideStartScriptFileName->setFilePath(scriptName);
}
FilePath AttachCoreDialog::sysRoot() const
{
return d->sysRootDirectory->filePath();
}
void AttachCoreDialog::setSysRoot(const FilePath &sysRoot)
{
d->sysRootDirectory->setFilePath(sysRoot);
} }
void runAttachToCoreDialog() void runAttachToCoreDialog()
{ {
AttachCoreDialog dlg(ICore::dialogParent()); AttachCoreDialog dlg;
QtcSettings *settings = ICore::settings(); QtcSettings *settings = ICore::settings();