Initial import

This commit is contained in:
con
2008-12-02 12:01:29 +01:00
commit 05c35356ab
1675 changed files with 229938 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
<plugin name="Debugger" version="0.9.1" compatVersion="0.9.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Technology Preview License Agreement</license>
<description>Debugger integration.</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="CppEditor" version="0.9.1"/><!-- Debugger plugin adds items to the editor's context menu -->
<dependency name="ProjectExplorer" version="0.9.1"/>
<dependency name="Core" version="0.9.1"/>
<dependency name="Find" version="0.9.1"/>
</dependencyList>
</plugin>

View File

@@ -0,0 +1,45 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_QWB_ASSERT_H
#define DEBUGGER_QWB_ASSERT_H
#ifdef Q_OS_UNIX
#define QWB_ASSERT(cond, action) \
if(cond){}else{qDebug()<<"ASSERTION"<<#cond<<"FAILED"<<__FILE__<<__LINE__;action;}
#else
#define QWB_ASSERT(cond, action) \
if(cond){}else{qDebug()<<"ASSERTION"<<#cond<<"FAILED";action;}
#endif
#endif

View File

@@ -0,0 +1,344 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "attachexternaldialog.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QPushButton>
#include <QStandardItemModel>
#include <QHeaderView>
using namespace Debugger::Internal;
AttachExternalDialog::AttachExternalDialog(QWidget *parent, const QString &pid)
: QDialog(parent)
{
setupUi(this);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
m_defaultPID = pid;
m_model = new QStandardItemModel(this);
procView->setSortingEnabled(true);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(procView, SIGNAL(activated(const QModelIndex &)),
this, SLOT(procSelected(const QModelIndex &)));
pidLineEdit->setText(m_defaultPID);
rebuildProcessList();
}
static bool isProcessName(const QString &procname)
{
for (int i = 0; i != procname.size(); ++i)
if (!procname.at(i).isDigit())
return false;
return true;
}
struct ProcData {
QString ppid;
QString name;
QString state;
};
static void insertItem(QStandardItem *root, const QString &pid,
const QMap<QString, ProcData> &procs, QMap<QString, QStandardItem *> &known)
{
//qDebug() << "HANDLING " << pid;
QStandardItem *parent = 0;
const ProcData &proc = procs[pid];
if (1 || pid == "0") {
parent = root;
} else {
if (!known.contains(proc.ppid))
insertItem(root, proc.ppid, procs, known);
parent = known[proc.ppid];
}
QList<QStandardItem *> row;
row.append(new QStandardItem(pid));
row.append(new QStandardItem(proc.name));
//row.append(new QStandardItem(proc.ppid));
row.append(new QStandardItem(proc.state));
parent->appendRow(row);
known[pid] = row[0];
}
void AttachExternalDialog::rebuildProcessList()
{
QStringList procnames = QDir("/proc/").entryList();
if (procnames.isEmpty()) {
procView->hide();
return;
}
typedef QMap<QString, ProcData> Procs;
Procs procs;
foreach (const QString &procname, procnames) {
if (!isProcessName(procname))
continue;
QString filename = "/proc/" + procname + "/stat";
QFile file(filename);
file.open(QIODevice::ReadOnly);
QStringList data = QString::fromLocal8Bit(file.readAll()).split(' ');
//qDebug() << filename << data;
ProcData proc;
proc.name = data.at(1);
if (proc.name.startsWith('(') && proc.name.endsWith(')'))
proc.name = proc.name.mid(1, proc.name.size() - 2);
proc.state = data.at(2);
proc.ppid = data.at(3);
procs[procname] = proc;
}
m_model->clear();
QMap<QString, QStandardItem *> known;
for (Procs::const_iterator it = procs.begin(); it != procs.end(); ++it)
insertItem(m_model->invisibleRootItem(), it.key(), procs, known);
m_model->setHeaderData(0, Qt::Horizontal, "Process ID", Qt::DisplayRole);
m_model->setHeaderData(1, Qt::Horizontal, "Name", Qt::DisplayRole);
//model->setHeaderData(2, Qt::Horizontal, "Parent", Qt::DisplayRole);
m_model->setHeaderData(2, Qt::Horizontal, "State", Qt::DisplayRole);
procView->setModel(m_model);
procView->expandAll();
procView->resizeColumnToContents(0);
procView->resizeColumnToContents(1);
}
#ifdef Q_OS_WINDOWS
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <stdio.h>
// Forward declarations:
BOOL GetProcessList( );
BOOL ListProcessModules( DWORD dwPID );
BOOL ListProcessThreads( DWORD dwOwnerPID );
void printError( TCHAR* msg );
BOOL GetProcessList( )
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
printError( TEXT("CreateToolhelp32Snapshot (of processes)") );
return( FALSE );
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof( PROCESSENTRY32 );
// Retrieve information about the first process,
// and exit if unsuccessful
if( !Process32First( hProcessSnap, &pe32 ) )
{
printError( TEXT("Process32First") ); // show cause of failure
CloseHandle( hProcessSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the snapshot of processes, and
// display information about each process in turn
do
{
printf( "\n\n=====================================================" );
_tprintf( TEXT("\nPROCESS NAME: %s"), pe32.szExeFile );
printf( "\n-----------------------------------------------------" );
// Retrieve the priority class.
dwPriorityClass = 0;
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );
if( hProcess == NULL )
printError( TEXT("OpenProcess") );
else
{
dwPriorityClass = GetPriorityClass( hProcess );
if( !dwPriorityClass )
printError( TEXT("GetPriorityClass") );
CloseHandle( hProcess );
}
printf( "\n Process ID = 0x%08X", pe32.th32ProcessID );
printf( "\n Thread count = %d", pe32.cntThreads );
printf( "\n Parent process ID = 0x%08X", pe32.th32ParentProcessID );
printf( "\n Priority base = %d", pe32.pcPriClassBase );
if( dwPriorityClass )
printf( "\n Priority class = %d", dwPriorityClass );
// List the modules and threads associated with this process
ListProcessModules( pe32.th32ProcessID );
ListProcessThreads( pe32.th32ProcessID );
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return( TRUE );
}
BOOL ListProcessModules( DWORD dwPID )
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
printError( TEXT("CreateToolhelp32Snapshot (of modules)") );
return( FALSE );
}
// Set the size of the structure before using it.
me32.dwSize = sizeof( MODULEENTRY32 );
// Retrieve information about the first module,
// and exit if unsuccessful
if( !Module32First( hModuleSnap, &me32 ) )
{
printError( TEXT("Module32First") ); // show cause of failure
CloseHandle( hModuleSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the module list of the process,
// and display information about each module
do
{
_tprintf( TEXT("\n\n MODULE NAME: %s"), me32.szModule );
_tprintf( TEXT("\n Executable = %s"), me32.szExePath );
printf( "\n Process ID = 0x%08X", me32.th32ProcessID );
printf( "\n Ref count (g) = 0x%04X", me32.GlblcntUsage );
printf( "\n Ref count (p) = 0x%04X", me32.ProccntUsage );
printf( "\n Base address = 0x%08X", (DWORD) me32.modBaseAddr );
printf( "\n Base size = %d", me32.modBaseSize );
} while( Module32Next( hModuleSnap, &me32 ) );
CloseHandle( hModuleSnap );
return( TRUE );
}
BOOL ListProcessThreads( DWORD dwOwnerPID )
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32 );
// Retrieve information about the first thread,
// and exit if unsuccessful
if( !Thread32First( hThreadSnap, &te32 ) )
{
printError( TEXT("Thread32First") ); // show cause of failure
CloseHandle( hThreadSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if( te32.th32OwnerProcessID == dwOwnerPID )
{
printf( "\n\n THREAD ID = 0x%08X", te32.th32ThreadID );
printf( "\n Base priority = %d", te32.tpBasePri );
printf( "\n Delta priority = %d", te32.tpDeltaPri );
}
} while( Thread32Next(hThreadSnap, &te32 ) );
CloseHandle( hThreadSnap );
return( TRUE );
}
void printError( TCHAR* msg )
{
DWORD eNum;
TCHAR sysMsg[256];
TCHAR* p;
eNum = GetLastError( );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
sysMsg, 256, NULL );
// Trim the end of the line and terminate it with a null
p = sysMsg;
while( ( *p > 31 ) || ( *p == 9 ) )
++p;
do { *p-- = 0; } while( ( p >= sysMsg ) &&
( ( *p == '.' ) || ( *p < 33 ) ) );
// Display the message
_tprintf( TEXT("\n WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg );
}
#endif
void AttachExternalDialog::procSelected(const QModelIndex &index0)
{
QModelIndex index = index0.sibling(index0.row(), 0);
QStandardItem *item = m_model->itemFromIndex(index);
if (!item)
return;
pidLineEdit->setText(item->text());
accept();
}
int AttachExternalDialog::attachPID() const
{
return pidLineEdit->text().toInt();
}

View File

@@ -0,0 +1,65 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef ATTACHEXTERNALDIALOG_H
#define ATTACHEXTERNALDIALOG_H
#include "ui_attachexternaldialog.h"
QT_BEGIN_NAMESPACE
class QStandardItemModel;
QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
class AttachExternalDialog : public QDialog, Ui::AttachExternalDialog
{
Q_OBJECT
public:
explicit AttachExternalDialog(QWidget *parent, const QString &pid);
int attachPID() const;
private slots:
void rebuildProcessList();
void procSelected(const QModelIndex &);
private:
QString m_defaultPID;
QStandardItemModel *m_model;
};
} // namespace Debugger
} // namespace Internal
#endif // ATTACHEEXTERNALDIALOG_H

View File

@@ -0,0 +1,64 @@
<ui version="4.0" >
<class>AttachExternalDialog</class>
<widget class="QDialog" name="AttachExternalDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<height>866</height>
</rect>
</property>
<property name="windowTitle" >
<string>Start Debugger</string>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>9</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<widget class="QLabel" name="pidLabel" >
<property name="text" >
<string>Attach to Process ID:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="pidLineEdit" />
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="procView" >
<property name="editTriggers" >
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,344 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "attachremotedialog.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QPushButton>
#include <QStandardItemModel>
#include <QHeaderView>
using namespace Debugger::Internal;
AttachRemoteDialog::AttachRemoteDialog(QWidget *parent, const QString &pid)
: QDialog(parent)
{
setupUi(this);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
m_defaultPID = pid;
m_model = new QStandardItemModel(this);
procView->setSortingEnabled(true);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(procView, SIGNAL(activated(const QModelIndex &)),
this, SLOT(procSelected(const QModelIndex &)));
pidLineEdit->setText(m_defaultPID);
rebuildProcessList();
}
static bool isProcessName(const QString &procname)
{
for (int i = 0; i != procname.size(); ++i)
if (!procname.at(i).isDigit())
return false;
return true;
}
struct ProcData {
QString ppid;
QString name;
QString state;
};
static void insertItem(QStandardItem *root, const QString &pid,
const QMap<QString, ProcData> &procs, QMap<QString, QStandardItem *> &known)
{
//qDebug() << "HANDLING " << pid;
QStandardItem *parent = 0;
const ProcData &proc = procs[pid];
if (1 || pid == "0") {
parent = root;
} else {
if (!known.contains(proc.ppid))
insertItem(root, proc.ppid, procs, known);
parent = known[proc.ppid];
}
QList<QStandardItem *> row;
row.append(new QStandardItem(pid));
row.append(new QStandardItem(proc.name));
//row.append(new QStandardItem(proc.ppid));
row.append(new QStandardItem(proc.state));
parent->appendRow(row);
known[pid] = row[0];
}
void AttachRemoteDialog::rebuildProcessList()
{
QStringList procnames = QDir("/proc/").entryList();
if (procnames.isEmpty()) {
procView->hide();
return;
}
typedef QMap<QString, ProcData> Procs;
Procs procs;
foreach (const QString &procname, procnames) {
if (!isProcessName(procname))
continue;
QString filename = "/proc/" + procname + "/stat";
QFile file(filename);
file.open(QIODevice::ReadOnly);
QStringList data = QString::fromLocal8Bit(file.readAll()).split(' ');
//qDebug() << filename << data;
ProcData proc;
proc.name = data.at(1);
if (proc.name.startsWith('(') && proc.name.endsWith(')'))
proc.name = proc.name.mid(1, proc.name.size() - 2);
proc.state = data.at(2);
proc.ppid = data.at(3);
procs[procname] = proc;
}
m_model->clear();
QMap<QString, QStandardItem *> known;
for (Procs::const_iterator it = procs.begin(); it != procs.end(); ++it)
insertItem(m_model->invisibleRootItem(), it.key(), procs, known);
m_model->setHeaderData(0, Qt::Horizontal, "Process ID", Qt::DisplayRole);
m_model->setHeaderData(1, Qt::Horizontal, "Name", Qt::DisplayRole);
//model->setHeaderData(2, Qt::Horizontal, "Parent", Qt::DisplayRole);
m_model->setHeaderData(2, Qt::Horizontal, "State", Qt::DisplayRole);
procView->setModel(m_model);
procView->expandAll();
procView->resizeColumnToContents(0);
procView->resizeColumnToContents(1);
}
#ifdef Q_OS_WINDOWS
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <stdio.h>
// Forward declarations:
BOOL GetProcessList( );
BOOL ListProcessModules( DWORD dwPID );
BOOL ListProcessThreads( DWORD dwOwnerPID );
void printError( TCHAR* msg );
BOOL GetProcessList( )
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
printError( TEXT("CreateToolhelp32Snapshot (of processes)") );
return( FALSE );
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof( PROCESSENTRY32 );
// Retrieve information about the first process,
// and exit if unsuccessful
if( !Process32First( hProcessSnap, &pe32 ) )
{
printError( TEXT("Process32First") ); // show cause of failure
CloseHandle( hProcessSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the snapshot of processes, and
// display information about each process in turn
do
{
printf( "\n\n=====================================================" );
_tprintf( TEXT("\nPROCESS NAME: %s"), pe32.szExeFile );
printf( "\n-----------------------------------------------------" );
// Retrieve the priority class.
dwPriorityClass = 0;
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );
if( hProcess == NULL )
printError( TEXT("OpenProcess") );
else
{
dwPriorityClass = GetPriorityClass( hProcess );
if( !dwPriorityClass )
printError( TEXT("GetPriorityClass") );
CloseHandle( hProcess );
}
printf( "\n Process ID = 0x%08X", pe32.th32ProcessID );
printf( "\n Thread count = %d", pe32.cntThreads );
printf( "\n Parent process ID = 0x%08X", pe32.th32ParentProcessID );
printf( "\n Priority base = %d", pe32.pcPriClassBase );
if( dwPriorityClass )
printf( "\n Priority class = %d", dwPriorityClass );
// List the modules and threads associated with this process
ListProcessModules( pe32.th32ProcessID );
ListProcessThreads( pe32.th32ProcessID );
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return( TRUE );
}
BOOL ListProcessModules( DWORD dwPID )
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
printError( TEXT("CreateToolhelp32Snapshot (of modules)") );
return( FALSE );
}
// Set the size of the structure before using it.
me32.dwSize = sizeof( MODULEENTRY32 );
// Retrieve information about the first module,
// and exit if unsuccessful
if( !Module32First( hModuleSnap, &me32 ) )
{
printError( TEXT("Module32First") ); // show cause of failure
CloseHandle( hModuleSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the module list of the process,
// and display information about each module
do
{
_tprintf( TEXT("\n\n MODULE NAME: %s"), me32.szModule );
_tprintf( TEXT("\n Executable = %s"), me32.szExePath );
printf( "\n Process ID = 0x%08X", me32.th32ProcessID );
printf( "\n Ref count (g) = 0x%04X", me32.GlblcntUsage );
printf( "\n Ref count (p) = 0x%04X", me32.ProccntUsage );
printf( "\n Base address = 0x%08X", (DWORD) me32.modBaseAddr );
printf( "\n Base size = %d", me32.modBaseSize );
} while( Module32Next( hModuleSnap, &me32 ) );
CloseHandle( hModuleSnap );
return( TRUE );
}
BOOL ListProcessThreads( DWORD dwOwnerPID )
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32 );
// Retrieve information about the first thread,
// and exit if unsuccessful
if( !Thread32First( hThreadSnap, &te32 ) )
{
printError( TEXT("Thread32First") ); // show cause of failure
CloseHandle( hThreadSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if( te32.th32OwnerProcessID == dwOwnerPID )
{
printf( "\n\n THREAD ID = 0x%08X", te32.th32ThreadID );
printf( "\n Base priority = %d", te32.tpBasePri );
printf( "\n Delta priority = %d", te32.tpDeltaPri );
}
} while( Thread32Next(hThreadSnap, &te32 ) );
CloseHandle( hThreadSnap );
return( TRUE );
}
void printError( TCHAR* msg )
{
DWORD eNum;
TCHAR sysMsg[256];
TCHAR* p;
eNum = GetLastError( );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
sysMsg, 256, NULL );
// Trim the end of the line and terminate it with a null
p = sysMsg;
while( ( *p > 31 ) || ( *p == 9 ) )
++p;
do { *p-- = 0; } while( ( p >= sysMsg ) &&
( ( *p == '.' ) || ( *p < 33 ) ) );
// Display the message
_tprintf( TEXT("\n WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg );
}
#endif
void AttachRemoteDialog::procSelected(const QModelIndex &index0)
{
QModelIndex index = index0.sibling(index0.row(), 0);
QStandardItem *item = m_model->itemFromIndex(index);
if (!item)
return;
pidLineEdit->setText(item->text());
accept();
}
int AttachRemoteDialog::attachPID() const
{
return pidLineEdit->text().toInt();
}

View File

@@ -0,0 +1,65 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef ATTACHREMOTE_DIALOG_H
#define ATTACHREMOTE_DIALOG_H
#include "ui_attachremotedialog.h"
QT_BEGIN_NAMESPACE
class QStandardItemModel;
QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
class AttachRemoteDialog : public QDialog, Ui::AttachRemoteDialog
{
Q_OBJECT
public:
explicit AttachRemoteDialog(QWidget *parent, const QString &pid);
int attachPID() const;
private slots:
void rebuildProcessList();
void procSelected(const QModelIndex &);
private:
QString m_defaultPID;
QStandardItemModel *m_model;
};
} // namespace Debugger
} // namespace Internal
#endif // ATTACHREMOTEDIALOG_H

View File

@@ -0,0 +1,64 @@
<ui version="4.0" >
<class>AttachRemoteDialog</class>
<widget class="QDialog" name="AttachRemoteDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<height>866</height>
</rect>
</property>
<property name="windowTitle" >
<string>Start Debugger</string>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>9</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<widget class="QLabel" name="pidLabel" >
<property name="text" >
<string>Attach to Process ID:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="pidLineEdit" />
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="procView" >
<property name="editTriggers" >
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BreakByFunctionDialog</class>
<widget class="QDialog" name="BreakByFunctionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>337</width>
<height>101</height>
</rect>
</property>
<property name="windowTitle">
<string>Start Debugger</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="functionLabel">
<property name="text">
<string>Function to break on:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="functionLineEdit"/>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BreakCondition</class>
<widget class="QDialog" name="BreakCondition">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>435</width>
<height>142</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="labelCondition">
<property name="text">
<string>Condition:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditCondition"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelIgnoreCount">
<property name="text">
<string>Ignore count:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBoxIgnoreCount">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="maximum">
<number>999999999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>BreakCondition</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>BreakCondition</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>

View File

@@ -0,0 +1,559 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "breakhandler.h"
#include "assert.h"
#include "imports.h" // TextEditor::BaseTextMark
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
using namespace Debugger;
using namespace Debugger::Internal;
//////////////////////////////////////////////////////////////////
//
// BreakpointMarker
//
//////////////////////////////////////////////////////////////////
namespace Debugger {
namespace Internal {
// The red blob on the left side in the cpp editor.
class BreakpointMarker : public TextEditor::BaseTextMark
{
Q_OBJECT
public:
BreakpointMarker(BreakpointData *data, const QString &fileName, int lineNumber)
: BaseTextMark(fileName, lineNumber), m_data(data), m_pending(true)
{
//qDebug() << "CREATE MARKER " << fileName << lineNumber;
}
~BreakpointMarker()
{
//qDebug() << "REMOVE MARKER ";
m_data = 0;
}
QIcon icon() const
{
static const QIcon icon(":/gdbdebugger/images/breakpoint.svg");
static const QIcon icon2(":/gdbdebugger/images/breakpoint_pending.svg");
return m_pending ? icon2 : icon;
}
void setPending(bool pending)
{
if (pending == m_pending)
return;
m_pending = pending;
updateMarker();
}
void updateBlock(const QTextBlock &)
{
//qDebug() << "BREAKPOINT MARKER UPDATE BLOCK";
}
void removedFromEditor()
{
if (!m_data)
return;
BreakHandler *handler = m_data->handler();
handler->removeBreakpoint(handler->indexOf(m_data));
handler->saveBreakpoints();
handler->updateMarkers();
}
void updateLineNumber(int lineNumber)
{
if (!m_data)
return;
//if (m_data->markerLineNumber == lineNumber)
// return;
if (m_data->markerLineNumber != lineNumber) {
m_data->markerLineNumber = lineNumber;
// FIXME: should we tell gdb about the change?
// Ignore it for now, as we would require re-compilation
// and debugger re-start anyway.
if (0 && !m_data->bpLineNumber.isEmpty()) {
if (!m_data->bpNumber.trimmed().isEmpty()) {
m_data->pending = true;
}
}
}
m_data->lineNumber = QString::number(lineNumber);
m_data->handler()->updateMarkers();
}
private:
BreakpointData *m_data;
bool m_pending;
};
} // namespace Internal
} // namespace Debugger
//////////////////////////////////////////////////////////////////
//
// BreakpointData
//
//////////////////////////////////////////////////////////////////
BreakpointData::BreakpointData(BreakHandler *handler)
{
//qDebug() << "CREATE BREAKPOINTDATA" << this;
m_handler = handler;
pending = true;
marker = 0;
markerLineNumber = 0;
bpMultiple = false;
}
BreakpointData::~BreakpointData()
{
removeMarker();
//qDebug() << "DESTROY BREAKPOINTDATA" << this;
}
void BreakpointData::removeMarker()
{
BreakpointMarker *m = marker;
marker = 0;
delete m;
}
void BreakpointData::updateMarker()
{
if (marker && (markerFileName != marker->fileName()
|| markerLineNumber != marker->lineNumber()))
removeMarker();
if (!marker && !markerFileName.isEmpty() && markerLineNumber > 0)
marker = new BreakpointMarker(this, markerFileName, markerLineNumber);
if (marker)
marker->setPending(pending);
}
QString BreakpointData::toToolTip() const
{
QString str;
str += "<table>";
str += "<tr><td>Marker File:</td><td>" + markerFileName + "</td></tr>";
str += "<tr><td>Marker Line:</td><td>" + QString::number(markerLineNumber) + "</td></tr>";
str += "<tr><td>BP Number:</td><td>" + bpNumber + "</td></tr>";
str += "<tr><td>BP Address:</td><td>" + bpAddress + "</td></tr>";
str += "<tr><td>----------</td><td></td><td></td></tr>";
str += "<tr><td>Property:</td><td>Wanted:</td><td>Actual:</td></tr>";
str += "<tr><td></td><td></td><td></td></tr>";
str += "<tr><td>Internal Number:</td><td>-</td><td>" + bpNumber + "</td></tr>";
str += "<tr><td>File Name:</td><td>" + fileName + "</td><td>" + bpFileName + "</td></tr>";
str += "<tr><td>Function Name:</td><td>" + funcName + "</td><td>" + bpFuncName + "</td></tr>";
str += "<tr><td>Line Number:</td><td>" + lineNumber + "</td><td>" + bpLineNumber + "</td></tr>";
str += "<tr><td>Condition:</td><td>" + condition + "</td><td>" + bpCondition + "</td></tr>";
str += "<tr><td>Ignore count:</td><td>" + ignoreCount + "</td><td>" + bpIgnoreCount + "</td></tr>";
str += "</table>";
return str;
}
bool BreakpointData::isLocatedAt(const QString &fileName_, int lineNumber_) const
{
/*
if (lineNumber != QString::number(lineNumber_))
return false;
if (fileName == fileName_)
return true;
if (fileName_.endsWith(fileName))
return true;
return false;
*/
return lineNumber_ == markerLineNumber && fileName_ == markerFileName;
}
bool BreakpointData::conditionsMatch() const
{
// same versions of gdb "beautify" the passed condition
QString s1 = condition;
s1.remove(QChar(' '));
QString s2 = bpCondition;
s2.remove(QChar(' '));
return s1 == s2;
}
//////////////////////////////////////////////////////////////////
//
// BreakHandler
//
//////////////////////////////////////////////////////////////////
BreakHandler::BreakHandler(QObject *parent)
: QAbstractItemModel(parent)
{
}
int BreakHandler::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 6;
}
int BreakHandler::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : size();
}
void BreakHandler::removeAt(int index)
{
BreakpointData *data = at(index);
m_bp.removeAt(index);
delete data;
}
void BreakHandler::clear()
{
for (int index = size(); --index >= 0; )
removeAt(index);
}
int BreakHandler::findBreakpoint(const BreakpointData &needle)
{
// looks for a breakpoint we might refer to
for (int index = 0; index != size(); ++index) {
const BreakpointData *data = at(index);
// clear hit.
if (data->bpNumber == needle.bpNumber)
return index;
// at least at a position we were looking for
// FIXME: breaks multiple breakpoints at the same location
if (data->fileName == needle.bpFileName
&& data->lineNumber == needle.bpLineNumber)
return index;
}
return -1;
}
int BreakHandler::findBreakpoint(int bpNumber)
{
for (int index = 0; index != size(); ++index)
if (at(index)->bpNumber == QString::number(bpNumber))
return index;
return -1;
}
void BreakHandler::saveBreakpoints()
{
QList<QVariant> list;
for (int index = 0; index != size(); ++index) {
const BreakpointData *data = at(index);
QMap<QString, QVariant> map;
if (!data->fileName.isEmpty())
map["filename"] = data->fileName;
if (!data->lineNumber.isEmpty())
map["linenumber"] = data->lineNumber;
if (!data->funcName.isEmpty())
map["funcname"] = data->funcName;
if (!data->condition.isEmpty())
map["condition"] = data->condition;
if (!data->ignoreCount.isEmpty())
map["ignorecount"] = data->ignoreCount;
list.append(map);
}
setSessionValueRequested("Breakpoints", list);
}
void BreakHandler::loadBreakpoints()
{
QVariant value;
sessionValueRequested("Breakpoints", &value);
QList<QVariant> list = value.toList();
clear();
foreach (const QVariant &var, list) {
const QMap<QString, QVariant> map = var.toMap();
BreakpointData *data = new BreakpointData(this);
data->fileName = map["filename"].toString();
data->lineNumber = map["linenumber"].toString();
data->condition = map["condition"].toString();
data->ignoreCount = map["ignorecount"].toString();
data->funcName = map["funcname"].toString();
data->markerFileName = data->fileName;
data->markerLineNumber = data->lineNumber.toInt();
append(data);
}
}
void BreakHandler::resetBreakpoints()
{
for (int index = size(); --index >= 0;) {
BreakpointData *data = at(index);
data->pending = true;
data->bpNumber.clear();
data->bpFuncName.clear();
data->bpFileName.clear();
data->bpLineNumber.clear();
data->bpCondition.clear();
data->bpIgnoreCount.clear();
// keep marker data if it was primary
if (data->markerFileName != data->fileName)
data->markerFileName.clear();
if (data->markerLineNumber != data->lineNumber.toInt())
data->markerLineNumber = 0;
}
}
void BreakHandler::updateMarkers()
{
for (int index = 0; index != size(); ++index)
at(index)->updateMarker();
emit layoutChanged();
}
QVariant BreakHandler::headerData(int section,
Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static QString headers[] = {
tr("Number"), tr("Function"), tr("File"), tr("Line"),
tr("Condition"), tr("Ignore")
};
return headers[section];
}
return QVariant();
}
QVariant BreakHandler::data(const QModelIndex &mi, int role) const
{
static const QIcon icon(":/gdbdebugger/images/breakpoint.svg");
static const QIcon icon2(":/gdbdebugger/images/breakpoint_pending.svg");
static const QString empty = QString(QLatin1Char('-'));
QWB_ASSERT(mi.isValid(), return QVariant());
if (mi.row() >= size())
return QVariant();
const BreakpointData *data = at(mi.row());
switch (mi.column()) {
case 0:
if (role == Qt::DisplayRole) {
QString str = data->bpNumber;
return str.isEmpty() ? empty : str;
}
if (role == Qt::DecorationRole)
return data->pending ? icon2 : icon;
break;
case 1:
if (role == Qt::DisplayRole) {
QString str = data->pending ? data->funcName : data->bpFuncName;
return str.isEmpty() ? empty : str;
}
break;
case 2:
if (role == Qt::DisplayRole) {
QString str = data->pending ? data->fileName : data->bpFileName;
str = QFileInfo(str).fileName();
//if (data->bpMultiple && str.isEmpty() && !data->markerFileName.isEmpty())
// str = data->markerFileName;
return str.isEmpty() ? empty : str;
}
break;
case 3:
if (role == Qt::DisplayRole) {
QString str = data->pending ? data->lineNumber : data->bpLineNumber;
//if (data->bpMultiple && str.isEmpty() && !data->markerFileName.isEmpty())
// str = data->markerLineNumber;
return str.isEmpty() ? empty : str;
}
break;
case 4:
if (role == Qt::DisplayRole)
return data->pending ? data->condition : data->bpCondition;
if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit if this condition is met.");
break;
case 5:
if (role == Qt::DisplayRole)
return data->pending ? data->ignoreCount : data->bpIgnoreCount;
if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit after being ignored so many times.");
break;
}
if (role == Qt::ToolTipRole)
return data->toToolTip();
return QVariant();
}
bool BreakHandler::setData(const QModelIndex &mi, const QVariant &value, int role)
{
if (role != Qt::EditRole)
return false;
BreakpointData *data = at(mi.row());
switch (mi.column()) {
case 4: {
QString val = value.toString();
if (val != data->condition) {
data->condition = val;
dataChanged(mi, mi);
}
return true;
}
case 5: {
QString val = value.toString();
if (val != data->ignoreCount) {
data->ignoreCount = val;
dataChanged(mi, mi);
}
return true;
}
default: {
return false;
}
}
}
QList<BreakpointData *> BreakHandler::takeRemovedBreakpoints()
{
QList<BreakpointData *> result = m_removed;
m_removed.clear();
return result;
}
void BreakHandler::removeBreakpointHelper(int index)
{
BreakpointData *data = m_bp.at(index);
m_bp.removeAt(index);
data->removeMarker();
m_removed.append(data);
}
void BreakHandler::removeBreakpoint(int index)
{
if (index < 0 || index >= size())
return;
BreakHandler::removeBreakpointHelper(index);
emit layoutChanged();
saveBreakpoints();
}
int BreakHandler::indexOf(const QString &fileName, int lineNumber)
{
for (int index = 0; index != size(); ++index)
if (at(index)->isLocatedAt(fileName, lineNumber))
return index;
return -1;
}
void BreakHandler::setBreakpoint(const QString &fileName, int lineNumber)
{
QFileInfo fi(fileName);
BreakpointData *data = new BreakpointData(this);
data->fileName = fileName;
data->lineNumber = QString::number(lineNumber);
data->pending = true;
data->markerFileName = fileName;
data->markerLineNumber = lineNumber;
append(data);
emit layoutChanged();
saveBreakpoints();
updateMarkers();
}
void BreakHandler::removeAllBreakpoints()
{
for (int index = size(); --index >= 0;)
removeBreakpointHelper(index);
emit layoutChanged();
saveBreakpoints();
updateMarkers();
}
void BreakHandler::setAllPending()
{
loadBreakpoints();
for (int index = size(); --index >= 0;)
at(index)->pending = true;
saveBreakpoints();
updateMarkers();
}
void BreakHandler::saveSessionData()
{
saveBreakpoints();
updateMarkers();
}
void BreakHandler::loadSessionData()
{
//resetBreakpoints();
loadBreakpoints();
updateMarkers();
}
void BreakHandler::activateBreakPoint(int index)
{
const BreakpointData *data = at(index);
//qDebug() << "BREAKPOINT ACTIVATED: " << data->fileName;
if (!data->markerFileName.isEmpty())
emit gotoLocation(data->markerFileName, data->markerLineNumber, false);
}
void BreakHandler::breakByFunction(const QString &functionName)
{
// One per function is enough for now
for (int index = size(); --index >= 0;) {
const BreakpointData *data = at(index);
QWB_ASSERT(data, break);
if (data->funcName == functionName && data->condition.isEmpty()
&& data->ignoreCount.isEmpty())
return;
}
BreakpointData *data = new BreakpointData(this);
data->funcName = functionName;
append(data);
saveBreakpoints();
updateMarkers();
}
#include "breakhandler.moc"

