forked from qt-creator/qt-creator
Fixes: Error logging, polish attach remote dialog
This commit is contained in:
committed by
unknown
parent
cb2cce5139
commit
355f44fe8f
@@ -1,7 +1,8 @@
|
||||
<ui version="4.0" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AttachRemoteDialog</class>
|
||||
<widget class="QDialog" name="AttachRemoteDialog" >
|
||||
<property name="geometry" >
|
||||
<widget class="QDialog" name="AttachRemoteDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
@@ -9,50 +10,76 @@
|
||||
<height>866</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<property name="windowTitle">
|
||||
<string>Start Debugger</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" >
|
||||
<item>
|
||||
<widget class="QLabel" name="pidLabel" >
|
||||
<property name="text" >
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="pidLabel">
|
||||
<property name="text">
|
||||
<string>Attach to Process ID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="pidLineEdit" />
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="pidLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Filter:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QWidget" name="filterWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="filterLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="filterClearToolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="procView" >
|
||||
<property name="editTriggers" >
|
||||
<widget class="QTreeView" name="procView">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line" >
|
||||
<property name="orientation" >
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="orientation" >
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons" >
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "debuggermanager.h"
|
||||
#include "breakhandler.h"
|
||||
#include "stackhandler.h"
|
||||
#include "watchhandler.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/winutils.h>
|
||||
@@ -50,11 +51,13 @@
|
||||
static const char *dbgEngineDllC = "dbgeng";
|
||||
static const char *debugCreateFuncC = "DebugCreate";
|
||||
|
||||
static QString debugEngineComError(HRESULT hr)
|
||||
static QString msgDebugEngineComResult(HRESULT hr)
|
||||
{
|
||||
if (!FAILED(hr))
|
||||
return QLatin1String("S_OK");
|
||||
switch (hr) {
|
||||
case S_OK:
|
||||
return QLatin1String("S_OK");
|
||||
case S_FALSE:
|
||||
return QLatin1String("S_FALSE");
|
||||
case E_FAIL:
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
@@ -207,6 +210,7 @@ bool CdbDebugEngine::startDebugger()
|
||||
m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
|
||||
QString errorMessage;
|
||||
bool rc = false;
|
||||
m_d->m_bIgnoreNextDebugEvent = false;
|
||||
switch (m_d->m_debuggerManager->startMode()) {
|
||||
case AttachExternal:
|
||||
rc = startAttachDebugger(m_d->m_debuggerManager->m_attachedPID, &errorMessage);
|
||||
@@ -235,7 +239,7 @@ bool CdbDebugEngine::startAttachDebugger(unsigned long pid, QString *errorMessag
|
||||
if (debugCDB)
|
||||
qDebug() << "Attaching to " << pid << " returns " << hr;
|
||||
if (FAILED(hr)) {
|
||||
*errorMessage = tr("AttachProcess failed for pid %1: %2").arg(pid).arg(debugEngineComError(hr));
|
||||
*errorMessage = tr("AttachProcess failed for pid %1: %2").arg(pid).arg(msgDebugEngineComResult(hr));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -276,7 +280,7 @@ bool CdbDebugEngine::startDebuggerWithExecutable(QString *errorMessage)
|
||||
m_d->m_debuggerManager->m_workingDir.utf16(),
|
||||
env);
|
||||
if (FAILED(hr)) {
|
||||
*errorMessage = tr("CreateProcess2Wide failed for '%1': %2").arg(cmd).arg(debugEngineComError(hr));
|
||||
*errorMessage = tr("CreateProcess2Wide failed for '%1': %2").arg(cmd).arg(msgDebugEngineComResult(hr));
|
||||
m_d->m_debuggerManagerAccess->notifyInferiorExited();
|
||||
return false;
|
||||
}
|
||||
@@ -295,6 +299,9 @@ void CdbDebugEngine::exitDebugger()
|
||||
|
||||
void CdbDebugEngine::updateWatchModel()
|
||||
{
|
||||
const QList<WatchData> incomplete = m_d->m_debuggerManagerAccess->watchHandler()->takeCurrentIncompletes();
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << incomplete.size();
|
||||
}
|
||||
|
||||
void CdbDebugEngine::stepExec()
|
||||
@@ -357,9 +364,12 @@ void CdbDebugEngine::nextExec()
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
HRESULT hr;
|
||||
hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
|
||||
startWatchTimer();
|
||||
const HRESULT hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
|
||||
if (SUCCEEDED(hr)) {
|
||||
startWatchTimer();
|
||||
} else {
|
||||
qWarning("%s failed: %s", Q_FUNC_INFO, qPrintable(msgDebugEngineComResult(hr)));
|
||||
}
|
||||
}
|
||||
|
||||
void CdbDebugEngine::stepIExec()
|
||||
@@ -372,8 +382,12 @@ void CdbDebugEngine::nextIExec()
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_d->m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
||||
startWatchTimer();
|
||||
const HRESULT hr = m_d->m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
||||
if (SUCCEEDED(hr)) {
|
||||
startWatchTimer();
|
||||
} else {
|
||||
qWarning("%s failed: %s", Q_FUNC_INFO, qPrintable(msgDebugEngineComResult(hr)));
|
||||
}
|
||||
}
|
||||
|
||||
void CdbDebugEngine::continueInferior()
|
||||
@@ -386,26 +400,30 @@ void CdbDebugEngine::continueInferior()
|
||||
|
||||
ULONG executionStatus;
|
||||
HRESULT hr = m_d->m_pDebugControl->GetExecutionStatus(&executionStatus);
|
||||
if (SUCCEEDED(hr) && executionStatus != DEBUG_STATUS_GO)
|
||||
m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
|
||||
|
||||
startWatchTimer();
|
||||
m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||
if (SUCCEEDED(hr) && executionStatus != DEBUG_STATUS_GO) {
|
||||
hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
|
||||
if (SUCCEEDED(hr)) {
|
||||
startWatchTimer();
|
||||
m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||
} else {
|
||||
qWarning("%s failed: %s", Q_FUNC_INFO, qPrintable(msgDebugEngineComResult(hr)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CdbDebugEngine::interruptInferior()
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << Q_FUNC_INFO << m_d->m_hDebuggeeProcess;
|
||||
|
||||
//TODO: better use IDebugControl::SetInterrupt?
|
||||
if (!m_d->m_hDebuggeeProcess)
|
||||
return;
|
||||
if (!DebugBreakProcess(m_d->m_hDebuggeeProcess)) {
|
||||
qWarning("DebugBreakProcess failed.");
|
||||
return;
|
||||
if (DebugBreakProcess(m_d->m_hDebuggeeProcess)) {
|
||||
m_d->m_debuggerManagerAccess->notifyInferiorStopped();
|
||||
} else {
|
||||
qWarning("DebugBreakProcess failed: %s", Core::Utils::winErrorMessage(GetLastError()));
|
||||
}
|
||||
m_d->m_debuggerManagerAccess->notifyInferiorStopped();
|
||||
}
|
||||
|
||||
void CdbDebugEngine::runToLineExec(const QString &fileName, int lineNumber)
|
||||
@@ -571,43 +589,30 @@ void CdbDebugEngine::timerEvent(QTimerEvent* te)
|
||||
if (te->timerId() != m_d->m_watchTimer)
|
||||
return;
|
||||
|
||||
if (debugCDB > 1)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
const HRESULT hr = m_d->m_pDebugControl->WaitForEvent(0, 1);
|
||||
if (debugCDB)
|
||||
if (debugCDB > 1 || hr != S_FALSE)
|
||||
qDebug() << Q_FUNC_INFO << "WaitForEvent" << msgDebugEngineComResult(hr);
|
||||
|
||||
HRESULT hr;
|
||||
hr = m_d->m_pDebugControl->WaitForEvent(0, 1);
|
||||
switch (hr) {
|
||||
case S_OK:
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent S_OK";
|
||||
|
||||
killWatchTimer();
|
||||
m_d->handleDebugEvent();
|
||||
break;
|
||||
case S_FALSE:
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent S_FALSE";
|
||||
break;
|
||||
case E_PENDING:
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent E_PENDING";
|
||||
case E_FAIL:
|
||||
break;
|
||||
case E_UNEXPECTED:
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent E_UNEXPECTED";
|
||||
killWatchTimer();
|
||||
break;
|
||||
case E_FAIL:
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent E_FAIL";
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CdbDebugEnginePrivate::handleDebugEvent()
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << Q_FUNC_INFO << m_hDebuggeeProcess;
|
||||
|
||||
if (m_bIgnoreNextDebugEvent) {
|
||||
m_engine->startWatchTimer();
|
||||
@@ -630,10 +635,18 @@ void CdbDebugEnginePrivate::handleDebugEvent()
|
||||
//}
|
||||
}
|
||||
|
||||
void CdbDebugEnginePrivate::setDebuggeeHandles(HANDLE hDebuggeeProcess, HANDLE hDebuggeeThread)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << hDebuggeeProcess << hDebuggeeThread;
|
||||
m_hDebuggeeProcess = hDebuggeeProcess;
|
||||
m_hDebuggeeThread = hDebuggeeThread;
|
||||
}
|
||||
|
||||
void CdbDebugEnginePrivate::updateThreadList()
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << Q_FUNC_INFO << m_hDebuggeeProcess;
|
||||
|
||||
ThreadsHandler* th = m_debuggerManagerAccess->threadsHandler();
|
||||
QList<ThreadData> threads;
|
||||
|
||||
@@ -62,6 +62,8 @@ struct CdbDebugEnginePrivate
|
||||
explicit CdbDebugEnginePrivate(const DebuggerEngineLibrary &lib, DebuggerManager *parent, CdbDebugEngine* engine);
|
||||
~CdbDebugEnginePrivate();
|
||||
|
||||
void setDebuggeeHandles(HANDLE hDebuggeeProcess, HANDLE hDebuggeeThread);
|
||||
|
||||
bool isDebuggeeRunning() const { return m_watchTimer != -1; }
|
||||
void handleDebugEvent();
|
||||
void updateThreadList();
|
||||
|
||||
@@ -91,6 +91,13 @@ STDMETHODIMP CdbDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT Bp)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static inline QString msgException(const EXCEPTION_RECORD64 *Exception, ULONG FirstChance)
|
||||
{
|
||||
return QString::fromLatin1("An exception occurred: Code=0x%1 FirstChance=%2").
|
||||
arg(QString::number(Exception->ExceptionCode, 16)).
|
||||
arg(FirstChance);
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::Exception(
|
||||
THIS_
|
||||
__in PEXCEPTION_RECORD64 Exception,
|
||||
@@ -99,7 +106,11 @@ STDMETHODIMP CdbDebugEventCallback::Exception(
|
||||
{
|
||||
Q_UNUSED(Exception)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << FirstChance;
|
||||
qDebug() << Q_FUNC_INFO << msgException(Exception, FirstChance);
|
||||
|
||||
// First chance are harmless
|
||||
if (!FirstChance)
|
||||
qWarning("%s", qPrintable(msgException(Exception, FirstChance)));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -161,8 +172,7 @@ STDMETHODIMP CdbDebugEventCallback::CreateProcess(
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << ModuleName;
|
||||
|
||||
m_pEngine->m_d->m_hDebuggeeProcess = (HANDLE)Handle;
|
||||
m_pEngine->m_d->m_hDebuggeeThread = (HANDLE)InitialThreadHandle;
|
||||
m_pEngine->m_d->setDebuggeeHandles(reinterpret_cast<HANDLE>(Handle), reinterpret_cast<HANDLE>(InitialThreadHandle));
|
||||
m_pEngine->m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||
|
||||
ULONG currentThreadId;
|
||||
@@ -183,8 +193,7 @@ STDMETHODIMP CdbDebugEventCallback::ExitProcess(
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << ExitCode;
|
||||
|
||||
m_pEngine->m_d->m_hDebuggeeProcess = 0;
|
||||
m_pEngine->m_d->m_hDebuggeeThread = 0;
|
||||
m_pEngine->m_d->setDebuggeeHandles(0, 0);
|
||||
m_pEngine->m_d->m_debuggerManagerAccess->notifyInferiorExited();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,72 @@
|
||||
#include <QtGui/QProxyModel>
|
||||
#include <QtGui/QSortFilterProxyModel>
|
||||
|
||||
using namespace Debugger::Internal;
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
bool operator<(const ProcData &p1, const ProcData &p2)
|
||||
{
|
||||
return p1.name < p2.name;
|
||||
}
|
||||
|
||||
// A filterable process list model
|
||||
class ProcessListFilterModel : public QSortFilterProxyModel {
|
||||
public:
|
||||
explicit ProcessListFilterModel(QObject *parent);
|
||||
QString processIdAt(const QModelIndex &index) const;
|
||||
void populate(QList<ProcData> processes, const QString &excludePid = QString());
|
||||
|
||||
private:
|
||||
QStandardItemModel *m_model;
|
||||
};
|
||||
|
||||
ProcessListFilterModel::ProcessListFilterModel(QObject *parent) :
|
||||
QSortFilterProxyModel(parent),
|
||||
m_model(new QStandardItemModel(this))
|
||||
{
|
||||
QStringList columns;
|
||||
columns << AttachExternalDialog::tr("Process ID")
|
||||
<< AttachExternalDialog::tr("Name")
|
||||
<< AttachExternalDialog::tr("State");
|
||||
m_model->setHorizontalHeaderLabels(columns);
|
||||
setSourceModel(m_model);
|
||||
setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
setFilterKeyColumn(1);
|
||||
}
|
||||
|
||||
QString ProcessListFilterModel::processIdAt(const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid()) {
|
||||
const QModelIndex index0 = mapToSource(index);
|
||||
QModelIndex index = index0.sibling(index0.row(), 0);
|
||||
if (const QStandardItem *item = m_model->itemFromIndex(index))
|
||||
return item->text();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void ProcessListFilterModel::populate(QList<ProcData> processes, const QString &excludePid)
|
||||
{
|
||||
qStableSort(processes);
|
||||
|
||||
if (const int rowCount = m_model->rowCount())
|
||||
m_model->removeRows(0, rowCount);
|
||||
|
||||
QStandardItem *root = m_model->invisibleRootItem();
|
||||
foreach(const ProcData &proc, processes) {
|
||||
QList<QStandardItem *> row;
|
||||
row.append(new QStandardItem(proc.ppid));
|
||||
row.append(new QStandardItem(proc.name));
|
||||
if (!proc.image.isEmpty())
|
||||
row.back()->setToolTip(proc.image);
|
||||
row.append(new QStandardItem(proc.state));
|
||||
if (proc.ppid == excludePid)
|
||||
foreach(QStandardItem *i, row)
|
||||
i->setEnabled(false);
|
||||
root->appendRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -105,17 +170,6 @@ void AttachCoreDialog::setCoreFile(const QString &fileName)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static QStandardItemModel *createProcessModel(QObject *parent)
|
||||
{
|
||||
QStandardItemModel *rc = new QStandardItemModel(parent);
|
||||
QStringList columns;
|
||||
columns << AttachExternalDialog::tr("Process ID")
|
||||
<< AttachExternalDialog::tr("Name")
|
||||
<< AttachExternalDialog::tr("State");
|
||||
rc->setHorizontalHeaderLabels(columns);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool isUnixProcessId(const QString &procname)
|
||||
{
|
||||
for (int i = 0; i != procname.size(); ++i)
|
||||
@@ -124,13 +178,6 @@ static bool isUnixProcessId(const QString &procname)
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
bool operator<(const ProcData &p1, const ProcData &p2)
|
||||
{
|
||||
return p1.name < p2.name;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
// Determine UNIX processes by reading "/proc"
|
||||
static QList<ProcData> unixProcessList()
|
||||
{
|
||||
@@ -162,40 +209,13 @@ static QList<ProcData> unixProcessList()
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline QStandardItem *createStandardItem(const QString &text,
|
||||
bool enabled)
|
||||
{
|
||||
QStandardItem *rc = new QStandardItem(text);
|
||||
rc->setEnabled(enabled);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Populate a standard item model with a list
|
||||
// of processes and gray out the excludePid.
|
||||
static void populateProcessModel(QStandardItemModel *model,
|
||||
const QString &excludePid = QString())
|
||||
static QList<ProcData> processList()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QList<ProcData> processes = winProcessList();
|
||||
return winProcessList();
|
||||
#else
|
||||
QList<ProcData> processes = unixProcessList();
|
||||
return unixProcessList();
|
||||
#endif
|
||||
qStableSort(processes);
|
||||
|
||||
if (const int rowCount = model->rowCount())
|
||||
model->removeRows(0, rowCount);
|
||||
|
||||
QStandardItem *root = model->invisibleRootItem();
|
||||
foreach(const ProcData &proc, processes) {
|
||||
const bool enabled = proc.ppid != excludePid;
|
||||
QList<QStandardItem *> row;
|
||||
row.append(createStandardItem(proc.ppid, enabled));
|
||||
row.append(createStandardItem(proc.name, enabled));
|
||||
if (!proc.image.isEmpty())
|
||||
row.back()->setToolTip(proc.image);
|
||||
row.append(createStandardItem(proc.state, enabled));
|
||||
root->appendRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
@@ -208,17 +228,13 @@ AttachExternalDialog::AttachExternalDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_selfPid(QString::number(QCoreApplication::applicationPid())),
|
||||
m_ui(new Ui::AttachExternalDialog),
|
||||
m_proxyModel(new QSortFilterProxyModel(this)),
|
||||
m_model(createProcessModel(this))
|
||||
m_model(new ProcessListFilterModel(this))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
okButton()->setDefault(true);
|
||||
okButton()->setEnabled(false);
|
||||
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_proxyModel->setFilterKeyColumn(1);
|
||||
m_ui->procView->setModel(m_proxyModel);
|
||||
m_ui->procView->setModel(m_model);
|
||||
m_ui->procView->setSortingEnabled(true);
|
||||
|
||||
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
@@ -227,7 +243,8 @@ AttachExternalDialog::AttachExternalDialog(QWidget *parent) :
|
||||
connect(refreshButton, SIGNAL(clicked()), this, SLOT(rebuildProcessList()));
|
||||
m_ui->buttonBox->addButton(refreshButton, QDialogButtonBox::ActionRole);
|
||||
|
||||
connect(m_ui->procView, SIGNAL(activated(QModelIndex)),
|
||||
// Do not use activated, will be single click in Oxygen
|
||||
connect(m_ui->procView, SIGNAL(doubleClicked(QModelIndex)),
|
||||
this, SLOT(procSelected(QModelIndex)));
|
||||
connect(m_ui->pidLineEdit, SIGNAL(textChanged(QString)),
|
||||
this, SLOT(pidChanged(QString)));
|
||||
@@ -235,7 +252,7 @@ AttachExternalDialog::AttachExternalDialog(QWidget *parent) :
|
||||
connect(m_ui->filterClearToolButton, SIGNAL(clicked()),
|
||||
m_ui->filterLineEdit, SLOT(clear()));
|
||||
connect(m_ui->filterLineEdit, SIGNAL(textChanged(QString)),
|
||||
m_proxyModel, SLOT(setFilterFixedString(QString)));
|
||||
m_model, SLOT(setFilterFixedString(QString)));
|
||||
|
||||
rebuildProcessList();
|
||||
}
|
||||
@@ -252,7 +269,7 @@ QPushButton *AttachExternalDialog::okButton() const
|
||||
|
||||
void AttachExternalDialog::rebuildProcessList()
|
||||
{
|
||||
populateProcessModel(m_model, m_selfPid);
|
||||
m_model->populate(processList(), m_selfPid);
|
||||
m_ui->procView->expandAll();
|
||||
m_ui->procView->resizeColumnToContents(0);
|
||||
m_ui->procView->resizeColumnToContents(1);
|
||||
@@ -260,10 +277,9 @@ void AttachExternalDialog::rebuildProcessList()
|
||||
|
||||
void AttachExternalDialog::procSelected(const QModelIndex &proxyIndex)
|
||||
{
|
||||
const QModelIndex index0 = m_proxyModel->mapToSource(proxyIndex);
|
||||
QModelIndex index = index0.sibling(index0.row(), 0);
|
||||
if (const QStandardItem *item = m_model->itemFromIndex(index)) {
|
||||
m_ui->pidLineEdit->setText(item->text());
|
||||
const QString proccessId = m_model->processIdAt(proxyIndex);
|
||||
if (!proccessId.isEmpty()) {
|
||||
m_ui->pidLineEdit->setText(proccessId);
|
||||
if (okButton()->isEnabled())
|
||||
okButton()->animateClick();
|
||||
}
|
||||
@@ -276,7 +292,7 @@ int AttachExternalDialog::attachPID() const
|
||||
|
||||
void AttachExternalDialog::pidChanged(const QString &pid)
|
||||
{
|
||||
okButton()->setEnabled(!pid.isEmpty() && pid != m_selfPid);
|
||||
okButton()->setEnabled(!pid.isEmpty() && pid != QLatin1String("0") && pid != m_selfPid);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
@@ -288,7 +304,7 @@ void AttachExternalDialog::pidChanged(const QString &pid)
|
||||
AttachRemoteDialog::AttachRemoteDialog(QWidget *parent, const QString &pid) :
|
||||
QDialog(parent),
|
||||
m_ui(new Ui::AttachRemoteDialog),
|
||||
m_model(createProcessModel(this))
|
||||
m_model(new ProcessListFilterModel(this))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
||||
@@ -300,9 +316,22 @@ AttachRemoteDialog::AttachRemoteDialog(QWidget *parent, const QString &pid) :
|
||||
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
|
||||
connect(m_ui->procView, SIGNAL(activated(QModelIndex)),
|
||||
// Do not use activated, will be single click in Oxygen
|
||||
connect(m_ui->procView, SIGNAL(doubleClicked(QModelIndex)),
|
||||
this, SLOT(procSelected(QModelIndex)));
|
||||
|
||||
QPushButton *refreshButton = new QPushButton(tr("Refresh"));
|
||||
connect(refreshButton, SIGNAL(clicked()), this, SLOT(rebuildProcessList()));
|
||||
m_ui->buttonBox->addButton(refreshButton, QDialogButtonBox::ActionRole);
|
||||
|
||||
connect(m_ui->pidLineEdit, SIGNAL(textChanged(QString)),
|
||||
this, SLOT(pidChanged(QString)));
|
||||
|
||||
connect(m_ui->filterClearToolButton, SIGNAL(clicked()),
|
||||
m_ui->filterLineEdit, SLOT(clear()));
|
||||
connect(m_ui->filterLineEdit, SIGNAL(textChanged(QString)),
|
||||
m_model, SLOT(setFilterFixedString(QString)));
|
||||
|
||||
m_ui->pidLineEdit->setText(m_defaultPID);
|
||||
rebuildProcessList();
|
||||
}
|
||||
@@ -312,22 +341,27 @@ AttachRemoteDialog::~AttachRemoteDialog()
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
QPushButton *AttachRemoteDialog::okButton() const
|
||||
{
|
||||
return m_ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||
}
|
||||
|
||||
void AttachRemoteDialog::rebuildProcessList()
|
||||
{
|
||||
populateProcessModel(m_model);
|
||||
m_model->populate(processList());
|
||||
m_ui->procView->expandAll();
|
||||
m_ui->procView->resizeColumnToContents(0);
|
||||
m_ui->procView->resizeColumnToContents(1);
|
||||
}
|
||||
|
||||
void AttachRemoteDialog::procSelected(const QModelIndex &index0)
|
||||
{
|
||||
QModelIndex index = index0.sibling(index0.row(), 0);
|
||||
QStandardItem *item = m_model->itemFromIndex(index);
|
||||
if (!item)
|
||||
return;
|
||||
m_ui->pidLineEdit->setText(item->text());
|
||||
accept();
|
||||
{
|
||||
const QString proccessId = m_model->processIdAt(index0);
|
||||
if (!proccessId.isEmpty()) {
|
||||
m_ui->pidLineEdit->setText(proccessId);
|
||||
if (okButton()->isEnabled())
|
||||
okButton()->animateClick();
|
||||
}
|
||||
}
|
||||
|
||||
int AttachRemoteDialog::attachPID() const
|
||||
@@ -335,6 +369,12 @@ int AttachRemoteDialog::attachPID() const
|
||||
return m_ui->pidLineEdit->text().toInt();
|
||||
}
|
||||
|
||||
void AttachRemoteDialog::pidChanged(const QString &pid)
|
||||
{
|
||||
okButton()->setEnabled(!pid.isEmpty() && pid != QLatin1String("0"));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// StartExternalDialog
|
||||
@@ -385,3 +425,6 @@ QString StartExternalDialog::executableArguments() const
|
||||
{
|
||||
return m_ui->argsEdit->text();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QModelIndex;
|
||||
class QStandardItemModel;
|
||||
class QSortFilterProxyModel;
|
||||
class QPushButton;
|
||||
|
||||
namespace Ui {
|
||||
@@ -52,6 +50,8 @@ QT_END_NAMESPACE
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class ProcessListFilterModel;
|
||||
|
||||
struct ProcData
|
||||
{
|
||||
QString ppid;
|
||||
@@ -98,8 +98,7 @@ private:
|
||||
const QString m_selfPid;
|
||||
|
||||
Ui::AttachExternalDialog *m_ui;
|
||||
QStandardItemModel *m_model;
|
||||
QSortFilterProxyModel *m_proxyModel;
|
||||
ProcessListFilterModel *m_model;
|
||||
};
|
||||
|
||||
|
||||
@@ -116,11 +115,13 @@ public:
|
||||
private slots:
|
||||
void rebuildProcessList();
|
||||
void procSelected(const QModelIndex &);
|
||||
void pidChanged(const QString &);
|
||||
|
||||
private:
|
||||
inline QPushButton *okButton() const;
|
||||
Ui::AttachRemoteDialog *m_ui;
|
||||
QString m_defaultPID;
|
||||
QStandardItemModel *m_model;
|
||||
ProcessListFilterModel *m_model;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user