Commit 1f32ba92 authored by hjk's avatar hjk
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 85010230 355f44fe
......@@ -1499,6 +1499,9 @@
paths may fail. For example, remounting parts of a file system
using the --bind mount option.
\o Running Qt Creator on Windows with 16 bit color depth results in
black icons and possible crashes. This was fixed in an updated
version released 05 March 2009.
\endlist
*/
......
......@@ -36,10 +36,26 @@
namespace Core {
namespace Utils {
static QString toAlphaNum(const QString &s)
{
QString rc;
const int len = s.size();
const QChar underscore = QLatin1Char('_');
for (int i = 0; i < len; i++) {
const QChar c = s.at(i);
if (c == underscore || c.isLetterOrNumber())
rc += c;
}
return rc;
}
QWORKBENCH_UTILS_EXPORT QString headerGuard(const QString &file)
{
QString rc = QFileInfo(file).baseName().toUpper();
rc += QLatin1String("_H");
const QFileInfo fi(file);
QString rc = toAlphaNum(fi.completeBaseName()).toUpper();
rc += QLatin1Char('_');
rc += toAlphaNum(fi.suffix()).toUpper();
return rc;
}
......
......@@ -207,8 +207,8 @@ EditorView::EditorView(EditorModel *model, QWidget *parent) :
m_lockButton(new QToolButton),
m_defaultToolBar(new QToolBar(this)),
m_infoWidget(new QFrame(this)),
m_statusWidget(new QFrame(this)),
m_editorForInfoWidget(0)
m_editorForInfoWidget(0),
m_statusWidget(new QFrame(this))
{
QVBoxLayout *tl = new QVBoxLayout(this);
tl->setSpacing(0);
......
......@@ -183,7 +183,7 @@ bool CppClassWizard::generateHeaderAndSource(const CppClassWizardParameters &par
return false;
const QString unqualifiedClassName = namespaceList.takeLast();
const QString guard = Core::Utils::headerGuard(unqualifiedClassName);
const QString guard = Core::Utils::headerGuard(params.headerFile);
// == Header file ==
QTextStream headerStr(header);
......
......@@ -369,10 +369,7 @@ void CPPEditor::jumpToMethod(int)
if (! symbol)
return;
Core::EditorManager::instance()->addCurrentPositionToNavigationHistory(true);
openEditorAt(symbol);
Core::EditorManager::instance()->addCurrentPositionToNavigationHistory();
setFocus();
}
void CPPEditor::updateMethodBoxIndex()
......@@ -977,7 +974,7 @@ bool CPPEditor::openEditorAt(Symbol *s)
--column;
if (s->isGenerated())
unsigned column = 0;
column = 0;
return openCppEditorAt(fileName, line, column);
}
......@@ -31,6 +31,8 @@
#include "cppeditor.h"
#include "cppeditorconstants.h"
#include <utils/codegeneration.h>
#include <QtCore/QTextStream>
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
......@@ -48,20 +50,6 @@ CppFileWizard::CppFileWizard(const BaseFileWizardParameters &parameters,
{
}
QString CppFileWizard::toAlphaNum(const QString &s)
{
QString rc;
const int len = s.size();
const QChar underscore = QLatin1Char('_');
for (int i = 0; i < len; i++) {
const QChar c = s.at(i);
if (c == underscore || c.isLetterOrNumber())
rc += c;
}
return rc;
}
Core::GeneratedFiles CppFileWizard::generateFilesFromPath(const QString &path,
const QString &name,
QString * /*errorMessage*/) const
......@@ -69,11 +57,11 @@ Core::GeneratedFiles CppFileWizard::generateFilesFromPath(const QString &path,
{
const QString mimeType = m_type == Source ? QLatin1String(Constants::CPP_SOURCE_MIMETYPE) : QLatin1String(Constants::CPP_HEADER_MIMETYPE);
const QString fileName = Core::BaseFileWizard::buildFileName(path, name, preferredSuffix(mimeType));
Core::GeneratedFile file(fileName);
file.setEditorKind(QLatin1String(Constants::C_CPPEDITOR));
const QString cleanName = toAlphaNum(QFileInfo(name).baseName());
file.setContents(fileContents(m_type, fileName));
return Core::GeneratedFiles() << file;
}
......@@ -84,8 +72,7 @@ QString CppFileWizard::fileContents(FileType type, const QString &fileName) cons
QTextStream str(&contents);
switch (type) {
case Header: {
QString guard = toAlphaNum(baseName).toUpper();
guard += QLatin1String("_H");
const QString guard = Core::Utils::headerGuard(fileName);
str << QLatin1String("#ifndef ") << guard
<< QLatin1String("\n#define ") << guard << QLatin1String("\n\n#endif // ")
<< guard << QLatin1String("\n");
......
......@@ -49,7 +49,6 @@ public:
QObject *parent = 0);
protected:
static QString toAlphaNum(const QString &s);
QString fileContents(FileType type, const QString &baseName) const;
protected:
......
<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;
}