View File

@@ -0,0 +1,174 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_BREAKHANDLER_H
#define DEBUGGER_BREAKHANDLER_H
#include <QtCore/QObject>
#include <QtCore/QAbstractItemModel>
namespace Debugger {
namespace Internal {
class BreakpointMarker;
class BreakHandler;
//////////////////////////////////////////////////////////////////
//
// BreakpointData
//
//////////////////////////////////////////////////////////////////
class BreakpointData
{
public:
explicit BreakpointData(BreakHandler *handler);
~BreakpointData();
void removeMarker();
void updateMarker();
QString toToolTip() const;
BreakHandler *handler() { return m_handler; }
bool isLocatedAt(const QString &fileName, int lineNumber) const;
bool conditionsMatch() const;
private:
// Intentionally unimplemented.
// Making it copiable is tricky because of the markers.
void operator=(const BreakpointData &);
BreakpointData(const BreakpointData &);
// Our owner
BreakHandler *m_handler; // not owned.
public:
bool pending; // does the debugger engine know about us already?
// this "user requested information". will get stored in the session
QString fileName; // short name of source file
QString condition; // condition associated with breakpoint
QString ignoreCount; // ignore count associated with breakpoint
QString lineNumber; // line in source file
QString funcName; // name of containing function
// this is what gdb produced in response
QString bpNumber; // breakpoint number assigned by the debugger engine
QString bpCondition; // condition acknowledged by the debugger engine
QString bpIgnoreCount; // ignore count acknowledged by the debugger engine
QString bpFileName; // file name acknowledged by the debugger engine
QString bpLineNumber; // line number acknowledged by the debugger engine
QString bpFuncName; // function name acknowledged by the debugger engine
QString bpAddress; // address acknowledged by the debugger engine
bool bpMultiple; // happens in constructors/gdb
// taken from either user input or gdb responses
QString markerFileName; // used to locate the marker
int markerLineNumber;
// our red blob in the editor
BreakpointMarker *marker;
};
//////////////////////////////////////////////////////////////////
//
// BreakHandler
//
//////////////////////////////////////////////////////////////////
class BreakHandler : public QAbstractItemModel
{
Q_OBJECT
public:
explicit BreakHandler(QObject *parent = 0);
void removeAllBreakpoints();
void setAllPending();
void loadSessionData();
void saveSessionData();
QAbstractItemModel *model() { return this; }
BreakpointData *at(int index) const { return index < size() ? m_bp.at(index) : 0; }
int size() const { return m_bp.size(); }
void append(BreakpointData *data) { m_bp.append(data); }
void removeAt(int index); // also deletes the marker
void clear(); // also deletes all the marker
int indexOf(BreakpointData *data) { return m_bp.indexOf(data); }
int indexOf(const QString &fileName, int lineNumber);
int findBreakpoint(const BreakpointData &data); // returns index
int findBreakpoint(int bpNumber); // returns index
void updateMarkers();
QList<BreakpointData *> takeRemovedBreakpoints();
public slots:
void setBreakpoint(const QString &fileName, int lineNumber);
void breakByFunction(const QString &functionName);
void activateBreakPoint(int index);
void removeBreakpoint(int index);
signals:
void gotoLocation(const QString &fileName, int lineNumber, bool setMarker);
void sessionValueRequested(const QString &name, QVariant *value);
void setSessionValueRequested(const QString &name, const QVariant &value);
private:
friend class BreakpointMarker;
// QAbstractItemModel
int columnCount(const QModelIndex &parent) const;
int rowCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &, int role);
QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
QModelIndex index(int row, int column, const QModelIndex &) const
{ return createIndex(row, column); }
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
void markerUpdated(BreakpointMarker *, int lineNumber);
void loadBreakpoints();
void saveBreakpoints();
void resetBreakpoints();
void removeBreakpointHelper(int index);
QList<BreakpointData *> m_bp;
QList<BreakpointData *> m_removed;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_BREAKHANDLER_H

View File

@@ -0,0 +1,164 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "breakwindow.h"
#include "ui_breakcondition.h"
#include <QAction>
#include <QDir>
#include <QFileInfo>
#include <QFileInfoList>
#include <QHeaderView>
#include <QKeyEvent>
#include <QMenu>
#include <QResizeEvent>
#include <QToolButton>
#include <QTreeView>
using Debugger::Internal::BreakWindow;
BreakWindow::BreakWindow(QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(false)
{
setWindowTitle(tr("Breakpoints"));
setWindowIcon(QIcon(":/gdbdebugger/images/debugger_breakpoints.png"));
setAlternatingRowColors(true);
setRootIsDecorated(false);
setIconSize(QSize(10, 10));
connect(this, SIGNAL(activated(QModelIndex)),
this, SLOT(rowActivated(QModelIndex)));
}
void BreakWindow::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Delete)
deleteBreakpoint(currentIndex());
QTreeView::keyPressEvent(event);
}
void BreakWindow::resizeEvent(QResizeEvent *event)
{
QHeaderView *hv = header();
int totalSize = event->size().width() - 180;
hv->resizeSection(0, 60);
hv->resizeSection(1, (totalSize * 30) / 100);
hv->resizeSection(2, (totalSize * 30) / 100);
hv->resizeSection(3, (totalSize * 30) / 100);
hv->resizeSection(4, 70);
hv->resizeSection(5, 50);
QTreeView::resizeEvent(event);
}
void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
QModelIndex index = indexAt(ev->pos());
QAction *act0 = new QAction("Delete breakpoint", &menu);
QAction *act1 = new QAction("Adjust column widths to contents", &menu);
QAction *act2 = new QAction("Always adjust column widths to contents", &menu);
QAction *act3 = new QAction("Edit condition...", &menu);
act2->setCheckable(true);
act2->setChecked(m_alwaysResizeColumnsToContents);
if (index.isValid()) {
menu.addAction(act0);
menu.addAction(act3);
menu.addSeparator();
}
menu.addAction(act1);
menu.addAction(act2);
QAction *act = menu.exec(ev->globalPos());
if (act == act0)
deleteBreakpoint(index);
else if (act == act1)
resizeColumnsToContents();
else if (act == act2)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == act3)
editCondition(index);
}
void BreakWindow::deleteBreakpoint(const QModelIndex &idx)
{
int row = idx.row();
if (row == model()->rowCount() - 1)
--row;
setCurrentIndex(idx.sibling(row, 0));
emit breakPointDeleted(idx.row());
}
void BreakWindow::editCondition(const QModelIndex &idx)
{
QDialog dlg(this);
Ui::BreakCondition ui;
ui.setupUi(&dlg);
int row = idx.row();
dlg.setWindowTitle(tr("Conditions on Breakpoint %1").arg(row));
ui.lineEditCondition->setText(model()->data(idx.sibling(row, 4)).toString());
ui.spinBoxIgnoreCount->setValue(model()->data(idx.sibling(row, 5)).toInt());
if (dlg.exec() == QDialog::Rejected)
return;
model()->setData(idx.sibling(row, 4), ui.lineEditCondition->text());
model()->setData(idx.sibling(row, 5), ui.spinBoxIgnoreCount->value());
}
void BreakWindow::resizeColumnsToContents()
{
resizeColumnToContents(0);
resizeColumnToContents(1);
resizeColumnToContents(2);
resizeColumnToContents(3);
}
void BreakWindow::setAlwaysResizeColumnsToContents(bool on)
{
m_alwaysResizeColumnsToContents = on;
QHeaderView::ResizeMode mode = on
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
header()->setResizeMode(0, mode);
header()->setResizeMode(1, mode);
header()->setResizeMode(2, mode);
header()->setResizeMode(3, mode);
}
void BreakWindow::rowActivated(const QModelIndex &index)
{
emit breakPointActivated(index.row());
}

View File

@@ -0,0 +1,76 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_BREAKWINDOW_H
#define DEBUGGER_BREAKWINDOW_H
#include <QTreeView>
namespace Debugger {
namespace Internal {
class BreakWindow : public QTreeView
{
Q_OBJECT
public:
BreakWindow(QWidget *parent = 0);
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
signals:
void breakPointDeleted(int index);
void breakPointActivated(int index);
private slots:
void rowActivated(const QModelIndex &index);
protected:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
void keyPressEvent(QKeyEvent *ev);
private:
void deleteBreakpoint(const QModelIndex &idx);
void editCondition(const QModelIndex &idx);
bool m_alwaysResizeColumnsToContents;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_BREAKWINDOW

View File

@@ -0,0 +1,92 @@
TEMPLATE = lib
TARGET = Debugger
# CONFIG += single
include(../../qworkbenchplugin.pri)
include(../../plugins/projectexplorer/projectexplorer.pri)
include(../../plugins/find/find.pri)
include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/texteditor/texteditor.pri)
include(../../plugins/cpptools/cpptools.pri)
include(../../libs/cplusplus/cplusplus.pri)
# DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
QT += gui network script
HEADERS += assert.h \
attachexternaldialog.h \
attachremotedialog.h \
breakhandler.h \
breakwindow.h \
debuggerconstants.h \
debuggermanager.h \
debuggeroutputwindow.h \
debuggerplugin.h \
debuggerrunner.h \
mode.h \
disassemblerhandler.h \
disassemblerwindow.h \
gdbengine.h \
gdbmi.h \
gdboptionpage.h \
idebuggerengine.h \
imports.h \
moduleshandler.h \
moduleswindow.h \
procinterrupt.h \
registerhandler.h \
registerwindow.h \
scriptengine.h \
stackhandler.h \
stackwindow.h \
startexternaldialog.h \
threadswindow.h \
watchhandler.h \
watchwindow.h
SOURCES += attachexternaldialog.cpp \
attachremotedialog.cpp \
breakhandler.cpp \
breakwindow.cpp \
breakwindow.h \
debuggermanager.cpp \
debuggeroutputwindow.cpp \
debuggerplugin.cpp \
debuggerrunner.cpp \
mode.cpp \
disassemblerhandler.cpp \
disassemblerwindow.cpp \
gdbengine.cpp \
gdbmi.cpp \
gdboptionpage.cpp \
gdbtypemacros.cpp \
gdbengine.h \
moduleshandler.cpp \
moduleswindow.cpp \
procinterrupt.cpp \
registerhandler.cpp \
registerwindow.cpp \
scriptengine.cpp \
stackhandler.cpp \
stackwindow.cpp \
startexternaldialog.cpp \
threadswindow.cpp \
watchhandler.cpp \
watchwindow.cpp
FORMS += attachexternaldialog.ui \
attachremotedialog.ui \
breakbyfunction.ui \
breakcondition.ui \
mode.ui \
gdboptionpage.ui \
gdbtypemacros.ui \
startexternaldialog.ui \
RESOURCES += debugger.qrc
false {
SOURCES += $$PWD/modeltest.cpp
HEADERS += $$PWD/modeltest.h
DEFINES += USE_MODEL_TEST=1
}

View File

@@ -0,0 +1,24 @@
<RCC>
<qresource prefix="/gdbdebugger" >
<file>images/breakpoint.svg</file>
<file>images/breakpoint_pending.svg</file>
<file>images/debugger_breakpoints.png</file>
<file>images/debugger_continue_small.png</file>
<file>images/debugger_interrupt_small.png</file>
<file>images/debugger_start.png</file>
<file>images/debugger_start_small.png</file>
<file>images/debugger_stepinto_small.png</file>
<file>images/debugger_stepout_small.png</file>
<file>images/debugger_stepover_small.png</file>
<file>images/debugger_steponeproc_small.png</file>
<file>images/debugger_stepoverproc_small.png</file>
<file>images/debugger_stop_small.png</file>
<file>images/delete.png</file>
<file>images/done.png</file>
<file>images/empty.svg</file>
<file>images/error.png</file>
<file>images/location.svg</file>
<file>images/newitem.png</file>
<file>images/running.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,65 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGERCONSTANTS_H
#define DEBUGGERCONSTANTS_H
namespace Debugger {
namespace Constants {
// modes and their priorities
const char * const MODE_DEBUG = "Debugger.Mode.Debug";
const int P_MODE_DEBUG = 85;
// common actions
const char * const INTERRUPT = "Debugger.Interrupt";
const char * const RESET = "Debugger.Reset";
const char * const STEP = "Debugger.StepLine";
const char * const STEPOUT = "Debugger.StepOut";
const char * const NEXT = "Debugger.NextLine";
const char * const STEPI = "Debugger.StepInstruction";
const char * const NEXTI = "Debugger.NextInstruction";
const char * const M_VIEW_DEBUG = "Debugger.Menu.View.Debug";
const char * const G_DEBUG = "Debugger.Group.Debug";
const char * const G_VIEW_DEBUG = "Debugger.Group.View.Debug";
const char * const C_GDBDEBUGGER = "Gdb Debugger";
const char * const GDBRUNNING = "Gdb.Running";
const char * const PROPERTY_REGISTER_FORMAT = "Debugger.Property.RegisterFormat";
} // namespace Constants
} // namespace Debugger
#endif // DEBUGGERCONSTANTS_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,451 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_DEBUGGERMANAGER_H
#define DEBUGGER_DEBUGGERMANAGER_H
#include <QtCore/QByteArray>
#include <QtCore/QObject>
#include <QtCore/QPoint>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
QT_BEGIN_NAMESPACE
class QAction;
class QAbstractItemModel;
class QDockWidget;
class QMainWindow;
class QModelIndex;
class QSplitter;
class QWidget;
QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
class DebuggerOutputWindow;
class DebuggerPlugin;
class DebugMode;
class BreakHandler;
class DisassemblerHandler;
class ModulesHandler;
class RegisterHandler;
class StackHandler;
class ThreadsHandler;
class WatchHandler;
class WatchData;
class BreakpointData;
// Note: the Debugger process itself is referred to as 'Debugger',
// whereas the debugged process is referred to as 'Inferior' or 'Debuggee'.
// DebuggerProcessNotReady
// |
// DebuggerProcessStartingUp
// |
// DebuggerReady [R] [N]
// | <-------------------------------------.
// DebuggerInferiorRunningRequested |
// | |
// DebuggerInferiorRunning |
// | |
// DebuggerInferiorStopRequested |
// | |
// DebuggerInferiorStopped |
// | |
// DebuggerInferiorUpdating |
// | |
// DebuggerInferiorUpdateFinishing |
// | |
// DebuggerInferiorReady [C] [N] |
// | |
// `---------------------------------------'
//
// Allowed actions:
// [R] : Run
// [C] : Continue
// [N] : Step, Next
enum DebuggerStatus
{
DebuggerProcessNotReady, // Debugger not started
DebuggerProcessStartingUp, // Debugger starting up
DebuggerProcessReady, // Debugger started, Inferior not yet
// running or already finished
DebuggerInferiorRunningRequested, // Debuggee requested to run
DebuggerInferiorRunning, // Debuggee running
DebuggerInferiorStopRequested, // Debuggee running, stop requested
DebuggerInferiorStopped, // Debuggee stopped
DebuggerInferiorUpdating, // Debuggee updating data views
DebuggerInferiorUpdateFinishing, // Debuggee updating data views aborting
DebuggerInferiorReady,
};
class IDebuggerEngine;
class GdbEngine;
class ScriptEngine;
class WinEngine;
// The construct below is not nice but enforces a bit of order. The
// DebuggerManager interfaces a lots of thing: The DebuggerPlugin,
// the DebuggerEngines, the RunMode, the handlers and views.
// Instead of making the whole interface public, we split in into
// smaller parts and grant friend access only to the classes that
// need it.
//
// IDebuggerManagerAccessForEngines
//
class IDebuggerManagerAccessForEngines
{
public:
virtual ~IDebuggerManagerAccessForEngines() {}
private:
// This is the part of the interface that's exclusively seen by the
// debugger engines.
friend class GdbEngine;
friend class ScriptEngine;
friend class WinEngine;
// called from the engines after successful startup
virtual void notifyStartupFinished() = 0;
virtual void notifyInferiorStopped() = 0;
virtual void notifyInferiorUpdateFinished() = 0;
virtual void notifyInferiorRunningRequested() = 0;
virtual void notifyInferiorRunning() = 0;
virtual void notifyInferiorExited() = 0;
virtual void notifyInferiorPidChanged(int) = 0;
virtual DisassemblerHandler *disassemblerHandler() = 0;
virtual ModulesHandler *modulesHandler() = 0;
virtual BreakHandler *breakHandler() = 0;
virtual RegisterHandler *registerHandler() = 0;
virtual StackHandler *stackHandler() = 0;
virtual ThreadsHandler *threadsHandler() = 0;
virtual WatchHandler *watchHandler() = 0;
virtual void showApplicationOutput(const QString &prefix, const QString &data) = 0;
virtual QAction *useCustomDumpersAction() const = 0;
virtual QAction *debugDumpersAction() const = 0;
virtual bool skipKnownFrames() const = 0;
virtual bool debugDumpers() const = 0;
virtual bool useCustomDumpers() const = 0;
virtual bool useFastStart() const = 0;
virtual void reloadDisassembler() = 0;
virtual void reloadModules() = 0;
virtual void reloadRegisters() = 0;
};
//
// IDebuggerManagerAccessForDebugMode
//
class IDebuggerManagerAccessForDebugMode
{
public:
virtual ~IDebuggerManagerAccessForDebugMode() {}
private:
friend class DebugMode;
virtual QWidget *threadsWindow() = 0;
virtual QList<QDockWidget*> dockWidgets() const = 0;
virtual void createDockWidgets() = 0;
};
//
// DebuggerManager
//
class DebuggerManager : public QObject,
public IDebuggerManagerAccessForEngines,
public IDebuggerManagerAccessForDebugMode
{
Q_OBJECT
public:
DebuggerManager();
~DebuggerManager();
IDebuggerManagerAccessForEngines *engineInterface();
IDebuggerManagerAccessForDebugMode *debugModeInterface();
QMainWindow *mainWindow() const { return m_mainWindow; }
enum StartMode { startInternal, startExternal, attachExternal };
enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger };
public slots:
bool startNewDebugger(StartMode mode);
void exitDebugger();
void setSimpleDockWidgetArrangement();
void setLocked(bool locked);
void dockToggled(bool on);
void setBusyCursor(bool on);
void queryCurrentTextEditor(QString *fileName, int *lineNumber, QObject **ed);
void querySessionValue(const QString &name, QVariant *value);
void setSessionValue(const QString &name, const QVariant &value);
QVariant configValue(const QString &name);
void queryConfigValue(const QString &name, QVariant *value);
void setConfigValue(const QString &name, const QVariant &value);
QVariant sessionValue(const QString &name);
void gotoLocation(const QString &file, int line, bool setLocationMarker);
void resetLocation();
void interruptDebuggingRequest();
void startExternalApplication();
void attachExternalApplication();
void jumpToLineExec();
void runToLineExec();
void runToFunctionExec();
void toggleBreakpoint();
void breakByFunction();
void breakByFunction(const QString &functionName);
void setBreakpoint(const QString &fileName, int lineNumber);
void watchExpression(const QString &expression);
void breakAtMain();
void activateFrame(int index);
void selectThread(int index);
void stepExec();
void stepOutExec();
void nextExec();
void stepIExec();
void nextIExec();
void continueExec();
void addToWatchWindow();
void updateWatchModel();
void removeWatchExpression(const QString &iname);
void expandChildren(const QModelIndex &idx);
void collapseChildren(const QModelIndex &idx);
void sessionLoaded();
void aboutToSaveSession();
void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand(const QString &command);
void showStatusMessage(const QString &msg, int timeout); // -1 forever
private slots:
void showDebuggerOutput(const QString &prefix, const QString &msg);
void showDebuggerInput(const QString &prefix, const QString &msg);
void showApplicationOutput(const QString &prefix, const QString &msg);
void reloadDisassembler();
void disassemblerDockToggled(bool on);
void reloadModules();
void modulesDockToggled(bool on);
void loadSymbols(const QString &moduleName);
void loadAllSymbols();
void reloadRegisters();
void registerDockToggled(bool on);
void setStatus(int status);
private:
//
// Implementation of IDebuggerManagerAccessForEngines
//
DisassemblerHandler *disassemblerHandler() { return m_disassemblerHandler; }
ModulesHandler *modulesHandler() { return m_modulesHandler; }
BreakHandler *breakHandler() { return m_breakHandler; }
RegisterHandler *registerHandler() { return m_registerHandler; }
StackHandler *stackHandler() { return m_stackHandler; }
ThreadsHandler *threadsHandler() { return m_threadsHandler; }
WatchHandler *watchHandler() { return m_watchHandler; }
QAction *useCustomDumpersAction() const { return m_useCustomDumpersAction; }
QAction *debugDumpersAction() const { return m_debugDumpersAction; }
bool skipKnownFrames() const;
bool debugDumpers() const;
bool useCustomDumpers() const;
bool useFastStart() const;
void notifyStartupFinished();
void notifyInferiorStopped();
void notifyInferiorUpdateFinished();
void notifyInferiorRunningRequested();
void notifyInferiorRunning();
void notifyInferiorExited();
void notifyInferiorPidChanged(int);
void cleanupViews();
//
// Implementation of IDebuggerManagerAccessForDebugMode
//
QWidget *threadsWindow() { return m_threadsWindow; }
QList<QDockWidget*> dockWidgets() const { return m_dockWidgets; }
void createDockWidgets();
//
// internal implementation
//
Q_SLOT void loadSessionData();
Q_SLOT void saveSessionData();
Q_SLOT void dumpLog();
public:
// stuff in this block should be made private by moving it to
// one of the interfaces
QAbstractItemModel *threadsModel();
int status() const { return m_status; }
StartMode startMode() const { return m_startMode; }
signals:
void debuggingFinished();
void inferiorPidChanged(qint64 pid);
void statusChanged(int newstatus);
void debugModeRequested();
void previousModeRequested();
void statusMessageRequested(const QString &msg, int timeout); // -1 for 'forever'
void gotoLocationRequested(const QString &file, int line, bool setLocationMarker);
void resetLocationRequested();
void currentTextEditorRequested(QString *fileName, int *lineNumber, QObject **ob);
void currentMainWindowRequested(QWidget **);
void sessionValueRequested(const QString &name, QVariant *value);
void setSessionValueRequested(const QString &name, const QVariant &value);
void configValueRequested(const QString &name, QVariant *value);
void setConfigValueRequested(const QString &name, const QVariant &value);
void applicationOutputAvailable(const QString &prefix, const QString &msg);
public:
// FIXME: make private
QString m_executable;
QStringList m_environment;
QString m_workingDir;
QString m_buildDir;
QStringList m_processArgs;
int m_attachedPID;
private:
void init();
void setDebuggerType(DebuggerType type);
QDockWidget *createDockForWidget(QWidget *widget);
void shutdown();
void toggleBreakpoint(const QString &fileName, int lineNumber);
void setToolTipExpression(const QPoint &pos, const QString &exp0);
StartMode m_startMode;
DebuggerType m_debuggerType;
/// Views
QMainWindow *m_mainWindow;
QDockWidget *m_breakDock;
QDockWidget *m_disassemblerDock;
QDockWidget *m_modulesDock;
QDockWidget *m_outputDock;
QDockWidget *m_registerDock;
QDockWidget *m_stackDock;
QDockWidget *m_threadsDock;
QDockWidget *m_watchDock;
QList<QDockWidget*> m_dockWidgets;
BreakHandler *m_breakHandler;
DisassemblerHandler *m_disassemblerHandler;
ModulesHandler *m_modulesHandler;
RegisterHandler *m_registerHandler;
StackHandler *m_stackHandler;
ThreadsHandler *m_threadsHandler;
WatchHandler *m_watchHandler;
/// Actions
friend class DebuggerPlugin;
QAction *m_startExternalAction;
QAction *m_attachExternalAction;
QAction *m_continueAction;
QAction *m_stopAction;
QAction *m_resetAction; // FIXME: Should not be needed in a stable release
QAction *m_stepAction;
QAction *m_stepOutAction;
QAction *m_runToLineAction;
QAction *m_runToFunctionAction;
QAction *m_jumpToLineAction;
QAction *m_nextAction;
QAction *m_watchAction;
QAction *m_breakAction;
QAction *m_breakByFunctionAction;
QAction *m_breakAtMainAction;
QAction *m_sepAction;
QAction *m_stepIAction;
QAction *m_nextIAction;
QAction *m_skipKnownFramesAction;
QAction *m_debugDumpersAction;
QAction *m_useCustomDumpersAction;
QAction *m_useFastStartAction;
QAction *m_dumpLogAction;
QWidget *m_breakWindow;
QWidget *m_disassemblerWindow;
QWidget *m_localsWindow;
QWidget *m_registerWindow;
QWidget *m_modulesWindow;
QWidget *m_tooltipWindow;
QWidget *m_stackWindow;
QWidget *m_threadsWindow;
QWidget *m_watchersWindow;
DebuggerOutputWindow *m_outputWindow;
int m_status;
bool m_busy;
IDebuggerEngine *engine();
IDebuggerEngine *m_engine;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_DEBUGGERMANAGER_H

View File

@@ -0,0 +1,318 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "debuggeroutputwindow.h"
#include <QtCore/QDebug>
#include <QtGui/QAction>
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QKeyEvent>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QMenu>
#include <QtGui/QSpacerItem>
#include <QtGui/QSplitter>
#include <QtGui/QTextBlock>
#ifndef GDBDEBUGGERLEAN
#include <aggregation/aggregate.h>
#include <find/basetextfind.h>
using namespace Find;
#endif // GDBDEBUGGERLEAN
using Debugger::Internal::DebuggerOutputWindow;
/////////////////////////////////////////////////////////////////////
//
// InputPane
//
/////////////////////////////////////////////////////////////////////
class DebuggerPane : public QTextEdit
{
public:
DebuggerPane(QWidget *parent)
: QTextEdit(parent)
{
m_clearContentsAction = new QAction(this);
m_clearContentsAction->setText("Clear contents");
m_clearContentsAction->setEnabled(true);
m_clearContentsAction->setShortcut(Qt::ControlModifier + Qt::Key_R);
connect(m_clearContentsAction, SIGNAL(triggered(bool)),
parent, SLOT(clearContents()));
m_saveContentsAction = new QAction(this);
m_saveContentsAction->setText("Save contents");
m_saveContentsAction->setEnabled(true);
}
void contextMenuEvent(QContextMenuEvent *ev)
{
QMenu *menu = createStandardContextMenu();
menu->addAction(m_clearContentsAction);
//menu->addAction(m_saveContentsAction);
addContextActions(menu);
menu->exec(ev->globalPos());
delete menu;
}
virtual void addContextActions(QMenu *) {}
public:
QAction *m_clearContentsAction;
QAction *m_saveContentsAction;
};
class InputPane : public DebuggerPane
{
Q_OBJECT
public:
InputPane(QWidget *parent) : DebuggerPane(parent)
{
m_commandExecutionAction = new QAction(this);
m_commandExecutionAction->setText("Execute line");
m_commandExecutionAction->setEnabled(true);
//m_commandExecutionAction->setShortcut
// (Qt::ControlModifier + Qt::Key_Return);
connect(m_commandExecutionAction, SIGNAL(triggered(bool)),
this, SLOT(executeCommand()));
}
signals:
void commandExecutionRequested(const QString &);
void clearContentsRequested();
void statusMessageRequested(const QString &, int);
void commandSelected(int);
private slots:
void executeCommand()
{
emit commandExecutionRequested(textCursor().block().text());
}
private:
void keyPressEvent(QKeyEvent *ev)
{
if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_Return)
emit commandExecutionRequested(textCursor().block().text());
else if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_R)
emit clearContentsRequested();
else
QTextEdit::keyPressEvent(ev);
}
void mouseDoubleClickEvent(QMouseEvent *ev)
{
QString line = cursorForPosition(ev->pos()).block().text();
int n = 0;
// cut time string
if (line.size() > 18 && line.at(0) == '[')
line = line.mid(18);
//qDebug() << line;
for (int i = 0; i != line.size(); ++i) {
QChar c = line.at(i);
if (!c.isDigit())
break;
n = 10 * n + c.unicode() - '0';
}
emit commandSelected(n);
}
void addContextActions(QMenu *menu)
{
menu->addAction(m_commandExecutionAction);
}
void focusInEvent(QFocusEvent *ev)
{
emit statusMessageRequested("Type Ctrl-<Return> to execute a line.", -1);
QTextEdit::focusInEvent(ev);
}
void focusOutEvent(QFocusEvent *ev)
{
emit statusMessageRequested(QString(), -1);
QTextEdit::focusOutEvent(ev);
}
QAction *m_commandExecutionAction;
};
/////////////////////////////////////////////////////////////////////
//
// CombinedPane
//
/////////////////////////////////////////////////////////////////////
class CombinedPane : public DebuggerPane
{
Q_OBJECT
public:
CombinedPane(QWidget *parent)
: DebuggerPane(parent)
{}
public slots:
void gotoResult(int i)
{
QString needle = QString::number(i) + '^';
QString needle2 = "stdout:" + needle;
QTextCursor cursor(document());
do {
const QString line = cursor.block().text();
if (line.startsWith(needle) || line.startsWith(needle2)) {
setFocus();
setTextCursor(cursor);
ensureCursorVisible();
cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
setTextCursor(cursor);
break;
}
} while (cursor.movePosition(QTextCursor::Down));
}
};
/////////////////////////////////////////////////////////////////////
//
// DebuggerOutputWindow
//
/////////////////////////////////////////////////////////////////////
DebuggerOutputWindow::DebuggerOutputWindow(QWidget *parent)
: QWidget(parent)
{
setWindowTitle(tr("Gdb"));
QSplitter *m_splitter = new QSplitter(Qt::Horizontal, this);
// mixed input/output
m_combinedText = new CombinedPane(this);
m_combinedText->setReadOnly(true);
m_combinedText->setReadOnly(false);
m_combinedText->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
// input only
m_inputText = new InputPane(this);
m_inputText->setReadOnly(false);
m_inputText->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
m_splitter->addWidget(m_inputText);
m_splitter->addWidget(m_combinedText);
QGridLayout *layout = new QGridLayout(this);
layout->setMargin(0);
layout->addWidget(m_splitter);
setLayout(layout);
#ifndef GDBDEBUGGERLEAN
Aggregation::Aggregate *aggregate = new Aggregation::Aggregate;
aggregate->add(m_combinedText);
aggregate->add(new BaseTextFind(m_combinedText));
aggregate = new Aggregation::Aggregate;
aggregate->add(m_inputText);
aggregate->add(new BaseTextFind(m_inputText));
#endif
connect(m_inputText, SIGNAL(commandExecutionRequested(QString)),
this, SIGNAL(commandExecutionRequested(QString)));
connect(m_inputText, SIGNAL(statusMessageRequested(QString,int)),
this, SIGNAL(statusMessageRequested(QString,int)));
connect(m_inputText, SIGNAL(commandSelected(int)),
m_combinedText, SLOT(gotoResult(int)));
};
void DebuggerOutputWindow::onReturnPressed()
{
emit commandExecutionRequested(m_commandEdit->text());
}
void DebuggerOutputWindow::showOutput(const QString &prefix, const QString &output)
{
if (output.isEmpty())
return;
foreach (QString line, output.split("\n")) {
// FIXME: QTextEdit asserts on really long lines...
const int n = 3000;
if (line.size() > n)
line = line.left(n) + " [...] <cut off>";
m_combinedText->append(prefix + line);
}
QTextCursor cursor = m_combinedText->textCursor();
cursor.movePosition(QTextCursor::End);
m_combinedText->setTextCursor(cursor);
m_combinedText->ensureCursorVisible();
}
void DebuggerOutputWindow::showInput(const QString &prefix, const QString &input)
{
m_inputText->append(input);
QTextCursor cursor = m_inputText->textCursor();
cursor.movePosition(QTextCursor::End);
m_inputText->setTextCursor(cursor);
m_inputText->ensureCursorVisible();
showOutput("input:", input);
}
void DebuggerOutputWindow::clearContents()
{
m_combinedText->clear();
m_inputText->clear();
}
void DebuggerOutputWindow::setCursor(const QCursor &cursor)
{
m_combinedText->setCursor(cursor);
m_inputText->setCursor(cursor);
QWidget::setCursor(cursor);
}
QString DebuggerOutputWindow::combinedContents() const
{
return m_combinedText->toPlainText();
}
QString DebuggerOutputWindow::inputContents() const
{
return m_inputText->toPlainText();
}
#include "debuggeroutputwindow.moc"

