Commit 7a6beafa authored by hjk's avatar hjk

debugger: merge attach to local and remote process dialogs

This also merges a larger part of the two code paths.

Change-Id: I84a88c53ebc0073becac88ba04e63efd9a4a98b3
Reviewed-by: default avatarThomas Hartmann <Thomas.Hartmann@nokia.com>
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 389dc900
This diff is collapsed.
......@@ -52,7 +52,6 @@ class DebuggerStartParameters;
namespace Internal {
class AttachCoreDialogPrivate;
class AttachExternalDialogPrivate;
class AttachToQmlPortDialogPrivate;
class ProcessListFilterModel;
class StartExternalDialogPrivate;
......@@ -61,37 +60,6 @@ class StartRemoteDialogPrivate;
class StartRemoteEngineDialogPrivate;
class StartRemoteParameters;
class AttachExternalDialog : public QDialog
{
Q_OBJECT
public:
explicit AttachExternalDialog(QWidget *parent);
~AttachExternalDialog();
qint64 attachPID() const;
QString executable() const;
int profileIndex() const;
void setProfileIndex(int);
Core::Id profileId() const;
void accept();
private slots:
void rebuildProcessList();
void procSelected(const QModelIndex &index);
void procClicked(const QModelIndex &index);
void pidChanged(const QString &index);
void setFilterString(const QString &filter);
private:
inline QPushButton *okButton() const;
inline QString attachPIDText() const;
AttachExternalDialogPrivate *d;
};
class StartExternalDialog : public QDialog
{
Q_OBJECT
......
......@@ -63,6 +63,7 @@
#include "debuggertooltipmanager.h"
#include "localsandexpressionswindow.h"
#include "loadcoredialog.h"
#include "hostutils.h"
#include "snapshothandler.h"
#include "threadshandler.h"
......@@ -94,11 +95,13 @@
#include <projectexplorer/abi.h>
#include <projectexplorer/applicationrunconfiguration.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorersettings.h>
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
#include <projectexplorer/profilechooser.h>
#include <projectexplorer/profileinformation.h>
#include <projectexplorer/profilemanager.h>
#include <projectexplorer/target.h>
......@@ -776,13 +779,12 @@ public slots:
void startRemoteCdbSession();
void startRemoteProcess();
void startRemoteServer();
//bool queryRemoteParameters(DebuggerStartParameters &sp, bool useScript);
void attachToRemoteServer();
void attachToProcess(bool startServerOnly);
void attachToRunningApplication();
void attachToQmlPort();
void startRemoteEngine();
void attachExternalApplication();
Q_SLOT void attachExternalApplication(ProjectExplorer::RunControl *rc);
//Q_SLOT void attachToLocalProcess(ProjectExplorer::RunControl *rc);
void runScheduled();
void attachCore();
......@@ -1122,7 +1124,6 @@ public:
QAction *m_attachToRemoteServerAction;
QAction *m_startRemoteCdbAction;
QAction *m_startRemoteLldbAction;
QAction *m_attachToLocalProcessAction;
QAction *m_attachToCoreAction;
QAction *m_detachAction;
QAction *m_continueAction;
......@@ -1245,7 +1246,6 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) :
m_attachToQmlPortAction = 0;
m_startRemoteCdbAction = 0;
m_startRemoteLldbAction = 0;
m_attachToLocalProcessAction = 0;
m_attachToCoreAction = 0;
m_detachAction = 0;
......@@ -1520,44 +1520,44 @@ void DebuggerPluginPrivate::startExternalApplication()
startDebugger(rc);
}
void DebuggerPluginPrivate::attachExternalApplication()
{
AttachExternalDialog dlg(mainWindow());
dlg.setProfileIndex(configValue(_("LastAttachExternalProfileIndex")).toInt());
if (dlg.exec() != QDialog::Accepted)
return;
if (dlg.attachPID() == 0) {
QMessageBox::warning(mainWindow(), tr("Warning"),
tr("Cannot attach to process with PID 0"));
return;
}
setConfigValue(_("LastAttachExternalProfileIndex"), QVariant(dlg.profileIndex()));
DebuggerStartParameters sp;
fillParameters(&sp, dlg.profileId());
sp.attachPID = dlg.attachPID();
sp.displayName = tr("Process %1").arg(dlg.attachPID());
sp.executable = dlg.executable();
sp.startMode = AttachExternal;
sp.closeMode = DetachAtClose;
if (DebuggerRunControl *rc = createDebugger(sp))
startDebugger(rc);
}
//void DebuggerPluginPrivate::attachToLocalProcessHelper()
//{
// AttachExternalDialog dlg(mainWindow());
// dlg.setProfileIndex(configValue(_("LastAttachExternalProfileIndex")).toInt());
// if (dlg.exec() != QDialog::Accepted)
// return;
// if (dlg.attachPID() == 0) {
// QMessageBox::warning(mainWindow(), tr("Warning"),
// tr("Cannot attach to process with PID 0"));
// return;
// }
// setConfigValue(_("LastAttachExternalProfileIndex"), QVariant(dlg.profileIndex()));
// DebuggerStartParameters sp;
// fillParameters(&sp, dlg.profileId());
// sp.attachPID = dlg.attachPID();
// sp.displayName = tr("Process %1").arg(dlg.attachPID());
// sp.executable = dlg.executable();
// sp.startMode = AttachExternal;
// sp.closeMode = DetachAtClose;
// if (DebuggerRunControl *rc = createDebugger(sp))
// startDebugger(rc);
//}
void DebuggerPluginPrivate::attachExternalApplication(RunControl *rc)
{
DebuggerStartParameters sp;
fillParameters(&sp, ProfileManager::instance()->defaultProfile()->id()); // FIXME: Extract from rc.
sp.attachPID = rc->applicationProcessHandle().pid();
sp.displayName = tr("Debugger attached to %1").arg(rc->displayName());
sp.startMode = AttachExternal;
sp.closeMode = DetachAtClose;
if (DebuggerRunControl *rc = createDebugger(sp))
startDebugger(rc);
}
//void DebuggerPluginPrivate::attachToLocalProcess(RunControl *rc)
//{
// DebuggerStartParameters sp;
// fillParameters(&sp, ProfileManager::instance()->defaultProfile()->id()); // FIXME: Extract from rc.
// sp.attachPID = rc->applicationProcessHandle().pid();
// sp.displayName = tr("Debugger attached to %1").arg(rc->displayName());
// sp.startMode = AttachExternal;
// sp.closeMode = DetachAtClose;
// if (DebuggerRunControl *rc = createDebugger(sp))
// startDebugger(rc);
//}
void DebuggerPluginPrivate::attachCore()
{
......@@ -1637,11 +1637,6 @@ void DebuggerPluginPrivate::startRemoteCdbSession()
startDebugger(rc);
}
//bool DebuggerPluginPrivate::queryRemoteParameters(DebuggerStartParameters &sp, bool useScript)
//{
// return StartRemoteDialog::run(mainWindow(), m_coreSettings, useScript, &sp);
//}
void DebuggerPluginPrivate::startRemoteProcess()
{
DebuggerStartParameters sp;
......@@ -1665,16 +1660,68 @@ void DebuggerPluginPrivate::attachToRemoteServer()
}
}
//const char LastProfile[] = "Debugger/LastProfile";
//const char LastDevice[] = "Debugger/LastDevice";
//const char LastProcessName[] = "Debugger/LastProcessName";
//const char LastLocalExecutable[] = "Debugger/LastLocalExecutable";
void DebuggerPluginPrivate::startRemoteServer()
{
StartGdbServerDialog dlg(mainWindow());
dlg.startGdbServer();
attachToProcess(true);
}
void DebuggerPluginPrivate::attachToRunningApplication()
{
StartGdbServerDialog dlg(mainWindow());
dlg.attachToRemoteProcess();
attachToProcess(false);
}
void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
{
DeviceProcessesDialog *dlg = new DeviceProcessesDialog(mainWindow());
dlg->showAllDevices();
if (dlg->exec() == QDialog::Rejected) {
delete dlg;
return;
}
dlg->setAttribute(Qt::WA_DeleteOnClose);
ProfileChooser *profileChooser = dlg->profileChooser();
Profile *profile = profileChooser->currentProfile();
QTC_ASSERT(profile, return);
IDevice::ConstPtr device = DeviceProfileInformation::device(profile);
QTC_ASSERT(device, return);
DeviceProcess process = dlg->currentProcess();
if (process.pid == 0) {
QMessageBox::warning(mainWindow(), tr("Warning"),
tr("Cannot attach to process with PID 0"));
return;
}
#ifdef Q_OS_WIN
if (isWinProcessBeingDebugged(process.pid)) {
QMessageBox::warning(ICore::mainWindow(), tr("Process Already Under Debugger Control"),
tr("The process %1 is already under the control of a debugger.\n"
"Qt Creator cannot attach to it.").arg(process.pid));
return;
}
#endif
//setConfigValue(_("LastAttachExternalProfileIndex"), QVariant(dlg->profileChooser()->currentProfileId()));
if (device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
DebuggerStartParameters sp;
fillParameters(&sp, profile->id());
sp.attachPID = process.pid;
sp.displayName = tr("Process %1").arg(process.pid);
sp.executable = process.exe;
sp.startMode = AttachExternal;
sp.closeMode = DetachAtClose;
if (DebuggerRunControl *rc = createDebugger(sp))
startDebugger(rc);
} else {
GdbServerStarter *starter = new GdbServerStarter(dlg, startServerOnly);
starter->run();
}
}
void DebuggerPluginPrivate::attachToQmlPort()
......@@ -2137,7 +2184,6 @@ void DebuggerPluginPrivate::setInitialState()
m_toolTipManager->closeAllToolTips();
m_startLocalProcessAction->setEnabled(true);
m_attachToLocalProcessAction->setEnabled(true);
m_attachToQmlPortAction->setEnabled(true);
m_attachToCoreAction->setEnabled(true);
m_startRemoteProcessAction->setEnabled(true);
......@@ -2264,7 +2310,6 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_startLocalProcessAction->setEnabled(true);
m_attachToQmlPortAction->setEnabled(true);
m_attachToLocalProcessAction->setEnabled(true);
m_attachToCoreAction->setEnabled(true);
m_startRemoteProcessAction->setEnabled(true);
m_attachToRemoteServerAction->setEnabled(true);
......@@ -2962,10 +3007,6 @@ void DebuggerPluginPrivate::extensionsInitialized()
connect(act, SIGNAL(triggered()), SLOT(startRemoteEngine()));
#endif
act = m_attachToLocalProcessAction = new QAction(this);
act->setText(tr("Attach to Running Local Application..."));
connect(act, SIGNAL(triggered()), SLOT(attachExternalApplication()));
act = m_attachToCoreAction = new QAction(this);
act->setText(tr("Load Core File..."));
connect(act, SIGNAL(triggered()), SLOT(attachCore()));
......@@ -3065,11 +3106,6 @@ void DebuggerPluginPrivate::extensionsInitialized()
cmd->setDescription(tr("Start Gdbserver"));
mstart->addAction(cmd, Constants::G_MANUAL_REMOTE);
cmd = ActionManager::registerAction(m_attachToLocalProcessAction,
"Debugger.AttachToLocalProcess", globalcontext);
cmd->setAttribute(Command::CA_Hide);
mstart->addAction(cmd, Constants::G_MANUAL_REMOTE);
#ifdef WITH_LLDB
cmd = ActionManager::registerAction(m_startRemoteLldbAction,
"Debugger.RemoteLldb", globalcontext);
......
......@@ -32,35 +32,26 @@
#define STARTGDBSERVERDIALOG_H
#include "debugger_global.h"
#include <QDialog>
#include <projectexplorer/profile.h>
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
namespace Debugger {
namespace Internal {
namespace Internal { class StartGdbServerDialogPrivate; }
class StartGdbServerDialogPrivate;
class DEBUGGER_EXPORT StartGdbServerDialog : public QDialog
class GdbServerStarter : public QObject
{
Q_OBJECT
public:
StartGdbServerDialog(QWidget *parent);
~StartGdbServerDialog();
void startGdbServer();
void attachToRemoteProcess();
GdbServerStarter(ProjectExplorer::DeviceProcessesDialog *dlg, bool startServerOnly);
~GdbServerStarter();
signals:
void processAborted();
void run();
private slots:
void attachToDevice();
void handleRemoteError(const QString &errorMessage);
void handleProcessListUpdated();
void updateProcessList();
void attachToProcess();
void handleProcessKilled();
void updateButtons();
void portGathererError(const QString &errorMessage);
void portListReady();
......@@ -71,13 +62,12 @@ private slots:
void handleConnectionError();
private:
void startGdbServerOnPort(int port, int pid);
void reportOpenPort(int port);
void reportFailure();
void attach(int port);
void logMessage(const QString &line);
Internal::StartGdbServerDialogPrivate *d;
StartGdbServerDialogPrivate *d;
};
} // namespace Internal
} // namespace Debugger
#endif // STARTGDBSERVERDIALOG_H
......@@ -32,37 +32,36 @@
#include "../projectexplorer_export.h"
#include <projectexplorer/profile.h>
#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/devicesupport/deviceprocesslist.h>
#include <QDialog>
namespace ProjectExplorer {
class DeviceProcessList;
class ProfileChooser;
namespace Internal {
class DeviceProcessesDialogPrivate;
namespace Internal { class DeviceProcessesDialogPrivate; }
class DeviceProcessesDialog : public QDialog
class PROJECTEXPLORER_EXPORT DeviceProcessesDialog : public QDialog
{
Q_OBJECT
public:
// Note: The dialog takes ownership of processList.
explicit DeviceProcessesDialog(DeviceProcessList *processList, QWidget *parent = 0);
explicit DeviceProcessesDialog(QWidget *parent = 0);
~DeviceProcessesDialog();
private slots:
void updateProcessList();
void killProcess();
void handleRemoteError(const QString &errorMsg);
void handleProcessListUpdated();
void handleProcessKilled();
void handleSelectionChanged();
void setDevice(const IDevice::ConstPtr &device);
void showAllDevices();
DeviceProcess currentProcess() const;
ProfileChooser *profileChooser() const;
void logMessage(const QString &line);
private:
Internal::DeviceProcessesDialogPrivate * const d;
};
} // namespace Internal
} // namespace RemoteLinux
#endif // REMOTELINUXPROCESSESDIALOG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProjectExplorer::Internal::DeviceProcessesDialog</class>
<widget class="QDialog" name="ProjectExplorer::Internal::DeviceProcessesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>766</width>
<height>684</height>
</rect>
</property>
<property name="windowTitle">
<string>List of Remote Processes</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="filterLabel">
<property name="text">
<string>&amp;Filter entries:</string>
</property>
<property name="buddy">
<cstring>processFilterLineEdit</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="processFilterLineEdit"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTreeView" name="treeView"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="updateListButton">
<property name="text">
<string>&amp;Update List</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="killProcessButton">
<property name="text">
<string>&amp;Kill Selected Process</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ProjectExplorer::Internal::DeviceProcessesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>290</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ProjectExplorer::Internal::DeviceProcessesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
......@@ -134,7 +134,10 @@ int DeviceProcessList::rowCount(const QModelIndex &parent) const
return parent.isValid() ? 0 : d->remoteProcesses.count();
}
int DeviceProcessList::columnCount(const QModelIndex &) const { return 2; }
int DeviceProcessList::columnCount(const QModelIndex &) const
{
return 2;
}
QVariant DeviceProcessList::headerData(int section, Qt::Orientation orientation,
int role) const
......@@ -142,7 +145,7 @@ QVariant DeviceProcessList::headerData(int section, Qt::Orientation orientation,
if (orientation != Qt::Horizontal || role != Qt::DisplayRole || section < 0
|| section >= columnCount())
return QVariant();
return section == 0? tr("PID") : tr("Command Line");
return section == 0? tr("Process ID") : tr("Command Line");
}
QVariant DeviceProcessList::data(const QModelIndex &index, int role) const
......
......@@ -248,7 +248,7 @@ int DeviceSettingsWidget::currentIndex() const
return m_ui->configurationComboBox->currentIndex();
}
QSharedPointer<const IDevice> DeviceSettingsWidget::currentDevice() const
IDevice::ConstPtr DeviceSettingsWidget::currentDevice() const
{
Q_ASSERT(currentIndex() != -1);
return m_deviceManagerModel->device(currentIndex());
......@@ -335,8 +335,9 @@ void DeviceSettingsWidget::handleAdditionalActionRequest(int actionId)
void DeviceSettingsWidget::handleProcessListRequested()
{
QTC_ASSERT(currentDevice()->canCreateProcessModel(), return);
DeviceProcessesDialog d(currentDevice()->createProcessListModel());
d.exec();
DeviceProcessesDialog dlg;
dlg.setDevice(currentDevice());
dlg.exec();
}
} // namespace Internal
......
......@@ -30,6 +30,7 @@
#ifndef DEVICESETTINGSWIDGET_H
#define DEVICESETTINGSWIDGET_H
#include "devicesupport/idevice.h"
#include <coreplugin/id.h>
#include <QList>
......@@ -75,7 +76,7 @@ private:
void initGui();
void displayCurrent();
void setDeviceInfoWidgetsEnabled(bool enable);
QSharedPointer<const IDevice> currentDevice() const;
IDevice::ConstPtr currentDevice() const;
int currentIndex() const;
void clearDetails();
QString parseTestOutput();
......
......@@ -174,7 +174,7 @@ void LocalProcessList::handleWindowsUpdate()
CloseHandle(snapshot);
reportProcessListUpdated(processes);
#endif //Q_OS_WIN
#endif
}
void LocalProcessList::handlePsError()
......
......@@ -245,7 +245,6 @@ FORMS += processstep.ui \
publishing/publishingwizardselectiondialog.ui \
codestylesettingspropertiespage.ui \
devicesupport/devicefactoryselectiondialog.ui \
devicesupport/deviceprocessesdialog.ui \
devicesupport/devicesettingswidget.ui