View File

@@ -0,0 +1,87 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_OUTPUTWINDOW_H
#define DEBUGGER_OUTPUTWINDOW_H
#include <QtGui/QLineEdit>
#include <QtGui/QSplitter>
#include <QtGui/QTextEdit>
#include <QtGui/QWidget>
namespace Debugger {
namespace Internal {
class DebuggerOutputWindow : public QWidget
{
Q_OBJECT
public:
DebuggerOutputWindow(QWidget *parent = 0);
QWidget *outputWidget(QWidget *) { return this; }
QList<QWidget*> toolBarWidgets(void) const { return QList<QWidget *>(); }
QString name() const { return windowTitle(); }
void visibilityChanged(bool /*visible*/) {}
void bringPaneToForeground() { emit showPage(); }
void setCursor(const QCursor &cursor);
QString combinedContents() const;
QString inputContents() const;
public slots:
void clearContents();
void showOutput(const QString &prefix, const QString &output);
void showInput(const QString &prefix, const QString &input);
signals:
void showPage();
void statusMessageRequested(const QString &msg, int);
void commandExecutionRequested(const QString &cmd);
private slots:
void onReturnPressed();
private:
QTextEdit *m_combinedText; // combined input/output
QTextEdit *m_inputText; // scriptable input alone
QLineEdit *m_commandEdit;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_OUTPUTWINDOW_H

View File

@@ -0,0 +1,610 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "debuggerplugin.h"
#include "assert.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "debuggerrunner.h"
#include "gdboptionpage.h"
#include "gdbengine.h"
#include "mode.h"
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <cplusplus/ExpressionUnderCursor.h>
#include <cppeditor/cppeditorconstants.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/session.h>
#include <texteditor/basetextmark.h>
#include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h>
#include <texteditor/basetexteditor.h>
#include <QtCore/QDebug>
#include <QtCore/qplugin.h>
#include <QtCore/QObject>
#include <QtCore/QPoint>
#include <QtCore/QSettings>
#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextBlock>
#include <QtGui/QTextCursor>
using namespace Debugger::Internal;
using namespace Debugger::Constants;
using namespace TextEditor;
using namespace Core;
using namespace ProjectExplorer;
using namespace CPlusPlus;
namespace Debugger {
namespace Constants {
const char * const STARTEXTERNAL = "Debugger.StartExternal";
const char * const ATTACHEXTERNAL = "Debugger.AttachExternal";
const char * const RUN_TO_LINE = "Debugger.RunToLine";
const char * const RUN_TO_FUNCTION = "Debugger.RunToFunction";
const char * const JUMP_TO_LINE = "Debugger.JumpToLine";
const char * const TOGGLE_BREAK = "Debugger.ToggleBreak";
const char * const BREAK_BY_FUNCTION = "Debugger.BreakByFunction";
const char * const BREAK_AT_MAIN = "Debugger.BreakAtMain";
const char * const DEBUG_DUMPERS = "Debugger.DebugDumpers";
const char * const ADD_TO_WATCH = "Debugger.AddToWatch";
const char * const USE_CUSTOM_DUMPERS = "Debugger.UseCustomDumpers";
const char * const USE_FAST_START = "Debugger.UseFastStart";
const char * const SKIP_KNOWN_FRAMES = "Debugger.SkipKnownFrames";
const char * const DUMP_LOG = "Debugger.DumpLog";
#ifdef Q_OS_MAC
const char * const INTERRUPT_KEY = "Shift+F5";
const char * const RESET_KEY = "Ctrl+Shift+F5";
const char * const STEP_KEY = "F7";
const char * const STEPOUT_KEY = "Shift+F7";
const char * const NEXT_KEY = "F6";
const char * const STEPI_KEY = "Shift+F9";
const char * const NEXTI_KEY = "Shift+F6";
const char * const RUN_TO_LINE_KEY = "Shift+F8";
const char * const RUN_TO_FUNCTION_KEY = "Ctrl+F6";
const char * const JUMP_TO_LINE_KEY = "Alt+D,Alt+L";
const char * const TOGGLE_BREAK_KEY = "F8";
const char * const BREAK_BY_FUNCTION_KEY = "Alt+D,Alt+F";
const char * const BREAK_AT_MAIN_KEY = "Alt+D,Alt+M";
const char * const ADD_TO_WATCH_KEY = "Alt+D,Alt+W";
#else
const char * const INTERRUPT_KEY = "Shift+F5";
const char * const RESET_KEY = "Ctrl+Shift+F5";
const char * const STEP_KEY = "F11";
const char * const STEPOUT_KEY = "Shift+F11";
const char * const NEXT_KEY = "F10";
const char * const STEPI_KEY = "";
const char * const NEXTI_KEY = "";
const char * const RUN_TO_LINE_KEY = "";
const char * const RUN_TO_FUNCTION_KEY = "";
const char * const JUMP_TO_LINE_KEY = "";
const char * const TOGGLE_BREAK_KEY = "F9";
const char * const BREAK_BY_FUNCTION_KEY = "";
const char * const BREAK_AT_MAIN_KEY = "";
const char * const ADD_TO_WATCH_KEY = "Ctrl+Alt+Q";
#endif
} // namespace Constants
} // namespace Debugger
///////////////////////////////////////////////////////////////////////
//
// LocationMark
//
///////////////////////////////////////////////////////////////////////
class Debugger::Internal::LocationMark
: public TextEditor::BaseTextMark
{
Q_OBJECT
public:
LocationMark(const QString &fileName, int linenumber)
: BaseTextMark(fileName, linenumber)
{
}
~LocationMark();
QIcon icon() const;
void updateLineNumber(int /*lineNumber*/) {}
void updateBlock(const QTextBlock & /*block*/) {}
void removedFromEditor() { deleteLater(); }
private:
};
LocationMark::~LocationMark()
{
//qDebug() << "LOCATIONMARK DESTRUCTOR" << m_editor;
}
QIcon LocationMark::icon() const
{
static const QIcon icon(":/gdbdebugger/images/location.svg");
return icon;
}
///////////////////////////////////////////////////////////////////////
//
// DebuggerPlugin
//
///////////////////////////////////////////////////////////////////////
DebuggerPlugin::DebuggerPlugin()
{
m_pm = 0;
m_generalOptionPage = 0;
m_typeMacroPage = 0;
m_locationMark = 0;
m_manager = 0;
}
DebuggerPlugin::~DebuggerPlugin()
{}
void DebuggerPlugin::shutdown()
{
if (m_debugMode)
m_debugMode->shutdown(); // saves state including manager information
QWB_ASSERT(m_manager, /**/);
if (m_manager)
m_manager->shutdown();
//qDebug() << "DebuggerPlugin::~DebuggerPlugin";
removeObject(m_debugMode);
removeObject(m_generalOptionPage);
removeObject(m_typeMacroPage);
// FIXME: when using the line below, BreakWindow etc gets deleted twice.
// so better leak for now...
delete m_debugMode;
m_debugMode = 0;
delete m_generalOptionPage;
m_generalOptionPage = 0;
delete m_typeMacroPage;
m_typeMacroPage = 0;
delete m_locationMark;
m_locationMark = 0;
delete m_manager;
m_manager = 0;
}
bool DebuggerPlugin::initialize(const QStringList &arguments, QString *error_message)
{
Q_UNUSED(arguments);
Q_UNUSED(error_message);
m_manager = new DebuggerManager;
m_pm = ExtensionSystem::PluginManager::instance();
ICore *core = m_pm->getObject<Core::ICore>();
QWB_ASSERT(core, return false);
Core::ActionManagerInterface *actionManager = core->actionManager();
QWB_ASSERT(actionManager, return false);
Core::UniqueIDManager *uidm = core->uniqueIDManager();
QWB_ASSERT(uidm, return false);
QList<int> globalcontext;
globalcontext << Core::Constants::C_GLOBAL_ID;
QList<int> cppcontext;
cppcontext << uidm->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX);
QList<int> debuggercontext;
debuggercontext << uidm->uniqueIdentifier(C_GDBDEBUGGER);
QList<int> cppeditorcontext;
cppeditorcontext << uidm->uniqueIdentifier(CppEditor::Constants::C_CPPEDITOR);
QList<int> texteditorcontext;
texteditorcontext << uidm->uniqueIdentifier(TextEditor::Constants::C_TEXTEDITOR);
m_gdbRunningContext = uidm->uniqueIdentifier(Constants::GDBRUNNING);
//Core::IActionContainer *mcppcontext =
// actionManager->actionContainer(CppEditor::Constants::M_CONTEXT);
Core::IActionContainer *mdebug =
actionManager->actionContainer(ProjectExplorer::Constants::M_DEBUG);
Core::ICommand *cmd = 0;
cmd = actionManager->registerAction(m_manager->m_startExternalAction,
Constants::STARTEXTERNAL, globalcontext);
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
#ifndef Q_OS_WIN
cmd = actionManager->registerAction(m_manager->m_attachExternalAction,
Constants::ATTACHEXTERNAL, globalcontext);
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
#endif
cmd = actionManager->registerAction(m_manager->m_continueAction,
ProjectExplorer::Constants::DEBUG, QList<int>()<< m_gdbRunningContext);
cmd = actionManager->registerAction(m_manager->m_stopAction,
Constants::INTERRUPT, globalcontext);
cmd->setAttribute(Core::ICommand::CA_UpdateText);
cmd->setAttribute(Core::ICommand::CA_UpdateIcon);
cmd->setDefaultKeySequence(QKeySequence(Constants::INTERRUPT_KEY));
cmd->setDefaultText(tr("Stop Debugger/Interrupt Debugger"));
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
cmd = actionManager->registerAction(m_manager->m_resetAction,
Constants::RESET, globalcontext);
cmd->setAttribute(Core::ICommand::CA_UpdateText);
cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY));
cmd->setDefaultText(tr("Reset Debugger"));
//disabled mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
QAction *sep = new QAction(this);
sep->setSeparator(true);
cmd = actionManager->registerAction(sep,
QLatin1String("GdbDebugger.Sep1"), globalcontext);
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_nextAction,
Constants::NEXT, debuggercontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::NEXT_KEY));
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_stepAction,
Constants::STEP, debuggercontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::STEP_KEY));
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_stepOutAction,
Constants::STEPOUT, debuggercontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::STEPOUT_KEY));
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_nextIAction,
Constants::NEXTI, debuggercontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::NEXTI_KEY));
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_stepIAction,
Constants::STEPI, debuggercontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::STEPI_KEY));
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_runToLineAction,
Constants::RUN_TO_LINE, debuggercontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY));
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_runToFunctionAction,
Constants::RUN_TO_FUNCTION, debuggercontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_FUNCTION_KEY));
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_jumpToLineAction,
Constants::JUMP_TO_LINE, debuggercontext);
mdebug->addAction(cmd);
sep = new QAction(this);
sep->setSeparator(true);
cmd = actionManager->registerAction(sep,
QLatin1String("GdbDebugger.Sep3"), globalcontext);
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_breakAction,
Constants::TOGGLE_BREAK, cppeditorcontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::TOGGLE_BREAK_KEY));
mdebug->addAction(cmd);
//mcppcontext->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_breakByFunctionAction,
Constants::BREAK_BY_FUNCTION, globalcontext);
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_breakAtMainAction,
Constants::BREAK_AT_MAIN, globalcontext);
mdebug->addAction(cmd);
sep = new QAction(this);
sep->setSeparator(true);
cmd = actionManager->registerAction(sep,
QLatin1String("GdbDebugger.Sep2"), globalcontext);
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_skipKnownFramesAction,
Constants::SKIP_KNOWN_FRAMES, globalcontext);
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_useCustomDumpersAction,
Constants::USE_CUSTOM_DUMPERS, globalcontext);
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_useFastStartAction,
Constants::USE_FAST_START, globalcontext);
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_dumpLogAction,
Constants::DUMP_LOG, globalcontext);
//cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+L")));
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F11")));
mdebug->addAction(cmd);
#ifdef QT_DEBUG
cmd = actionManager->registerAction(m_manager->m_debugDumpersAction,
Constants::DEBUG_DUMPERS, debuggercontext);
mdebug->addAction(cmd);
#endif
sep = new QAction(this);
sep->setSeparator(true);
cmd = actionManager->registerAction(sep,
QLatin1String("GdbDebugger.Sep4"), globalcontext);
mdebug->addAction(cmd);
cmd = actionManager->registerAction(m_manager->m_watchAction,
Constants::ADD_TO_WATCH, cppeditorcontext);
//cmd->setDefaultKeySequence(QKeySequence(tr("ALT+D,ALT+W")));
mdebug->addAction(cmd);
m_generalOptionPage = 0;
m_typeMacroPage = 0;
// FIXME:
m_generalOptionPage = new GdbOptionPage(&theGdbSettings());
addObject(m_generalOptionPage);
m_typeMacroPage = new TypeMacroPage(&theGdbSettings());
addObject(m_typeMacroPage);
m_locationMark = 0;
m_debugMode = new DebugMode(m_manager, this);
//addAutoReleasedObject(m_debugMode);
addObject(m_debugMode);
addAutoReleasedObject(new DebuggerRunner(m_manager));
// ProjectExplorer
connect(projectExplorer()->session(), SIGNAL(sessionLoaded()),
m_manager, SLOT(sessionLoaded()));
connect(projectExplorer()->session(), SIGNAL(aboutToSaveSession()),
m_manager, SLOT(aboutToSaveSession()));
// EditorManager
QObject *editorManager = core->editorManager();
connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
this, SLOT(editorAboutToClose(Core::IEditor*)));
connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
this, SLOT(editorOpened(Core::IEditor*)));
// Application interaction
connect(m_manager, SIGNAL(currentTextEditorRequested(QString*,int*,QObject**)),
this, SLOT(queryCurrentTextEditor(QString*,int*,QObject**)));
connect(m_manager, SIGNAL(setSessionValueRequested(QString,QVariant)),
this, SLOT(setSessionValue(QString,QVariant)));
connect(m_manager, SIGNAL(sessionValueRequested(QString,QVariant*)),
this, SLOT(querySessionValue(QString,QVariant*)));
connect(m_manager, SIGNAL(setConfigValueRequested(QString,QVariant)),
this, SLOT(setConfigValue(QString,QVariant)));
connect(m_manager, SIGNAL(configValueRequested(QString,QVariant*)),
this, SLOT(queryConfigValue(QString,QVariant*)));
connect(m_manager, SIGNAL(resetLocationRequested()),
this, SLOT(resetLocation()));
connect(m_manager, SIGNAL(gotoLocationRequested(QString,int,bool)),
this, SLOT(gotoLocation(QString,int,bool)));
connect(m_manager, SIGNAL(statusChanged(int)),
this, SLOT(changeStatus(int)));
connect(m_manager, SIGNAL(previousModeRequested()),
this, SLOT(activatePreviousMode()));
connect(m_manager, SIGNAL(debugModeRequested()),
this, SLOT(activateDebugMode()));
return true;
}
void DebuggerPlugin::extensionsInitialized()
{
}
ProjectExplorer::ProjectExplorerPlugin *DebuggerPlugin::projectExplorer() const
{
return m_pm->getObject<ProjectExplorer::ProjectExplorerPlugin>();
}
/*! Activates the previous mode when the current mode is the debug mode. */
void DebuggerPlugin::activatePreviousMode()
{
ICore *core = m_pm->getObject<Core::ICore>();
Core::ModeManager *const modeManager = core->modeManager();
if (modeManager->currentMode() == modeManager->mode(Constants::MODE_DEBUG)
&& !m_previousMode.isEmpty()) {
modeManager->activateMode(m_previousMode);
m_previousMode.clear();
}
}
void DebuggerPlugin::activateDebugMode()
{
ICore *core = m_pm->getObject<Core::ICore>();
Core::ModeManager *modeManager = core->modeManager();
m_previousMode = QLatin1String(modeManager->currentMode()->uniqueModeName());
modeManager->activateMode(QLatin1String(MODE_DEBUG));
}
void DebuggerPlugin::queryCurrentTextEditor(QString *fileName, int *lineNumber, QObject **object)
{
ICore *core = m_pm->getObject<Core::ICore>();
if (!core || !core->editorManager())
return;
Core::IEditor *editor = core->editorManager()->currentEditor();
ITextEditor *textEditor = qobject_cast<ITextEditor*>(editor);
if (!textEditor)
return;
if (fileName)
*fileName = textEditor->file()->fileName();
if (lineNumber)
*lineNumber = textEditor->currentLine();
if (object)
*object = textEditor->widget();
}
void DebuggerPlugin::editorOpened(Core::IEditor *editor)
{
if (ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor)) {
connect(textEditor, SIGNAL(markRequested(TextEditor::ITextEditor*,int)),
this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
connect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
}
}
void DebuggerPlugin::editorAboutToClose(Core::IEditor *editor)
{
if (ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor)) {
disconnect(textEditor, SIGNAL(markRequested(TextEditor::ITextEditor*,int)),
this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
disconnect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
}
}
void DebuggerPlugin::requestMark(TextEditor::ITextEditor *editor, int lineNumber)
{
m_manager->toggleBreakpoint(editor->file()->fileName(), lineNumber);
}
void DebuggerPlugin::showToolTip(TextEditor::ITextEditor *editor,
const QPoint &point, int pos)
{
QPlainTextEdit *plaintext = qobject_cast<QPlainTextEdit*>(editor->widget());
if (!plaintext)
return;
QString expr = plaintext->textCursor().selectedText();
if (expr.isEmpty()) {
QTextCursor tc(plaintext->document());
tc.setPosition(pos);
const QChar ch = editor->characterAt(pos);
if (ch.isLetterOrNumber() || ch == QLatin1Char('_'))
tc.movePosition(QTextCursor::EndOfWord);
// Fetch the expression's code.
ExpressionUnderCursor expressionUnderCursor;
expr = expressionUnderCursor(tc);
}
//qDebug() << " TOOLTIP EXPR " << expr;
m_manager->setToolTipExpression(point, expr);
}
void DebuggerPlugin::setSessionValue(const QString &name, const QVariant &value)
{
//qDebug() << "SET SESSION VALUE" << name << value;
ProjectExplorerPlugin *pe = projectExplorer();
if (pe->session())
pe->session()->setValue(name, value);
else
qDebug() << "FIXME: Session does not exist yet";
}
void DebuggerPlugin::querySessionValue(const QString &name, QVariant *value)
{
ProjectExplorerPlugin *pe = projectExplorer();
*value = pe->session()->value(name);
//qDebug() << "GET SESSION VALUE: " << name << value;
}
void DebuggerPlugin::setConfigValue(const QString &name, const QVariant &value)
{
QWB_ASSERT(m_debugMode, return);
m_debugMode->settings()->setValue(name, value);
}
void DebuggerPlugin::queryConfigValue(const QString &name, QVariant *value)
{
QWB_ASSERT(m_debugMode, return);
*value = m_debugMode->settings()->value(name);
}
void DebuggerPlugin::resetLocation()
{
//qDebug() << "RESET_LOCATION: current:" << currentTextEditor();
//qDebug() << "RESET_LOCATION: locations:" << m_locationMark;
//qDebug() << "RESET_LOCATION: stored:" << m_locationMark->editor();
delete m_locationMark;
m_locationMark = 0;
}
void DebuggerPlugin::gotoLocation(const QString &fileName, int lineNumber,
bool setMarker)
{
TextEditor::BaseTextEditor::openEditorAt(fileName, lineNumber);
if (setMarker) {
resetLocation();
m_locationMark = new LocationMark(fileName, lineNumber);
}
}
void DebuggerPlugin::changeStatus(int status)
{
bool startIsContinue = (status == DebuggerInferiorStopped);
ICore *core = m_pm->getObject<Core::ICore>();
if (startIsContinue) {
core->addAdditionalContext(m_gdbRunningContext);
core->updateContext();
} else {
core->removeAdditionalContext(m_gdbRunningContext);
core->updateContext();
}
}
#include "debuggerplugin.moc"
Q_EXPORT_PLUGIN(DebuggerPlugin)

View File

@@ -0,0 +1,111 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGERPLUGIN_H
#define DEBUGGERPLUGIN_H
#include <projectexplorer/projectexplorer.h>
#include <extensionsystem/iplugin.h>
#include <QtCore/QObject>
QT_BEGIN_NAMESPACE
class QAction;
class QCursor;
class QAbstractItemView;
QT_END_NAMESPACE
namespace Core { class IEditor; }
namespace TextEditor { class ITextEditor; }
namespace Debugger {
namespace Internal {
class DebuggerManager;
class DebugMode;
class GdbOptionPage;
class TypeMacroPage;
class LocationMark;
class DebuggerPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
public:
DebuggerPlugin();
~DebuggerPlugin();
private:
bool initialize(const QStringList &arguments, QString *error_message);
void shutdown();
void extensionsInitialized();
private slots:
void activatePreviousMode();
void activateDebugMode();
void queryCurrentTextEditor(QString *fileName, int *line, QObject **object);
void editorOpened(Core::IEditor *);
void editorAboutToClose(Core::IEditor *);
void changeStatus(int status);
void requestMark(TextEditor::ITextEditor *editor, int lineNumber);
void showToolTip(TextEditor::ITextEditor *editor, const QPoint &pnt, int pos);
void querySessionValue(const QString &name, QVariant *value);
void setSessionValue(const QString &name, const QVariant &value);
void queryConfigValue(const QString &name, QVariant *value);
void setConfigValue(const QString &name, const QVariant &value);
void resetLocation();
void gotoLocation(const QString &fileName, int line, bool setMarker);
private:
friend class DebuggerManager;
friend class DebugMode; // FIXME: Just a hack now so that it can access the views
ProjectExplorer::ProjectExplorerPlugin *projectExplorer() const;
DebuggerManager *m_manager;
DebugMode *m_debugMode;
ExtensionSystem::PluginManager *m_pm;
GdbOptionPage *m_generalOptionPage;
TypeMacroPage *m_typeMacroPage;
QString m_previousMode;
LocationMark *m_locationMark;
int m_gdbRunningContext;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGERPLUGIN_H

View File

@@ -0,0 +1,161 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "debuggerrunner.h"
#include "assert.h"
#include "debuggermanager.h"
#include <projectexplorer/applicationrunconfiguration.h>
#include <projectexplorer/environment.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
using namespace Debugger::Internal;
using ProjectExplorer::RunConfiguration;
using ProjectExplorer::RunControl;
using ProjectExplorer::ApplicationRunConfiguration;
////////////////////////////////////////////////////////////////////////
//
// DebuggerRunner
//
////////////////////////////////////////////////////////////////////////
DebuggerRunner::DebuggerRunner(DebuggerManager *manager)
: m_manager(manager)
{}
bool DebuggerRunner::canRun(RunConfigurationPtr runConfiguration, const QString &mode)
{
return mode == ProjectExplorer::Constants::DEBUGMODE
&& !qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration).isNull();
}
QString DebuggerRunner::displayName() const
{
return QObject::tr("Debug");
}
RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration, const QString &mode)
{
Q_UNUSED(mode);
Q_ASSERT(mode == ProjectExplorer::Constants::DEBUGMODE);
ApplicationRunConfigurationPtr rc =
qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration);
Q_ASSERT(rc);
//qDebug() << "***** Debugging" << rc->name() << rc->executable();
return new DebuggerRunControl(m_manager, rc);
}
QWidget *DebuggerRunner::configurationWidget(RunConfigurationPtr runConfiguration)
{
// NBS TODO: Add GDB-specific configuration widget
Q_UNUSED(runConfiguration);
return 0;
}
////////////////////////////////////////////////////////////////////////
//
// DebuggerRunControl
//
////////////////////////////////////////////////////////////////////////
DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
QSharedPointer<ApplicationRunConfiguration> runConfiguration)
: RunControl(runConfiguration), m_manager(manager), m_running(false)
{
connect(m_manager, SIGNAL(debuggingFinished()),
this, SLOT(debuggingFinished()));
connect(m_manager, SIGNAL(applicationOutputAvailable(QString, QString)),
this, SLOT(slotAddToOutputWindow(QString, QString)));
connect(m_manager, SIGNAL(inferiorPidChanged(qint64)),
this, SLOT(bringApplicationToForeground(qint64)));
}
void DebuggerRunControl::start()
{
m_running = true;
ApplicationRunConfigurationPtr rc =
qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration());
QWB_ASSERT(rc, return);
ProjectExplorer::Project *project = rc->project();
QWB_ASSERT(project, return);
m_manager->m_executable = rc->executable();
m_manager->m_environment = rc->environment().toStringList();
m_manager->m_workingDir = rc->workingDirectory();
m_manager->m_processArgs = rc->commandLineArguments();
m_manager->m_buildDir =
project->buildDirectory(project->activeBuildConfiguration());
//<daniel> andre: + "\qtc-gdbmacros\"
//emit addToOutputWindow(this, tr("Debugging %1").arg(m_executable));
if (m_manager->startNewDebugger(DebuggerManager::startInternal))
emit started();
else
debuggingFinished();
}
void DebuggerRunControl::slotAddToOutputWindow(const QString &prefix, const QString &line)
{
Q_UNUSED(prefix);
foreach (const QString &l, line.split('\n'))
emit addToOutputWindow(this, prefix + l);
//emit addToOutputWindow(this, prefix + line);
}
void DebuggerRunControl::stop()
{
m_manager->exitDebugger();
}
void DebuggerRunControl::debuggingFinished()
{
m_running = false;
//emit addToOutputWindow(this, tr("Debugging %1 finished").arg(m_executable));
emit finished();
}
bool DebuggerRunControl::isRunning() const
{
return m_running;
}

View File

@@ -0,0 +1,96 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGERRUNNER_H
#define DEBUGGERRUNNER_H
#include <projectexplorer/runconfiguration.h>
namespace ProjectExplorer {
class ApplicationRunConfiguration;
}
namespace Debugger {
namespace Internal {
class DebuggerManager;
class StartData;
typedef QSharedPointer<ProjectExplorer::RunConfiguration>
RunConfigurationPtr;
typedef QSharedPointer<ProjectExplorer::ApplicationRunConfiguration>
ApplicationRunConfigurationPtr;
class DebuggerRunner : public ProjectExplorer::IRunConfigurationRunner
{
Q_OBJECT
public:
explicit DebuggerRunner(DebuggerManager *manager);
virtual bool canRun(RunConfigurationPtr runConfiguration, const QString &mode);
virtual QString displayName() const;
virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration,
const QString &mode);
virtual QWidget *configurationWidget(RunConfigurationPtr runConfiguration);
private:
DebuggerManager *m_manager;
};
class DebuggerRunControl : public ProjectExplorer::RunControl
{
Q_OBJECT
public:
DebuggerRunControl(DebuggerManager *manager,
ApplicationRunConfigurationPtr runConfiguration);
virtual void start();
virtual void stop();
virtual bool isRunning() const;
private slots:
void debuggingFinished();
void slotAddToOutputWindow(const QString &prefix, const QString &line);
private:
DebuggerManager *m_manager;
bool m_running;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGERRUNNER_H

View File

@@ -0,0 +1,187 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "disassemblerhandler.h"
#include "assert.h"
#include <QtCore/QDebug>
#include <QtCore/QAbstractTableModel>
#include <QtGui/QIcon>
using namespace Debugger;
using namespace Debugger::Internal;
//////////////////////////////////////////////////////////////////
//
// DisassemblerModel
//
//////////////////////////////////////////////////////////////////
/*! A model to represent the stack in a QTreeView. */
class Debugger::Internal::DisassemblerModel : public QAbstractTableModel
{
public:
DisassemblerModel(QObject *parent);
// ItemModel
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
// Properties
void setLines(const QList<DisassemblerLine> &lines);
QList<DisassemblerLine> lines() const;
void setCurrentLine(int line) { m_currentLine = line; }
private:
friend class DisassemblerHandler;
QList<DisassemblerLine> m_lines;
int m_currentLine;
QIcon m_positionIcon;
QIcon m_emptyIcon;
};
DisassemblerModel::DisassemblerModel(QObject *parent)
: QAbstractTableModel(parent), m_currentLine(0)
{
m_emptyIcon = QIcon(":/gdbdebugger/images/empty.svg");
m_positionIcon = QIcon(":/gdbdebugger/images/location.svg");
}
int DisassemblerModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_lines.size();
}
int DisassemblerModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 3;
}
QVariant DisassemblerModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= m_lines.size())
return QVariant();
const DisassemblerLine &line = m_lines.at(index.row());
if (role == Qt::DisplayRole) {
switch (index.column()) {
case 0:
return line.addressDisplay;
case 1:
return line.symbolDisplay;
case 2:
return line.mnemonic;
}
} else if (role == Qt::ToolTipRole) {
return QString();
} else if (role == Qt::DecorationRole && index.column() == 0) {
// Return icon that indicates whether this is the active stack frame
return (index.row() == m_currentLine) ? m_positionIcon : m_emptyIcon;
}
return QVariant();
}
QVariant DisassemblerModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static const char * const headers[] = {
QT_TR_NOOP("Address"),
QT_TR_NOOP("Symbol"),
QT_TR_NOOP("Mnemonic"),
};
if (section < 3)
return tr(headers[section]);
}
return QVariant();
}
void DisassemblerModel::setLines(const QList<DisassemblerLine> &lines)
{
m_lines = lines;
if (m_currentLine >= m_lines.size())
m_currentLine = m_lines.size() - 1;
reset();
}
QList<DisassemblerLine> DisassemblerModel::lines() const
{
return m_lines;
}
//////////////////////////////////////////////////////////////////
//
// DisassemblerHandler
//
//////////////////////////////////////////////////////////////////
DisassemblerHandler::DisassemblerHandler()
{
m_model = new DisassemblerModel(this);
}
void DisassemblerHandler::removeAll()
{
m_model->m_lines.clear();
}
QAbstractItemModel *DisassemblerHandler::model() const
{
return m_model;
}
void DisassemblerHandler::setLines(const QList<DisassemblerLine> &lines)
{
m_model->setLines(lines);
}
QList<DisassemblerLine> DisassemblerHandler::lines() const
{
return m_model->lines();
}
void DisassemblerHandler::setCurrentLine(int line)
{
m_model->setCurrentLine(line);
}

View File

@@ -0,0 +1,78 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DISASSEMBLERHANDLER_H
#define DISASSEMBLERHANDLER_H
#include <QtCore/QObject>
#include <QtCore/QAbstractItemModel>
#include <QtGui/QIcon>
namespace Debugger {
namespace Internal {
class DisassemblerLine
{
public:
QString address;
QString symbol;
QString addressDisplay;
QString symbolDisplay;
QString mnemonic;
};
class DisassemblerModel;
class DisassemblerHandler : public QObject
{
Q_OBJECT
public:
DisassemblerHandler();
QAbstractItemModel *model() const;
public slots:
void removeAll();
void setLines(const QList<DisassemblerLine> &lines);
QList<DisassemblerLine> lines() const;
void setCurrentLine(int line);
private:
DisassemblerModel *m_model;
};
} // namespace Internal
} // namespace Debugger
#endif // DISASSEMBLERHANDLER_H

View File

@@ -0,0 +1,140 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "disassemblerwindow.h"
#include <QAction>
#include <QDebug>
#include <QHeaderView>
#include <QMenu>
#include <QResizeEvent>
using namespace Debugger::Internal;
DisassemblerWindow::DisassemblerWindow()
: m_alwaysResizeColumnsToContents(true), m_alwaysReloadContents(false)
{
setWindowTitle(tr("Disassembler"));
setSortingEnabled(false);
setAlternatingRowColors(true);
setRootIsDecorated(false);
header()->hide();
//setIconSize(QSize(10, 10));
//setWindowIcon(QIcon(":/gdbdebugger/images/debugger_breakpoints.png"));
//QHeaderView *hv = header();
//hv->setDefaultAlignment(Qt::AlignLeft);
//hv->setClickable(true);
//hv->setSortIndicatorShown(true);
}
void DisassemblerWindow::resizeEvent(QResizeEvent *ev)
{
//QHeaderView *hv = header();
//int totalSize = ev->size().width() - 110;
//hv->resizeSection(0, 60);
//hv->resizeSection(1, (totalSize * 50) / 100);
//hv->resizeSection(2, (totalSize * 50) / 100);
//hv->resizeSection(3, 50);
QTreeView::resizeEvent(ev);
}
void DisassemblerWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
//QTreeWidgetItem *item = itemAt(ev->pos());
QAction *act1 = new QAction("Adjust column widths to contents", &menu);
QAction *act2 = new QAction("Always adjust column widths to contents", &menu);
act2->setCheckable(true);
act2->setChecked(m_alwaysResizeColumnsToContents);
QAction *act3 = new QAction("Reload disassembler listing", &menu);
QAction *act4 = new QAction("Always reload disassembler listing", &menu);
act4->setCheckable(true);
act4->setChecked(m_alwaysReloadContents);
//if (item) {
// menu.addAction(act0);
// menu.addSeparator();
//}
menu.addAction(act3);
//menu.addAction(act4);
menu.addSeparator();
menu.addAction(act1);
menu.addAction(act2);
QAction *act = menu.exec(ev->globalPos());
if (act == act1)
resizeColumnsToContents();
else if (act == act2)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == act3)
reloadContents();
else if (act == act2)
setAlwaysReloadContents(!m_alwaysReloadContents);
}
void DisassemblerWindow::resizeColumnsToContents()
{
resizeColumnToContents(0);
resizeColumnToContents(1);
resizeColumnToContents(2);
}
void DisassemblerWindow::setAlwaysResizeColumnsToContents(bool on)
{
m_alwaysResizeColumnsToContents = on;
QHeaderView::ResizeMode mode = on
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
header()->setResizeMode(0, mode);
header()->setResizeMode(1, mode);
header()->setResizeMode(2, mode);
}
void DisassemblerWindow::setAlwaysReloadContents(bool on)
{
m_alwaysReloadContents = on;
if (m_alwaysReloadContents)
reloadContents();
}
void DisassemblerWindow::reloadContents()
{
emit reloadDisassemblerRequested();
}
void DisassemblerWindow::setModel(QAbstractItemModel *model)
{
QTreeView::setModel(model);
setAlwaysResizeColumnsToContents(true);
}

View File

@@ -0,0 +1,71 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_DISASSEMBLERWINDOW_H
#define DEBUGGER_DISASSEMBLERWINDOW_H
#include <QTreeView>
namespace Debugger {
namespace Internal {
class DisassemblerWindow : public QTreeView
{
Q_OBJECT
public:
DisassemblerWindow();
void setModel(QAbstractItemModel *model);
signals:
void reloadDisassemblerRequested();
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
void reloadContents();
void setAlwaysReloadContents(bool on);
protected:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
private:
bool m_alwaysResizeColumnsToContents;
bool m_alwaysReloadContents;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_DISASSEMBLERWINDOW_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,351 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_GDBENGINE_H
#define DEBUGGER_GDBENGINE_H
#include <QtCore/QByteArray>
#include <QtCore/QHash>
#include <QtCore/QMap>
#include <QtCore/QObject>
#include <QtCore/QProcess>
#include <QtCore/QPoint>
#include <QtCore/QVariant>
QT_BEGIN_NAMESPACE
class QAction;
class QAbstractItemModel;
class QWidget;
QT_END_NAMESPACE
#include "idebuggerengine.h"
#include "gdbmi.h"
namespace Debugger {
namespace Internal {
class DebuggerManager;
class IDebuggerManagerAccessForEngines;
class GdbResultRecord;
class GdbMi;
class WatchData;
class BreakpointData;
struct GdbCookie
{
GdbCookie() : type(0), synchronized(false) {}
QString command;
int type;
bool synchronized;
QVariant cookie;
};
enum DataDumperState
{
DataDumperUninitialized,
DataDumperLoadTried,
DataDumperAvailable,
DataDumperUnavailable,
};
// FIXME: Move to extra file?
class GdbSettings
{
public:
GdbSettings() { m_autoRun = m_autoQuit = false; }
public:
QString m_gdbCmd;
QString m_gdbEnv;
bool m_autoRun;
bool m_autoQuit;
QString m_scriptFile;
QMap<QString, QVariant> m_typeMacros;
};
GdbSettings &theGdbSettings();
class GdbEngine : public IDebuggerEngine
{
Q_OBJECT
public:
GdbEngine(DebuggerManager *parent);
~GdbEngine();
signals:
void gdbResponseAvailable();
void gdbInputAvailable(const QString &prefix, const QString &msg);
void gdbOutputAvailable(const QString &prefix, const QString &msg);
void applicationOutputAvailable(const QString &prefix, const QString &msg);
private:
//
// IDebuggerEngine implementation
//
void stepExec();
void stepOutExec();
void nextExec();
void stepIExec();
void nextIExec();
void shutdown();
void setToolTipExpression(const QPoint &pos, const QString &exp);
bool startDebugger();
void exitDebugger();
void continueInferior();
void runInferior();
void interruptInferior();
void runToLineExec(const QString &fileName, int lineNumber);
void runToFunctionExec(const QString &functionName);
void jumpToLineExec(const QString &fileName, int lineNumber);
void activateFrame(int index);
void selectThread(int index);
Q_SLOT void attemptBreakpointSynchronization();
void loadSessionData() {}
void saveSessionData() {}
void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand(const QString & command);
void loadSymbols(const QString &moduleName);
void loadAllSymbols();
//
// Own stuff
//
int currentFrame() const;
QString currentWorkingDirectory() const { return m_pwd; }
bool supportsThreads() const;
void init(); // called by destructor
void queryFullName(const QString &fileName, QString *fullName);
QString fullName(const QString &fileName);
QString shortName(const QString &fullName);
// get one usable name out of these, try full names first
QString fullName(const QStringList &candidates);
void handleResult(const GdbResultRecord &, int type, const QVariant &);
// type and cookie are sender-internal data, opaque for the "event
// queue". resultNeeded == true increments m_pendingResults on
// send and decrements on receipt, effectively preventing
// watch model updates before everything is finished.
void sendCommand(const QString & command,
int type = 0, const QVariant &cookie = QVariant(),
bool needStop = false, bool synchronized = false);
void sendSynchronizedCommand(const QString & command,
int type = 0, const QVariant &cookie = QVariant(),
bool needStop = false);
void setTokenBarrier();
void updateLocals();
private slots:
void setDebugDumpers(bool on);
void setCustomDumpersWanted(bool on);
void handleResponse();
void gdbProcError(QProcess::ProcessError error);
void readGdbStandardOutput();
void readGdbStandardError();
private:
int terminationIndex(const QByteArray &buffer, int &length);
void handleStreamOutput(const QString &output, char code);
void handleAsyncOutput2(const GdbMi &data);
void handleAsyncOutput(const GdbMi &data);
void handleResultRecord(const GdbResultRecord &response);
void handleFileExecAndSymbols(const GdbResultRecord &response);
void handleExecRun(const GdbResultRecord &response);
void handleExecJumpToLine(const GdbResultRecord &response);
void handleExecRunToFunction(const GdbResultRecord &response);
void handleInfoShared(const GdbResultRecord &response);
void handleInfoProc(const GdbResultRecord &response);
void handleShowVersion(const GdbResultRecord &response);
void handleQueryPwd(const GdbResultRecord &response);
void handleQuerySources(const GdbResultRecord &response);
void handleQuerySources2(const GdbResultRecord &response,
const QVariant &);
QByteArray m_inbuffer;
QProcess m_gdbProc;
QHash<int, GdbCookie> m_cookieForToken;
QHash<int, QByteArray> m_customOutputForToken;
QByteArray m_pendingConsoleStreamOutput;
QByteArray m_pendingTargetStreamOutput;
QByteArray m_pendingLogStreamOutput;
//QByteArray m_pendingCustomValueContents;
QString m_pwd;
// contains the first token number for the current round
// of evaluation. Responses with older tokens are considers
// out of date and discarded.
int m_oldestAcceptableToken;
int m_gdbVersion; // 6.8.0 is 680
int m_shared;
// awful hack to keep track of used files
QHash<QString, QString> m_shortToFullName;
QHash<QString, QString> m_fullToShortName;
//
// Breakpoint specific stuff
//
void handleBreakList(const GdbResultRecord &record);
void handleBreakList(const GdbMi &table);
void handleBreakIgnore(const GdbResultRecord &record, int index);
void handleBreakInsert(const GdbResultRecord &record, int index);
void handleBreakInsert1(const GdbResultRecord &record, int index);
void handleBreakCondition(const GdbResultRecord &record, int index);
void handleBreakInfo(const GdbResultRecord &record, int index);
void extractDataFromInfoBreak(const QString &output, BreakpointData *data);
void breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt);
void sendInsertBreakpoint(int index);
//
// Disassembler specific stuff
//
void handleDisassemblerList(const GdbResultRecord &record,
const QString &cookie);
void reloadDisassembler();
QString m_address;
//
// Modules specific stuff
//
void reloadModules();
void handleModulesList(const GdbResultRecord &record);
//
// Register specific stuff
//
void reloadRegisters();
void handleRegisterListNames(const GdbResultRecord &record);
void handleRegisterListValues(const GdbResultRecord &record);
//
// Stack specific stuff
//
void handleStackListFrames(const GdbResultRecord &record);
void handleStackSelectThread(const GdbResultRecord &record, int cookie);
void handleStackListThreads(const GdbResultRecord &record, int cookie);
//
// Tooltip specific stuff
//
void sendToolTipCommand(const QString &command, const QString &cookie);
//
// Watch specific stuff
//
// FIXME: BaseClass. called to improve situation for a watch item
void updateSubItem(const WatchData &data);
void updateWatchModel();
Q_SLOT void updateWatchModel2();
void insertData(const WatchData &data);
void sendWatchParameters(const QByteArray &params0);
void createGdbVariable(const WatchData &data);
void handleTypeContents(const QString &output);
void maybeHandleInferiorPidChanged(const QString &pid);
void tryLoadCustomDumpers();
void runCustomDumper(const WatchData &data, bool dumpChildren);
bool isCustomValueDumperAvailable(const QString &type) const;
void handleVarListChildren(const GdbResultRecord &record,
const WatchData &cookie);
void handleVarCreate(const GdbResultRecord &record,
const WatchData &cookie);
void handleVarAssign();
void handleEvaluateExpression(const GdbResultRecord &record,
const WatchData &cookie);
void handleToolTip(const GdbResultRecord &record,
const QString &cookie);
void handleDumpCustomValue1(const GdbResultRecord &record,
const WatchData &cookie);
void handleQueryDataDumper1(const GdbResultRecord &record);
void handleQueryDataDumper2(const GdbResultRecord &record);
void handleDumpCustomValue2(const GdbResultRecord &record,
const WatchData &cookie);
void handleDumpCustomEditValue(const GdbResultRecord &record);
void handleDumpCustomSetup(const GdbResultRecord &record);
void handleStackListLocals(const GdbResultRecord &record);
void handleStackListArguments(const GdbResultRecord &record);
void handleVarListChildrenHelper(const GdbMi &child,
const WatchData &parent);
void setWatchDataType(WatchData &data, const GdbMi &mi);
QString m_editedData;
int m_pendingRequests;
int m_inferiorPid;
QStringList m_availableSimpleDumpers;
QString m_namespace; // namespace used in "namespaced Qt";
DataDumperState m_dataDumperState; // state of qt creator dumpers
QList<GdbMi> m_currentFunctionArgs;
QString m_currentFrame;
QMap<QString, QString> m_varToType;
DebuggerManager *q;
IDebuggerManagerAccessForEngines *qq;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_GDBENGINE_H

View File

@@ -0,0 +1,473 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "gdbmi.h"
#include "assert.h"
#include <QtCore/QByteArray>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
namespace Debugger {
namespace Internal {
QTextStream & operator<<(QTextStream & os, const GdbMi & mi)
{
return os << mi.toString();
}
//static void skipSpaces(const GdbMi::Char *&from, const GdbMi::Char *to)
//{
// while (from != to && QChar(*from).isSpace())
// ++from;
//}
void GdbMi::parseResultOrValue(const Char *&from, const Char *to)
{
//skipSpaces(from, to);
while (from != to && QChar(*from).isSpace())
++from;
//qDebug() << "parseResultOrValue: " << QByteArray::fromLatin1(from, to - from);
parseValue(from, to);
if (isValid()) {
//qDebug() << "no valid result in " << QByteArray::fromLatin1(from, to - from);
return;
}
if (from == to || *from == '(')
return;
const Char *ptr = from;
while (ptr < to && *ptr != '=') {
//qDebug() << "adding" << QChar(*ptr) << "to name";
++ptr;
}
m_name = QByteArray(from, ptr - from);
from = ptr;
if (from < to && *from == '=') {
++from;
parseValue(from, to);
}
}
QByteArray GdbMi::parseCString(const Char *&from, const Char *to)
{
QByteArray result;
//qDebug() << "parseCString: " << QByteArray::fromUtf16(from, to - from);
if (*from != '"') {
qDebug() << "MI Parse Error, double quote expected";
return QByteArray();
}
const Char *ptr = from;
++ptr;
while (ptr < to) {
if (*ptr == '"') {
++ptr;
result = QByteArray(from + 1, ptr - from - 2);
break;
}
if (*ptr == '\\' && ptr < to - 1)
++ptr;
++ptr;
}
if (result.contains('\\')) {
if (result.contains("\\032\\032"))
result.clear();
else {
result = result.replace("\\n", "\n");
result = result.replace("\\t", "\t");
result = result.replace("\\\"", "\"");
}
}
from = ptr;
return result;
}
void GdbMi::parseValue(const Char *&from, const Char *to)
{
//qDebug() << "parseValue: " << QByteArray::fromUtf16(from, to - from);
switch (*from) {
case '{':
parseTuple(from, to);
break;
case '[':
parseList(from, to);
break;
case '"':
m_type = Const;
m_data = parseCString(from, to);
break;
default:
break;
}
}
void GdbMi::parseTuple(const Char *&from, const Char *to)
{
//qDebug() << "parseTuple: " << QByteArray::fromUtf16(from, to - from);
QWB_ASSERT(*from == '{', /**/);
++from;
parseTuple_helper(from, to);
}
void GdbMi::parseTuple_helper(const Char *&from, const Char *to)
{
//qDebug() << "parseTuple_helper: " << QByteArray::fromUtf16(from, to - from);
m_type = Tuple;
while (from < to) {
if (*from == '}') {
++from;
break;
}
GdbMi child;
child.parseResultOrValue(from, to);
//qDebug() << "\n=======\n" << qPrintable(child.toString()) << "\n========\n";
if (!child.isValid())
return;
m_children += child;
if (*from == ',')
++from;
}
}
void GdbMi::parseList(const Char *&from, const Char *to)
{
//qDebug() << "parseList: " << QByteArray::fromUtf16(from, to - from);
QWB_ASSERT(*from == '[', /**/);
++from;
m_type = List;
while (from < to) {
if (*from == ']') {
++from;
break;
}
GdbMi child;
child.parseResultOrValue(from, to);
if (child.isValid())
m_children += child;
if (*from == ',')
++from;
}
}
void GdbMi::setStreamOutput(const QByteArray &name, const QByteArray &content)
{
if (content.isEmpty())
return;
GdbMi child;
child.m_type = Const;
child.m_name = name;
child.m_data = content;
m_children += child;
if (m_type == Invalid)
m_type = Tuple;
}
static QByteArray ind(int indent)
{
return QByteArray(2 * indent, ' ');
}
void GdbMi::dumpChildren(QByteArray * str, bool multiline, int indent) const
{
for (int i = 0; i < m_children.size(); ++i) {
if (i != 0) {
*str += ',';
if (multiline)
*str += '\n';
}
if (multiline)
*str += ind(indent);
*str += m_children.at(i).toString(multiline, indent);
}
}
QByteArray GdbMi::toString(bool multiline, int indent) const
{
QByteArray result;
switch (m_type) {
case Invalid:
if (multiline) {
result += ind(indent) + "Invalid\n";
} else {
result += "Invalid";
}
break;
case Const:
if (!m_name.isEmpty())
result += m_name + "=";
if (multiline) {
result += "\"" + m_data + "\"";
} else {
result += "\"" + m_data + "\"";
}
break;
case Tuple:
if (!m_name.isEmpty())
result += m_name + "=";
if (multiline) {
result += "{\n";
dumpChildren(&result, multiline, indent + 1);
result += '\n' + ind(indent) + "}";
} else {
result += "{";
dumpChildren(&result, multiline, indent + 1);
result += "}";
}
break;
case List:
if (!m_name.isEmpty())
result += m_name + "=";
if (multiline) {
result += "[\n";
dumpChildren(&result, multiline, indent + 1);
result += "]";
} else {
result += "[";
dumpChildren(&result, multiline, indent + 1);
result += '\n' + ind(indent) + "]";
}
break;
}
return result;
}
void GdbMi::fromString(const QByteArray &ba)
{
const Char *from = ba.constBegin();
const Char *to = ba.constEnd();
parseResultOrValue(from, to);
}
GdbMi GdbMi::findChild(const QByteArray &name) const
{
for (int i = 0; i < m_children.size(); ++i)
if (m_children.at(i).m_name == name)
return m_children.at(i);
return GdbMi();
}
GdbMi GdbMi::findChild(const QByteArray &name, const QByteArray &defaultData) const
{
for (int i = 0; i < m_children.size(); ++i)
if (m_children.at(i).m_name == name)
return m_children.at(i);
GdbMi result;
result.m_data = defaultData;
return result;
}
//////////////////////////////////////////////////////////////////////////////////
//
// GdbResultRecord
//
//////////////////////////////////////////////////////////////////////////////////
QByteArray stringFromResultClass(GdbResultClass resultClass)
{
switch (resultClass) {
case GdbResultDone: return "done";
case GdbResultRunning: return "running";
case GdbResultConnected: return "connected";
case GdbResultError: return "error";
case GdbResultExit: return "exit";
default: return "unknown";
}
};
QByteArray GdbResultRecord::toString() const
{
QByteArray result;
if (token != -1)
result = QByteArray::number(token);
result += '^';
result += stringFromResultClass(resultClass);
if (data.isValid())
result += ',' + data.toString();
result += '\n';
return result;
}
//////////////////////////////////////////////////////////////////////////////////
//
// GdbStreamOutput
//
//////////////////////////////////////////////////////////////////////////////////
#if 0
static const char test1[] =
"1^done,stack=[frame={level=\"0\",addr=\"0x00000000004061ca\","
"func=\"main\",file=\"test1.cpp\","
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
"(gdb)\n";
static const char test2[] =
"2^done,stack=[frame={level=\"0\",addr=\"0x00002ac058675840\","
"func=\"QApplication\",file=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\","
"fullname=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\",line=\"592\"},"
"frame={level=\"1\",addr=\"0x00000000004061e0\",func=\"main\",file=\"test1.cpp\","
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
"(gdb)\n";
static const char test3[] =
"3^done,stack=[frame={level=\"0\",addr=\"0x00000000004061ca\","
"func=\"main\",file=\"test1.cpp\","
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
"(gdb)\n";
static const char test4[] =
"&\"source /home/apoenitz/dev/ide/main/bin/gdb/qt4macros\\n\"\n"
"4^done\n"
"(gdb)\n";
static const char test5[] =
"1*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"1\","
"frame={addr=\"0x0000000000405738\",func=\"main\","
"args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\"0x7fff1ac78f28\"}],"
"file=\"test1.cpp\",fullname=\"/home/apoenitz/work/test1/test1.cpp\","
"line=\"209\"}\n"
"(gdb)\n";
static const char test6[] =
"{u = {u = 2048, v = 16788279, w = -689265400}, a = 1, b = -689265424, c = 11063, s = {static null = {<No data fields>}, static shared_null = {ref = {value = 2}, alloc = 0, size = 0, data = 0x6098da, clean = 0, simpletext = 0, righttoleft = 0, asciiCache = 0, capacity = 0, reserved = 0, array = {0}}, static shared_empty = {ref = {value = 1}, alloc = 0, size = 0, data = 0x2b37d84f8fba, clean = 0, simpletext = 0, righttoleft = 0, asciiCache = 0, capacity = 0, reserved = 0, array = {0}}, d = 0x6098c0, static codecForCStrings = 0x0}}";
static const char test8[] =
"8^done,data={locals={{name=\"a\"},{name=\"w\"}}}\n"
"(gdb)\n";
static const char test9[] =
"9^done,data={locals=[name=\"baz\",name=\"urgs\",name=\"purgs\"]}\n"
"(gdb)\n";
static const char test10[] =
"16^done,name=\"urgs\",numchild=\"1\",type=\"Urgs\"\n"
"(gdb)\n"
"17^done,name=\"purgs\",numchild=\"1\",type=\"Urgs *\"\n"
"(gdb)\n"
"18^done,name=\"bar\",numchild=\"0\",type=\"int\"\n"
"(gdb)\n"
"19^done,name=\"z\",numchild=\"0\",type=\"int\"\n"
"(gdb)\n";
static const char test11[] =
"[{name=\"size\",value=\"1\",type=\"size_t\",readonly=\"true\"},"
"{name=\"0\",value=\"one\",type=\"QByteArray\"}]";
static const char test12[] =
"{iname=\"local.hallo\",value=\"\\\"\\\"\",type=\"QByteArray\",numchild=\"0\"}";
static struct Tester {
Tester() {
//test(test10);
test2(test12);
//test(test4);
//apple();
exit(0);
}
void test(const char* input)
{
//qDebug("\n<<<<\n%s\n====\n%s\n>>>>\n", input,
//qPrintable(GdbResponse(input).toString()));
}
void test2(const char* input)
{
GdbMi mi(input);
qDebug("\n<<<<\n%s\n====\n%s\n>>>>\n", input,
qPrintable(mi.toString()));
}
void apple()
{
QByteArray input(test9);
/*
qDebug() << "input: " << input;
input = input.replace("{{","[");
input = input.replace("},{",",");
input = input.replace("}}","]");
qDebug() << "input: " << input;
GdbResponse response(input);
qDebug() << "read: " << response.toString();
GdbMi list = response.results[0].data.findChild("data").findChild("locals");
QByteArrayList locals;
foreach (const GdbMi &item, list.children())
locals.append(item.string());
qDebug() << "Locals (new): " << locals;
*/
}
void parse(const QByteArray &str)
{
QByteArray result;
result += "\n ";
int indent = 0;
int from = 0;
int to = str.size();
if (str.size() && str[0] == '{' /*'}'*/) {
++from;
--to;
}
for (int i = from; i < to; ++i) {
if (str[i] == '{')
result += "{\n" + QByteArray(2*++indent + 1, QChar(' '));
else if (str[i] == '}') {
if (!result.isEmpty() && result[result.size() - 1] != '\n')
result += "\n";
result += QByteArray(2*--indent + 1, QChar(' ')) + "}\n";
}
else if (str[i] == ',') {
if (true || !result.isEmpty() && result[result.size() - 1] != '\n')
result += "\n";
result += QByteArray(2*indent, QChar(' '));
}
else
result += str[i];
}
qDebug() << "result:\n" << result;
}
} dummy;
#endif
} // namespace Internal
} // namespace Debugger

View File

@@ -0,0 +1,183 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_GDBMI_H
#define DEBUGGER_GDBMI_H
#include <qglobal.h>
#include <QtCore/QByteArray>
#include <QtCore/QList>
namespace Debugger {
namespace Internal {
/*
output ==>
( out-of-band-record )* [ result-record ] "(gdb)" nl
result-record ==>
[ token ] "^" result-class ( "," result )* nl
out-of-band-record ==>
async-record | stream-record
async-record ==>
exec-async-output | status-async-output | notify-async-output
exec-async-output ==>
[ token ] "*" async-output
status-async-output ==>
[ token ] "+" async-output
notify-async-output ==>
[ token ] "=" async-output
async-output ==>
async-class ( "," result )* nl
result-class ==>
"done" | "running" | "connected" | "error" | "exit"
async-class ==>
"stopped" | others (where others will be added depending on the needs--this is still in development).
result ==>
variable "=" value
variable ==>
string
value ==>
const | tuple | list
const ==>
c-string
tuple ==>
"{}" | "{" result ( "," result )* "}"
list ==>
"[]" | "[" value ( "," value )* "]" | "[" result ( "," result )* "]"
stream-record ==>
console-stream-output | target-stream-output | log-stream-output
console-stream-output ==>
"~" c-string
target-stream-output ==>
"@" c-string
log-stream-output ==>
"&" c-string
nl ==>
CR | CR-LF
token ==>
any sequence of digits.
*/
// FIXME: rename into GdbMiValue
class GdbMi
{
public:
GdbMi() : m_type(Invalid) {}
explicit GdbMi(const QByteArray &str) { fromString(str); }
QByteArray m_name;
QByteArray m_data;
QList<GdbMi> m_children;
enum Type {
Invalid,
Const,
Tuple,
List,
};
Type m_type;
inline Type type() const { return m_type; }
inline QByteArray name() const { return m_name; }
inline bool hasName(const char *name) const { return m_name == name; }
inline bool isValid() const { return m_type != Invalid; }
inline bool isConst() const { return m_type == Const; }
inline bool isTuple() const { return m_type == Tuple; }
inline bool isList() const { return m_type == List; }
inline QByteArray data() const { return m_data; }
inline const QList<GdbMi> &children() const { return m_children; }
inline int childCount() const { return m_children.size(); }
const GdbMi & childAt(int index) const { return m_children[index]; }
GdbMi & childAt(int index) { return m_children[index]; }
GdbMi findChild(const QByteArray &name) const;
GdbMi findChild(const QByteArray &name, const QByteArray &defaultString) const;
QByteArray toString(bool multiline = false, int indent = 0) const;
void fromString(const QByteArray &str);
void setStreamOutput(const QByteArray &name, const QByteArray &content);
private:
friend class GdbResultRecord;
friend class GdbEngine;
//typedef ushort Char;
typedef char Char;
static QByteArray parseCString(const Char *&from, const Char *to);
void parseResultOrValue(const Char *&from, const Char *to);
void parseValue(const Char *&from, const Char *to);
void parseTuple(const Char *&from, const Char *to);
void parseTuple_helper(const Char *&from, const Char *to);
void parseList(const Char *&from, const Char *to);
void dumpChildren(QByteArray *str, bool multiline, int indent) const;
};
enum GdbResultClass
{
// "done" | "running" | "connected" | "error" | "exit"
GdbResultUnknown,
GdbResultDone,
GdbResultCustomDone,
GdbResultRunning,
GdbResultConnected,
GdbResultError,
GdbResultExit,
};
class GdbResultRecord
{
public:
GdbResultRecord() : token(-1), resultClass(GdbResultUnknown) {}
QByteArray toString() const;
int token;
GdbResultClass resultClass;
GdbMi data;
private:
friend class GdbMi;
};
} // namespace Internal
} // namespace Debugger
//Q_DECLARE_METATYPE(GdbDebugger::Internal::GdbMi);
#endif // DEBUGGER_GDBMI_H

View File

@@ -0,0 +1,128 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "gdboptionpage.h"
#include "gdbengine.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <QtCore/QSettings>
#include <QtGui/QLineEdit>
#include <QtGui/QFileDialog>
using namespace Debugger::Internal;
GdbOptionPage::GdbOptionPage(GdbSettings *settings)
{
m_pm = ExtensionSystem::PluginManager::instance();
m_settings = settings;
Core::ICore *coreIFace = m_pm->getObject<Core::ICore>();
if (!coreIFace || !coreIFace->settings())
return;
QSettings *s = coreIFace->settings();
s->beginGroup("GdbOptions");
QString defaultCommand("gdb");
#if defined(Q_OS_WIN32)
defaultCommand.append(".exe");
#endif
m_settings->m_gdbCmd = s->value("Location", defaultCommand).toString();
m_settings->m_gdbEnv = s->value("Environment", "").toString();
m_settings->m_autoRun = s->value("AutoRun", true).toBool();
m_settings->m_autoQuit = s->value("AutoQuit", true).toBool();
s->endGroup();
}
QString GdbOptionPage::name() const
{
return tr("Gdb");
}
QString GdbOptionPage::category() const
{
return "Debugger|Gdb";
}
QString GdbOptionPage::trCategory() const
{
return tr("Debugger|Gdb");
}
QWidget *GdbOptionPage::createPage(QWidget *parent)
{
QWidget *w = new QWidget(parent);
m_ui.setupUi(w);
m_ui.gdbEdit->setText(m_settings->m_gdbCmd);
m_ui.envEdit->setText(m_settings->m_gdbEnv);
m_ui.autoStartBox->setChecked(m_settings->m_autoRun);
m_ui.autoQuitBox->setChecked(m_settings->m_autoQuit);
connect(m_ui.pushButtonBrowse, SIGNAL(clicked()),
this, SLOT(browse()));
return w;
}
void GdbOptionPage::browse()
{
QString fileName = QFileDialog::getOpenFileName(m_ui.pushButtonBrowse,
"Browse for gdb executable");
if (fileName.isEmpty())
return;
m_settings->m_gdbCmd = fileName;
m_ui.gdbEdit->setText(fileName);
}
void GdbOptionPage::finished(bool accepted)
{
if (!accepted)
return;
m_settings->m_gdbCmd = m_ui.gdbEdit->text();
m_settings->m_gdbEnv = m_ui.envEdit->text();
m_settings->m_autoRun = m_ui.autoStartBox->isChecked();
m_settings->m_autoQuit = m_ui.autoQuitBox->isChecked();
Core::ICore *coreIFace = m_pm->getObject<Core::ICore>();
if (!coreIFace || !coreIFace->settings())
return;
QSettings *s = coreIFace->settings();
s->beginGroup("GdbOptions");
s->setValue("Location", m_settings->m_gdbCmd);
s->setValue("Environment", m_settings->m_gdbEnv);
s->setValue("AutoRun", m_settings->m_autoRun);
s->setValue("AutoQuit", m_settings->m_autoQuit);
s->endGroup();
}

View File

@@ -0,0 +1,106 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef GDBOPTIONPAGE_H
#define GDBOPTIONPAGE_H
#include "ui_gdboptionpage.h"
#include "ui_gdbtypemacros.h"
#include <coreplugin/dialogs/ioptionspage.h>
#include <QtGui/QWidget>
namespace ExtensionSystem { class PluginManager; }
namespace Debugger {
namespace Internal {
class GdbSettings;
class GdbOptionPage : public Core::IOptionsPage
{
Q_OBJECT
public:
GdbOptionPage(GdbSettings *settings);
QString name() const;
QString category() const;
QString trCategory() const;
QWidget *createPage(QWidget *parent);
void finished(bool accepted);
public slots:
void browse();
private:
ExtensionSystem::PluginManager *m_pm;
Ui::GdbOptionPage m_ui;
GdbSettings *m_settings;
};
class TypeMacroPage : public Core::IOptionsPage
{
Q_OBJECT
public:
TypeMacroPage(GdbSettings *settings);
QString name() const;
QString category() const;
QString trCategory() const;
QWidget *createPage(QWidget *parent);
void finished(bool accepted);
private slots:
void onScriptButton();
void onAddButton();
void onDelButton();
void currentItemChanged(QTreeWidgetItem *item);
void updateButtonState();
private:
ExtensionSystem::PluginManager *m_pm;
Ui::TypeMacroPage m_ui;
GdbSettings *m_settings;
QWidget *m_widget;
};
} // namespace Internal
} // namespace Debugger
#endif // GDBOPTIONPAGE_H

View File

@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GdbOptionPage</class>
<widget class="QWidget" name="GdbOptionPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>433</width>
<height>216</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Gdb Debug Options</string>
</property>
<layout class="QGridLayout">
<property name="margin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="1">
<widget class="QLineEdit" name="gdbEdit"/>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLineEdit" name="envEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Gdb Location:</string>
</property>
<property name="buddy">
<cstring>gdbEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Environment:</string>
</property>
<property name="buddy">
<cstring>envEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButtonBrowse">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../coreplugin/core.qrc">
<normaloff>:/qworkbench/images/fileopen.png</normaloff>:/qworkbench/images/fileopen.png</iconset>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoStartBox">
<property name="text">
<string>Auto run executable on debugger startup</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoQuitBox">
<property name="text">
<string>Quit debugger when the executable exits</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>415</width>
<height>41</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources>
<include location="../coreplugin/core.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,214 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "gdboptionpage.h"
#include "gdbengine.h"
#include "imports.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <QtCore/QSettings>
#include <QtCore/QByteArray>
#include <QtGui/QFileDialog>
using namespace Debugger::Internal;
TypeMacroPage::TypeMacroPage(GdbSettings *settings)
{
m_pm = ExtensionSystem::PluginManager::instance();
m_settings = settings;
Core::ICore *coreIFace = m_pm->getObject<Core::ICore>();
if (!coreIFace || !coreIFace->settings())
return;
QSettings *s = coreIFace->settings();
s->beginGroup("GdbOptions");
if (!s->contains("ScriptFile") && !s->contains("TypeMacros")) {
//insert qt4 defaults
m_settings->m_scriptFile = coreIFace->resourcePath() +
QLatin1String("/gdb/qt4macros");
for (int i=0; i<3; ++i) {
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
switch(i) {
case 0:
stream << QString("printqstring") << (int)1;
m_settings->m_typeMacros.insert(QLatin1String("QString"), data);
break;
case 1:
stream << QString("printqcolor") << (int)0;
m_settings->m_typeMacros.insert(QLatin1String("QColor"), data);
break;
case 2:
stream << QString("printqfont") << (int)1;
m_settings->m_typeMacros.insert(QLatin1String("QFont"), data);
break;
}
}
s->setValue("ScriptFile", m_settings->m_scriptFile);
s->setValue("TypeMacros", m_settings->m_typeMacros);
} else {
m_settings->m_scriptFile = s->value("ScriptFile", QString()).toString();
m_settings->m_typeMacros = s->value("TypeMacros", QMap<QString,QVariant>()).toMap();
}
s->endGroup();
}
QString TypeMacroPage::name() const
{
return tr("Type Macros");
}
QString TypeMacroPage::category() const
{
return "Debugger|Gdb";
}
QString TypeMacroPage::trCategory() const
{
return tr("Debugger|Gdb");
}
QWidget *TypeMacroPage::createPage(QWidget *parent)
{
QString macro;
int index;
m_widget = new QWidget(parent);
m_ui.setupUi(m_widget);
connect(m_ui.addButton, SIGNAL(clicked()),
this, SLOT(onAddButton()));
connect(m_ui.delButton, SIGNAL(clicked()),
this, SLOT(onDelButton()));
connect(m_ui.scriptButton, SIGNAL(clicked()),
this, SLOT(onScriptButton()));
connect(m_ui.treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
this, SLOT(currentItemChanged(QTreeWidgetItem *)));
connect(m_ui.typeEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updateButtonState()));
connect(m_ui.macroEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updateButtonState()));
QMap<QString, QVariant>::const_iterator i = m_settings->m_typeMacros.constBegin();
while (i != m_settings->m_typeMacros.constEnd()) {
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.treeWidget);
QDataStream stream(i.value().toByteArray());
stream >> macro >> index;
item->setText(0, i.key());
item->setText(1, macro);
item->setData(0, Qt::UserRole, index);
++i;
}
m_ui.scriptEdit->setText(m_settings->m_scriptFile);
updateButtonState();
return m_widget;
}
void TypeMacroPage::finished(bool accepted)
{
if (!accepted)
return;
m_settings->m_typeMacros.clear();
m_settings->m_scriptFile = m_ui.scriptEdit->text();
for (int i=0; i<m_ui.treeWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = m_ui.treeWidget->topLevelItem(i);
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << item->text(1) << item->data(0, Qt::UserRole).toInt();
m_settings->m_typeMacros.insert(item->text(0), data);
}
Core::ICore *coreIFace = m_pm->getObject<Core::ICore>();
if (coreIFace && coreIFace->settings()) {
QSettings *s = coreIFace->settings();
s->beginGroup("GdbOptions");
s->setValue("ScriptFile", m_settings->m_scriptFile);
s->setValue("TypeMacros", m_settings->m_typeMacros);
s->endGroup();
}
}
void TypeMacroPage::onScriptButton()
{
QString fileName = QFileDialog::getOpenFileName(m_widget, tr("Select Gdb Script"));
m_ui.scriptEdit->setText(fileName);
updateButtonState();
}
void TypeMacroPage::onAddButton()
{
if (m_ui.typeEdit->text().isEmpty() || m_ui.macroEdit->text().isEmpty())
return;
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.treeWidget);
item->setText(0, m_ui.typeEdit->text());
item->setText(1, m_ui.macroEdit->text());
item->setData(0, Qt::UserRole, m_ui.parseAsBox->currentIndex());
updateButtonState();
}
void TypeMacroPage::onDelButton()
{
if (QTreeWidgetItem *item = m_ui.treeWidget->currentItem())
delete item;
updateButtonState();
}
void TypeMacroPage::currentItemChanged(QTreeWidgetItem *item)
{
m_ui.typeEdit->setText(item ? item->text(0) : QString());
m_ui.macroEdit->setText(item ? item->text(1) : QString());
m_ui.parseAsBox->setCurrentIndex(item ? item->data(0, Qt::UserRole).toInt() : 0);
updateButtonState();
}
void TypeMacroPage::updateButtonState()
{
m_ui.delButton->setEnabled(m_ui.treeWidget->currentItem() != 0);
m_ui.addButton->setDisabled(m_ui.typeEdit->text().isEmpty()
|| m_ui.macroEdit->text().isEmpty());
}

View File

@@ -0,0 +1,186 @@
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<class>TypeMacroPage</class>
<widget class="QWidget" name="TypeMacroPage" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>519</width>
<height>238</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Script File</string>
</property>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLineEdit" name="scriptEdit" />
</item>
<item>
<widget class="QToolButton" name="scriptButton" >
<property name="minimumSize" >
<size>
<width>21</width>
<height>23</height>
</size>
</property>
<property name="text" >
<string>...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QGridLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="0" colspan="2" >
<widget class="QTreeWidget" name="treeWidget" >
<property name="rootIsDecorated" >
<bool>false</bool>
</property>
<column>
<property name="text" >
<string>Type</string>
</property>
</column>
<column>
<property name="text" >
<string>Macro</string>
</property>
</column>
</widget>
</item>
<item row="1" column="2" >
<widget class="QToolButton" name="addButton" >
<property name="minimumSize" >
<size>
<width>21</width>
<height>23</height>
</size>
</property>
<property name="text" >
<string>+</string>
</property>
<property name="icon" >
<iconset resource="gdbdebugger.qrc" >:/gdbdebugger/images/newitem.png</iconset>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Macro Name:</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Parse as:</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="macroEdit" />
</item>
<item row="0" column="2" >
<layout class="QVBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="delButton" >
<property name="minimumSize" >
<size>
<width>21</width>
<height>23</height>
</size>
</property>
<property name="text" >
<string>-</string>
</property>
<property name="icon" >
<iconset resource="gdbdebugger.qrc" >:/gdbdebugger/images/delete.png</iconset>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="typeEdit" />
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Type:</string>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QComboBox" name="parseAsBox" >
<item>
<property name="text" >
<string>ASCII (char *)</string>
</property>
</item>
<item>
<property name="text" >
<string>Unicode (short)</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<pixmapfunction></pixmapfunction>
<resources>
<include location="gdbdebugger.qrc" />
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,88 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_IDEBUGGERENGINE_H
#define DEBUGGER_IDEBUGGERENGINE_H
#include <QtCore/QObject>
namespace Debugger {
namespace Internal {
class IDebuggerEngine : public QObject
{
public:
IDebuggerEngine(QObject *parent = 0) : QObject(parent) {}
virtual void shutdown() = 0;
virtual void setToolTipExpression(const QPoint &pos, const QString &exp) = 0;
virtual bool startDebugger() = 0;
virtual void exitDebugger() = 0;
virtual void updateWatchModel() = 0;
virtual void stepExec() = 0;
virtual void stepOutExec() = 0;
virtual void nextExec() = 0;
virtual void stepIExec() = 0;
virtual void nextIExec() = 0;
virtual void continueInferior() = 0;
virtual void runInferior() = 0;
virtual void interruptInferior() = 0;
virtual void runToLineExec(const QString &fileName, int lineNumber) = 0;
virtual void runToFunctionExec(const QString &functionName) = 0;
virtual void jumpToLineExec(const QString &fileName, int lineNumber) = 0;
virtual void assignValueInDebugger(const QString &expr, const QString &value) = 0;
virtual void executeDebuggerCommand(const QString &command) = 0;
virtual void activateFrame(int index) = 0;
virtual void selectThread(int index) = 0;
virtual void attemptBreakpointSynchronization() = 0;
virtual void loadSessionData() = 0;
virtual void saveSessionData() = 0;
virtual void reloadDisassembler() = 0;
virtual void reloadModules() = 0;
virtual void loadSymbols(const QString &moduleName) = 0;
virtual void loadAllSymbols() = 0;
virtual void reloadRegisters() = 0;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_IDEBUGGERENGINE_H

View File

@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="14"
height="14"
id="svg2270"
sodipodi:version="0.32"
inkscape:version="0.45.1"
version="1.0"
sodipodi:docbase="D:\depot\research\main\editor\images"
sodipodi:docname="breakpoint.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2272">
<linearGradient
id="linearGradient7029">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop7031" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop7033" />
</linearGradient>
<linearGradient
id="linearGradient17794">
<stop
style="stop-color:#f18383;stop-opacity:1;"
offset="0"
id="stop17798" />
<stop
id="stop8006"
offset="0.3807947"
style="stop-color:#ed6767;stop-opacity:1;" />
<stop
style="stop-color:#e62323;stop-opacity:1;"
offset="1"
id="stop17796" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient17794"
id="linearGradient24732"
gradientUnits="userSpaceOnUse"
x1="472.42236"
y1="436.79602"
x2="461.39169"
y2="424.95065" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient17794"
id="linearGradient2438"
gradientUnits="userSpaceOnUse"
x1="472.42236"
y1="436.79602"
x2="461.39169"
y2="424.95065" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient17794"
id="radialGradient6052"
cx="466.73566"
cy="431.19708"
fx="466.73566"
fy="431.19708"
r="9.3095722"
gradientTransform="matrix(1,0,0,1.0057859,0,-2.4948735)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient7029"
id="linearGradient7035"
x1="6.75"
y1="0.5"
x2="6.75"
y2="12.5"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="8.6877264"
inkscape:cy="6.3888789"
inkscape:document-units="px"
inkscape:current-layer="g25843"
width="14px"
height="14px"
inkscape:window-width="1280"
inkscape:window-height="998"
inkscape:window-x="0"
inkscape:window-y="0"
showgrid="true"
gridspacingx="0.5px"
gridspacingy="0.5px"
gridempspacing="2"
inkscape:grid-points="true" />
<metadata
id="metadata2275">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g25843"
transform="matrix(0.7931251,0,0,0.7931251,-372.13374,-408.22195)">
<path
sodipodi:type="arc"
style="fill:url(#radialGradient6052);fill-opacity:1.0;stroke:#c80000;stroke-width:1.43637741;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path22737"
sodipodi:cx="466.73566"
sodipodi:cy="431.19708"
sodipodi:rx="8.5913839"
sodipodi:ry="8.6452484"
d="M 475.32704 431.19708 A 8.5913839 8.6452484 0 1 1 458.14427,431.19708 A 8.5913839 8.6452484 0 1 1 475.32704 431.19708 z"
transform="matrix(0.8805346,0,0,0.8750503,66.41784,145.57686)" />
<path
sodipodi:type="arc"
style="opacity:1;fill:url(#linearGradient7035);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path6058"
sodipodi:cx="6.75"
sodipodi:cy="6.5"
sodipodi:rx="5.75"
sodipodi:ry="6"
d="M 12.5 6.5 A 5.75 6 0 1 1 1,6.5 A 5.75 6 0 1 1 12.5 6.5 z"
transform="matrix(0.9867408,0,0,0.6304178,470.73423,515.01579)" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -0,0 +1,534 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="14"
height="14"
id="svg2270"
sodipodi:version="0.32"
inkscape:version="0.45.1"
version="1.0"
sodipodi:docbase="c:\depot\research\main\editor\images"
sodipodi:docname="pendingbreakpoint.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2272">
<linearGradient
id="linearGradient7029">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop7031" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop7033" />
</linearGradient>
<linearGradient
id="linearGradient17794">
<stop
style="stop-color:#f18383;stop-opacity:1;"
offset="0"
id="stop17798" />
<stop
id="stop8006"
offset="0.3807947"
style="stop-color:#ed6767;stop-opacity:1;" />
<stop
style="stop-color:#e62323;stop-opacity:1;"
offset="1"
id="stop17796" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient17794"
id="linearGradient24732"
gradientUnits="userSpaceOnUse"
x1="472.42236"
y1="436.79602"
x2="461.39169"
y2="424.95065" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient17794"
id="linearGradient2438"
gradientUnits="userSpaceOnUse"
x1="472.42236"
y1="436.79602"
x2="461.39169"
y2="424.95065" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient17794"
id="radialGradient6052"
cx="466.73566"
cy="431.19708"
fx="466.73566"
fy="431.19708"
r="9.3095722"
gradientTransform="matrix(1,0,0,1.0057859,0,-2.4948735)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient7029"
id="linearGradient7035"
x1="6.75"
y1="0.5"
x2="6.75"
y2="12.5"
gradientUnits="userSpaceOnUse" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="12.5"
x2="6.75"
y1="0.5"
x1="6.75"
id="linearGradient2228"
xlink:href="#linearGradient7029"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.0057859,0,-2.4948735)"
r="9.3095722"
fy="431.19708"
fx="466.73566"
cy="431.19708"
cx="466.73566"
id="radialGradient2226"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
y2="424.95065"
x2="461.39169"
y1="436.79602"
x1="472.42236"
gradientUnits="userSpaceOnUse"
id="linearGradient2224"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
y2="424.95065"
x2="461.39169"
y1="436.79602"
x1="472.42236"
gradientUnits="userSpaceOnUse"
id="linearGradient2222"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
id="linearGradient2214">
<stop
id="stop2216"
offset="0"
style="stop-color:#f18383;stop-opacity:1;" />
<stop
style="stop-color:#ed6767;stop-opacity:1;"
offset="0.3807947"
id="stop2218" />
<stop
id="stop2220"
offset="1"
style="stop-color:#e62323;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient2208">
<stop
id="stop2210"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop2212"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.2661544,0,0,1.2608351,469.23729,510.59508)"
y2="10.60876"
x2="10.981011"
y1="9.9135647"
x1="10.946278"
gradientUnits="userSpaceOnUse"
id="linearGradient4173"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(1.2608351,0,0,1.2608351,475.7834,516.59183)"
y2="9.578125"
x2="5.859375"
y1="6.609375"
x1="5.953125"
gradientUnits="userSpaceOnUse"
id="linearGradient4159"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="11"
x2="11"
y1="10"
x1="11"
id="linearGradient4156"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
y2="521.00476"
x2="472.35138"
y1="519.11353"
x1="472.35138"
gradientTransform="matrix(1,0,0,1.0000093,10.421461,10.71221)"
gradientUnits="userSpaceOnUse"
id="linearGradient4138"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(1,0,0,0.9687523,10.283691,16.9106)"
gradientUnits="userSpaceOnUse"
y2="521.00476"
x2="472.35138"
y1="519.11353"
x1="472.35138"
id="linearGradient4134"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
y2="424.95065"
x2="461.39169"
y1="436.79602"
x1="472.42236"
gradientUnits="userSpaceOnUse"
id="linearGradient2293"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
y2="424.95065"
x2="461.39169"
y1="436.79602"
x1="472.42236"
gradientUnits="userSpaceOnUse"
id="linearGradient2291"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
id="linearGradient2285">
<stop
id="stop2287"
offset="0"
style="stop-color:#c80000;stop-opacity:1;" />
<stop
id="stop2289"
offset="1"
style="stop-color:#ffa0a0;stop-opacity:1;" />
</linearGradient>
<linearGradient
y2="424.95065"
x2="461.39169"
y1="436.79602"
x1="472.42236"
gradientUnits="userSpaceOnUse"
id="linearGradient25826"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
id="linearGradient4128">
<stop
id="stop4130"
offset="0"
style="stop-color:#ffffff;stop-opacity:0.78431374;" />
<stop
id="stop4132"
offset="1"
style="stop-color:#ffffff;stop-opacity:0.23529412;" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.2661544,0,0,1.2608351,469.23729,510.59508)"
y2="10.60876"
x2="10.981011"
y1="9.9135647"
x1="10.946278"
gradientUnits="userSpaceOnUse"
id="linearGradient2378"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="11.147234"
x2="11.02502"
y1="9.6892195"
x1="10.968282"
id="linearGradient2376"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(1.2608351,0,0,1.2608351,475.7834,516.59183)"
y2="9.578125"
x2="5.859375"
y1="6.609375"
x1="5.953125"
gradientUnits="userSpaceOnUse"
id="linearGradient2374"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="11"
x2="11"
y1="10"
x1="11"
id="linearGradient2372"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
y2="521.00476"
x2="472.35138"
y1="519.11353"
x1="472.35138"
gradientTransform="matrix(1,0,0,0.6666648,10.303108,184.09099)"
gradientUnits="userSpaceOnUse"
id="linearGradient2370"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
y2="521.00476"
x2="472.35138"
y1="519.11353"
x1="472.35138"
gradientTransform="matrix(1,0,0,0.6666648,10.342666,173.98441)"
gradientUnits="userSpaceOnUse"
id="linearGradient2368"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
y2="521.00476"
x2="472.35138"
y1="519.11353"
x1="472.35138"
gradientTransform="matrix(1,0,0,1.0000093,10.421461,10.71221)"
gradientUnits="userSpaceOnUse"
id="linearGradient2366"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(1,0,0,0.9687523,10.283691,16.9106)"
gradientUnits="userSpaceOnUse"
y2="521.00476"
x2="472.35138"
y1="519.11353"
x1="472.35138"
id="linearGradient2364"
xlink:href="#linearGradient4128"
inkscape:collect="always" />
<linearGradient
y2="424.95065"
x2="461.39169"
y1="436.79602"
x1="472.42236"
gradientUnits="userSpaceOnUse"
id="linearGradient2362"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
y2="424.95065"
x2="461.39169"
y1="436.79602"
x1="472.42236"
gradientUnits="userSpaceOnUse"
id="linearGradient2360"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
id="linearGradient2354">
<stop
id="stop2356"
offset="0"
style="stop-color:#c80000;stop-opacity:1;" />
<stop
id="stop2358"
offset="1"
style="stop-color:#ffa0a0;stop-opacity:1;" />
</linearGradient>
<linearGradient
y2="424.95065"
x2="461.39169"
y1="436.79602"
x1="472.42236"
gradientUnits="userSpaceOnUse"
id="linearGradient2352"
xlink:href="#linearGradient17794"
inkscape:collect="always" />
<linearGradient
id="linearGradient2346">
<stop
id="stop2348"
offset="0"
style="stop-color:#ffffff;stop-opacity:0.78431374;" />
<stop
id="stop2350"
offset="1"
style="stop-color:#ffffff;stop-opacity:0.23529412;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4128"
id="linearGradient2392"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.6666648,10.342666,173.98441)"
x1="472.35138"
y1="519.11353"
x2="472.35138"
y2="521.00476" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4128"
id="linearGradient2394"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.6666648,10.303108,184.09099)"
x1="472.35138"
y1="519.11353"
x2="472.35138"
y2="521.00476" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4128"
id="linearGradient2396"
gradientUnits="userSpaceOnUse"
x1="10.968282"
y1="9.6892195"
x2="11.02502"
y2="11.147234" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="45.254834"
inkscape:cx="13.678175"
inkscape:cy="6.8291478"
inkscape:document-units="px"
inkscape:current-layer="g25843"
width="14px"
height="14px"
inkscape:window-width="1280"
inkscape:window-height="998"
inkscape:window-x="44"
inkscape:window-y="58"
showgrid="true"
gridspacingx="0.5px"
gridspacingy="0.5px"
gridempspacing="2"
inkscape:grid-points="true" />
<metadata
id="metadata2275">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g25843"
transform="matrix(0.7931251,0,0,0.7931251,-372.13374,-408.22195)">
<path
sodipodi:type="arc"
style="fill:url(#radialGradient6052);fill-opacity:1.0;stroke:#c80000;stroke-width:1.43637741;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path22737"
sodipodi:cx="466.73566"
sodipodi:cy="431.19708"
sodipodi:rx="8.5913839"
sodipodi:ry="8.6452484"
d="M 475.32704 431.19708 A 8.5913839 8.6452484 0 1 1 458.14427,431.19708 A 8.5913839 8.6452484 0 1 1 475.32704 431.19708 z"
transform="matrix(0.8805346,0,0,0.8750503,66.41784,145.57686)" />
<path
sodipodi:type="arc"
style="opacity:1;fill:url(#linearGradient7035);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path6058"
sodipodi:cx="6.75"
sodipodi:cy="6.5"
sodipodi:rx="5.75"
sodipodi:ry="6"
d="M 12.5 6.5 A 5.75 6 0 1 1 1,6.5 A 5.75 6 0 1 1 12.5 6.5 z"
transform="matrix(0.9867408,0,0,0.6304178,470.73423,515.01579)" />
<g
id="g2380"
inkscape:label="Layer 1"
transform="matrix(1.2608365,0,0,1.2633098,469.19929,514.69071)">
<g
transform="matrix(0.7931251,0,0,0.7931251,-372.13374,-408.22195)"
id="g2382">
<path
style="fill:#7f7f8c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 481.17723,524.15684 C 481.17723,524.15684 482.11277,524.68766 483.0584,524.68766 C 484.00403,524.68766 484.95974,524.15684 484.95974,524.15684 L 483.4493,526.03249 L 483.4493,527.83201 L 484.8944,528.56151 L 484.95974,531.09144 L 481.17723,531.09144 L 481.16963,528.69627 L 482.71594,527.80266 L 482.72456,526.04216 L 481.17723,524.15684 z "
id="path2442"
sodipodi:nodetypes="czcccccccccc" />
<path
style="opacity:0.2;fill:#7f7f7f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 481.17723,521.00476 L 481.17723,523.52643 L 482.43807,526.0481 L 481.17723,528.56977 L 481.17723,531.72186 L 484.95974,531.72186 L 484.95974,528.56977 L 483.6989,526.0481 L 484.95974,523.52643 L 484.95974,521.00476 L 481.17723,521.00476 z "
id="path2444"
sodipodi:nodetypes="ccccccccccc" />
<path
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path2174"
d="M 480.54682,520.37434 L 480.54681,523.52643 L 481.80765,526.0481 L 480.54681,528.56977 L 480.54682,531.72185 L 485.59016,531.72185 L 485.59015,528.56977 L 484.32932,526.0481 L 485.59015,523.52643 L 485.59016,520.37434 L 480.54682,520.37434 z M 481.80766,521.63517 L 484.32932,521.63517 L 484.32932,523.52643 L 483.46249,526.0481 L 484.32932,528.56977 L 484.32932,530.46102 L 481.80766,530.46102 L 481.80765,528.56977 L 482.72372,526.0481 L 481.80765,523.52643 L 481.80766,521.63517 z "
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<rect
ry="1.2608351"
y="519.7439"
x="479.28598"
height="2.5216701"
width="7.565001"
id="rect2172"
style="opacity:1;fill:#7f2aff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
ry="1.2608351"
y="529.83063"
x="479.28598"
height="2.5216701"
width="7.565001"
id="rect2170"
style="opacity:1;fill:#6600ff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
ry="0.63040882"
y="520.0589"
x="480.17267"
height="1.2608176"
width="5.6737618"
id="rect4140"
style="opacity:1;fill:url(#linearGradient2392);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
ry="0.63040882"
y="530.16577"
x="480.13324"
height="1.2608176"
width="5.6737618"
id="rect4144"
style="opacity:1;fill:url(#linearGradient2394);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cssz"
transform="matrix(1.2608351,0,0,1.2608351,469.1993,514.70058)"
id="path4161"
d="M 11.007811,9.9179701 C 10.386665,9.9257826 9.6414144,10.484263 9.5594939,10.992187 C 9.5017174,11.350414 12.494284,11.43273 12.441847,10.914063 C 12.40754,10.574731 11.628908,9.9101582 11.007811,9.9179701 z "
style="fill:url(#linearGradient2396);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="14"
height="14"
id="svg2243"
sodipodi:version="0.32"
inkscape:version="0.45.1"
version="1.0"
sodipodi:docbase="c:\depot\research\main\editor\images"
sodipodi:docname="location.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2245">
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="64"
inkscape:cx="8.3920091"
inkscape:cy="7.4257237"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="14px"
height="14px"
showborder="true"
inkscape:window-width="1600"
inkscape:window-height="1174"
inkscape:window-x="0"
inkscape:window-y="0"
gridempspacing="2"
showgrid="true"
inkscape:grid-points="true"
gridspacingx="0.5px"
gridspacingy="0.5px" />
<metadata
id="metadata2248">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="14"
height="14"
id="svg2243"
sodipodi:version="0.32"
inkscape:version="0.45.1"
version="1.0"
sodipodi:docbase="c:\depot\research\main\editor\images"
sodipodi:docname="location.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2245">
<linearGradient
id="linearGradient3134">
<stop
style="stop-color:#dcdc23;stop-opacity:1;"
offset="0"
id="stop3136" />
<stop
id="stop5080"
offset="0.64285713"
style="stop-color:#e5d044;stop-opacity:1;" />
<stop
style="stop-color:#b89354;stop-opacity:1;"
offset="1"
id="stop3138" />
</linearGradient>
<linearGradient
id="linearGradient3137">
<stop
style="stop-color:#ffffff;stop-opacity:0.86274511;"
offset="0"
id="stop3139" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3141" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3137"
id="linearGradient3143"
x1="6.5"
y1="3"
x2="6.515625"
y2="12.180227"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3134"
id="linearGradient3140"
x1="6.5"
y1="3.015625"
x2="6.484375"
y2="11.984375"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="64"
inkscape:cx="8.3920091"
inkscape:cy="7.4257237"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="14px"
height="14px"
showborder="true"
inkscape:window-width="1600"
inkscape:window-height="1174"
inkscape:window-x="0"
inkscape:window-y="0"
gridempspacing="2"
showgrid="true"
inkscape:grid-points="true"
gridspacingx="0.5px"
gridspacingy="0.5px" />
<metadata
id="metadata2248">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:url(#linearGradient3140);fill-opacity:1.0;fill-rule:evenodd;stroke:#b18b1b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 6.5,3 L 6.5,5.5 L 0.5,5.5 L 0.5,9.5 L 6.5,9.5 L 6.5,12 L 13.125,7.5 L 6.5,3 z "
id="path2216"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:url(#linearGradient3143);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:1"
d="M 6.5,3 L 6.5,5.5 L 0.5,5.5 L 0.5,7.5 C 7,6.5 7.5,9.5 13,7.5 L 6.5,3 z "
id="path5066"
sodipodi:nodetypes="cccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

View File

@@ -0,0 +1,49 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_IMPORTS_H
#define DEBUGGER_IMPORTS_H
// FIXME: Plan is to remove this file. It's needed to get "harmless"
// replacements for GH internals in the standalone version
#ifndef GDBDEBUGGERLEAN
#include <texteditor/basetextmark.h>
#else
#include "lean.h"
#endif
#endif // DEBUGGER_IMPORTS_H

View File

@@ -0,0 +1,233 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "mode.h"
#include "assert.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/minisplitter.h>
#include <coreplugin/findplaceholder.h>
#include <coreplugin/outputpane.h>
#include <coreplugin/navigationwidget.h>
#include <coreplugin/rightpane.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <QtCore/QDebug>
#include <QtCore/QSettings>
#include <QtGui/QDockWidget>
#include <QtGui/QLabel>
#include <QtGui/QMainWindow>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>
using namespace Core;
using namespace ExtensionSystem;
using namespace Debugger;
using namespace Debugger::Internal;
using namespace Debugger::Constants;
DebugMode::DebugMode(DebuggerManager *manager, QObject *parent)
: BaseMode(tr("Debug"), Constants::MODE_DEBUG,
QIcon(":/fancyactionbar/images/mode_Debug.png"),
Constants::P_MODE_DEBUG, 0, parent),
m_manager(manager)
{
IDebuggerManagerAccessForDebugMode *managerAccess =
m_manager->debugModeInterface();
UniqueIDManager *uidm =
PluginManager::instance()->getObject<ICore>()->uniqueIDManager();
QList<int> context;
context.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER));
context.append(uidm->uniqueIdentifier(Constants::C_GDBDEBUGGER));
context.append(uidm->uniqueIdentifier(Core::Constants::C_NAVIGATION_PANE));
setContext(context);
QBoxLayout *editorHolderLayout = new QVBoxLayout;
editorHolderLayout->setMargin(0);
editorHolderLayout->setSpacing(0);
editorHolderLayout->addWidget(new EditorManagerPlaceHolder(this));
editorHolderLayout->addWidget(new FindToolBarPlaceHolder(this));
QWidget *editorAndFindWidget = new QWidget;
editorAndFindWidget->setLayout(editorHolderLayout);
MiniSplitter *rightPaneSplitter = new MiniSplitter;
rightPaneSplitter->addWidget(editorAndFindWidget);
rightPaneSplitter->addWidget(new RightPanePlaceHolder(this));
rightPaneSplitter->setStretchFactor(0, 1);
rightPaneSplitter->setStretchFactor(1, 0);
QWidget *centralWidget = new QWidget;
QBoxLayout *toolBarAddingLayout = new QVBoxLayout(centralWidget);
toolBarAddingLayout->setMargin(0);
toolBarAddingLayout->setSpacing(0);
toolBarAddingLayout->addWidget(rightPaneSplitter);
m_manager->mainWindow()->setCentralWidget(centralWidget);
MiniSplitter *splitter = new MiniSplitter;
splitter->addWidget(m_manager->mainWindow());
splitter->addWidget(new OutputPanePlaceHolder(this));
splitter->setStretchFactor(0, 10);
splitter->setStretchFactor(1, 0);
splitter->setOrientation(Qt::Vertical);
MiniSplitter *splitter2 = new MiniSplitter;
splitter2 = new MiniSplitter;
splitter2->addWidget(new NavigationWidgetPlaceHolder(this));
splitter2->addWidget(splitter);
splitter2->setStretchFactor(0, 0);
splitter2->setStretchFactor(1, 1);
setWidget(splitter2);
QToolBar *toolBar = createToolBar();
toolBarAddingLayout->addWidget(toolBar);
managerAccess->createDockWidgets();
m_manager->setSimpleDockWidgetArrangement();
readSettings();
connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
this, SLOT(focusCurrentEditor(Core::IMode*)));
widget()->setFocusProxy(EditorManager::instance());
}
DebugMode::~DebugMode()
{
// Make sure the editor manager does not get deleted
EditorManager::instance()->setParent(0);
}
void DebugMode::shutdown()
{
writeSettings();
}
QToolBar *DebugMode::createToolBar()
{
IDebuggerManagerAccessForDebugMode *managerAccess =
m_manager->debugModeInterface();
Core::ActionManagerInterface *am =
ExtensionSystem::PluginManager::instance()
->getObject<Core::ICore>()->actionManager();
QToolBar *debugToolBar = new QToolBar;
debugToolBar->addAction(am->command(ProjectExplorer::Constants::DEBUG)->action());
debugToolBar->addAction(am->command(Constants::INTERRUPT)->action());
debugToolBar->addAction(am->command(Constants::NEXT)->action());
debugToolBar->addAction(am->command(Constants::STEP)->action());
debugToolBar->addAction(am->command(Constants::STEPOUT)->action());
debugToolBar->addSeparator();
debugToolBar->addAction(am->command(Constants::STEPI)->action());
debugToolBar->addAction(am->command(Constants::NEXTI)->action());
debugToolBar->addSeparator();
debugToolBar->addWidget(new QLabel(tr("Threads:")));
QComboBox *threadBox = new QComboBox;
threadBox->setModel(m_manager->threadsModel());
connect(threadBox, SIGNAL(activated(int)),
managerAccess->threadsWindow(), SIGNAL(threadSelected(int)));
debugToolBar->addWidget(threadBox);
QWidget *stretch = new QWidget;
stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
debugToolBar->addWidget(stretch);
QMenu *viewMenu = new QMenu(debugToolBar);
m_toggleLockedAction = new QAction(tr("Locked"), viewMenu);
m_toggleLockedAction->setCheckable(true);
m_toggleLockedAction->setChecked(true);
connect(m_toggleLockedAction, SIGNAL(toggled(bool)),
m_manager, SLOT(setLocked(bool)));
foreach (QDockWidget *dockWidget, managerAccess->dockWidgets())
viewMenu->addAction(dockWidget->toggleViewAction());
viewMenu->addSeparator();
viewMenu->addAction(m_toggleLockedAction);
viewMenu->addSeparator();
QAction *resetToSimpleAction = viewMenu->addAction(tr("Reset to default layout"));
connect(resetToSimpleAction, SIGNAL(triggered()),
m_manager, SLOT(setSimpleDockWidgetArrangement()));
QToolButton *viewMenuButton = new QToolButton(debugToolBar);
viewMenuButton->setText(tr("View "));
viewMenuButton->setPopupMode(QToolButton::InstantPopup);
viewMenuButton->setMenu(viewMenu);
debugToolBar->addWidget(viewMenuButton);
return debugToolBar;
}
void DebugMode::focusCurrentEditor(IMode *mode)
{
if (mode != this)
return;
EditorManager *editorManager = EditorManager::instance();
if (editorManager->currentEditor())
editorManager->currentEditor()->widget()->setFocus();
}
void DebugMode::writeSettings() const
{
QSettings *s = settings();
QWB_ASSERT(m_manager, return);
QWB_ASSERT(m_manager->mainWindow(), return);
s->beginGroup(QLatin1String("DebugMode"));
s->setValue(QLatin1String("State"), m_manager->mainWindow()->saveState());
s->setValue(QLatin1String("Locked"), m_toggleLockedAction->isChecked());
s->endGroup();
}
void DebugMode::readSettings()
{
QSettings *s = settings();
s->beginGroup(QLatin1String("DebugMode"));
m_manager->mainWindow()->restoreState(s->value(QLatin1String("State"), QByteArray()).toByteArray());
m_toggleLockedAction->setChecked(s->value(QLatin1String("Locked"), true).toBool());
s->endGroup();
}
QSettings *DebugMode::settings()
{
return PluginManager::instance()->getObject<ICore>()->settings();
}

View File

@@ -0,0 +1,84 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_DEBUGMODE_H
#define DEBUGGER_DEBUGMODE_H
#include <coreplugin/basemode.h>
#include <QtCore/QList>
#include <QtCore/QPointer>
QT_BEGIN_NAMESPACE
class QAction;
class QDockWidget;
class QMainWindow;
class QSettings;
class QSplitter;
class QToolBar;
class QWidget;
QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
class DebuggerManager;
class DebugMode : public Core::BaseMode
{
Q_OBJECT
public:
DebugMode(DebuggerManager *manager, QObject *parent = 0);
~DebugMode();
// IMode
void activated();
void shutdown();
static QSettings *settings();
private slots:
void focusCurrentEditor(Core::IMode *mode);
private:
QToolBar *createToolBar();
void writeSettings() const;
void readSettings();
QPointer<DebuggerManager> m_manager;
QAction *m_toggleLockedAction;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_DEBUGMODE_H

View File

@@ -0,0 +1,76 @@
<ui version="4.0" >
<class>DebugMode</class>
<widget class="QWidget" name="DebugMode" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>558</width>
<height>353</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" >
<property name="spacing" >
<number>0</number>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="vSplitter" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<widget class="QWidget" native="1" name="editorHolder" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
<horstretch>10</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QWidget" name="layoutWidget" >
<layout class="QVBoxLayout" name="verticalLayout" >
<property name="spacing" >
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="toolbarLayout" >
<property name="spacing" >
<number>0</number>
</property>
</layout>
</item>
<item>
<widget class="QSplitter" name="hSplitter" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTabWidget" name="bottomTabWidget" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="tabPosition" >
<enum>QTabWidget::South</enum>
</property>
<property name="tabShape" >
<enum>QTabWidget::Rounded</enum>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,172 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "moduleshandler.h"
#include "assert.h"
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QList>
#include <QtCore/QTextStream>
#include <QtGui/QAction>
#include <QtGui/QMainWindow>
#include <QtGui/QStandardItemModel>
#include <QtGui/QSortFilterProxyModel>
using namespace Debugger;
using namespace Debugger::Internal;
//////////////////////////////////////////////////////////////////
//
// ModulesModel
//
//////////////////////////////////////////////////////////////////
class Debugger::Internal::ModulesModel : public QAbstractItemModel
{
public:
ModulesModel(ModulesHandler *parent)
: QAbstractItemModel(parent)
{}
// QAbstractItemModel
int columnCount(const QModelIndex &parent) const
{ return parent.isValid() ? 0 : 4; }
int rowCount(const QModelIndex &parent) const
{ return parent.isValid() ? 0 : m_modules.size(); }
QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
QModelIndex index(int row, int column, const QModelIndex &) const
{ return createIndex(row, column); }
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
void clearModel() { if (!m_modules.isEmpty()) { m_modules.clear(); update(); } }
void update() { reset(); }
public:
QList<Module> m_modules;
};
QVariant ModulesModel::headerData(int section,
Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static QString headers[] = {
tr("Module name") + " ",
tr("Symbols read") + " ",
tr("Start address") + " ",
tr("End addAress") + " "
};
return headers[section];
}
return QVariant();
}
QVariant ModulesModel::data(const QModelIndex &index, int role) const
{
//static const QIcon icon(":/gdbdebugger/images/breakpoint.svg");
//static const QIcon icon2(":/gdbdebugger/images/breakpoint_pending.svg");
int row = index.row();
if (row < 0 || row >= m_modules.size())
return QVariant();
const Module &module = m_modules.at(row);
switch (index.column()) {
case 0:
if (role == Qt::DisplayRole)
return module.moduleName;
// FIXME: add icons
//if (role == Qt::DecorationRole)
// return module.symbolsRead ? icon2 : icon;
break;
case 1:
if (role == Qt::DisplayRole)
return module.symbolsRead ? "yes" : "no";
break;
case 2:
if (role == Qt::DisplayRole)
return module.startAddress;
break;
case 3:
if (role == Qt::DisplayRole)
return module.endAddress;
break;
}
return QVariant();
}
bool ModulesModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
return QAbstractItemModel::setData(index, value, role);
}
//////////////////////////////////////////////////////////////////
//
// ModulesHandler
//
//////////////////////////////////////////////////////////////////
ModulesHandler::ModulesHandler()
{
m_model = new ModulesModel(this);
m_proxyModel = new QSortFilterProxyModel(this);
m_proxyModel->setSourceModel(m_model);
}
QAbstractItemModel *ModulesHandler::model() const
{
return m_proxyModel;
}
void ModulesHandler::removeAll()
{
m_model->clearModel();
}
void ModulesHandler::setModules(const QList<Module> &modules)
{
m_model->m_modules = modules;
m_model->update();
}
QList<Module> ModulesHandler::modules() const
{
return m_model->m_modules;
}

View File

@@ -0,0 +1,104 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_MODULESHANDLER_H
#define DEBUGGER_MODULESHANDLER_H
#include <QtCore/QList>
#include <QtCore/QObject>
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
class QSortFilterProxyModel;
QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
class ModulesModel;
enum ModulesModelRoles
{
DisplaySourceRole = Qt::UserRole,
LoadSymbolsRole,
LoadAllSymbolsRole
};
//////////////////////////////////////////////////////////////////
//
// Module
//
//////////////////////////////////////////////////////////////////
class Module
{
public:
Module() : symbolsRead(false) {}
public:
QString moduleName;
bool symbolsRead;
QString startAddress;
QString endAddress;
};
//////////////////////////////////////////////////////////////////
//
// ModulesHandler
//
//////////////////////////////////////////////////////////////////
class ModulesHandler : public QObject
{
Q_OBJECT
public:
ModulesHandler();
QAbstractItemModel *model() const;
void setModules(const QList<Module> &modules);
QList<Module> modules() const;
void removeAll();
private:
ModulesModel *m_model;
QSortFilterProxyModel *m_proxyModel;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_MODULESHANDLER_H

View File

@@ -0,0 +1,136 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "moduleswindow.h"
#include "moduleshandler.h" // for model roles
#include <QAction>
#include <QDebug>
#include <QHeaderView>
#include <QMenu>
#include <QResizeEvent>
#include <QToolButton>
using Debugger::Internal::ModulesWindow;
ModulesWindow::ModulesWindow(QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(false)
{
setWindowTitle(tr("Modules"));
setSortingEnabled(true);
setAlternatingRowColors(true);
setRootIsDecorated(false);
setIconSize(QSize(10, 10));
}
void ModulesWindow::resizeEvent(QResizeEvent *event)
{
//QHeaderView *hv = header();
//int totalSize = event->size().width() - 110;
//hv->resizeSection(0, totalSize / 4);
//hv->resizeSection(1, totalSize / 4);
//hv->resizeSection(2, totalSize / 4);
//hv->resizeSection(3, totalSize / 4);
//hv->resizeSection(0, 60);
//hv->resizeSection(1, (totalSize * 50) / 100);
//hv->resizeSection(2, (totalSize * 50) / 100);
//hv->resizeSection(3, 50);
//setColumnHidden(3, true);
QTreeView::resizeEvent(event);
}
void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QModelIndex index = indexAt(ev->pos());
index = index.sibling(index.row(), 0);
QString name = model()->data(index).toString();
QMenu menu;
QAction *act0 = new QAction("Update module list", &menu);
QAction *act1 = new QAction("Adjust column widths to contents", &menu);
QAction *act2 = new QAction("Always adjust column widths to contents", &menu);
act2->setCheckable(true);
act2->setChecked(m_alwaysResizeColumnsToContents);
QAction *act3 = new QAction("Show source files for module " + name, &menu);
QAction *act4 = new QAction("Load symbols for all modules", &menu);
QAction *act5 = new QAction("Load symbols for module " + name, &menu);
act5->setDisabled(name.isEmpty());
menu.addAction(act0);
menu.addAction(act4);
menu.addAction(act5);
menu.addSeparator();
menu.addAction(act1);
menu.addAction(act2);
QAction *act = menu.exec(ev->globalPos());
if (act == act0)
emit reloadModulesRequested();
else if (act == act1)
resizeColumnsToContents();
else if (act == act2)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == act3)
emit displaySourceRequested(name);
else if (act == act4)
emit loadAllSymbolsRequested();
else if (act == act5)
emit loadSymbolsRequested(name);
}
void ModulesWindow::resizeColumnsToContents()
{
resizeColumnToContents(0);
resizeColumnToContents(1);
resizeColumnToContents(2);
}
void ModulesWindow::setAlwaysResizeColumnsToContents(bool on)
{
m_alwaysResizeColumnsToContents = on;
QHeaderView::ResizeMode mode = on
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
header()->setResizeMode(0, mode);
header()->setResizeMode(1, mode);
header()->setResizeMode(2, mode);
header()->setResizeMode(3, mode);
//setColumnHidden(3, true);
}
void ModulesWindow::setModel(QAbstractItemModel *model)
{
QTreeView::setModel(model);
setAlwaysResizeColumnsToContents(true);
}

View File

@@ -0,0 +1,71 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_MODULESWINDOW_H
#define DEBUGGER_MODULESWINDOW_H
#include <QTreeView>
namespace Debugger {
namespace Internal {
class ModulesWindow : public QTreeView
{
Q_OBJECT
public:
explicit ModulesWindow(QWidget *parent = 0);
signals:
void reloadModulesRequested();
void displaySourceRequested(const QString &modulesName);
void loadSymbolsRequested(const QString &modulesName);
void loadAllSymbolsRequested();
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
protected:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
void setModel(QAbstractItemModel *model);
private:
bool m_alwaysResizeColumnsToContents;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_MODULESWINDOW_H

View File

@@ -0,0 +1,182 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "procinterrupt.h"
#ifdef Q_OS_WIN
#include <windows.h>
#include <Tlhelp32.h>
using namespace Debugger::Internal;
typedef HANDLE (WINAPI *PtrCreateRemoteThread)(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
PtrCreateRemoteThread resolveCreateRemoteThread()
{
HINSTANCE hLib = LoadLibraryA("Kernel32");
return (PtrCreateRemoteThread)GetProcAddress(hLib, "CreateRemoteThread");
}
DWORD findProcessId(DWORD parentId)
{
HANDLE hProcList = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(PROCESSENTRY32);
DWORD procId = 0;
BOOL moreProc = Process32First(hProcList, &procEntry);
while (moreProc) {
if (procEntry.th32ParentProcessID == parentId) {
procId = procEntry.th32ProcessID;
break;
}
moreProc = Process32Next(hProcList, &procEntry);
}
CloseHandle(hProcList);
return procId;
}
#else
#include <QtCore/QLatin1String>
#include <QtCore/QString>
#include <QtCore/QDir>
#include <QtCore/QFileInfoList>
#include <QtCore/QByteArray>
#include <QtCore/QDebug>
#include <sys/types.h>
#include <signal.h>
#include <sys/sysctl.h>
#define OPProcessValueUnknown UINT_MAX
/* Mac OS X
int OPParentIDForProcessID(int pid)
// Returns the parent process id for the given process id (pid)
{
struct kinfo_proc info;
size_t length = sizeof(struct kinfo_proc);
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
if (sysctl(mib, 4, &info, &length, NULL, 0) < 0)
return OPProcessValueUnknown;
if (length == 0)
return OPProcessValueUnknown;
return info.kp_eproc.e_ppid;
}
*/
int findParentProcess(int procId)
{
QFile statFile(QLatin1String("/proc/") + QString::number(procId) +
QLatin1String("/stat"));
if (!statFile.open(QIODevice::ReadOnly))
return -1;
QByteArray line = statFile.readLine();
line = line.mid(line.indexOf(')') + 4);
//qDebug() << "1: " << line;
line = line.left(line.indexOf(' '));
//qDebug() << "2: " << line;
return QString(line).toInt();
}
int findChildProcess(int parentId)
{
QDir proc(QLatin1String("/proc"));
QFileInfoList procList = proc.entryInfoList(QDir::Dirs);
foreach (const QFileInfo &info, procList) {
int procId = 0;
bool ok = false;
procId = info.baseName().toInt(&ok);
if (!ok || !procId)
continue;
if (findParentProcess(procId) == parentId)
return procId;
}
return -1;
}
#endif
bool Debugger::Internal::interruptProcess(int pID)
{
#ifdef Q_OS_WIN
DWORD pid = pID;
if (!pid)
return false;
PtrCreateRemoteThread libFunc = resolveCreateRemoteThread();
if (libFunc) {
DWORD dwThreadId = 0;
HANDLE hproc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
HANDLE hthread = libFunc(hproc, NULL, 0, (LPTHREAD_START_ROUTINE)DebugBreak, 0, 0, &dwThreadId);
CloseHandle(hthread);
if (dwThreadId)
return true;
}
#else
int procId = pID;
if (procId != -1) {
if (kill(procId, 2) == 0)
return true;
}
#endif
return false;
}
bool Debugger::Internal::interruptChildProcess(Q_PID parentPID)
{
#ifdef WIN32
DWORD pid = findProcessId(parentPID->dwProcessId);
return interruptProcess(pid);
#else
int procId = findChildProcess(parentPID);
//qDebug() << "INTERRUPTING PROCESS" << procId;
return interruptProcess(procId);
#endif
}

View File

@@ -0,0 +1,47 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_PROCINTERRUPT_H
#define DEBUGGER_PROCINTERRUPT_H
#include <QtCore/QProcess>
namespace Debugger {
namespace Internal {
bool interruptProcess(int pID);
bool interruptChildProcess(Q_PID parentPID);
} // Internal
} // GdbDebugger
#endif // DEBUGGER_PROCINTERRUPT_H

View File

@@ -0,0 +1,128 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "registerhandler.h"
#include "assert.h"
#include "debuggerconstants.h"
#include <QtCore/QAbstractTableModel>
#include <QtCore/QDebug>
#include <QtGui/QColor>
using namespace Debugger;
using namespace Debugger::Internal;
using namespace Debugger::Constants;
//////////////////////////////////////////////////////////////////
//
// RegisterHandler
//
//////////////////////////////////////////////////////////////////
RegisterHandler::RegisterHandler(QObject *parent)
: QAbstractTableModel(parent)
{
setProperty(PROPERTY_REGISTER_FORMAT, "x");
}
int RegisterHandler::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_registers.size();
}
int RegisterHandler::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 2;
}
QVariant RegisterHandler::data(const QModelIndex &index, int role) const
{
static const QVariant red = QColor(200, 0, 0);
if (!index.isValid() || index.row() >= m_registers.size())
return QVariant();
const Register &reg = m_registers.at(index.row());
if (role == Qt::DisplayRole) {
switch (index.column()) {
case 0:
return reg.name;
case 1:
return reg.value;
}
}
if (role == Qt::TextColorRole && reg.changed && index.column() == 1)
return red;
return QVariant();
}
QVariant RegisterHandler::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static const char * const headers[] = {
QT_TR_NOOP("Name"),
QT_TR_NOOP("Value"),
};
if (section < 2)
return tr(headers[section]);
}
return QVariant();
}
void RegisterHandler::removeAll()
{
m_registers.clear();
reset();
}
bool RegisterHandler::isEmpty() const
{
return m_registers.isEmpty();
}
void RegisterHandler::setRegisters(const QList<Register> &registers)
{
m_registers = registers;
reset();
}
QList<Register> RegisterHandler::registers() const
{
return m_registers;
}

View File

@@ -0,0 +1,81 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_REGISTERHANDLER_H
#define DEBUGGER_REGISTERHANDLER_H
#include <QtCore/QAbstractTableModel>
namespace Debugger {
namespace Internal {
class Register
{
public:
Register() : changed(true) {}
Register(QString const &name_) : name(name_), changed(true) {}
public:
QString name;
QString value;
bool changed;
};
class RegisterHandler : public QAbstractTableModel
{
Q_OBJECT
public:
RegisterHandler(QObject *parent = 0);
void sessionClosed();
QAbstractItemModel *model() { return this; }
bool isEmpty() const; // nothing known so far?
void setRegisters(const QList<Register> &registers);
QList<Register> registers() const;
void removeAll();
private:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QList<Register> m_registers;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_REGISTERHANDLER_H

View File

@@ -0,0 +1,181 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "registerwindow.h"
#include "debuggerconstants.h"
#include <QAction>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QFileInfoList>
#include <QHeaderView>
#include <QMenu>
#include <QResizeEvent>
#include <QToolButton>
using namespace Debugger::Internal;
using namespace Debugger::Constants;
RegisterWindow::RegisterWindow()
: m_alwaysResizeColumnsToContents(true), m_alwaysReloadContents(false)
{
setWindowTitle(tr("Registers"));
setSortingEnabled(true);
setAlternatingRowColors(true);
setRootIsDecorated(false);
//header()->hide();
//setIconSize(QSize(10, 10));
//setWindowIcon(QIcon(":/gdbdebugger/images/debugger_breakpoints.png"));
//QHeaderView *hv = header();
//hv->setDefaultAlignment(Qt::AlignLeft);
//hv->setClickable(true);
//hv->setSortIndicatorShown(true);
}
void RegisterWindow::resizeEvent(QResizeEvent *ev)
{
//QHeaderView *hv = header();
//int totalSize = ev->size().width() - 110;
//hv->resizeSection(0, totalSize / 4);
//hv->resizeSection(1, totalSize / 4);
QTreeView::resizeEvent(ev);
}
void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
{
enum { Hex, Bin, Dec, Raw, Oct, Nat,
Adjust, AlwaysAdjust, Reload, AlwaysReload, Count };
QMenu menu;
QAction *actions[Count];
//QTreeWidgetItem *item = itemAt(ev->pos());
QString format = model()->property(PROPERTY_REGISTER_FORMAT).toString();
qDebug() << "FORMAT: " << format;
actions[Adjust] = menu.addAction("Adjust column widths to contents");
actions[AlwaysAdjust] = menu.addAction("Always adjust column widths to contents");
actions[AlwaysAdjust]->setCheckable(true);
actions[AlwaysAdjust]->setChecked(m_alwaysResizeColumnsToContents);
actions[Reload] = menu.addAction("Reload register listing");
actions[AlwaysReload] = menu.addAction("Always reload register listing");
actions[AlwaysReload]->setCheckable(true);
actions[AlwaysReload]->setChecked(m_alwaysReloadContents);
menu.addSeparator();
actions[Hex] = menu.addAction("Hexadecimal");
actions[Hex]->setCheckable(true);
actions[Hex]->setChecked(format == "h");
actions[Bin] = menu.addAction("Binary");
actions[Bin]->setCheckable(true);
actions[Bin]->setChecked(format == "t");
actions[Dec] = menu.addAction("Decimal");
actions[Dec]->setCheckable(true);
actions[Dec]->setChecked(format == "d");
actions[Raw] = menu.addAction("Raw");
actions[Raw]->setCheckable(true);
actions[Raw]->setChecked(format == "r");
actions[Nat] = menu.addAction("Natural");
actions[Nat]->setCheckable(true);
actions[Nat]->setChecked(format == "N");
actions[Oct] = menu.addAction("Octal");
actions[Oct]->setCheckable(true);
actions[Oct]->setChecked(format == "o");
QAction *act = menu.exec(ev->globalPos());
if (act == actions[Adjust])
resizeColumnsToContents();
else if (act == actions[AlwaysAdjust])
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == actions[Reload])
reloadContents();
else if (act == actions[AlwaysReload])
setAlwaysReloadContents(!m_alwaysReloadContents);
else if (act == actions[Hex])
model()->setProperty(PROPERTY_REGISTER_FORMAT, "h");
else if (act == actions[Oct])
model()->setProperty(PROPERTY_REGISTER_FORMAT, "o");
else if (act == actions[Bin])
model()->setProperty(PROPERTY_REGISTER_FORMAT, "t");
else if (act == actions[Dec])
model()->setProperty(PROPERTY_REGISTER_FORMAT, "d");
else if (act == actions[Nat])
model()->setProperty(PROPERTY_REGISTER_FORMAT, "N");
}
void RegisterWindow::resizeColumnsToContents()
{
resizeColumnToContents(0);
resizeColumnToContents(1);
}
void RegisterWindow::setAlwaysResizeColumnsToContents(bool on)
{
m_alwaysResizeColumnsToContents = on;
QHeaderView::ResizeMode mode = on
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
header()->setResizeMode(0, mode);
header()->setResizeMode(1, mode);
}
void RegisterWindow::setAlwaysReloadContents(bool on)
{
m_alwaysReloadContents = on;
if (m_alwaysReloadContents)
reloadContents();
}
void RegisterWindow::reloadContents()
{
emit reloadRegisterRequested();
}
void RegisterWindow::setModel(QAbstractItemModel *model)
{
QTreeView::setModel(model);
setAlwaysResizeColumnsToContents(true);
}

View File

@@ -0,0 +1,71 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_REGISTERWINDOW_H
#define DEBUGGER_REGISTERWINDOW_H
#include <QTreeView>
namespace Debugger {
namespace Internal {
class RegisterWindow : public QTreeView
{
Q_OBJECT
public:
RegisterWindow();
void setModel(QAbstractItemModel *model);
signals:
void reloadRegisterRequested();
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
void reloadContents();
void setAlwaysReloadContents(bool on);
protected:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
private:
bool m_alwaysResizeColumnsToContents;
bool m_alwaysReloadContents;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_REGISTERWINDOW_H

View File

@@ -0,0 +1,677 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "scriptengine.h"
#include "assert.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "disassemblerhandler.h"
#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "stackhandler.h"
#include "watchhandler.h"
#include "startexternaldialog.h"
#include "attachexternaldialog.h"
#include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QTimer>
#include <QtGui/QAction>
#include <QtGui/QToolTip>
#include <QtScript/QScriptContext>
#include <QtScript/QScriptClassPropertyIterator>
#include <QtScript/QScriptContextInfo>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptEngineAgent>
#include <QtScript/QScriptValue>
#include <QtScript/QScriptValueIterator>
using namespace Debugger;
using namespace Debugger::Internal;
using namespace Debugger::Constants;
///////////////////////////////////////////////////////////////////////
//
// ScriptEngine
//
///////////////////////////////////////////////////////////////////////
class Debugger::Internal::ScriptAgent : public QScriptEngineAgent
{
public:
ScriptAgent(ScriptEngine *debugger, QScriptEngine *script);
~ScriptAgent() {}
void contextPop();
void contextPush();
void exceptionCatch(qint64 scriptId, const QScriptValue &exception);
void exceptionThrow(qint64 scriptId, const QScriptValue & exception,
bool hasHandler);
void functionEntry(qint64 scriptId);
void functionExit(qint64 scriptId, const QScriptValue &returnValue);
void positionChange(qint64 scriptId, int lineNumber, int columnNumber);
void scriptLoad(qint64 id, const QString &program, const QString &fileName,
int baseLineNumber);
void scriptUnload(qint64 id);
private:
void maybeBreakNow(bool byFunction);
ScriptEngine *q;
};
ScriptAgent::ScriptAgent(ScriptEngine *debugger, QScriptEngine *script)
: QScriptEngineAgent(script), q(debugger)
{}
void ScriptAgent::contextPop()
{
qDebug() << "ScriptAgent::contextPop: ";
}
void ScriptAgent::contextPush()
{
qDebug() << "ScriptAgent::contextPush: ";
}
void ScriptAgent::exceptionCatch(qint64 scriptId, const QScriptValue & exception)
{
qDebug() << "ScriptAgent::exceptionCatch: " << scriptId << &exception;
}
void ScriptAgent::exceptionThrow(qint64 scriptId, const QScriptValue &exception,
bool hasHandler)
{
qDebug() << "ScriptAgent::exceptionThrow: " << scriptId << &exception
<< hasHandler;
}
void ScriptAgent::functionEntry(qint64 scriptId)
{
Q_UNUSED(scriptId);
q->maybeBreakNow(true);
}
void ScriptAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue)
{
qDebug() << "ScriptAgent::functionExit: " << scriptId << &returnValue;
}
void ScriptAgent::positionChange(qint64 scriptId, int lineNumber, int columnNumber)
{
//qDebug() << "ScriptAgent::position: " << lineNumber;
Q_UNUSED(scriptId);
Q_UNUSED(lineNumber);
Q_UNUSED(columnNumber);
q->maybeBreakNow(false);
}
void ScriptAgent::scriptLoad(qint64 scriptId, const QString &program,
const QString &fileName, int baseLineNumber)
{
Q_UNUSED(scriptId);
Q_UNUSED(program);
Q_UNUSED(fileName);
Q_UNUSED(baseLineNumber);
//qDebug() << "ScriptAgent::scriptLoad: " << program << fileName
// << baseLineNumber;
}
void ScriptAgent::scriptUnload(qint64 scriptId)
{
Q_UNUSED(scriptId);
//qDebug() << "ScriptAgent::scriptUnload: " << scriptId;
}
///////////////////////////////////////////////////////////////////////
//
// ScriptEngine
//
///////////////////////////////////////////////////////////////////////
ScriptEngine::ScriptEngine(DebuggerManager *parent)
{
q = parent;
qq = parent->engineInterface();
m_scriptEngine = new QScriptEngine(this);
m_scriptAgent = new ScriptAgent(this, m_scriptEngine);
m_scriptEngine->setAgent(m_scriptAgent);
m_scriptEngine->setProcessEventsInterval(1 /*ms*/);
}
ScriptEngine::~ScriptEngine()
{
}
void ScriptEngine::executeDebuggerCommand(const QString &command)
{
Q_UNUSED(command);
qDebug() << "FIXME: ScriptEngine::executeDebuggerCommand()";
}
void ScriptEngine::shutdown()
{
exitDebugger();
}
void ScriptEngine::exitDebugger()
{
//qDebug() << " ScriptEngine::exitDebugger()";
m_stopped = false;
m_stopOnNextLine = false;
m_scriptEngine->abortEvaluation();
qq->notifyInferiorExited();
}
bool ScriptEngine::startDebugger()
{
m_stopped = false;
m_stopOnNextLine = false;
m_scriptEngine->abortEvaluation();
QFileInfo fi(q->m_executable);
m_scriptFileName = fi.absoluteFilePath();
QFile scriptFile(m_scriptFileName);
if (!scriptFile.open(QIODevice::ReadOnly))
return false;
QTextStream stream(&scriptFile);
m_scriptContents = stream.readAll();
scriptFile.close();
attemptBreakpointSynchronization();
QTimer::singleShot(0, q, SLOT(notifyStartupFinished()));
return true;
}
void ScriptEngine::continueInferior()
{
//qDebug() << "ScriptEngine::continueInferior()";
m_stopped = false;
m_stopOnNextLine = false;
}
void ScriptEngine::runInferior()
{
//qDebug() << "ScriptEngine::runInferior()";
QScriptValue result = m_scriptEngine->evaluate(m_scriptContents, m_scriptFileName);
}
void ScriptEngine::interruptInferior()
{
m_stopped = false;
m_stopOnNextLine = true;
qDebug() << "FIXME: ScriptEngine::interruptInferior()";
}
void ScriptEngine::stepExec()
{
//qDebug() << "FIXME: ScriptEngine::stepExec()";
m_stopped = false;
m_stopOnNextLine = true;
}
void ScriptEngine::stepIExec()
{
//qDebug() << "FIXME: ScriptEngine::stepIExec()";
m_stopped = false;
m_stopOnNextLine = true;
}
void ScriptEngine::stepOutExec()
{
//qDebug() << "FIXME: ScriptEngine::stepOutExec()";
m_stopped = false;
m_stopOnNextLine = true;
}
void ScriptEngine::nextExec()
{
//qDebug() << "FIXME: ScriptEngine::nextExec()";
m_stopped = false;
m_stopOnNextLine = true;
}
void ScriptEngine::nextIExec()
{
//qDebug() << "FIXME: ScriptEngine::nextIExec()";
m_stopped = false;
m_stopOnNextLine = true;
}
void ScriptEngine::runToLineExec(const QString &fileName, int lineNumber)
{
Q_UNUSED(fileName);
Q_UNUSED(lineNumber);
qDebug() << "FIXME: ScriptEngine::runToLineExec()";
}
void ScriptEngine::runToFunctionExec(const QString &functionName)
{
Q_UNUSED(functionName);
qDebug() << "FIXME: ScriptEngine::runToFunctionExec()";
}
void ScriptEngine::jumpToLineExec(const QString &fileName, int lineNumber)
{
Q_UNUSED(fileName);
Q_UNUSED(lineNumber);
qDebug() << "FIXME: ScriptEngine::jumpToLineExec()";
}
void ScriptEngine::activateFrame(int index)
{
Q_UNUSED(index);
}
void ScriptEngine::selectThread(int index)
{
Q_UNUSED(index);
}
void ScriptEngine::attemptBreakpointSynchronization()
{
BreakHandler *handler = qq->breakHandler();
bool updateNeeded = false;
for (int index = 0; index != handler->size(); ++index) {
BreakpointData *data = handler->at(index);
if (data->pending) {
data->pending = false; // FIXME
updateNeeded = true;
}
if (data->bpNumber.isEmpty()) {
data->bpNumber = QString::number(index + 1);
updateNeeded = true;
}
if (!data->fileName.isEmpty() && data->markerFileName.isEmpty()) {
data->markerFileName = data->fileName;
data->markerLineNumber = data->lineNumber.toInt();
updateNeeded = true;
}
}
if (updateNeeded)
handler->updateMarkers();
}
void ScriptEngine::reloadDisassembler()
{
}
void ScriptEngine::loadSymbols(const QString &moduleName)
{
Q_UNUSED(moduleName);
}
void ScriptEngine::loadAllSymbols()
{
}
void ScriptEngine::reloadModules()
{
}
//////////////////////////////////////////////////////////////////////
//
// Tooltip specific stuff
//
//////////////////////////////////////////////////////////////////////
static WatchData m_toolTip;
static QPoint m_toolTipPos;
static QHash<QString, WatchData> m_toolTipCache;
static bool hasLetterOrNumber(const QString &exp)
{
for (int i = exp.size(); --i >= 0; )
if (exp[i].isLetterOrNumber())
return true;
return false;
}
static bool hasSideEffects(const QString &exp)
{
// FIXME: complete?
return exp.contains("-=")
|| exp.contains("+=")
|| exp.contains("/=")
|| exp.contains("*=")
|| exp.contains("&=")
|| exp.contains("|=")
|| exp.contains("^=")
|| exp.contains("--")
|| exp.contains("++");
}
void ScriptEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
{
Q_UNUSED(pos);
Q_UNUSED(exp0);
if (q->status() != DebuggerInferiorStopped) {
//qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED";
return;
}
//m_toolTipPos = pos;
QString exp = exp0;
/*
if (m_toolTipCache.contains(exp)) {
const WatchData & data = m_toolTipCache[exp];
q->watchHandler()->removeChildren(data.iname);
insertData(data);
return;
}
*/
QToolTip::hideText();
if (exp.isEmpty() || exp.startsWith("#")) {
QToolTip::hideText();
return;
}
if (!hasLetterOrNumber(exp)) {
QToolTip::showText(m_toolTipPos,
"'" + exp + "' contains no identifier");
return;
}
if (exp.startsWith('"') && exp.endsWith('"')) {
QToolTip::showText(m_toolTipPos, "String literal " + exp);
return;
}
if (exp.startsWith("++") || exp.startsWith("--"))
exp = exp.mid(2);
if (exp.endsWith("++") || exp.endsWith("--"))
exp = exp.mid(2);
if (exp.startsWith("<") || exp.startsWith("["))
return;
if (hasSideEffects(exp)) {
QToolTip::showText(m_toolTipPos,
"Cowardly refusing to evaluate expression '" + exp
+ "' with potential side effects");
return;
}
#if 0
//if (m_manager->status() != DebuggerInferiorStopped)
// return;
// FIXME: 'exp' can contain illegal characters
m_toolTip = WatchData();
m_toolTip.exp = exp;
m_toolTip.name = exp;
m_toolTip.iname = tooltipIName;
insertData(m_toolTip);
#endif
}
//////////////////////////////////////////////////////////////////////
//
// Watch specific stuff
//
//////////////////////////////////////////////////////////////////////
void ScriptEngine::assignValueInDebugger(const QString &expression,
const QString &value)
{
Q_UNUSED(expression);
Q_UNUSED(value);
}
void ScriptEngine::maybeBreakNow(bool byFunction)
{
QScriptContext *context = m_scriptEngine->currentContext();
QScriptContextInfo info(context);
//
// Update breakpoints
//
QString functionName = info.functionName();
QString fileName = info.fileName();
int lineNumber = info.lineNumber();
if (byFunction)
lineNumber = info.functionStartLineNumber();
BreakHandler *handler = qq->breakHandler();
if (m_stopOnNextLine) {
m_stopOnNextLine = false;
} else {
int index = 0;
for (; index != handler->size(); ++index) {
BreakpointData *data = handler->at(index);
if (byFunction) {
if (!functionName.isEmpty() && data->funcName == functionName)
break;
} else {
if (info.lineNumber() == data->lineNumber.toInt()
&& fileName == data->fileName)
break;
}
}
if (index == handler->size())
return;
// we just run into a breakpoint
//qDebug() << "RESOLVING BREAKPOINT AT " << fileName << lineNumber;
BreakpointData *data = handler->at(index);
data->bpLineNumber = QString::number(lineNumber);
data->bpFileName = fileName;
data->bpFuncName = functionName;
data->markerLineNumber = lineNumber;
data->markerFileName = fileName;
data->pending = false;
data->updateMarker();
}
qq->notifyInferiorStopped();
q->gotoLocation(fileName, lineNumber, true);
qq->watchHandler()->reinitializeWatchers();
//qDebug() << "UPDATE LOCALS";
//
// Build stack
//
QList<StackFrame> stackFrames;
int i = 0;
for (QScriptContext *c = context; c; c = c->parentContext(), ++i) {
QScriptContextInfo info(c);
StackFrame frame;
frame.level = i;
frame.file = info.fileName();
frame.function = info.functionName();
frame.from = QString::number(info.functionStartLineNumber());
frame.to = QString::number(info.functionEndLineNumber());
frame.line = info.lineNumber();
if (frame.function.isEmpty())
frame.function = "<global scope>";
//frame.address = ...;
stackFrames.append(frame);
}
qq->stackHandler()->setFrames(stackFrames);
//
// Build locals
//
WatchData data;
data.iname = "local";
data.name = "local";
data.scriptValue = context->activationObject();
qq->watchHandler()->insertData(data);
updateWatchModel();
// FIXME: Use an extra thread. This here is evil
m_stopped = true;
while (m_stopped) {
//qDebug() << "LOOPING";
QApplication::processEvents();
}
//qDebug() << "RUNNING AGAIN";
}
void ScriptEngine::updateWatchModel()
{
while (true) {
QList<WatchData> list = qq->watchHandler()->takeCurrentIncompletes();
if (list.isEmpty())
break;
foreach (const WatchData &data, list)
updateSubItem(data);
}
qq->watchHandler()->rebuildModel();
q->showStatusMessage(tr("Stopped."), 5000);
}
void ScriptEngine::updateSubItem(const WatchData &data0)
{
WatchData data = data0;
//qDebug() << "\nUPDATE SUBITEM: " << data.toString();
QWB_ASSERT(data.isValid(), return);
if (data.isTypeNeeded() || data.isValueNeeded()) {
QScriptValue ob = data.scriptValue;
if (ob.isArray()) {
data.setType("Array");
data.setValue(" ");
} else if (ob.isBool()) {
data.setType("Bool");
data.setValue(ob.toBool() ? "true" : "false");
data.setChildCount(0);
} else if (ob.isDate()) {
data.setType("Date");
data.setValue(ob.toDateTime().toString().toUtf8());
data.setChildCount(0);
} else if (ob.isError()) {
data.setType("Error");
data.setValue(" ");
} else if (ob.isFunction()) {
data.setType("Function");
data.setValue(" ");
} else if (ob.isNull()) {
data.setType("<null>");
data.setValue("<null>");
} else if (ob.isNumber()) {
data.setType("Number");
data.setValue(QString::number(ob.toNumber()).toUtf8());
data.setChildCount(0);
} else if (ob.isObject()) {
data.setType("Object");
data.setValue(" ");
} else if (ob.isQMetaObject()) {
data.setType("QMetaObject");
data.setValue(" ");
} else if (ob.isQObject()) {
data.setType("QObject");
data.setValue(" ");
} else if (ob.isRegExp()) {
data.setType("RegExp");
data.setValue(ob.toRegExp().pattern().toUtf8());
} else if (ob.isString()) {
data.setType("String");
data.setValue(ob.toString().toUtf8());
} else if (ob.isVariant()) {
data.setType("Variant");
data.setValue(" ");
} else if (ob.isUndefined()) {
data.setType("<undefined>");
data.setValue("<unknown>");
} else {
data.setType("<unknown>");
data.setValue("<unknown>");
}
qq->watchHandler()->insertData(data);
return;
}
if (data.isChildrenNeeded()) {
int numChild = 0;
QScriptValueIterator it(data.scriptValue);
while (it.hasNext()) {
it.next();
WatchData data1;
data1.iname = data.iname + "." + it.name();
data1.name = it.name();
data1.scriptValue = it.value();
if (qq->watchHandler()->isExpandedIName(data1.iname))
data1.setChildrenNeeded();
else
data1.setChildrenUnneeded();
qq->watchHandler()->insertData(data1);
++numChild;
}
//qDebug() << " ... CHILDREN: " << numChild;
data.setChildCount(numChild);
data.setChildrenUnneeded();
qq->watchHandler()->insertData(data);
return;
}
if (data.isChildCountNeeded()) {
int numChild = 0;
QScriptValueIterator it(data.scriptValue);
while (it.hasNext()) {
it.next();
++numChild;
}
data.setChildCount(numChild);
//qDebug() << " ... CHILDCOUNT: " << numChild;
qq->watchHandler()->insertData(data);
return;
}
QWB_ASSERT(false, return);
}
IDebuggerEngine *createScriptEngine(DebuggerManager *parent)
{
return new ScriptEngine(parent);
}

View File

@@ -0,0 +1,134 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_SCRIPTENGINE_H
#define DEBUGGER_SCRIPTENGINE_H
#include <QtCore/QByteArray>
#include <QtCore/QHash>
#include <QtCore/QMap>
#include <QtCore/QObject>
#include <QtCore/QProcess>
#include <QtCore/QPoint>
#include <QtCore/QSet>
#include <QtCore/QVariant>
#include <QtNetwork/QLocalSocket>
QT_BEGIN_NAMESPACE
class QAction;
class QAbstractItemModel;
class QSplitter;
class QToolBar;
class QScriptEngine;
class QScriptValue;
QT_END_NAMESPACE
#include "idebuggerengine.h"
namespace Debugger {
namespace Internal {
class DebuggerManager;
class IDebuggerManagerAccessForEngines;
class ScriptAgent;
class WatchData;
class ScriptEngine : public IDebuggerEngine
{
Q_OBJECT
public:
ScriptEngine(DebuggerManager *parent);
~ScriptEngine();
private:
// IDebuggerEngine implementation
void stepExec();
void stepOutExec();
void nextExec();
void stepIExec();
void nextIExec();
void shutdown();
void setToolTipExpression(const QPoint &pos, const QString &exp);
bool startDebugger();
void exitDebugger();
void continueInferior();
void runInferior();
void interruptInferior();
void runToLineExec(const QString &fileName, int lineNumber);
void runToFunctionExec(const QString &functionName);
void jumpToLineExec(const QString &fileName, int lineNumber);
void activateFrame(int index);
void selectThread(int index);
void attemptBreakpointSynchronization();
void loadSessionData() {}
void saveSessionData() {}
void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand(const QString & command);
void loadSymbols(const QString &moduleName);
void loadAllSymbols();
void reloadDisassembler();
void reloadModules();
void reloadRegisters() {}
bool supportsThreads() const { return true; }
void maybeBreakNow(bool byFunction);
void updateWatchModel();
void updateSubItem(const WatchData &data0);
private:
friend class ScriptAgent;
DebuggerManager *q;
IDebuggerManagerAccessForEngines *qq;
QScriptEngine *m_scriptEngine;
QString m_scriptContents;
QString m_scriptFileName;
ScriptAgent *m_scriptAgent;
bool m_stopped;
bool m_stopOnNextLine;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_SCRIPTENGINE_H

View File

@@ -0,0 +1,271 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "stackhandler.h"
#include "assert.h"
#include <QtCore/QAbstractTableModel>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
using namespace Debugger::Internal;
////////////////////////////////////////////////////////////////////////
//
// StackHandler
//
////////////////////////////////////////////////////////////////////////
StackHandler::StackHandler(QObject *parent)
: QAbstractTableModel(parent), m_currentIndex(0)
{
m_emptyIcon = QIcon(":/gdbdebugger/images/empty.svg");
m_positionIcon = QIcon(":/gdbdebugger/images/location.svg");
}
int StackHandler::rowCount(const QModelIndex &parent) const
{
// Since the stack is not a tree, row count is 0 for any valid parent
return parent.isValid() ? 0 : m_stackFrames.size();
}
int StackHandler::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 4;
}
QVariant StackHandler::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= m_stackFrames.size())
return QVariant();
const StackFrame &frame = m_stackFrames.at(index.row());
if (role == Qt::DisplayRole) {
switch (index.column()) {
case 0: // Stack frame level
return QString::number(frame.level);
case 1: // Function name
return frame.function;
case 2: // File name
return frame.file.isEmpty() ? frame.from : QFileInfo(frame.file).fileName();
case 3: // Line number
return frame.line;
case 4: // Address
return frame.address;
}
} else if (role == Qt::ToolTipRole) {
return "<table><tr><td>Address:</td><td>" + frame.address + "</td></tr>"
+ "<tr><td>Function: </td><td>" + frame.function + "</td></tr>"
+ "<tr><td>File: </td><td>" + frame.file + "</td></tr>"
+ "<tr><td>Line: </td><td>" + QString::number(frame.line) + "</td></tr>"
+ "<tr><td>From: </td><td>" + frame.from + "</td></tr></table>"
+ "<tr><td>To: </td><td>" + frame.to + "</td></tr></table>";
} else if (role == Qt::DecorationRole && index.column() == 0) {
// Return icon that indicates whether this is the active stack frame
return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon;
}
return QVariant();
}
QVariant StackHandler::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static const char * const headers[] = {
QT_TR_NOOP("Level"),
QT_TR_NOOP("Function"),
QT_TR_NOOP("File"),
QT_TR_NOOP("Line"),
QT_TR_NOOP("Address")
};
if (section < 5)
return tr(headers[section]);
}
return QVariant();
}
Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
{
if (index.row() >= m_stackFrames.size())
return 0;
const StackFrame &frame = m_stackFrames.at(index.row());
const bool isValid = !frame.file.isEmpty() && !frame.function.isEmpty();
return isValid ? QAbstractTableModel::flags(index) : Qt::ItemFlags(0);
}
StackFrame StackHandler::currentFrame() const
{
QWB_ASSERT(m_currentIndex >= 0, return StackFrame());
QWB_ASSERT(m_currentIndex < m_stackFrames.size(), return StackFrame());
return m_stackFrames.at(m_currentIndex);
}
void StackHandler::setCurrentIndex(int level)
{
if (level == m_currentIndex)
return;
// Emit changed for previous frame
QModelIndex i = index(m_currentIndex, 0);
emit dataChanged(i, i);
m_currentIndex = level;
// Emit changed for new frame
i = index(m_currentIndex, 0);
emit dataChanged(i, i);
}
void StackHandler::removeAll()
{
m_stackFrames.clear();
m_currentIndex = 0;
reset();
}
void StackHandler::setFrames(const QList<StackFrame> &frames)
{
m_stackFrames = frames;
if (m_currentIndex >= m_stackFrames.size())
m_currentIndex = m_stackFrames.size() - 1;
reset();
}
QList<StackFrame> StackHandler::frames() const
{
return m_stackFrames;
}
bool StackHandler::isDebuggingDumpers() const
{
for (int i = m_stackFrames.size(); --i >= 0; )
if (m_stackFrames.at(i).function.startsWith("qDumpObjectData"))
return true;
return false;
}
////////////////////////////////////////////////////////////////////////
//
// ThreadsHandler
//
////////////////////////////////////////////////////////////////////////
ThreadsHandler::ThreadsHandler(QObject *parent)
: QAbstractTableModel(parent), m_currentIndex(0)
{
m_emptyIcon = QIcon(":/gdbdebugger/images/empty.svg");
m_positionIcon = QIcon(":/gdbdebugger/images/location.svg");
}
int ThreadsHandler::rowCount(const QModelIndex &parent) const
{
// Since the stack is not a tree, row count is 0 for any valid parent
return parent.isValid() ? 0 : m_threads.size();
}
int ThreadsHandler::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 1;
}
QVariant ThreadsHandler::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= m_threads.size())
return QVariant();
if (role == Qt::DisplayRole) {
switch (index.column()) {
case 0: // Thread ID
return m_threads.at(index.row()).id;
case 1: // Function name
return "???";
}
} else if (role == Qt::ToolTipRole) {
return "Thread: " + QString::number(m_threads.at(index.row()).id);
} else if (role == Qt::DecorationRole && index.column() == 0) {
// Return icon that indicates whether this is the active stack frame
return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon;
}
return QVariant();
}
QVariant ThreadsHandler::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static const char * const headers[] = {
QT_TR_NOOP("Thread ID"),
};
if (section < 1)
return tr(headers[section]);
}
return QVariant();
}
void ThreadsHandler::setCurrentThread(int index)
{
if (index == m_currentIndex)
return;
// Emit changed for previous frame
QModelIndex i = ThreadsHandler::index(m_currentIndex, 0);
emit dataChanged(i, i);
m_currentIndex = index;
// Emit changed for new frame
i = ThreadsHandler::index(m_currentIndex, 0);
emit dataChanged(i, i);
}
void ThreadsHandler::setThreads(const QList<ThreadData> &threads)
{
m_threads = threads;
if (m_currentIndex >= m_threads.size())
m_currentIndex = m_threads.size() - 1;
reset();
}
QList<ThreadData> ThreadsHandler::threads() const
{
return m_threads;
}
void ThreadsHandler::removeAll()
{
m_threads.clear();
m_currentIndex = 0;
reset();
}

View File

@@ -0,0 +1,136 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_STACKHANDLER_H
#define DEBUGGER_STACKHANDLER_H
#include <QtCore/QAbstractTableModel>
#include <QtCore/QObject>
#include <QtGui/QIcon>
namespace Debugger {
namespace Internal {
////////////////////////////////////////////////////////////////////////
//
// StackModel
//
////////////////////////////////////////////////////////////////////////
struct StackFrame
{
int level;
QString function;
QString file; // we try to put an absolute file name in there
QString from;
QString to;
int line;
QString address;
};
/*! A model to represent the stack in a QTreeView. */
class StackHandler : public QAbstractTableModel
{
public:
StackHandler(QObject *parent = 0);
void setFrames(const QList<StackFrame> &frames);
QList<StackFrame> frames() const;
void setCurrentIndex(int index);
int currentIndex() const { return m_currentIndex; }
StackFrame currentFrame() const;
int stackSize() const { return m_stackFrames.size(); }
// Called from StackHandler after a new stack list has been received
void removeAll();
QAbstractItemModel *stackModel() { return this; }
bool isDebuggingDumpers() const;
private:
// QAbstractTableModel
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QList<StackFrame> m_stackFrames;
int m_currentIndex;
QIcon m_positionIcon;
QIcon m_emptyIcon;
};
////////////////////////////////////////////////////////////////////////
//
// ThreadsHandler
//
////////////////////////////////////////////////////////////////////////
struct ThreadData
{
int id;
};
/*! A model to represent the running threads in a QTreeView or ComboBox */
class ThreadsHandler : public QAbstractTableModel
{
public:
ThreadsHandler(QObject *parent = 0);
void setCurrentThread(int index);
void selectThread(int index);
void setThreads(const QList<ThreadData> &threads);
void removeAll();
QList<ThreadData> threads() const;
QAbstractItemModel *threadsModel() { return this; }
private:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
private:
friend class StackHandler;
QList<ThreadData> m_threads;
int m_currentIndex;
QIcon m_positionIcon;
QIcon m_emptyIcon;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_STACKHANDLER_H

View File

@@ -0,0 +1,117 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "stackwindow.h"
#include "assert.h"
#include "stackhandler.h"
#include <QAction>
#include <QComboBox>
#include <QDebug>
#include <QHeaderView>
#include <QMenu>
#include <QResizeEvent>
#include <QTreeView>
#include <QVBoxLayout>
using Debugger::Internal::StackWindow;
StackWindow::StackWindow(QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(false)
{
setWindowTitle(tr("Stack"));
setAlternatingRowColors(true);
setRootIsDecorated(false);
setIconSize(QSize(10, 10));
header()->setDefaultAlignment(Qt::AlignLeft);
connect(this, SIGNAL(activated(QModelIndex)),
this, SLOT(rowActivated(QModelIndex)));
}
void StackWindow::resizeEvent(QResizeEvent *event)
{
QHeaderView *hv = header();
int totalSize = event->size().width() - 120;
if (totalSize > 10) {
hv->resizeSection(0, 45);
hv->resizeSection(1, totalSize / 2);
hv->resizeSection(2, totalSize / 2);
hv->resizeSection(3, 55);
}
QTreeView::resizeEvent(event);
}
void StackWindow::rowActivated(const QModelIndex &index)
{
//qDebug() << "ACTIVATED: " << index.row() << index.column();
emit frameActivated(index.row());
}
void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
QAction *act1 = new QAction(tr("Adjust column widths to contents"), &menu);
QAction *act2 = new QAction(tr("Always adjust column widths to contents"), &menu);
act2->setCheckable(true);
act2->setChecked(m_alwaysResizeColumnsToContents);
menu.addAction(act1);
menu.addAction(act2);
QAction *act = menu.exec(ev->globalPos());
if (act == act1)
resizeColumnsToContents();
else if (act == act2)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
}
void StackWindow::resizeColumnsToContents()
{
resizeColumnToContents(0);
resizeColumnToContents(1);
resizeColumnToContents(2);
}
void StackWindow::setAlwaysResizeColumnsToContents(bool on)
{
m_alwaysResizeColumnsToContents = on;
QHeaderView::ResizeMode mode = on
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
header()->setResizeMode(0, mode);
header()->setResizeMode(1, mode);
header()->setResizeMode(2, mode);
}

View File

@@ -0,0 +1,75 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_STACKWINDOW_H
#define DEBUGGER_STACKWINDOW_H
#include <QtGui/QTreeView>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class QComboBox;
class QModelIndex;
QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
class StackWindow : public QTreeView
{
Q_OBJECT
public:
StackWindow(QWidget *parent = 0);
signals:
void frameActivated(int);
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
private slots:
void rowActivated(const QModelIndex &index);
private:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
bool m_alwaysResizeColumnsToContents;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_STACKWINDOW_H

View File

@@ -0,0 +1,124 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "startexternaldialog.h"
#include <QtGui/QFileDialog>
#include <QtGui/QPushButton>
using namespace Debugger::Internal;
StartExternalDialog::StartExternalDialog(QWidget *parent)
: QDialog(parent)
{
setupUi(this);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
//execLabel->setHidden(false);
//execEdit->setHidden(false);
//browseButton->setHidden(false);
execLabel->setText(tr("Executable:"));
argLabel->setText(tr("Arguments:"));
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(browseButton, SIGNAL(clicked()),
this, SLOT(onBrowseButton()));
}
void StartExternalDialog::setExecutableFile(const QString &str)
{
execEdit->setText(str);
}
void StartExternalDialog::setExecutableArguments(const QString &str)
{
argsEdit->setText(str);
}
QString StartExternalDialog::executableFile() const
{
return execEdit->text();
}
QString StartExternalDialog::executableArguments() const
{
return argsEdit->text();
/*
bool inQuotes = false;
QString args = argsEdit->text();
QChar current;
QChar last;
QString arg;
QStringList result;
if (!args.isEmpty())
result << QLatin1String("--args");
result << execEdit->text();
for(int i=0; i<args.length(); ++i) {
current = args.at(i);
if (current == QLatin1Char('\"') && last != QLatin1Char('\\')) {
if (inQuotes && !arg.isEmpty()) {
result << arg;
arg.clear();
}
inQuotes = !inQuotes;
} else if (!inQuotes && current == QLatin1Char(' ')) {
arg = arg.trimmed();
if (!arg.isEmpty()) {
result << arg;
arg.clear();
}
} else {
arg += current;
}
last = current;
}
if (!arg.isEmpty())
result << arg;
return result;
*/
}
void StartExternalDialog::onBrowseButton()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Executable"),
execEdit->text());
execEdit->setText(fileName);
}

View File

@@ -0,0 +1,63 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_STARTEXTERNALDIALOG_H
#define DEBUGGER_STARTEXTERNALDIALOG_H
#include <QtGui/QDialog>
#include "ui_startexternaldialog.h"
namespace Debugger {
namespace Internal {
class StartExternalDialog : public QDialog, Ui::StartExternalDialog
{
Q_OBJECT
public:
StartExternalDialog(QWidget *parent);
void setExecutableFile(const QString &executable);
void setExecutableArguments(const QString &args);
QString executableFile() const;
QString executableArguments() const;
private slots:
void onBrowseButton();
};
} // namespace Debugger
} // namespace Internal
#endif // DEBUGGER_STARTEXTERNALDIALOG_H

View File

@@ -0,0 +1,93 @@
<ui version="4.0" >
<class>StartExternalDialog</class>
<widget class="QDialog" name="StartExternalDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>425</width>
<height>127</height>
</rect>
</property>
<property name="windowTitle" >
<string>Start Debugger</string>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>9</number>
</property>
<item>
<layout class="QGridLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="1" column="1" >
<widget class="QLineEdit" name="argsEdit" />
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="execEdit" />
</item>
<item row="0" column="0" >
<widget class="QLabel" name="execLabel" >
<property name="text" >
<string>Executable:</string>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QToolButton" name="browseButton" >
<property name="text" >
<string>...</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="argLabel" >
<property name="text" >
<string>Arguments:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>407</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="line" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,112 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "threadswindow.h"
#include "assert.h"
#include "stackhandler.h"
#include <QAction>
#include <QComboBox>
#include <QDebug>
#include <QHeaderView>
#include <QMenu>
#include <QResizeEvent>
#include <QTreeView>
#include <QVBoxLayout>
using Debugger::Internal::ThreadsWindow;
ThreadsWindow::ThreadsWindow(QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(false)
{
setWindowTitle(tr("Thread"));
setAlternatingRowColors(true);
setRootIsDecorated(false);
setIconSize(QSize(10, 10));
header()->setDefaultAlignment(Qt::AlignLeft);
connect(this, SIGNAL(activated(const QModelIndex &)),
this, SLOT(rowActivated(const QModelIndex &)));
}
void ThreadsWindow::resizeEvent(QResizeEvent *event)
{
//QHeaderView *hv = header();
//int totalSize = event->size().width() - 120;
//hv->resizeSection(0, 45);
//hv->resizeSection(1, totalSize);
//hv->resizeSection(2, 55);
QTreeView::resizeEvent(event);
}
void ThreadsWindow::rowActivated(const QModelIndex &index)
{
//qDebug() << "ACTIVATED: " << index.row() << index.column();
emit threadSelected(index.row());
}
void ThreadsWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
QAction *act1 = new QAction(tr("Adjust column widths to contents"), &menu);
QAction *act2 = new QAction(tr("Always adjust column widths to contents"), &menu);
act2->setCheckable(true);
act2->setChecked(m_alwaysResizeColumnsToContents);
menu.addAction(act1);
menu.addAction(act2);
QAction *act = menu.exec(ev->globalPos());
if (act == act1)
resizeColumnsToContents();
else if (act == act2)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
}
void ThreadsWindow::resizeColumnsToContents()
{
resizeColumnToContents(0);
//resizeColumnToContents(1);
}
void ThreadsWindow::setAlwaysResizeColumnsToContents(bool on)
{
m_alwaysResizeColumnsToContents = on;
QHeaderView::ResizeMode mode = on
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
header()->setResizeMode(0, mode);
//header()->setResizeMode(1, mode);
}

View File

@@ -0,0 +1,68 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_THREADWINDOW_H
#define DEBUGGER_THREADWINDOW_H
#include <QtGui/QTreeView>
namespace Debugger {
namespace Internal {
class ThreadsWindow : public QTreeView
{
Q_OBJECT
public:
ThreadsWindow(QWidget *parent = 0);
signals:
void threadSelected(int);
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
private slots:
void rowActivated(const QModelIndex &index);
private:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
bool m_alwaysResizeColumnsToContents;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_THREADWINDOW_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,219 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_WATCHHANDLER_H
#define DEBUGGER_WATCHHANDLER_H
#include <QtCore/QPointer>
#include <QtCore/QObject>
#include <QtCore/QHash>
#include <QtCore/QSet>
#include <QtGui/QStandardItem>
#include <QtGui/QStandardItemModel>
#include <QtGui/QTreeView>
#include <QtScript/QScriptValue>
namespace Debugger {
namespace Internal {
class WatchData
{
public:
WatchData();
enum State
{
Complete = 0,
ChildCountNeeded = 1,
ValueNeeded = 2,
TypeNeeded = 4,
ChildrenNeeded = 8,
NeededMask = ValueNeeded
| TypeNeeded
| ChildrenNeeded
| ChildCountNeeded,
InitialState = ValueNeeded
| TypeNeeded
| ChildrenNeeded
| ChildCountNeeded
};
void setValue(const QByteArray &);
void setType(const QString &);
void setValueToolTip(const QString &);
void setError(const QString &);
void setAddress(const QString &address);
bool isSomethingNeeded() const { return state & NeededMask; }
void setAllNeeded() { state = NeededMask; }
void setAllUnneeded() { state = State(0); }
bool isTypeNeeded() const { return state & TypeNeeded; }
bool isTypeKnown() const { return !(state & TypeNeeded); }
void setTypeNeeded() { state = State(state | TypeNeeded); }
void setTypeUnneeded() { state = State(state & ~TypeNeeded); }
bool isValueNeeded() const { return state & ValueNeeded; }
bool isValueKnown() const { return !(state & ValueNeeded); }
void setValueNeeded() { state = State(state | ValueNeeded); }
void setValueUnneeded() { state = State(state & ~ValueNeeded); }
bool isChildrenNeeded() const { return state & ChildrenNeeded; }
bool isChildrenKnown() const { return !(state & ChildrenNeeded); }
void setChildrenNeeded() { state = State(state | ChildrenNeeded); }
void setChildrenUnneeded() { state = State(state & ~ChildrenNeeded); }
bool isChildCountNeeded() const { return state & ChildCountNeeded; }
bool isChildCountKnown() const { return !(state & ChildCountNeeded); }
void setChildCountNeeded() { state = State(state | ChildCountNeeded); }
void setChildCountUnneeded() { state = State(state & ~ChildCountNeeded); }
void setChildCount(int n) { childCount = n; setChildCountUnneeded();
if (n == 0) setChildrenUnneeded(); }
QString toString() const;
bool isLocal() const { return iname.startsWith(QLatin1String("local.")); }
bool isWatcher() const { return iname.startsWith(QLatin1String("watch.")); };
bool isValid() const { return !iname.isEmpty(); }
public:
QString iname; // internal name sth like 'local.baz.public.a'
QString exp; // the expression
QString name; // displayed name
QString value; // displayed value
QByteArray editvalue; // displayed value
QString valuetooltip; // tooltip in value column
QString type; // displayed type
QString variable; // name of internal Gdb variable if created
QString addr; // displayed adress
QString framekey; // key for type cache
QScriptValue scriptValue; // if needed...
int childCount;
bool valuedisabled; // value will be greyed out
private:
public:
int state;
// Model
int parentIndex;
int row;
int level;
QList<int> childIndex;
bool changed;
};
enum { INameRole = Qt::UserRole, VisualRole };
class WatchHandler : public QAbstractItemModel
{
Q_OBJECT
public:
WatchHandler();
QAbstractItemModel *model() { return this; }
//
// QAbstractItemModel
//
bool setData(const QModelIndex &index, const QVariant &value, int role);
QVariant data(const QModelIndex &index, int role) const;
QModelIndex index(int, int, const QModelIndex &idx) const;
QModelIndex parent(const QModelIndex &idx) const;
int rowCount(const QModelIndex &idx) const;
int columnCount(const QModelIndex &idx) const;
bool hasChildren(const QModelIndex &idx) const;
Qt::ItemFlags flags(const QModelIndex &idx) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
bool checkIndex(int id) const;
//public slots:
void cleanup();
void watchExpression(const QString &exp);
void removeWatchExpression(const QString &exp);
void reinitializeWatchers();
void collapseChildren(const QModelIndex &idx);
void expandChildren(const QModelIndex &idx);
void rebuildModel(); // unconditionally version of above
void showEditValue(const WatchData &data);
bool isDisplayedIName(const QString &iname) const
{ return m_displayedINames.contains(iname); }
bool isExpandedIName(const QString &iname) const
{ return m_expandedINames.contains(iname); }
void insertData(const WatchData &data);
QList<WatchData> takeCurrentIncompletes();
bool canFetchMore(const QModelIndex &parent) const;
void fetchMore(const QModelIndex &parent);
WatchData *findData(const QString &iname);
signals:
void watchModelUpdateRequested();
private:
WatchData takeData(const QString &iname);
QString toString() const;
void cleanModel();
bool m_expandPointers;
bool m_inChange;
typedef QMap<QString, QPointer<QWidget> > EditWindows;
EditWindows m_editWindows;
QList<WatchData> m_incompleteSet;
QList<WatchData> m_completeSet;
QList<WatchData> m_oldSet;
QList<WatchData> m_displaySet;
void setDisplayedIName(const QString &iname, bool on);
QSet<QString> m_expandedINames; // those expanded in the treeview
QSet<QString> m_displayedINames; // those with "external" viewers
bool m_inFetchMore;
};
} // namespace Internal
} // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::WatchData);
#endif // DEBUGGER_WATCHHANDLER_H

View File

@@ -0,0 +1,253 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "watchwindow.h"
#include <QtCore/QDebug>
#include <QtCore/QTimer>
#include <QtGui/QAction>
#include <QtGui/QContextMenuEvent>
#include <QtGui/QHeaderView>
#include <QtGui/QLineEdit>
#include <QtGui/QMenu>
#include <QtGui/QResizeEvent>
#include <QtGui/QSplitter>
using namespace Debugger::Internal;
enum { INameRole = Qt::UserRole, VisualRole };
/////////////////////////////////////////////////////////////////////
//
// WatchWindow
//
/////////////////////////////////////////////////////////////////////
WatchWindow::WatchWindow(Type type, QWidget *parent)
: QTreeView(parent), m_type(type)
{
m_blocked = false;
setWindowTitle(tr("Locals and Watchers"));
setAlternatingRowColors(true);
setIndentation(indentation() * 9/10);
setUniformRowHeights(true);
connect(itemDelegate(), SIGNAL(commitData(QWidget *)),
this, SLOT(handleChangedItem(QWidget *)));
connect(this, SIGNAL(expanded(QModelIndex)),
this, SLOT(expandNode(QModelIndex)));
connect(this, SIGNAL(collapsed(QModelIndex)),
this, SLOT(collapseNode(QModelIndex)));
}
void WatchWindow::expandNode(const QModelIndex &idx)
{
//QModelIndex mi0 = idx.sibling(idx.row(), 0);
//QString iname = model()->data(mi0, INameRole).toString();
//QString name = model()->data(mi0, Qt::DisplayRole).toString();
//qDebug() << "\n\nEXPAND NODE " // << iname << name
// << idx << (m_blocked ? "blocked" : "passed");
//if (isExpanded(idx))
// return;
//if (m_blocked)
// return;
emit requestExpandChildren(idx);
}
void WatchWindow::collapseNode(const QModelIndex &idx)
{
//QModelIndex mi0 = idx.sibling(idx.row(), 0);
//QString iname = model()->data(mi0, INameRole).toString();
//QString name = model()->data(mi0, Qt::DisplayRole).toString();
//qDebug() << "COLLAPSE NODE " << idx;
if (m_blocked)
return;
emit requestCollapseChildren(idx);
}
void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
QAction *act1 = new QAction("Adjust column widths to contents", &menu);
QAction *act2 = new QAction("Always adjust column widths to contents", &menu);
act2->setCheckable(true);
act2->setChecked(m_alwaysResizeColumnsToContents);
menu.addAction(act1);
menu.addAction(act2);
QAction *act3 = 0;
QAction *act4 = 0;
QModelIndex idx = indexAt(ev->pos());
QModelIndex mi0 = idx.sibling(idx.row(), 0);
QString exp = model()->data(mi0).toString();
QString iname = model()->data(mi0, INameRole).toString();
QModelIndex mi1 = idx.sibling(idx.row(), 0);
QString value = model()->data(mi1).toString();
bool visual = false;
if (idx.isValid()) {
menu.addSeparator();
if (m_type == LocalsType)
act3 = new QAction("Watch expression '" + exp + "'", &menu);
else
act3 = new QAction("Remove expression '" + exp + "'", &menu);
menu.addAction(act3);
visual = model()->data(mi0, VisualRole).toBool();
act4 = new QAction("Watch expression '" + exp + "' in separate widget", &menu);
act4->setCheckable(true);
act4->setChecked(visual);
// FIXME: menu.addAction(act4);
}
QAction *act = menu.exec(ev->globalPos());
if (!act)
;
else if (act == act1)
resizeColumnsToContents();
else if (act == act2)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == act3)
if (m_type == LocalsType)
emit requestWatchExpression(exp);
else
emit requestRemoveWatchExpression(iname);
else if (act == act4)
model()->setData(mi0, !visual, VisualRole);
}
void WatchWindow::resizeColumnsToContents()
{
resizeColumnToContents(0);
resizeColumnToContents(1);
}
void WatchWindow::setAlwaysResizeColumnsToContents(bool on)
{
if (!header())
return;
m_alwaysResizeColumnsToContents = on;
QHeaderView::ResizeMode mode = on
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
header()->setResizeMode(0, mode);
header()->setResizeMode(1, mode);
}
void WatchWindow::editItem(const QModelIndex &idx)
{
Q_UNUSED(idx); // FIXME
}
void WatchWindow::reset()
{
int row = 0;
if (m_type == TooltipType)
row = 1;
else if (m_type == WatchersType)
row = 2;
//qDebug() << "WATCHWINDOW::RESET" << row;
QTreeView::reset();
setRootIndex(model()->index(row, 0, model()->index(0, 0)));
//setRootIndex(model()->index(0, 0));
}
void WatchWindow::setModel(QAbstractItemModel *model)
{
QTreeView::setModel(model);
setRootIsDecorated(true);
header()->setDefaultAlignment(Qt::AlignLeft);
header()->setResizeMode(QHeaderView::ResizeToContents);
if (m_type != LocalsType)
header()->hide();
connect(model, SIGNAL(modelAboutToBeReset()),
this, SLOT(modelAboutToBeReset()));
connect(model, SIGNAL(modelReset()),
this, SLOT(modelReset()));
}
void WatchWindow::modelAboutToBeReset()
{
m_blocked = true;
//qDebug() << "Model about to be reset";
m_expandedItems.clear();
m_expandedItems.insert("local");
m_expandedItems.insert("watch");
modelAboutToBeResetHelper(model()->index(0, 0));
//qDebug() << " expanded: " << m_expandedItems;
}
void WatchWindow::modelAboutToBeResetHelper(const QModelIndex &idx)
{
QString iname = model()->data(idx, INameRole).toString();
//qDebug() << "Model about to be reset helper" << iname << idx
// << isExpanded(idx);
if (isExpanded(idx))
m_expandedItems.insert(iname);
for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
QModelIndex idx1 = model()->index(i, 0, idx);
modelAboutToBeResetHelper(idx1);
}
}
void WatchWindow::modelReset()
{
//qDebug() << "Model reset";
expand(model()->index(0, 0));
modelResetHelper(model()->index(0, 0));
m_blocked = false;
}
void WatchWindow::modelResetHelper(const QModelIndex &idx)
{
QString name = model()->data(idx, Qt::DisplayRole).toString();
QString iname = model()->data(idx, INameRole).toString();
//qDebug() << "Model reset helper" << iname << name;
if (m_expandedItems.contains(iname)) {
expand(idx);
for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
QModelIndex idx1 = model()->index(i, 0, idx);
modelResetHelper(idx1);
}
}
}
void WatchWindow::handleChangedItem(QWidget *widget)
{
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
if (lineEdit)
requestAssignValue("foo", lineEdit->text());
}

View File

@@ -0,0 +1,95 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DEBUGGER_WATCHWINDOW_H
#define DEBUGGER_WATCHWINDOW_H
#include <QtGui/QTreeView>
namespace Debugger {
namespace Internal {
/////////////////////////////////////////////////////////////////////
//
// WatchWindow
//
/////////////////////////////////////////////////////////////////////
class WatchWindow : public QTreeView
{
Q_OBJECT
public:
enum Type { LocalsType, TooltipType, WatchersType };
WatchWindow(Type type, QWidget *parent = 0);
void setType(Type type) { m_type = type; }
Type type() const { return m_type; }
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on = true);
void setModel(QAbstractItemModel *model);
signals:
void requestWatchExpression(const QString &exp);
void requestRemoveWatchExpression(const QString &iname);
void requestAssignValue(const QString &exp, const QString &value);
void requestExpandChildren(const QModelIndex &idx);
void requestCollapseChildren(const QModelIndex &idx);
private slots:
void handleChangedItem(QWidget *);
void expandNode(const QModelIndex &index);
void collapseNode(const QModelIndex &index);
void modelAboutToBeReset();
void modelReset();
private:
void contextMenuEvent(QContextMenuEvent *ev);
void editItem(const QModelIndex &idx);
void reset(); /* reimpl */
void modelAboutToBeResetHelper(const QModelIndex &idx);
void modelResetHelper(const QModelIndex &idx);
bool m_alwaysResizeColumnsToContents;
Type m_type;
bool m_blocked;
QSet<QString> m_expandedItems;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_WATCHWINDOW_H