forked from qt-creator/qt-creator
Merge branch 'master' of ../mainline into dui-editor
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
IDE_BUILD_TREE = $$OUT_PWD/..
|
|
||||||
|
|
||||||
include(../qtcreator.pri)
|
include(../qtcreator.pri)
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 117 KiB |
@@ -37,9 +37,9 @@
|
|||||||
files and classes using minimal keystrokes.
|
files and classes using minimal keystrokes.
|
||||||
\o \bold{Support for qmake's .pro file format}: The project's \c{.pro}
|
\o \bold{Support for qmake's .pro file format}: The project's \c{.pro}
|
||||||
file is used as a project description file.
|
file is used as a project description file.
|
||||||
\o \bold{Debugging Interface to GDB}: Applications can be debugged
|
\o \bold{Debugging Interface}: Applications can be debugged
|
||||||
within Qt Creator using a graphical frontend to the GNU symbolic
|
within Qt Creator using a graphical frontend to the GNU symbolic
|
||||||
debugger.
|
debugger (GDB) and the Microsoft Console Debugger (CDB).
|
||||||
\endlist
|
\endlist
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
@@ -57,6 +57,7 @@
|
|||||||
\o \l{Debugging with Qt Creator}
|
\o \l{Debugging with Qt Creator}
|
||||||
\o \l{CMake Support in Qt Creator}
|
\o \l{CMake Support in Qt Creator}
|
||||||
\o \l{Support for Generic Projects in Qt Creator}
|
\o \l{Support for Generic Projects in Qt Creator}
|
||||||
|
\o \l{Handling External Libraries}
|
||||||
\o \l{Tips and Tricks}
|
\o \l{Tips and Tricks}
|
||||||
\o \l{Keyboard Shortcuts}
|
\o \l{Keyboard Shortcuts}
|
||||||
\o \l{Glossary}
|
\o \l{Glossary}
|
||||||
@@ -694,7 +695,6 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\contentspage index.html
|
\contentspage index.html
|
||||||
\previouspage creator-writing-program.html
|
\previouspage creator-writing-program.html
|
||||||
@@ -1072,7 +1072,7 @@
|
|||||||
|
|
||||||
Here, you can lock or unlock the location of your views as well as display
|
Here, you can lock or unlock the location of your views as well as display
|
||||||
or hide them. Among the views you can display are \gui Breakpoints,
|
or hide them. Among the views you can display are \gui Breakpoints,
|
||||||
\gui Disassembler, \gui Modules, \gui Registers, \gui Gdb, \gui Stack, and
|
\gui Disassembler, \gui Modules, \gui Registers, \gui Debugger, \gui Stack, and
|
||||||
\gui Thread. The position of your dock widgets will be saved for future
|
\gui Thread. The position of your dock widgets will be saved for future
|
||||||
sessions.
|
sessions.
|
||||||
|
|
||||||
@@ -1358,7 +1358,7 @@
|
|||||||
\contentspage index.html
|
\contentspage index.html
|
||||||
\previouspage creator-debugging.html
|
\previouspage creator-debugging.html
|
||||||
\page creator-cmake-support.html
|
\page creator-cmake-support.html
|
||||||
\nextpage creator-tips.html
|
\nextpage creator-generic-projects.html
|
||||||
|
|
||||||
\title CMake Support in Qt Creator
|
\title CMake Support in Qt Creator
|
||||||
|
|
||||||
@@ -1412,7 +1412,7 @@
|
|||||||
\contentspage index.html
|
\contentspage index.html
|
||||||
\previouspage creator-cmake-support.html
|
\previouspage creator-cmake-support.html
|
||||||
\page creator-generic-projects.html
|
\page creator-generic-projects.html
|
||||||
\nextpage creator-tips.html
|
\nextpage creator-external-library-handling.html
|
||||||
|
|
||||||
\title Support for Generic Projects in Qt Creator
|
\title Support for Generic Projects in Qt Creator
|
||||||
|
|
||||||
@@ -1428,10 +1428,65 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\contentspage index.html
|
||||||
|
\previouspage creator-generic-projects.html
|
||||||
|
\page creator-external-library-handling.html
|
||||||
|
\nextpage creator-tips.html
|
||||||
|
|
||||||
|
\title Handling External Libraries
|
||||||
|
|
||||||
|
Knowing external libraries is not only important for the
|
||||||
|
underlying build system, but also for Qt Creator itself.
|
||||||
|
This way, it can support code completion and syntax highlighting
|
||||||
|
for external libraries as if they were part of the current
|
||||||
|
project or the Qt library.
|
||||||
|
|
||||||
|
The way to add a library to the project depends on the
|
||||||
|
project type, which influcences the build system used.
|
||||||
|
The following sections describe the the procedure required
|
||||||
|
for each project type.
|
||||||
|
|
||||||
|
\section1 QMake Projects (the default)
|
||||||
|
|
||||||
|
Open your your (ending in \c{.pro}) file from the
|
||||||
|
\gui{Projects} pane, which will now show up in the editor.
|
||||||
|
Follow the description in the
|
||||||
|
\l{http://doc.qtsoftware.com/latest/make-project-files.html#declaring-other-libraries}
|
||||||
|
{Declaring other Libraries} section of the Qt documentation.
|
||||||
|
|
||||||
|
If your project does sucessfully build and link against
|
||||||
|
the external library, syntax completion and highlighting
|
||||||
|
should also work.
|
||||||
|
|
||||||
|
\section1 CMake Projects
|
||||||
|
|
||||||
|
In CMake, libaries are usually detected using the \c{FIND_PACKAGE()} macro.
|
||||||
|
A couple of them are already being shipped with CMake, they can be found in
|
||||||
|
the \c{Modules} directory of your CMake installation. If you provide
|
||||||
|
libraries on your own, you will need to provide your own \c{FindFoo.cmake}
|
||||||
|
file. Refer to the \l{http://vtk.org/Wiki/CMake_FAQ#Writing_FindXXX.cmake_files}
|
||||||
|
{CMake FAQ} for details.
|
||||||
|
|
||||||
|
As with qmake project, syntax completion and highlighting should work if
|
||||||
|
you can sucessfully build and link against the external library.
|
||||||
|
|
||||||
|
\section1 Generic Projects
|
||||||
|
|
||||||
|
If you import a project using the \e{Generic Projects} function, Qt Creator will
|
||||||
|
create a file called \c{<projectname>.includes} in your project root directory. It will
|
||||||
|
contain all project subdirectories it that was able to find relevant header files in.
|
||||||
|
Simply add your include pathes there.
|
||||||
|
|
||||||
|
Note that in Generic Project mode, Qt Creator will refrain from touching any
|
||||||
|
project settings, so the above is merely a hint for the code completion and
|
||||||
|
the syntax highlighter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\contentspage index.html
|
\contentspage index.html
|
||||||
\previouspage creator-debugging.html
|
\previouspage creator-external-library-handling.html
|
||||||
\page creator-tips.html
|
\page creator-tips.html
|
||||||
\nextpage creator-keyboard-shortcuts.html
|
\nextpage creator-keyboard-shortcuts.html
|
||||||
|
|
||||||
@@ -1526,6 +1581,9 @@
|
|||||||
\row
|
\row
|
||||||
\o Go to a line
|
\o Go to a line
|
||||||
\o Ctrl + L
|
\o Ctrl + L
|
||||||
|
\row
|
||||||
|
\o Navigate between pages
|
||||||
|
\o Alt + Left, Alt + Right
|
||||||
\row
|
\row
|
||||||
\o Start debugging
|
\o Start debugging
|
||||||
\o F5
|
\o F5
|
||||||
@@ -1734,4 +1792,3 @@
|
|||||||
QtCreator/src/shared/cplusplus
|
QtCreator/src/shared/cplusplus
|
||||||
\endlist
|
\endlist
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
IDE_SOURCE_TREE = $$PWD
|
|
||||||
|
|
||||||
defineReplace(cleanPath) {
|
defineReplace(cleanPath) {
|
||||||
win32:1 ~= s|\\\\|/|g
|
win32:1 ~= s|\\\\|/|g
|
||||||
contains(1, ^/.*):pfx = /
|
contains(1, ^/.*):pfx = /
|
||||||
@@ -18,6 +16,19 @@ defineReplace(targetPath) {
|
|||||||
return($$1)
|
return($$1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# For use in custom compilers which just copy files
|
||||||
|
win32:i_flag = i
|
||||||
|
defineReplace(stripSrcDir) {
|
||||||
|
win32 {
|
||||||
|
!contains(1, ^.:.*):1 = $$OUT_PWD/$$1
|
||||||
|
} else {
|
||||||
|
!contains(1, ^/.*):1 = $$OUT_PWD/$$1
|
||||||
|
}
|
||||||
|
out = $$cleanPath($$1)
|
||||||
|
out ~= s|^$$re_escape($$PWD/)||$$i_flag
|
||||||
|
return($$out)
|
||||||
|
}
|
||||||
|
|
||||||
isEmpty(TEST):CONFIG(debug, debug|release) {
|
isEmpty(TEST):CONFIG(debug, debug|release) {
|
||||||
!debug_and_release|build_pass {
|
!debug_and_release|build_pass {
|
||||||
TEST = 1
|
TEST = 1
|
||||||
@@ -35,18 +46,23 @@ equals(TEST, 1) {
|
|||||||
DEFINES += WITH_TESTS
|
DEFINES += WITH_TESTS
|
||||||
}
|
}
|
||||||
|
|
||||||
isEmpty(IDE_BUILD_TREE) {
|
IDE_SOURCE_TREE = $$PWD
|
||||||
error("qtcreator.pri: including file must define IDE_BUILD_TREE (probably a relative path)")
|
sub_dir = $$_PRO_FILE_PWD_
|
||||||
}
|
sub_dir ~= s,^$$re_escape($$PWD),,
|
||||||
IDE_BUILD_TREE = $$cleanPath($$IDE_BUILD_TREE)
|
IDE_BUILD_TREE = $$cleanPath($$OUT_PWD)
|
||||||
|
IDE_BUILD_TREE ~= s,$$re_escape($$sub_dir)$,,
|
||||||
|
IDE_APP_PATH = $$IDE_BUILD_TREE/bin
|
||||||
macx {
|
macx {
|
||||||
IDE_APP_TARGET = QtCreator
|
IDE_APP_TARGET = QtCreator
|
||||||
IDE_LIBRARY_PATH = $$IDE_BUILD_TREE/bin/$${IDE_APP_TARGET}.app/Contents/PlugIns
|
IDE_LIBRARY_PATH = $$IDE_APP_PATH/$${IDE_APP_TARGET}.app/Contents/PlugIns
|
||||||
IDE_PLUGIN_PATH = $$IDE_LIBRARY_PATH
|
IDE_PLUGIN_PATH = $$IDE_LIBRARY_PATH
|
||||||
IDE_DATA_PATH = $$IDE_BUILD_TREE/bin/$${IDE_APP_TARGET}.app/Contents/Resources
|
IDE_LIBEXEC_PATH = $$IDE_APP_PATH/$${IDE_APP_TARGET}.app/Contents/Resources
|
||||||
|
IDE_DATA_PATH = $$IDE_APP_PATH/$${IDE_APP_TARGET}.app/Contents/Resources
|
||||||
contains(QT_CONFIG, ppc):CONFIG += ppc x86
|
contains(QT_CONFIG, ppc):CONFIG += ppc x86
|
||||||
|
copydata = 1
|
||||||
} else {
|
} else {
|
||||||
win32 {
|
win32 {
|
||||||
|
contains(TEMPLATE, vc.*)|contains(TEMPLATE_PREFIX, vc):vcproj = 1
|
||||||
IDE_APP_TARGET = qtcreator
|
IDE_APP_TARGET = qtcreator
|
||||||
} else {
|
} else {
|
||||||
IDE_APP_WRAPPER = qtcreator
|
IDE_APP_WRAPPER = qtcreator
|
||||||
@@ -54,9 +70,10 @@ macx {
|
|||||||
}
|
}
|
||||||
IDE_LIBRARY_PATH = $$IDE_BUILD_TREE/$$IDE_LIBRARY_BASENAME/qtcreator
|
IDE_LIBRARY_PATH = $$IDE_BUILD_TREE/$$IDE_LIBRARY_BASENAME/qtcreator
|
||||||
IDE_PLUGIN_PATH = $$IDE_LIBRARY_PATH/plugins
|
IDE_PLUGIN_PATH = $$IDE_LIBRARY_PATH/plugins
|
||||||
|
IDE_LIBEXEC_PATH = $$IDE_APP_PATH # FIXME
|
||||||
IDE_DATA_PATH = $$IDE_BUILD_TREE/share/qtcreator
|
IDE_DATA_PATH = $$IDE_BUILD_TREE/share/qtcreator
|
||||||
|
!isEqual(IDE_SOURCE_TREE, $$IDE_BUILD_TREE):copydata = 1
|
||||||
}
|
}
|
||||||
IDE_APP_PATH = $$IDE_BUILD_TREE/bin
|
|
||||||
|
|
||||||
INCLUDEPATH += \
|
INCLUDEPATH += \
|
||||||
$$IDE_SOURCE_TREE/src/libs \
|
$$IDE_SOURCE_TREE/src/libs \
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#version check qt
|
#version check qt
|
||||||
TOO_OLD_LIST=$$find(QT_VERSION, ^4\.[0-4])
|
contains(QT_VERSION, ^4\.[0-4]\..*) {
|
||||||
count(TOO_OLD_LIST, 1) {
|
message("Cannot build Qt Creator with Qt version $$QT_VERSION.")
|
||||||
message("Cannot build the Qt Creator with a Qt version that old:" $$QT_VERSION)
|
|
||||||
error("Use at least Qt 4.5.")
|
error("Use at least Qt 4.5.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
include(qtcreator.pri)
|
||||||
include(doc/doc.pri)
|
include(doc/doc.pri)
|
||||||
|
|
||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
CONFIG += ordered
|
CONFIG += ordered
|
||||||
|
|
||||||
SUBDIRS = src share
|
SUBDIRS = src share
|
||||||
unix:!macx:!equals(_PRO_FILE_PWD_, $$OUT_PWD):SUBDIRS += bin
|
unix:!macx:!isEmpty(copydata):SUBDIRS += bin
|
||||||
|
|||||||
@@ -1,21 +1,5 @@
|
|||||||
IDE_BUILD_TREE = $$OUT_PWD/../..
|
|
||||||
|
|
||||||
include(../../qtcreator.pri)
|
include(../../qtcreator.pri)
|
||||||
|
|
||||||
win32:i_flag = i
|
|
||||||
defineReplace(stripSrcDir) {
|
|
||||||
win32 {
|
|
||||||
!contains(1, ^.:.*):1 = $$OUT_PWD/$$1
|
|
||||||
} else {
|
|
||||||
!contains(1, ^/.*):1 = $$OUT_PWD/$$1
|
|
||||||
}
|
|
||||||
out = $$cleanPath($$1)
|
|
||||||
out ~= s|^$$re_escape($$PWD/)||$$i_flag
|
|
||||||
return($$out)
|
|
||||||
}
|
|
||||||
|
|
||||||
contains(TEMPLATE, vc.*)|contains(TEMPLATE_PREFIX, vc):vcproj = 1
|
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET = phony_target
|
TARGET = phony_target
|
||||||
|
|
||||||
@@ -39,7 +23,7 @@ DATA_DIRS = \
|
|||||||
schemes \
|
schemes \
|
||||||
gdbmacros
|
gdbmacros
|
||||||
|
|
||||||
macx|!equals(_PRO_FILE_PWD_, $$OUT_PWD) {
|
!isEmpty(copydata) {
|
||||||
|
|
||||||
for(data_dir, DATA_DIRS) {
|
for(data_dir, DATA_DIRS) {
|
||||||
files = $$files($$PWD/$$data_dir/*.*, true)
|
files = $$files($$PWD/$$data_dir/*.*, true)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
IDE_BUILD_TREE = $$OUT_PWD/../../..
|
|
||||||
include(../../../qtcreator.pri)
|
include(../../../qtcreator.pri)
|
||||||
|
|
||||||
TRANSLATIONS = de ja
|
TRANSLATIONS = de ja
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
IDE_BUILD_TREE = $$OUT_PWD/../..
|
|
||||||
|
|
||||||
include(../../qtcreator.pri)
|
include(../../qtcreator.pri)
|
||||||
include(../shared/qtsingleapplication/qtsingleapplication.pri)
|
include(../shared/qtsingleapplication/qtsingleapplication.pri)
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET = $$IDE_APP_TARGET
|
TARGET = $$IDE_APP_TARGET
|
||||||
DESTDIR = ../../bin
|
DESTDIR = $$IDE_APP_PATH
|
||||||
|
|
||||||
|
|
||||||
SOURCES += main.cpp
|
SOURCES += main.cpp
|
||||||
|
|||||||
86
src/libs/utils/consoleprocess.cpp
Normal file
86
src/libs/utils/consoleprocess.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at qt-sales@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "consoleprocess.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
QString ConsoleProcess::modeOption(Mode m)
|
||||||
|
{
|
||||||
|
switch (m) {
|
||||||
|
case Debug:
|
||||||
|
return QLatin1String("debug");
|
||||||
|
case Suspend:
|
||||||
|
return QLatin1String("suspend");
|
||||||
|
case Run:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QLatin1String("run");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConsoleProcess::msgCommChannelFailed(const QString &error)
|
||||||
|
{
|
||||||
|
return tr("Cannot set up communication channel: %1").arg(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConsoleProcess::msgPromptToClose()
|
||||||
|
{
|
||||||
|
//! Showed in a terminal which might have
|
||||||
|
//! a different character set on Windows.
|
||||||
|
return tr("Press <RETURN> to close this window...");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConsoleProcess::msgCannotCreateTempFile(const QString &why)
|
||||||
|
{
|
||||||
|
return tr("Cannot create temporary file: %1").arg(why);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConsoleProcess::msgCannotCreateTempDir(const QString & dir, const QString &why)
|
||||||
|
{
|
||||||
|
return tr("Cannot create temporary directory '%1': %2").arg(dir, why);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConsoleProcess::msgUnexpectedOutput()
|
||||||
|
{
|
||||||
|
return tr("Unexpected output from helper program.");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConsoleProcess::msgCannotChangeToWorkDir(const QString & dir, const QString &why)
|
||||||
|
{
|
||||||
|
return tr("Cannot change to working directory '%1': %2").arg(dir, why);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ConsoleProcess::msgCannotExecute(const QString & p, const QString &why)
|
||||||
|
{
|
||||||
|
return tr("Cannot execute '%1': %2").arg(p, why);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,14 +59,15 @@ class QWORKBENCH_UTILS_EXPORT ConsoleProcess : public QObject, public AbstractPr
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Mode { Run, Debug, Suspend };
|
||||||
ConsoleProcess(QObject *parent = 0);
|
ConsoleProcess(QObject *parent = 0);
|
||||||
~ConsoleProcess();
|
~ConsoleProcess();
|
||||||
|
|
||||||
bool start(const QString &program, const QStringList &args);
|
bool start(const QString &program, const QStringList &args);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void setDebug(bool on) { m_debug = on; }
|
void setMode(Mode m) { m_mode = m; }
|
||||||
bool isDebug() const { return m_debug; }
|
Mode mode() const { return m_mode; }
|
||||||
|
|
||||||
bool isRunning() const; // This reflects the state of the console+stub
|
bool isRunning() const; // This reflects the state of the console+stub
|
||||||
qint64 applicationPID() const { return m_appPid; }
|
qint64 applicationPID() const { return m_appPid; }
|
||||||
@@ -99,6 +100,15 @@ private slots:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static QString modeOption(Mode m);
|
||||||
|
static QString msgCommChannelFailed(const QString &error);
|
||||||
|
static QString msgPromptToClose();
|
||||||
|
static QString msgCannotCreateTempFile(const QString &why);
|
||||||
|
static QString msgCannotCreateTempDir(const QString & dir, const QString &why);
|
||||||
|
static QString msgUnexpectedOutput();
|
||||||
|
static QString msgCannotChangeToWorkDir(const QString & dir, const QString &why);
|
||||||
|
static QString msgCannotExecute(const QString & p, const QString &why);
|
||||||
|
|
||||||
QString stubServerListen();
|
QString stubServerListen();
|
||||||
void stubServerShutdown();
|
void stubServerShutdown();
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
@@ -106,7 +116,7 @@ private:
|
|||||||
void cleanupInferior();
|
void cleanupInferior();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool m_debug;
|
Mode m_mode;
|
||||||
qint64 m_appPid;
|
qint64 m_appPid;
|
||||||
int m_appCode;
|
int m_appCode;
|
||||||
QString m_executable;
|
QString m_executable;
|
||||||
|
|||||||
@@ -44,14 +44,13 @@
|
|||||||
|
|
||||||
using namespace Core::Utils;
|
using namespace Core::Utils;
|
||||||
|
|
||||||
ConsoleProcess::ConsoleProcess(QObject *parent)
|
ConsoleProcess::ConsoleProcess(QObject *parent) :
|
||||||
: QObject(parent)
|
QObject(parent),
|
||||||
|
m_mode(Run),
|
||||||
|
m_appPid(0),
|
||||||
|
m_stubSocket(0),
|
||||||
|
m_settings(0)
|
||||||
{
|
{
|
||||||
m_debug = false;
|
|
||||||
m_appPid = 0;
|
|
||||||
m_stubSocket = 0;
|
|
||||||
m_settings = 0;
|
|
||||||
|
|
||||||
connect(&m_stubServer, SIGNAL(newConnection()), SLOT(stubConnectionAvailable()));
|
connect(&m_stubServer, SIGNAL(newConnection()), SLOT(stubConnectionAvailable()));
|
||||||
|
|
||||||
m_process.setProcessChannelMode(QProcess::ForwardedChannels);
|
m_process.setProcessChannelMode(QProcess::ForwardedChannels);
|
||||||
@@ -69,9 +68,9 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
|
|||||||
if (isRunning())
|
if (isRunning())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QString err = stubServerListen();
|
const QString err = stubServerListen();
|
||||||
if (!err.isEmpty()) {
|
if (!err.isEmpty()) {
|
||||||
emit processError(tr("Cannot set up communication channel: %1").arg(err));
|
emit processError(msgCommChannelFailed(err));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +78,7 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
|
|||||||
m_tempFile = new QTemporaryFile();
|
m_tempFile = new QTemporaryFile();
|
||||||
if (!m_tempFile->open()) {
|
if (!m_tempFile->open()) {
|
||||||
stubServerShutdown();
|
stubServerShutdown();
|
||||||
emit processError(tr("Cannot create temporary file: %1").arg(m_tempFile->errorString()));
|
emit processError(msgCannotCreateTempFile(m_tempFile->errorString()));
|
||||||
delete m_tempFile;
|
delete m_tempFile;
|
||||||
m_tempFile = 0;
|
m_tempFile = 0;
|
||||||
return false;
|
return false;
|
||||||
@@ -94,13 +93,13 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
|
|||||||
QStringList xtermArgs = terminalEmulator(m_settings).split(QLatin1Char(' ')); // FIXME: quoting
|
QStringList xtermArgs = terminalEmulator(m_settings).split(QLatin1Char(' ')); // FIXME: quoting
|
||||||
xtermArgs
|
xtermArgs
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
<< (QCoreApplication::applicationDirPath() + "/../Resources/qtcreator_process_stub")
|
<< (QCoreApplication::applicationDirPath() + QLatin1String("/../Resources/qtcreator_process_stub"))
|
||||||
#else
|
#else
|
||||||
<< (QCoreApplication::applicationDirPath() + "/qtcreator_process_stub")
|
<< (QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_process_stub"))
|
||||||
#endif
|
#endif
|
||||||
<< (m_debug ? "debug" : "exec")
|
<< modeOption(m_mode)
|
||||||
<< m_stubServer.fullServerName()
|
<< m_stubServer.fullServerName()
|
||||||
<< tr("Press <RETURN> to close this window...")
|
<< msgPromptToClose()
|
||||||
<< workingDirectory()
|
<< workingDirectory()
|
||||||
<< (m_tempFile ? m_tempFile->fileName() : 0)
|
<< (m_tempFile ? m_tempFile->fileName() : 0)
|
||||||
<< program << args;
|
<< program << args;
|
||||||
@@ -145,7 +144,7 @@ QString ConsoleProcess::stubServerListen()
|
|||||||
{
|
{
|
||||||
QTemporaryFile tf;
|
QTemporaryFile tf;
|
||||||
if (!tf.open())
|
if (!tf.open())
|
||||||
return tr("Cannot create temporary file: %1").arg(tf.errorString());
|
return msgCannotCreateTempFile(tf.errorString());
|
||||||
stubFifoDir = QFile::encodeName(tf.fileName());
|
stubFifoDir = QFile::encodeName(tf.fileName());
|
||||||
}
|
}
|
||||||
// By now the temp file was deleted again
|
// By now the temp file was deleted again
|
||||||
@@ -153,9 +152,9 @@ QString ConsoleProcess::stubServerListen()
|
|||||||
if (!::mkdir(m_stubServerDir.constData(), 0700))
|
if (!::mkdir(m_stubServerDir.constData(), 0700))
|
||||||
break;
|
break;
|
||||||
if (errno != EEXIST)
|
if (errno != EEXIST)
|
||||||
return tr("Cannot create temporary directory '%1': %2").arg(stubFifoDir, strerror(errno));
|
return msgCannotCreateTempDir(stubFifoDir, QString::fromLocal8Bit(strerror(errno)));
|
||||||
}
|
}
|
||||||
QString stubServer = stubFifoDir + "/stub-socket";
|
const QString stubServer = stubFifoDir + "/stub-socket";
|
||||||
if (!m_stubServer.listen(stubServer)) {
|
if (!m_stubServer.listen(stubServer)) {
|
||||||
::rmdir(m_stubServerDir.constData());
|
::rmdir(m_stubServerDir.constData());
|
||||||
return tr("Cannot create socket '%1': %2").arg(stubServer, m_stubServer.errorString());
|
return tr("Cannot create socket '%1': %2").arg(stubServer, m_stubServer.errorString());
|
||||||
@@ -190,11 +189,9 @@ void ConsoleProcess::readStubOutput()
|
|||||||
QByteArray out = m_stubSocket->readLine();
|
QByteArray out = m_stubSocket->readLine();
|
||||||
out.chop(1); // \n
|
out.chop(1); // \n
|
||||||
if (out.startsWith("err:chdir ")) {
|
if (out.startsWith("err:chdir ")) {
|
||||||
emit processError(tr("Cannot change to working directory '%1': %2")
|
emit processError(msgCannotChangeToWorkDir(workingDirectory(), errorMsg(out.mid(10).toInt())));
|
||||||
.arg(workingDirectory(), errorMsg(out.mid(10).toInt())));
|
|
||||||
} else if (out.startsWith("err:exec ")) {
|
} else if (out.startsWith("err:exec ")) {
|
||||||
emit processError(tr("Cannot execute '%1': %2")
|
emit processError(msgCannotExecute(m_executable, errorMsg(out.mid(9).toInt())));
|
||||||
.arg(m_executable, errorMsg(out.mid(9).toInt())));
|
|
||||||
} else if (out.startsWith("pid ")) {
|
} else if (out.startsWith("pid ")) {
|
||||||
// Will not need it any more
|
// Will not need it any more
|
||||||
delete m_tempFile;
|
delete m_tempFile;
|
||||||
@@ -213,7 +210,7 @@ void ConsoleProcess::readStubOutput()
|
|||||||
m_appPid = 0;
|
m_appPid = 0;
|
||||||
emit processStopped();
|
emit processStopped();
|
||||||
} else {
|
} else {
|
||||||
emit processError(tr("Unexpected output from helper program."));
|
emit processError(msgUnexpectedOutput());
|
||||||
m_process.terminate();
|
m_process.terminate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -250,7 +247,7 @@ QString ConsoleProcess::defaultTerminalEmulator()
|
|||||||
|
|
||||||
QString ConsoleProcess::terminalEmulator(const QSettings *settings)
|
QString ConsoleProcess::terminalEmulator(const QSettings *settings)
|
||||||
{
|
{
|
||||||
QString dflt = defaultTerminalEmulator() + QLatin1String(" -e");
|
const QString dflt = defaultTerminalEmulator() + QLatin1String(" -e");
|
||||||
if (!settings)
|
if (!settings)
|
||||||
return dflt;
|
return dflt;
|
||||||
return settings->value(QLatin1String("General/TerminalEmulator"), dflt).toString();
|
return settings->value(QLatin1String("General/TerminalEmulator"), dflt).toString();
|
||||||
|
|||||||
@@ -42,18 +42,17 @@
|
|||||||
|
|
||||||
using namespace Core::Utils;
|
using namespace Core::Utils;
|
||||||
|
|
||||||
ConsoleProcess::ConsoleProcess(QObject *parent)
|
ConsoleProcess::ConsoleProcess(QObject *parent) :
|
||||||
: QObject(parent)
|
QObject(parent),
|
||||||
|
m_mode(Run),
|
||||||
|
m_appPid(0),
|
||||||
|
m_pid(0),
|
||||||
|
m_hInferior(NULL),
|
||||||
|
m_tempFile(0),
|
||||||
|
m_stubSocket(0),
|
||||||
|
processFinishedNotifier(0),
|
||||||
|
inferiorFinishedNotifier(0)
|
||||||
{
|
{
|
||||||
m_debug = false;
|
|
||||||
m_appPid = 0;
|
|
||||||
m_pid = 0;
|
|
||||||
m_hInferior = NULL;
|
|
||||||
m_tempFile = 0;
|
|
||||||
m_stubSocket = 0;
|
|
||||||
processFinishedNotifier = 0;
|
|
||||||
inferiorFinishedNotifier = 0;
|
|
||||||
|
|
||||||
connect(&m_stubServer, SIGNAL(newConnection()), SLOT(stubConnectionAvailable()));
|
connect(&m_stubServer, SIGNAL(newConnection()), SLOT(stubConnectionAvailable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,9 +66,9 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
|
|||||||
if (isRunning())
|
if (isRunning())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QString err = stubServerListen();
|
const QString err = stubServerListen();
|
||||||
if (!err.isEmpty()) {
|
if (!err.isEmpty()) {
|
||||||
emit processError(tr("Cannot set up communication channel: %1").arg(err));
|
emit processError(msgCommChannelFailed(err));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
|
|||||||
m_tempFile = new QTemporaryFile();
|
m_tempFile = new QTemporaryFile();
|
||||||
if (!m_tempFile->open()) {
|
if (!m_tempFile->open()) {
|
||||||
stubServerShutdown();
|
stubServerShutdown();
|
||||||
emit processError(tr("Cannot create temporary file: %1").arg(m_tempFile->errorString()));
|
emit processError(msgCannotCreateTempFile(m_tempFile->errorString()));
|
||||||
delete m_tempFile;
|
delete m_tempFile;
|
||||||
m_tempFile = 0;
|
m_tempFile = 0;
|
||||||
return false;
|
return false;
|
||||||
@@ -102,15 +101,15 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
|
|||||||
workDir.append('\\');
|
workDir.append('\\');
|
||||||
|
|
||||||
QStringList stubArgs;
|
QStringList stubArgs;
|
||||||
stubArgs << (m_debug ? "debug" : "exec")
|
stubArgs << modeOption(m_mode)
|
||||||
<< m_stubServer.fullServerName()
|
<< m_stubServer.fullServerName()
|
||||||
<< workDir
|
<< workDir
|
||||||
<< (m_tempFile ? m_tempFile->fileName() : 0)
|
<< (m_tempFile ? m_tempFile->fileName() : 0)
|
||||||
<< createWinCommandline(program, args)
|
<< createWinCommandline(program, args)
|
||||||
<< tr("Press <RETURN> to close this window...");
|
<< msgPromptToClose();
|
||||||
|
|
||||||
QString cmdLine = createWinCommandline(
|
const QString cmdLine = createWinCommandline(
|
||||||
QCoreApplication::applicationDirPath() + "/qtcreator_process_stub.exe", stubArgs);
|
QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_process_stub.exe"), stubArgs);
|
||||||
|
|
||||||
bool success = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
|
bool success = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
|
||||||
0, 0, FALSE, CREATE_NEW_CONSOLE,
|
0, 0, FALSE, CREATE_NEW_CONSOLE,
|
||||||
@@ -180,13 +179,11 @@ void ConsoleProcess::readStubOutput()
|
|||||||
QByteArray out = m_stubSocket->readLine();
|
QByteArray out = m_stubSocket->readLine();
|
||||||
out.chop(2); // \r\n
|
out.chop(2); // \r\n
|
||||||
if (out.startsWith("err:chdir ")) {
|
if (out.startsWith("err:chdir ")) {
|
||||||
emit processError(tr("Cannot change to working directory '%1': %2")
|
emit processError(msgCannotChangeToWorkDir(workingDirectory(), winErrorMessage(out.mid(10).toInt())));
|
||||||
.arg(workingDirectory(), winErrorMessage(out.mid(10).toInt())));
|
|
||||||
} else if (out.startsWith("err:exec ")) {
|
} else if (out.startsWith("err:exec ")) {
|
||||||
emit processError(tr("Cannot execute '%1': %2")
|
emit processError(msgCannotExecute(m_executable, winErrorMessage(out.mid(9).toInt())));
|
||||||
.arg(m_executable, winErrorMessage(out.mid(9).toInt())));
|
|
||||||
} else if (out.startsWith("pid ")) {
|
} else if (out.startsWith("pid ")) {
|
||||||
// Will not need it any more
|
// Wil not need it any more
|
||||||
delete m_tempFile;
|
delete m_tempFile;
|
||||||
m_tempFile = 0;
|
m_tempFile = 0;
|
||||||
|
|
||||||
@@ -204,7 +201,7 @@ void ConsoleProcess::readStubOutput()
|
|||||||
connect(inferiorFinishedNotifier, SIGNAL(activated(HANDLE)), SLOT(inferiorExited()));
|
connect(inferiorFinishedNotifier, SIGNAL(activated(HANDLE)), SLOT(inferiorExited()));
|
||||||
emit processStarted();
|
emit processStarted();
|
||||||
} else {
|
} else {
|
||||||
emit processError(tr("Unexpected output from helper program."));
|
emit processError(msgUnexpectedOutput());
|
||||||
TerminateProcess(m_pid->hProcess, (unsigned)-1);
|
TerminateProcess(m_pid->hProcess, (unsigned)-1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
IDE_BUILD_TREE = $$OUT_PWD/../../..
|
|
||||||
include(../../../qtcreator.pri)
|
include(../../../qtcreator.pri)
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET = qtcreator_process_stub
|
TARGET = qtcreator_process_stub
|
||||||
macx {
|
DESTDIR = $$IDE_LIBEXEC_PATH
|
||||||
DESTDIR = $$IDE_BUILD_TREE/bin/$${IDE_APP_TARGET}.app/Contents/Resources
|
|
||||||
} else {
|
|
||||||
DESTDIR = ../../../bin
|
|
||||||
}
|
|
||||||
|
|
||||||
CONFIG += warn_on console use_c_linker
|
CONFIG += warn_on console use_c_linker
|
||||||
CONFIG -= qt app_bundle
|
CONFIG -= qt app_bundle
|
||||||
@@ -24,5 +19,5 @@ unix {
|
|||||||
LIBS += -lshell32
|
LIBS += -lshell32
|
||||||
}
|
}
|
||||||
|
|
||||||
target.path = /bin
|
target.path = /bin # FIXME: libexec, more or less
|
||||||
INSTALLS += target
|
INSTALLS += target
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
static FILE *qtcFd;
|
static FILE *qtcFd;
|
||||||
static wchar_t *sleepMsg;
|
static wchar_t *sleepMsg;
|
||||||
|
|
||||||
|
enum RunMode { Run, Debug, Suspend };
|
||||||
|
|
||||||
/* Print some "press enter" message, wait for that, exit. */
|
/* Print some "press enter" message, wait for that, exit. */
|
||||||
static void doExit(int code)
|
static void doExit(int code)
|
||||||
{
|
{
|
||||||
@@ -112,6 +114,7 @@ int main()
|
|||||||
STARTUPINFOW si;
|
STARTUPINFOW si;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
DEBUG_EVENT dbev;
|
DEBUG_EVENT dbev;
|
||||||
|
enum RunMode mode = Run;
|
||||||
|
|
||||||
argv = CommandLineToArgvW(GetCommandLine(), &argc);
|
argv = CommandLineToArgvW(GetCommandLine(), &argc);
|
||||||
|
|
||||||
@@ -158,8 +161,20 @@ int main()
|
|||||||
si.cb = sizeof(si);
|
si.cb = sizeof(si);
|
||||||
|
|
||||||
creationFlags = CREATE_UNICODE_ENVIRONMENT;
|
creationFlags = CREATE_UNICODE_ENVIRONMENT;
|
||||||
if (!wcscmp(argv[ArgAction], L"debug"))
|
if (!wcscmp(argv[ArgAction], L"debug")) {
|
||||||
|
mode = Debug;
|
||||||
|
} else if (!wcscmp(argv[ArgAction], L"suspend")) {
|
||||||
|
mode = Suspend;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case Debug:
|
||||||
creationFlags |= DEBUG_ONLY_THIS_PROCESS;
|
creationFlags |= DEBUG_ONLY_THIS_PROCESS;
|
||||||
|
break;
|
||||||
|
case Suspend:
|
||||||
|
creationFlags |= CREATE_SUSPENDED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!CreateProcessW(0, argv[ArgCmdLine], 0, 0, FALSE, creationFlags, env, 0, &si, &pi)) {
|
if (!CreateProcessW(0, argv[ArgCmdLine], 0, 0, FALSE, creationFlags, env, 0, &si, &pi)) {
|
||||||
/* Only expected error: no such file or direcotry, i.e. executable not found */
|
/* Only expected error: no such file or direcotry, i.e. executable not found */
|
||||||
sendMsg("err:exec %d\n", GetLastError());
|
sendMsg("err:exec %d\n", GetLastError());
|
||||||
@@ -172,7 +187,7 @@ int main()
|
|||||||
So instead we start a debugged process, eat all the initial
|
So instead we start a debugged process, eat all the initial
|
||||||
debug events, suspend the process and detach from it. If gdb
|
debug events, suspend the process and detach from it. If gdb
|
||||||
tries to attach *now*, everything goes smoothly. Yay. */
|
tries to attach *now*, everything goes smoothly. Yay. */
|
||||||
if (creationFlags & DEBUG_ONLY_THIS_PROCESS) {
|
if (mode == Debug) {
|
||||||
do {
|
do {
|
||||||
if (!WaitForDebugEvent (&dbev, INFINITE))
|
if (!WaitForDebugEvent (&dbev, INFINITE))
|
||||||
systemError("Cannot fetch debug event, error %d\n");
|
systemError("Cannot fetch debug event, error %d\n");
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ SOURCES += \
|
|||||||
savedaction.cpp \
|
savedaction.cpp \
|
||||||
submiteditorwidget.cpp \
|
submiteditorwidget.cpp \
|
||||||
synchronousprocess.cpp \
|
synchronousprocess.cpp \
|
||||||
submitfieldwidget.cpp
|
submitfieldwidget.cpp \
|
||||||
|
consoleprocess.cpp
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
SOURCES += abstractprocess_win.cpp \
|
SOURCES += abstractprocess_win.cpp \
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ using namespace Core::Internal;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ActionContainerPrivate::ActionContainerPrivate(int id)
|
ActionContainerPrivate::ActionContainerPrivate(int id)
|
||||||
: m_data(CS_None), m_id(id)
|
: m_data(0), m_id(id)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -168,16 +168,6 @@ bool ActionContainerPrivate::hasEmptyAction(EmptyAction ea) const
|
|||||||
return (m_data & EA_Mask) == ea;
|
return (m_data & EA_Mask) == ea;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionContainerPrivate::setState(ContainerState state)
|
|
||||||
{
|
|
||||||
m_data |= state;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ActionContainerPrivate::hasState(ContainerState state) const
|
|
||||||
{
|
|
||||||
return (m_data & state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionContainerPrivate::appendGroup(const QString &group)
|
void ActionContainerPrivate::appendGroup(const QString &group)
|
||||||
{
|
{
|
||||||
int gid = UniqueIDManager::instance()->uniqueIdentifier(group);
|
int gid = UniqueIDManager::instance()->uniqueIdentifier(group);
|
||||||
@@ -198,26 +188,14 @@ void ActionContainerPrivate::addAction(Command *action, const QString &group)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ActionManagerPrivate *am = ActionManagerPrivate::instance();
|
ActionManagerPrivate *am = ActionManagerPrivate::instance();
|
||||||
Action *a = static_cast<Action *>(action);
|
UniqueIDManager *idmanager = UniqueIDManager::instance();
|
||||||
if (a->stateFlags() & CommandPrivate::CS_PreLocation) {
|
int grpid = idmanager->uniqueIdentifier(Constants::G_DEFAULT_TWO);
|
||||||
QList<CommandLocation> locs = a->locations();
|
if (!group.isEmpty())
|
||||||
for (int i=0; i<locs.size(); ++i) {
|
grpid = idmanager->uniqueIdentifier(group);
|
||||||
if (ActionContainer *aci = am->actionContainer(locs.at(i).m_container)) {
|
if (!m_groups.contains(grpid) && !am->defaultGroups().contains(grpid))
|
||||||
ActionContainerPrivate *ac = static_cast<ActionContainerPrivate *>(aci);
|
qWarning() << "*** addAction(): Unknown group: " << group;
|
||||||
ac->addAction(action, locs.at(i).m_position, false);
|
int pos = ((grpid << 16) | 0xFFFF);
|
||||||
}
|
addAction(action, pos, true);
|
||||||
}
|
|
||||||
a->setStateFlags(a->stateFlags() | CommandPrivate::CS_Initialized);
|
|
||||||
} else {
|
|
||||||
UniqueIDManager *idmanager = UniqueIDManager::instance();
|
|
||||||
int grpid = idmanager->uniqueIdentifier(Constants::G_DEFAULT_TWO);
|
|
||||||
if (!group.isEmpty())
|
|
||||||
grpid = idmanager->uniqueIdentifier(group);
|
|
||||||
if (!m_groups.contains(grpid) && !am->defaultGroups().contains(grpid))
|
|
||||||
qWarning() << "*** addAction(): Unknown group: " << group;
|
|
||||||
int pos = ((grpid << 16) | 0xFFFF);
|
|
||||||
addAction(action, pos, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionContainerPrivate::addMenu(ActionContainer *menu, const QString &group)
|
void ActionContainerPrivate::addMenu(ActionContainer *menu, const QString &group)
|
||||||
@@ -227,24 +205,14 @@ void ActionContainerPrivate::addMenu(ActionContainer *menu, const QString &group
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ActionManagerPrivate *am = ActionManagerPrivate::instance();
|
ActionManagerPrivate *am = ActionManagerPrivate::instance();
|
||||||
MenuActionContainer *mc = static_cast<MenuActionContainer *>(menu);
|
UniqueIDManager *idmanager = UniqueIDManager::instance();
|
||||||
if (mc->hasState(ActionContainerPrivate::CS_PreLocation)) {
|
int grpid = idmanager->uniqueIdentifier(Constants::G_DEFAULT_TWO);
|
||||||
CommandLocation loc = mc->location();
|
if (!group.isEmpty())
|
||||||
if (ActionContainer *aci = am->actionContainer(loc.m_container)) {
|
grpid = idmanager->uniqueIdentifier(group);
|
||||||
ActionContainerPrivate *ac = static_cast<ActionContainerPrivate *>(aci);
|
if (!m_groups.contains(grpid) && !am->defaultGroups().contains(grpid))
|
||||||
ac->addMenu(menu, loc.m_position, false);
|
qWarning() << "*** addMenu(): Unknown group: " << group;
|
||||||
}
|
int pos = ((grpid << 16) | 0xFFFF);
|
||||||
mc->setState(ActionContainerPrivate::CS_Initialized);
|
addMenu(menu, pos, true);
|
||||||
} else {
|
|
||||||
UniqueIDManager *idmanager = UniqueIDManager::instance();
|
|
||||||
int grpid = idmanager->uniqueIdentifier(Constants::G_DEFAULT_TWO);
|
|
||||||
if (!group.isEmpty())
|
|
||||||
grpid = idmanager->uniqueIdentifier(group);
|
|
||||||
if (!m_groups.contains(grpid) && !am->defaultGroups().contains(grpid))
|
|
||||||
qWarning() << "*** addMenu(): Unknown group: " << group;
|
|
||||||
int pos = ((grpid << 16) | 0xFFFF);
|
|
||||||
addMenu(menu, pos, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ActionContainerPrivate::id() const
|
int ActionContainerPrivate::id() const
|
||||||
@@ -264,14 +232,7 @@ QMenuBar *ActionContainerPrivate::menuBar() const
|
|||||||
|
|
||||||
bool ActionContainerPrivate::canAddAction(Command *action) const
|
bool ActionContainerPrivate::canAddAction(Command *action) const
|
||||||
{
|
{
|
||||||
if (action->type() != Command::CT_OverridableAction)
|
return (action->action() != 0);
|
||||||
return false;
|
|
||||||
|
|
||||||
CommandPrivate *cmd = static_cast<CommandPrivate *>(action);
|
|
||||||
if (cmd->stateFlags() & CommandPrivate::CS_Initialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionContainerPrivate::addAction(Command *action, int pos, bool setpos)
|
void ActionContainerPrivate::addAction(Command *action, int pos, bool setpos)
|
||||||
@@ -444,9 +405,6 @@ bool MenuActionContainer::update()
|
|||||||
|
|
||||||
bool MenuActionContainer::canBeAddedToMenu() const
|
bool MenuActionContainer::canBeAddedToMenu() const
|
||||||
{
|
{
|
||||||
if (hasState(ActionContainerPrivate::CS_Initialized))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,22 +41,12 @@ namespace Internal {
|
|||||||
class ActionContainerPrivate : public Core::ActionContainer
|
class ActionContainerPrivate : public Core::ActionContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum ContainerState {
|
|
||||||
CS_None = 0x000000,
|
|
||||||
CS_Initialized = 0x010000,
|
|
||||||
CS_PreLocation = 0x020000,
|
|
||||||
CS_UserDefined = 0x040000
|
|
||||||
};
|
|
||||||
|
|
||||||
ActionContainerPrivate(int id);
|
ActionContainerPrivate(int id);
|
||||||
virtual ~ActionContainerPrivate() {}
|
virtual ~ActionContainerPrivate() {}
|
||||||
|
|
||||||
void setEmptyAction(EmptyAction ea);
|
void setEmptyAction(EmptyAction ea);
|
||||||
bool hasEmptyAction(EmptyAction ea) const;
|
bool hasEmptyAction(EmptyAction ea) const;
|
||||||
|
|
||||||
void setState(ContainerState state);
|
|
||||||
bool hasState(ContainerState state) const;
|
|
||||||
|
|
||||||
QAction *insertLocation(const QString &group) const;
|
QAction *insertLocation(const QString &group) const;
|
||||||
void appendGroup(const QString &group);
|
void appendGroup(const QString &group);
|
||||||
void addAction(Command *action, const QString &group = QString());
|
void addAction(Command *action, const QString &group = QString());
|
||||||
|
|||||||
@@ -335,13 +335,12 @@ Command *ActionManagerPrivate::registerOverridableAction(QAction *action, const
|
|||||||
OverrideableAction *a = 0;
|
OverrideableAction *a = 0;
|
||||||
const int uid = UniqueIDManager::instance()->uniqueIdentifier(id);
|
const int uid = UniqueIDManager::instance()->uniqueIdentifier(id);
|
||||||
if (CommandPrivate *c = m_idCmdMap.value(uid, 0)) {
|
if (CommandPrivate *c = m_idCmdMap.value(uid, 0)) {
|
||||||
if (c->type() != Command::CT_OverridableAction) {
|
a = qobject_cast<OverrideableAction *>(c);
|
||||||
|
if (!a) {
|
||||||
qWarning() << "registerAction: id" << id << "is registered with a different command type.";
|
qWarning() << "registerAction: id" << id << "is registered with a different command type.";
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
a = static_cast<OverrideableAction *>(c);
|
} else {
|
||||||
}
|
|
||||||
if (!a) {
|
|
||||||
a = new OverrideableAction(uid);
|
a = new OverrideableAction(uid);
|
||||||
m_idCmdMap.insert(uid, a);
|
m_idCmdMap.insert(uid, a);
|
||||||
}
|
}
|
||||||
@@ -381,11 +380,11 @@ Command *ActionManagerPrivate::registerShortcut(QShortcut *shortcut, const QStri
|
|||||||
Shortcut *sc = 0;
|
Shortcut *sc = 0;
|
||||||
int uid = UniqueIDManager::instance()->uniqueIdentifier(id);
|
int uid = UniqueIDManager::instance()->uniqueIdentifier(id);
|
||||||
if (CommandPrivate *c = m_idCmdMap.value(uid, 0)) {
|
if (CommandPrivate *c = m_idCmdMap.value(uid, 0)) {
|
||||||
if (c->type() != Command::CT_Shortcut) {
|
sc = qobject_cast<Shortcut *>(c);
|
||||||
|
if (!sc) {
|
||||||
qWarning() << "registerShortcut: id" << id << "is registered with a different command type.";
|
qWarning() << "registerShortcut: id" << id << "is registered with a different command type.";
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
sc = static_cast<Shortcut *>(c);
|
|
||||||
} else {
|
} else {
|
||||||
sc = new Shortcut(uid);
|
sc = new Shortcut(uid);
|
||||||
m_idCmdMap.insert(uid, sc);
|
m_idCmdMap.insert(uid, sc);
|
||||||
|
|||||||
@@ -38,80 +38,165 @@
|
|||||||
\mainclass
|
\mainclass
|
||||||
|
|
||||||
\brief The class Command represents an action like a menu item, tool button, or shortcut.
|
\brief The class Command represents an action like a menu item, tool button, or shortcut.
|
||||||
|
You don't create Command objects directly, instead use \l{ActionManager::registerAction()}
|
||||||
|
to register an action and retrieve a Command. The Command object represents the user visible
|
||||||
|
action and its properties. If multiple actions are registered with the same ID (but
|
||||||
|
different contexts) the returned Command is the shared one between these actions.
|
||||||
|
|
||||||
*/
|
A Command has two basic properties: A default shortcut and a default text. The default
|
||||||
|
shortcut is a key sequence that the user can use to trigger the active action that
|
||||||
|
the Command represents. The default text is e.g. used for representing the Command
|
||||||
|
in the keyboard shortcut preference pane. If the default text is empty, the text
|
||||||
|
of the visible action is used.
|
||||||
|
|
||||||
/*!
|
The user visible action is updated to represent the state of the active action (if any).
|
||||||
\enum Command::CommandType
|
For performance reasons only the enabled and visible state are considered by default though.
|
||||||
|
You can tell a Command to also update the actions icon and text by setting the
|
||||||
|
corresponding \l{Command::CommandAttribute}{attribute}.
|
||||||
|
|
||||||
|
If there is no active action, the default behavior of the visible action is to be disabled.
|
||||||
|
You can change that behavior to make the visible action hide instead via the Command's
|
||||||
|
\l{Command::CommandAttribute}{attributes}.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\enum Command::CommandAttribute
|
\enum Command::CommandAttribute
|
||||||
|
Defines how the user visible action is updated when the active action changes.
|
||||||
|
The default is to update the enabled and visible state, and to disable the
|
||||||
|
user visible action when there is no active action.
|
||||||
|
\omitvalue CA_Mask
|
||||||
|
\value CA_UpdateText
|
||||||
|
Also update the actions text.
|
||||||
|
\value CA_UpdateIcon
|
||||||
|
Also update the actions icon.
|
||||||
|
\value CA_Hide
|
||||||
|
When there is no active action, hide the user "visible" action, instead of just
|
||||||
|
disabling it.
|
||||||
|
\value CA_NonConfigureable
|
||||||
|
Flag to indicate that the keyboard shortcut of this Command should not be
|
||||||
|
configurable by the user.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual void Command::setDefaultKeySequence(const QKeySequence &key)
|
\fn void Command::setDefaultKeySequence(const QKeySequence &key)
|
||||||
|
Set the default keyboard shortcut that can be used to activate this command to \a key.
|
||||||
|
This is used if the user didn't customize the shortcut, or resets the shortcut
|
||||||
|
to the default one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual int Command::id() const
|
\fn void Command::defaultKeySequence() const
|
||||||
|
Returns the default keyboard shortcut that can be used to activate this command.
|
||||||
|
\sa setDefaultKeySequence()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual CommandType Command::type() const
|
\fn void Command::keySequenceChanged()
|
||||||
|
Sent when the keyboard shortcut assigned to this Command changes, e.g.
|
||||||
|
when the user sets it in the keyboard shortcut settings dialog.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual QAction *Command::action() const
|
\fn QKeySequence Command::keySequence() const
|
||||||
|
Returns the current keyboard shortcut assigned to this Command.
|
||||||
|
\sa defaultKeySequence()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual QShortcut *Command::shortcut() const
|
\fn void Command::setKeySequence(const QKeySequence &key)
|
||||||
|
\internal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual void Command::setAttribute(CommandAttribute attr)
|
\fn void Command::setDefaultText(const QString &text)
|
||||||
|
Set the \a text that is used to represent the Command in the
|
||||||
|
keyboard shortcut settings dialog. If you don't set this,
|
||||||
|
the current text from the user visible action is taken (which
|
||||||
|
is ok in many cases).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual void Command::removeAttribute(CommandAttribute attr)
|
\fn QString Command::defaultText() const
|
||||||
|
Returns the text that is used to present this Command to the user.
|
||||||
|
\sa setDefaultText()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual bool Command::hasAttribute(CommandAttribute attr) const
|
\fn int Command::id() const
|
||||||
|
\internal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual bool Command::isActive() const
|
\fn QString Command::stringWithAppendedShortcut(const QString &string) const
|
||||||
|
Returns the \a string with an appended representation of the keyboard shortcut
|
||||||
|
that is currently assigned to this Command.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn virtual Command::~Command()
|
\fn QAction *Command::action() const
|
||||||
|
Returns the user visible action for this Command.
|
||||||
|
If the Command represents a shortcut, it returns null.
|
||||||
|
Use this action to put it on e.g. tool buttons. The action
|
||||||
|
automatically forwards trigger and toggle signals to the
|
||||||
|
action that is currently active for this Command.
|
||||||
|
It also shows the current keyboard shortcut in its
|
||||||
|
tool tip (in addition to the tool tip of the active action)
|
||||||
|
and gets disabled/hidden when there is
|
||||||
|
no active action for the current context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QShortcut *Command::shortcut() const
|
||||||
|
Returns the shortcut for this Command.
|
||||||
|
If the Command represents an action, it returns null.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void Command::setAttribute(CommandAttribute attribute)
|
||||||
|
Add the \a attribute to the attributes of this Command.
|
||||||
|
\sa CommandAttribute
|
||||||
|
\sa removeAttribute()
|
||||||
|
\sa hasAttribute()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void Command::removeAttribute(CommandAttribute attribute)
|
||||||
|
Remove the \a attribute from the attributes of this Command.
|
||||||
|
\sa CommandAttribute
|
||||||
|
\sa setAttribute()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool Command::hasAttribute(CommandAttribute attribute) const
|
||||||
|
Returns if the Command has the \a attribute set.
|
||||||
|
\sa CommandAttribute
|
||||||
|
\sa removeAttribute()
|
||||||
|
\sa setAttribute()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool Command::isActive() const
|
||||||
|
Returns if the Command has an active action/shortcut for the current
|
||||||
|
context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn Command::~Command()
|
||||||
|
\internal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using namespace Core::Internal;
|
using namespace Core::Internal;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class CommandPrivate
|
\class CommandPrivate
|
||||||
\inheaderfile command_p.h
|
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CommandPrivate::CommandPrivate(CommandType type, int id)
|
CommandPrivate::CommandPrivate(int id)
|
||||||
: m_type(type), m_id(id)
|
: m_attributes(0), m_id(id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandPrivate::setStateFlags(int state)
|
|
||||||
{
|
|
||||||
m_type |= (state & CS_Mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CommandPrivate::stateFlags() const
|
|
||||||
{
|
|
||||||
return (m_type & CS_Mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandPrivate::setDefaultKeySequence(const QKeySequence &key)
|
void CommandPrivate::setDefaultKeySequence(const QKeySequence &key)
|
||||||
{
|
{
|
||||||
m_defaultKey = key;
|
m_defaultKey = key;
|
||||||
@@ -137,11 +222,6 @@ int CommandPrivate::id() const
|
|||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandPrivate::CommandType CommandPrivate::type() const
|
|
||||||
{
|
|
||||||
return (CommandType)(m_type & CT_Mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction *CommandPrivate::action() const
|
QAction *CommandPrivate::action() const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -154,17 +234,17 @@ QShortcut *CommandPrivate::shortcut() const
|
|||||||
|
|
||||||
void CommandPrivate::setAttribute(CommandAttribute attr)
|
void CommandPrivate::setAttribute(CommandAttribute attr)
|
||||||
{
|
{
|
||||||
m_type |= attr;
|
m_attributes |= attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandPrivate::removeAttribute(CommandAttribute attr)
|
void CommandPrivate::removeAttribute(CommandAttribute attr)
|
||||||
{
|
{
|
||||||
m_type &= ~attr;
|
m_attributes &= ~attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandPrivate::hasAttribute(CommandAttribute attr) const
|
bool CommandPrivate::hasAttribute(CommandAttribute attr) const
|
||||||
{
|
{
|
||||||
return (m_type & attr);
|
return (m_attributes & attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CommandPrivate::stringWithAppendedShortcut(const QString &str) const
|
QString CommandPrivate::stringWithAppendedShortcut(const QString &str) const
|
||||||
@@ -177,20 +257,15 @@ QString CommandPrivate::stringWithAppendedShortcut(const QString &str) const
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class Shortcut
|
\class Shortcut
|
||||||
|
\internal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
Shortcut::Shortcut(int id)
|
Shortcut::Shortcut(int id)
|
||||||
: CommandPrivate(CT_Shortcut, id), m_shortcut(0)
|
: CommandPrivate(id), m_shortcut(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
QString Shortcut::name() const
|
QString Shortcut::name() const
|
||||||
{
|
{
|
||||||
if (!m_shortcut)
|
if (!m_shortcut)
|
||||||
@@ -199,41 +274,26 @@ QString Shortcut::name() const
|
|||||||
return m_shortcut->whatsThis();
|
return m_shortcut->whatsThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void Shortcut::setShortcut(QShortcut *shortcut)
|
void Shortcut::setShortcut(QShortcut *shortcut)
|
||||||
{
|
{
|
||||||
m_shortcut = shortcut;
|
m_shortcut = shortcut;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
QShortcut *Shortcut::shortcut() const
|
QShortcut *Shortcut::shortcut() const
|
||||||
{
|
{
|
||||||
return m_shortcut;
|
return m_shortcut;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void Shortcut::setContext(const QList<int> &context)
|
void Shortcut::setContext(const QList<int> &context)
|
||||||
{
|
{
|
||||||
m_context = context;
|
m_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
QList<int> Shortcut::context() const
|
QList<int> Shortcut::context() const
|
||||||
{
|
{
|
||||||
return m_context;
|
return m_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void Shortcut::setDefaultKeySequence(const QKeySequence &key)
|
void Shortcut::setDefaultKeySequence(const QKeySequence &key)
|
||||||
{
|
{
|
||||||
setKeySequence(key);
|
setKeySequence(key);
|
||||||
@@ -261,9 +321,6 @@ QString Shortcut::defaultText() const
|
|||||||
return m_defaultText;
|
return m_defaultText;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
bool Shortcut::setCurrentContext(const QList<int> &context)
|
bool Shortcut::setCurrentContext(const QList<int> &context)
|
||||||
{
|
{
|
||||||
foreach (int ctxt, m_context) {
|
foreach (int ctxt, m_context) {
|
||||||
@@ -276,9 +333,6 @@ bool Shortcut::setCurrentContext(const QList<int> &context)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
bool Shortcut::isActive() const
|
bool Shortcut::isActive() const
|
||||||
{
|
{
|
||||||
return m_shortcut->isEnabled();
|
return m_shortcut->isEnabled();
|
||||||
@@ -287,21 +341,15 @@ bool Shortcut::isActive() const
|
|||||||
// ---------- Action ------------
|
// ---------- Action ------------
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class Action
|
\class Action
|
||||||
|
\internal
|
||||||
*/
|
*/
|
||||||
|
Action::Action(int id)
|
||||||
/*!
|
: CommandPrivate(id), m_action(0)
|
||||||
...
|
|
||||||
*/
|
|
||||||
Action::Action(CommandType type, int id)
|
|
||||||
: CommandPrivate(type, id), m_action(0)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
QString Action::name() const
|
QString Action::name() const
|
||||||
{
|
{
|
||||||
if (!m_action)
|
if (!m_action)
|
||||||
@@ -310,9 +358,6 @@ QString Action::name() const
|
|||||||
return m_action->text();
|
return m_action->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void Action::setAction(QAction *action)
|
void Action::setAction(QAction *action)
|
||||||
{
|
{
|
||||||
m_action = action;
|
m_action = action;
|
||||||
@@ -322,33 +367,21 @@ void Action::setAction(QAction *action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
QAction *Action::action() const
|
QAction *Action::action() const
|
||||||
{
|
{
|
||||||
return m_action;
|
return m_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void Action::setLocations(const QList<CommandLocation> &locations)
|
void Action::setLocations(const QList<CommandLocation> &locations)
|
||||||
{
|
{
|
||||||
m_locations = locations;
|
m_locations = locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
QList<CommandLocation> Action::locations() const
|
QList<CommandLocation> Action::locations() const
|
||||||
{
|
{
|
||||||
return m_locations;
|
return m_locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void Action::setDefaultKeySequence(const QKeySequence &key)
|
void Action::setDefaultKeySequence(const QKeySequence &key)
|
||||||
{
|
{
|
||||||
setKeySequence(key);
|
setKeySequence(key);
|
||||||
@@ -379,28 +412,20 @@ QKeySequence Action::keySequence() const
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class OverrideableAction
|
\class OverrideableAction
|
||||||
|
\internal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
OverrideableAction::OverrideableAction(int id)
|
OverrideableAction::OverrideableAction(int id)
|
||||||
: Action(CT_OverridableAction, id), m_currentAction(0), m_active(false),
|
: Action(id), m_currentAction(0), m_active(false),
|
||||||
m_contextInitialized(false)
|
m_contextInitialized(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void OverrideableAction::setAction(QAction *action)
|
void OverrideableAction::setAction(QAction *action)
|
||||||
{
|
{
|
||||||
Action::setAction(action);
|
Action::setAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
bool OverrideableAction::setCurrentContext(const QList<int> &context)
|
bool OverrideableAction::setCurrentContext(const QList<int> &context)
|
||||||
{
|
{
|
||||||
m_context = context;
|
m_context = context;
|
||||||
@@ -440,9 +465,6 @@ bool OverrideableAction::setCurrentContext(const QList<int> &context)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void OverrideableAction::addOverrideAction(QAction *action, const QList<int> &context)
|
void OverrideableAction::addOverrideAction(QAction *action, const QList<int> &context)
|
||||||
{
|
{
|
||||||
if (context.isEmpty()) {
|
if (context.isEmpty()) {
|
||||||
@@ -457,9 +479,6 @@ void OverrideableAction::addOverrideAction(QAction *action, const QList<int> &co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
void OverrideableAction::actionChanged()
|
void OverrideableAction::actionChanged()
|
||||||
{
|
{
|
||||||
if (hasAttribute(CA_UpdateIcon)) {
|
if (hasAttribute(CA_UpdateIcon)) {
|
||||||
@@ -482,9 +501,6 @@ void OverrideableAction::actionChanged()
|
|||||||
m_action->setVisible(m_currentAction->isVisible());
|
m_action->setVisible(m_currentAction->isVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
bool OverrideableAction::isActive() const
|
bool OverrideableAction::isActive() const
|
||||||
{
|
{
|
||||||
return m_active;
|
return m_active;
|
||||||
|
|||||||
@@ -42,12 +42,6 @@ class CORE_EXPORT Command : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum CommandType {
|
|
||||||
CT_Shortcut = 0x0001,
|
|
||||||
CT_OverridableAction = 0x0002,
|
|
||||||
CT_Mask = 0x00FF
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CommandAttribute {
|
enum CommandAttribute {
|
||||||
CA_Hide = 0x0100,
|
CA_Hide = 0x0100,
|
||||||
CA_UpdateText = 0x0200,
|
CA_UpdateText = 0x0200,
|
||||||
@@ -57,14 +51,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtual void setDefaultKeySequence(const QKeySequence &key) = 0;
|
virtual void setDefaultKeySequence(const QKeySequence &key) = 0;
|
||||||
virtual void setKeySequence(const QKeySequence &key) = 0;
|
|
||||||
virtual QKeySequence defaultKeySequence() const = 0;
|
virtual QKeySequence defaultKeySequence() const = 0;
|
||||||
virtual QKeySequence keySequence() const = 0;
|
virtual QKeySequence keySequence() const = 0;
|
||||||
virtual void setDefaultText(const QString &text) = 0;
|
virtual void setDefaultText(const QString &text) = 0;
|
||||||
virtual QString defaultText() const = 0;
|
virtual QString defaultText() const = 0;
|
||||||
|
|
||||||
virtual int id() const = 0;
|
virtual int id() const = 0;
|
||||||
virtual CommandType type() const = 0;
|
|
||||||
|
|
||||||
virtual QAction *action() const = 0;
|
virtual QAction *action() const = 0;
|
||||||
virtual QShortcut *shortcut() const = 0;
|
virtual QShortcut *shortcut() const = 0;
|
||||||
@@ -77,6 +69,8 @@ public:
|
|||||||
|
|
||||||
virtual ~Command() {}
|
virtual ~Command() {}
|
||||||
|
|
||||||
|
virtual void setKeySequence(const QKeySequence &key) = 0;
|
||||||
|
|
||||||
virtual QString stringWithAppendedShortcut(const QString &str) const = 0;
|
virtual QString stringWithAppendedShortcut(const QString &str) const = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
@@ -45,19 +45,9 @@ class CommandPrivate : public Core::Command
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum CommandState {
|
CommandPrivate(int id);
|
||||||
CS_PreLocation = 0x020000,
|
|
||||||
CS_LocationChanged = 0x040000,
|
|
||||||
CS_Initialized = 0x080000,
|
|
||||||
CS_Mask = 0xFF0000
|
|
||||||
};
|
|
||||||
|
|
||||||
CommandPrivate(CommandType type, int id);
|
|
||||||
virtual ~CommandPrivate() {}
|
virtual ~CommandPrivate() {}
|
||||||
|
|
||||||
void setStateFlags(int state);
|
|
||||||
int stateFlags() const;
|
|
||||||
|
|
||||||
virtual QString name() const = 0;
|
virtual QString name() const = 0;
|
||||||
|
|
||||||
void setDefaultKeySequence(const QKeySequence &key);
|
void setDefaultKeySequence(const QKeySequence &key);
|
||||||
@@ -67,7 +57,6 @@ public:
|
|||||||
QString defaultText() const;
|
QString defaultText() const;
|
||||||
|
|
||||||
int id() const;
|
int id() const;
|
||||||
CommandType type() const;
|
|
||||||
|
|
||||||
QAction *action() const;
|
QAction *action() const;
|
||||||
QShortcut *shortcut() const;
|
QShortcut *shortcut() const;
|
||||||
@@ -82,7 +71,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString m_category;
|
QString m_category;
|
||||||
int m_type;
|
int m_attributes;
|
||||||
int m_id;
|
int m_id;
|
||||||
QKeySequence m_defaultKey;
|
QKeySequence m_defaultKey;
|
||||||
QString m_defaultText;
|
QString m_defaultText;
|
||||||
@@ -121,7 +110,7 @@ class Action : public CommandPrivate
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Action(CommandType type, int id);
|
Action(int id);
|
||||||
|
|
||||||
QString name() const;
|
QString name() const;
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,9 @@
|
|||||||
|
|
||||||
#include <coreplugin/ifile.h>
|
#include <coreplugin/ifile.h>
|
||||||
|
|
||||||
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QDir>
|
||||||
#include <QtGui/QPushButton>
|
#include <QtGui/QPushButton>
|
||||||
#include <QtGui/QTreeWidget>
|
#include <QtGui/QTreeWidget>
|
||||||
#include <QtGui/QHeaderView>
|
#include <QtGui/QHeaderView>
|
||||||
@@ -69,7 +71,7 @@ SaveItemsDialog::SaveItemsDialog(QWidget *parent,
|
|||||||
visibleName = info.fileName();
|
visibleName = info.fileName();
|
||||||
}
|
}
|
||||||
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.treeWidget, QStringList()
|
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.treeWidget, QStringList()
|
||||||
<< visibleName << directory);
|
<< visibleName << QDir::toNativeSeparators(directory));
|
||||||
item->setData(0, Qt::UserRole, qVariantFromValue(file));
|
item->setData(0, Qt::UserRole, qVariantFromValue(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ void CppHighlighter::highlightBlock(const QString &text)
|
|||||||
braceDepth = previousState >> 8;
|
braceDepth = previousState >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SimpleLexer tokenize;
|
SimpleLexer tokenize;
|
||||||
tokenize.setQtMocRunEnabled(false);
|
tokenize.setQtMocRunEnabled(false);
|
||||||
|
|
||||||
@@ -210,6 +211,28 @@ void CppHighlighter::highlightBlock(const QString &text)
|
|||||||
|
|
||||||
TextEditDocumentLayout::setParentheses(currentBlock(), parentheses);
|
TextEditDocumentLayout::setParentheses(currentBlock(), parentheses);
|
||||||
|
|
||||||
|
|
||||||
|
// optimization: if only the brace depth changes, we adjust subsequent blocks
|
||||||
|
// to have QSyntaxHighlighter stop the rehighlighting
|
||||||
|
int currentState = currentBlockState();
|
||||||
|
if (currentState != -1) {
|
||||||
|
int oldState = currentState & 0xff;
|
||||||
|
int oldBraceDepth = currentState >> 8;
|
||||||
|
if (oldState == tokenize.state() && oldBraceDepth != braceDepth) {
|
||||||
|
int delta = braceDepth - oldBraceDepth;
|
||||||
|
QTextBlock block = currentBlock().next();
|
||||||
|
while (block.isValid()) {
|
||||||
|
currentState = block.userState();
|
||||||
|
if (currentState != -1) {
|
||||||
|
oldState = currentState & 0xff;
|
||||||
|
oldBraceDepth = currentState >> 8;
|
||||||
|
block.setUserState(qMax(0, (oldBraceDepth + delta) << 8 ) | oldState);
|
||||||
|
}
|
||||||
|
block = block.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentBlockState((braceDepth << 8) | tokenize.state());
|
setCurrentBlockState((braceDepth << 8) | tokenize.state());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent, const QSharedPointer<Cdb
|
|||||||
IDebuggerEngine(parent),
|
IDebuggerEngine(parent),
|
||||||
m_d(new CdbDebugEnginePrivate(parent, options, this))
|
m_d(new CdbDebugEnginePrivate(parent, options, this))
|
||||||
{
|
{
|
||||||
// m_d->m_consoleStubProc.setDebug(true);
|
m_d->m_consoleStubProc.setMode(Core::Utils::ConsoleProcess::Suspend);
|
||||||
connect(&m_d->m_consoleStubProc, SIGNAL(processError(QString)), this, SLOT(slotConsoleStubError(QString)));
|
connect(&m_d->m_consoleStubProc, SIGNAL(processError(QString)), this, SLOT(slotConsoleStubError(QString)));
|
||||||
connect(&m_d->m_consoleStubProc, SIGNAL(processStarted()), this, SLOT(slotConsoleStubStarted()));
|
connect(&m_d->m_consoleStubProc, SIGNAL(processStarted()), this, SLOT(slotConsoleStubStarted()));
|
||||||
connect(&m_d->m_consoleStubProc, SIGNAL(wrapperStopped()), this, SLOT(slotConsoleStubTerminated()));
|
connect(&m_d->m_consoleStubProc, SIGNAL(wrapperStopped()), this, SLOT(slotConsoleStubTerminated()));
|
||||||
@@ -469,10 +469,12 @@ bool CdbDebugEngine::startDebugger()
|
|||||||
m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
|
m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
bool rc = false;
|
bool rc = false;
|
||||||
|
bool needWatchTimer = false;
|
||||||
m_d->clearForRun();
|
m_d->clearForRun();
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case AttachExternal:
|
case AttachExternal:
|
||||||
rc = startAttachDebugger(m_d->m_debuggerManager->m_attachedPID, &errorMessage);
|
rc = startAttachDebugger(m_d->m_debuggerManager->m_attachedPID, &errorMessage);
|
||||||
|
needWatchTimer = true;
|
||||||
break;
|
break;
|
||||||
case StartInternal:
|
case StartInternal:
|
||||||
case StartExternal:
|
case StartExternal:
|
||||||
@@ -484,7 +486,9 @@ bool CdbDebugEngine::startDebugger()
|
|||||||
rc = m_d->m_consoleStubProc.start(m_d->m_debuggerManager->m_executable, m_d->m_debuggerManager->m_processArgs);
|
rc = m_d->m_consoleStubProc.start(m_d->m_debuggerManager->m_executable, m_d->m_debuggerManager->m_processArgs);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
errorMessage = tr("The console stub process was unable to start '%1'.").arg(m_d->m_debuggerManager->m_executable);
|
errorMessage = tr("The console stub process was unable to start '%1'.").arg(m_d->m_debuggerManager->m_executable);
|
||||||
|
// continues in slotConsoleStubStarted()...
|
||||||
} else {
|
} else {
|
||||||
|
needWatchTimer = true;
|
||||||
rc = startDebuggerWithExecutable(mode, &errorMessage);
|
rc = startDebuggerWithExecutable(mode, &errorMessage);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -494,7 +498,8 @@ bool CdbDebugEngine::startDebugger()
|
|||||||
}
|
}
|
||||||
if (rc) {
|
if (rc) {
|
||||||
m_d->m_debuggerManager->showStatusMessage(tr("Debugger Running"), -1);
|
m_d->m_debuggerManager->showStatusMessage(tr("Debugger Running"), -1);
|
||||||
startWatchTimer();
|
if (needWatchTimer)
|
||||||
|
startWatchTimer();
|
||||||
} else {
|
} else {
|
||||||
qWarning("%s\n", qPrintable(errorMessage));
|
qWarning("%s\n", qPrintable(errorMessage));
|
||||||
}
|
}
|
||||||
@@ -503,12 +508,12 @@ bool CdbDebugEngine::startDebugger()
|
|||||||
|
|
||||||
bool CdbDebugEngine::startAttachDebugger(qint64 pid, QString *errorMessage)
|
bool CdbDebugEngine::startAttachDebugger(qint64 pid, QString *errorMessage)
|
||||||
{
|
{
|
||||||
// Need to aatrach invasively, otherwise, no notification signals
|
// Need to attrach invasively, otherwise, no notification signals
|
||||||
// for for CreateProcess/ExitProcess occur.
|
// for for CreateProcess/ExitProcess occur.
|
||||||
const HRESULT hr = m_d->m_cif.debugClient->AttachProcess(NULL, pid,
|
const ULONG flags = DEBUG_ATTACH_INVASIVE_RESUME_PROCESS;
|
||||||
DEBUG_ATTACH_INVASIVE_RESUME_PROCESS);
|
const HRESULT hr = m_d->m_cif.debugClient->AttachProcess(NULL, pid, flags);
|
||||||
if (debugCDB)
|
if (debugCDB)
|
||||||
qDebug() << "Attaching to " << pid << " returns " << hr;
|
qDebug() << "Attaching to " << pid << " returns " << hr << executionStatusString(m_d->m_cif.debugControl);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
*errorMessage = tr("AttachProcess failed for pid %1: %2").arg(pid).arg(msgDebugEngineComResult(hr));
|
*errorMessage = tr("AttachProcess failed for pid %1: %2").arg(pid).arg(msgDebugEngineComResult(hr));
|
||||||
return false;
|
return false;
|
||||||
@@ -560,7 +565,6 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString *
|
|||||||
m_d->m_mode = sm;
|
m_d->m_mode = sm;
|
||||||
}
|
}
|
||||||
m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1318,7 +1322,9 @@ void CdbDebugEngine::slotConsoleStubStarted()
|
|||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
if (startAttachDebugger(appPid, &errorMessage)) {
|
if (startAttachDebugger(appPid, &errorMessage)) {
|
||||||
m_d->m_debuggerManager->m_attachedPID = appPid;
|
m_d->m_debuggerManager->m_attachedPID = appPid;
|
||||||
|
startWatchTimer();
|
||||||
m_d->m_debuggerManagerAccess->notifyInferiorPidChanged(appPid);
|
m_d->m_debuggerManagerAccess->notifyInferiorPidChanged(appPid);
|
||||||
|
m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::critical(m_d->m_debuggerManager->mainWindow(), tr("Debugger Error"), errorMessage);
|
QMessageBox::critical(m_d->m_debuggerManager->mainWindow(), tr("Debugger Error"), errorMessage);
|
||||||
}
|
}
|
||||||
@@ -1343,7 +1349,8 @@ void CdbDebugEnginePrivate::notifyCrashed()
|
|||||||
void CdbDebugEnginePrivate::handleDebugEvent()
|
void CdbDebugEnginePrivate::handleDebugEvent()
|
||||||
{
|
{
|
||||||
if (debugCDB)
|
if (debugCDB)
|
||||||
qDebug() << Q_FUNC_INFO << m_hDebuggeeProcess;
|
qDebug() << Q_FUNC_INFO << '\n' << m_hDebuggeeProcess << m_breakEventMode
|
||||||
|
<< executionStatusString(m_cif.debugControl);
|
||||||
|
|
||||||
// restore mode and do special handling
|
// restore mode and do special handling
|
||||||
const HandleBreakEventMode mode = m_breakEventMode;
|
const HandleBreakEventMode mode = m_breakEventMode;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
#include "breakhandler.h"
|
#include "breakhandler.h"
|
||||||
#include "cdbstacktracecontext.h"
|
#include "cdbstacktracecontext.h"
|
||||||
|
|
||||||
enum { cppExceptionCode = 0xe06d7363 };
|
enum { cppExceptionCode = 0xe06d7363, startupCompleteTrap = 0x406d1388 };
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
@@ -245,6 +245,9 @@ void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str)
|
|||||||
case cppExceptionCode:
|
case cppExceptionCode:
|
||||||
str << "C++ exception";
|
str << "C++ exception";
|
||||||
break;
|
break;
|
||||||
|
case startupCompleteTrap:
|
||||||
|
str << "Startup complete";
|
||||||
|
break;
|
||||||
case EXCEPTION_ACCESS_VIOLATION: {
|
case EXCEPTION_ACCESS_VIOLATION: {
|
||||||
const bool writeOperation = e->ExceptionInformation[0];
|
const bool writeOperation = e->ExceptionInformation[0];
|
||||||
str << (writeOperation ? "write" : "read")
|
str << (writeOperation ? "write" : "read")
|
||||||
@@ -341,7 +344,7 @@ static bool isFatalException(LONG code)
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
case EXCEPTION_BREAKPOINT:
|
case EXCEPTION_BREAKPOINT:
|
||||||
case EXCEPTION_SINGLE_STEP:
|
case EXCEPTION_SINGLE_STEP:
|
||||||
case 0x406d1388: // Mysterious exception at start of application
|
case startupCompleteTrap: // Mysterious exception at start of application
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -362,7 +365,7 @@ STDMETHODIMP CdbDebugEventCallback::Exception(
|
|||||||
}
|
}
|
||||||
const bool fatal = isFatalException(Exception->ExceptionCode);
|
const bool fatal = isFatalException(Exception->ExceptionCode);
|
||||||
if (debugCDB)
|
if (debugCDB)
|
||||||
qDebug() << Q_FUNC_INFO << '\n' << fatal << msg;
|
qDebug() << Q_FUNC_INFO << "\nex=" << Exception->ExceptionCode << " fatal=" << fatal << msg;
|
||||||
m_pEngine->m_d->m_debuggerManagerAccess->showApplicationOutput(msg);
|
m_pEngine->m_d->m_debuggerManagerAccess->showApplicationOutput(msg);
|
||||||
if (fatal)
|
if (fatal)
|
||||||
m_pEngine->m_d->notifyCrashed();
|
m_pEngine->m_d->notifyCrashed();
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ bool CdbDumperHelper::ensureInitialized(QString *errorMessage)
|
|||||||
return false;
|
return false;
|
||||||
case CallLoadNoQtApp:
|
case CallLoadNoQtApp:
|
||||||
m_access->showDebuggerOutput(m_messagePrefix, QCoreApplication::translate("CdbDumperHelper", "The debuggee does not appear to be Qt application."));
|
m_access->showDebuggerOutput(m_messagePrefix, QCoreApplication::translate("CdbDumperHelper", "The debuggee does not appear to be Qt application."));
|
||||||
disable();
|
m_state = Disabled; // No message here
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -367,7 +367,7 @@ bool CdbDumperHelper::ensureInitialized(QString *errorMessage)
|
|||||||
m_access->showDebuggerOutput(m_messagePrefix, m_helper.toString());
|
m_access->showDebuggerOutput(m_messagePrefix, m_helper.toString());
|
||||||
m_state = Initialized;
|
m_state = Initialized;
|
||||||
} else {
|
} else {
|
||||||
disable();
|
m_state = Disabled; // No message here
|
||||||
*errorMessage = QCoreApplication::translate("CdbDumperHelper", "The custom dumper library could not be initialized: %1").arg(*errorMessage);
|
*errorMessage = QCoreApplication::translate("CdbDumperHelper", "The custom dumper library could not be initialized: %1").arg(*errorMessage);
|
||||||
m_access->showDebuggerOutput(m_messagePrefix, *errorMessage);
|
m_access->showDebuggerOutput(m_messagePrefix, *errorMessage);
|
||||||
m_access->showQtDumperLibraryWarning(*errorMessage);
|
m_access->showQtDumperLibraryWarning(*errorMessage);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
|
||||||
const char * const CDB_SETTINGS_ID = QT_TRANSLATE_NOOP("Debugger::Internal::CdbOptionsPageWidget", "CDB");
|
const char * const CDB_SETTINGS_ID = QT_TRANSLATE_NOOP("Debugger::Internal::CdbOptionsPageWidget", "Cdb");
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<string>These options take effect at the next start of Qt Creator.</string>
|
<string>These options take effect at the next start of Qt Creator.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>CDB</string>
|
<string>Cdb</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ SOURCES += \
|
|||||||
gdboptionspage.cpp
|
gdboptionspage.cpp
|
||||||
|
|
||||||
FORMS += attachexternaldialog.ui \
|
FORMS += attachexternaldialog.ui \
|
||||||
attachremotedialog.ui \
|
|
||||||
attachcoredialog.ui \
|
attachcoredialog.ui \
|
||||||
breakbyfunction.ui \
|
breakbyfunction.ui \
|
||||||
breakcondition.ui \
|
breakcondition.ui \
|
||||||
@@ -85,6 +84,7 @@ FORMS += attachexternaldialog.ui \
|
|||||||
gdboptionspage.ui \
|
gdboptionspage.ui \
|
||||||
commonoptionspage.ui \
|
commonoptionspage.ui \
|
||||||
startexternaldialog.ui \
|
startexternaldialog.ui \
|
||||||
|
startremotedialog.ui \
|
||||||
|
|
||||||
RESOURCES += debugger.qrc
|
RESOURCES += debugger.qrc
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
#include "ui_attachcoredialog.h"
|
#include "ui_attachcoredialog.h"
|
||||||
#include "ui_attachexternaldialog.h"
|
#include "ui_attachexternaldialog.h"
|
||||||
#include "ui_attachremotedialog.h"
|
|
||||||
#include "ui_startexternaldialog.h"
|
#include "ui_startexternaldialog.h"
|
||||||
|
#include "ui_startremotedialog.h"
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
# include "dbgwinutils.h"
|
# include "dbgwinutils.h"
|
||||||
@@ -302,37 +302,39 @@ void AttachExternalDialog::pidChanged(const QString &pid)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// AttachRemoteDialog
|
// StartRemoteDialog
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AttachRemoteDialog::AttachRemoteDialog(QWidget *parent)
|
StartRemoteDialog::StartRemoteDialog(QWidget *parent)
|
||||||
: QDialog(parent),
|
: QDialog(parent),
|
||||||
m_ui(new Ui::AttachRemoteDialog)
|
m_ui(new Ui::StartRemoteDialog)
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
||||||
|
m_ui->serverStartScript->setExpectedKind(Core::Utils::PathChooser::File);
|
||||||
|
m_ui->serverStartScript->setPromptDialogTitle(tr("Select Executable"));
|
||||||
|
|
||||||
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachRemoteDialog::~AttachRemoteDialog()
|
StartRemoteDialog::~StartRemoteDialog()
|
||||||
{
|
{
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachRemoteDialog::setRemoteChannel(const QString &channel)
|
void StartRemoteDialog::setRemoteChannel(const QString &channel)
|
||||||
{
|
{
|
||||||
m_ui->channelLineEdit->setText(channel);
|
m_ui->channelLineEdit->setText(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AttachRemoteDialog::remoteChannel() const
|
QString StartRemoteDialog::remoteChannel() const
|
||||||
{
|
{
|
||||||
return m_ui->channelLineEdit->text();
|
return m_ui->channelLineEdit->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachRemoteDialog::setRemoteArchitectures(const QStringList &list)
|
void StartRemoteDialog::setRemoteArchitectures(const QStringList &list)
|
||||||
{
|
{
|
||||||
m_ui->architectureComboBox->clear();
|
m_ui->architectureComboBox->clear();
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
@@ -341,19 +343,28 @@ void AttachRemoteDialog::setRemoteArchitectures(const QStringList &list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachRemoteDialog::setRemoteArchitecture(const QString &arch)
|
void StartRemoteDialog::setRemoteArchitecture(const QString &arch)
|
||||||
{
|
{
|
||||||
int index = m_ui->architectureComboBox->findText(arch);
|
int index = m_ui->architectureComboBox->findText(arch);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
m_ui->architectureComboBox->setCurrentIndex(index);
|
m_ui->architectureComboBox->setCurrentIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AttachRemoteDialog::remoteArchitecture() const
|
QString StartRemoteDialog::remoteArchitecture() const
|
||||||
{
|
{
|
||||||
int index = m_ui->architectureComboBox->currentIndex();
|
int index = m_ui->architectureComboBox->currentIndex();
|
||||||
return m_ui->architectureComboBox->itemText(index);
|
return m_ui->architectureComboBox->itemText(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StartRemoteDialog::setServerStartScript(const QString &scriptName)
|
||||||
|
{
|
||||||
|
m_ui->serverStartScript->setPath(scriptName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString StartRemoteDialog::serverStartScript() const
|
||||||
|
{
|
||||||
|
return m_ui->serverStartScript->path();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ class QPushButton;
|
|||||||
namespace Ui {
|
namespace Ui {
|
||||||
class AttachCoreDialog;
|
class AttachCoreDialog;
|
||||||
class AttachExternalDialog;
|
class AttachExternalDialog;
|
||||||
class AttachRemoteDialog;
|
|
||||||
class StartExternalDialog;
|
class StartExternalDialog;
|
||||||
|
class StartRemoteDialog;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
@@ -101,22 +101,24 @@ private:
|
|||||||
ProcessListFilterModel *m_model;
|
ProcessListFilterModel *m_model;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AttachRemoteDialog : public QDialog
|
class StartRemoteDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AttachRemoteDialog(QWidget *parent);
|
explicit StartRemoteDialog(QWidget *parent);
|
||||||
~AttachRemoteDialog();
|
~StartRemoteDialog();
|
||||||
|
|
||||||
void setRemoteChannel(const QString &host);
|
void setRemoteChannel(const QString &host);
|
||||||
void setRemoteArchitecture(const QString &arch);
|
void setRemoteArchitecture(const QString &arch);
|
||||||
void setRemoteArchitectures(const QStringList &arches);
|
void setRemoteArchitectures(const QStringList &arches);
|
||||||
QString remoteChannel() const;
|
QString remoteChannel() const;
|
||||||
QString remoteArchitecture() const;
|
QString remoteArchitecture() const;
|
||||||
|
void setServerStartScript(const QString &scriptName);
|
||||||
|
QString serverStartScript() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::AttachRemoteDialog *m_ui;
|
Ui::StartRemoteDialog *m_ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StartExternalDialog : public QDialog
|
class StartExternalDialog : public QDialog
|
||||||
|
|||||||
@@ -929,21 +929,24 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
|
|||||||
m_attachedPID = -1;
|
m_attachedPID = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttachRemote: {
|
case StartRemote: {
|
||||||
AttachRemoteDialog dlg(mainWindow());
|
StartRemoteDialog dlg(mainWindow());
|
||||||
QStringList arches;
|
QStringList arches;
|
||||||
arches.append(_("i386:x86-64:intel"));
|
arches.append(_("i386:x86-64:intel"));
|
||||||
dlg.setRemoteArchitectures(arches);
|
dlg.setRemoteArchitectures(arches);
|
||||||
dlg.setRemoteChannel(configValue(_("LastRemoteChannel")).toString());
|
dlg.setRemoteChannel(configValue(_("LastRemoteChannel")).toString());
|
||||||
dlg.setRemoteArchitecture(configValue(_("LastRemoteArchtecture")).toString());
|
dlg.setRemoteArchitecture(configValue(_("LastRemoteArchtecture")).toString());
|
||||||
|
dlg.setServerStartScript(configValue(_("LastServerStartScript")).toString());
|
||||||
if (dlg.exec() != QDialog::Accepted) {
|
if (dlg.exec() != QDialog::Accepted) {
|
||||||
runControl->debuggingFinished();
|
runControl->debuggingFinished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
|
setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
|
||||||
setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
|
setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
|
||||||
|
setConfigValue(_("LastServerStartScript"), dlg.serverStartScript());
|
||||||
m_remoteChannel = dlg.remoteChannel();
|
m_remoteChannel = dlg.remoteChannel();
|
||||||
m_remoteArchitecture = dlg.remoteArchitecture();
|
m_remoteArchitecture = dlg.remoteArchitecture();
|
||||||
|
m_serverStartScript = dlg.serverStartScript();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ enum DebuggerStartMode
|
|||||||
StartExternal, // Start binary found in file system
|
StartExternal, // Start binary found in file system
|
||||||
AttachExternal, // Attach to running process
|
AttachExternal, // Attach to running process
|
||||||
AttachCore, // Attach to a core file
|
AttachCore, // Attach to a core file
|
||||||
AttachRemote // Attach to a remote process
|
StartRemote // Start and attach to a remote process
|
||||||
};
|
};
|
||||||
|
|
||||||
class IDebuggerEngine;
|
class IDebuggerEngine;
|
||||||
@@ -359,8 +359,10 @@ public:
|
|||||||
QString m_dumperLib;
|
QString m_dumperLib;
|
||||||
int m_attachedPID;
|
int m_attachedPID;
|
||||||
bool m_useTerminal;
|
bool m_useTerminal;
|
||||||
|
// for remote debugging
|
||||||
QString m_remoteChannel;
|
QString m_remoteChannel;
|
||||||
QString m_remoteArchitecture;
|
QString m_remoteArchitecture;
|
||||||
|
QString m_serverStartScript;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ public slots:
|
|||||||
DebuggerOutputWindow::DebuggerOutputWindow(QWidget *parent)
|
DebuggerOutputWindow::DebuggerOutputWindow(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Gdb"));
|
setWindowTitle(tr("Debugger"));
|
||||||
|
|
||||||
QSplitter *m_splitter = new QSplitter(Qt::Horizontal, this);
|
QSplitter *m_splitter = new QSplitter(Qt::Horizontal, this);
|
||||||
// mixed input/output
|
// mixed input/output
|
||||||
|
|||||||
@@ -480,10 +480,10 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
|
|||||||
m_attachCoreAction->setText(tr("Attach to Core..."));
|
m_attachCoreAction->setText(tr("Attach to Core..."));
|
||||||
connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
|
connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
|
||||||
|
|
||||||
m_attachRemoteAction = new QAction(this);
|
m_startRemoteAction = new QAction(this);
|
||||||
m_attachRemoteAction->setText(tr("Attach to Running Remote Application..."));
|
m_startRemoteAction->setText(tr("Start and Attach to Remote Application..."));
|
||||||
connect(m_attachRemoteAction, SIGNAL(triggered()),
|
connect(m_startRemoteAction, SIGNAL(triggered()),
|
||||||
this, SLOT(attachRemoteApplication()));
|
this, SLOT(startRemoteApplication()));
|
||||||
|
|
||||||
|
|
||||||
Core::ActionContainer *mdebug =
|
Core::ActionContainer *mdebug =
|
||||||
@@ -502,12 +502,9 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
|
|||||||
Constants::ATTACHCORE, globalcontext);
|
Constants::ATTACHCORE, globalcontext);
|
||||||
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
||||||
|
|
||||||
#if 1
|
cmd = am->registerAction(m_startRemoteAction,
|
||||||
// FIXME: not yet functional
|
|
||||||
cmd = am->registerAction(m_attachRemoteAction,
|
|
||||||
Constants::ATTACHREMOTE, globalcontext);
|
Constants::ATTACHREMOTE, globalcontext);
|
||||||
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
||||||
#endif
|
|
||||||
|
|
||||||
cmd = am->registerAction(m_manager->m_continueAction,
|
cmd = am->registerAction(m_manager->m_continueAction,
|
||||||
ProjectExplorer::Constants::DEBUG, QList<int>() << m_gdbRunningContext);
|
ProjectExplorer::Constants::DEBUG, QList<int>() << m_gdbRunningContext);
|
||||||
@@ -1090,11 +1087,11 @@ void DebuggerPlugin::attachCore()
|
|||||||
runControl->start();
|
runControl->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPlugin::attachRemoteApplication()
|
void DebuggerPlugin::startRemoteApplication()
|
||||||
{
|
{
|
||||||
QSharedPointer<RunConfiguration> rc = activeRunConfiguration();
|
QSharedPointer<RunConfiguration> rc = activeRunConfiguration();
|
||||||
if (RunControl *runControl = m_debuggerRunner
|
if (RunControl *runControl = m_debuggerRunner
|
||||||
->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachRemote))
|
->run(rc, ProjectExplorer::Constants::DEBUGMODE, StartRemote))
|
||||||
runControl->start();
|
runControl->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,9 +98,9 @@ private slots:
|
|||||||
void showSettingsDialog();
|
void showSettingsDialog();
|
||||||
|
|
||||||
void startExternalApplication();
|
void startExternalApplication();
|
||||||
|
void startRemoteApplication();
|
||||||
void attachExternalApplication();
|
void attachExternalApplication();
|
||||||
void attachCore();
|
void attachCore();
|
||||||
void attachRemoteApplication();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readSettings();
|
void readSettings();
|
||||||
@@ -122,9 +122,9 @@ private:
|
|||||||
QAction *m_toggleLockedAction;
|
QAction *m_toggleLockedAction;
|
||||||
|
|
||||||
QAction *m_startExternalAction;
|
QAction *m_startExternalAction;
|
||||||
|
QAction *m_startRemoteAction;
|
||||||
QAction *m_attachExternalAction;
|
QAction *m_attachExternalAction;
|
||||||
QAction *m_attachCoreAction;
|
QAction *m_attachCoreAction;
|
||||||
QAction *m_attachRemoteAction;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
# This is a compile check for the dumpers only. Don't install the library!
|
||||||
|
|
||||||
|
include(../../qworkbenchlibrary.pri)
|
||||||
|
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
TARGET = DebuggingHelper
|
TARGET = DebuggingHelper
|
||||||
CONFIG += shared
|
CONFIG += shared
|
||||||
DESTDIR = ../../../bin
|
DESTDIR = $$IDE_LIBRARY_PATH # /tmp would be better in some respect ...
|
||||||
include(../../qworkbenchlibrary.pri)
|
|
||||||
|
|
||||||
linux-* {
|
linux-* {
|
||||||
CONFIG -= release
|
CONFIG -= release
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ GdbEngine::GdbEngine(DebuggerManager *parent)
|
|||||||
{
|
{
|
||||||
q = parent;
|
q = parent;
|
||||||
qq = parent->engineInterface();
|
qq = parent->engineInterface();
|
||||||
m_stubProc.setDebug(true);
|
m_stubProc.setMode(Core::Utils::ConsoleProcess::Debug);
|
||||||
initializeVariables();
|
initializeVariables();
|
||||||
initializeConnections();
|
initializeConnections();
|
||||||
}
|
}
|
||||||
@@ -131,22 +131,28 @@ GdbEngine::~GdbEngine()
|
|||||||
void GdbEngine::initializeConnections()
|
void GdbEngine::initializeConnections()
|
||||||
{
|
{
|
||||||
// Gdb Process interaction
|
// Gdb Process interaction
|
||||||
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)), this,
|
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
|
||||||
SLOT(gdbProcError(QProcess::ProcessError)));
|
this, SLOT(gdbProcError(QProcess::ProcessError)));
|
||||||
connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()), this,
|
connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
|
||||||
SLOT(readGdbStandardOutput()));
|
this, SLOT(readGdbStandardOutput()));
|
||||||
connect(&m_gdbProc, SIGNAL(readyReadStandardError()), this,
|
connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
|
||||||
SLOT(readGdbStandardError()));
|
this, SLOT(readGdbStandardError()));
|
||||||
connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)), q,
|
connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
|
||||||
SLOT(exitDebugger()));
|
q, SLOT(exitDebugger()));
|
||||||
|
|
||||||
connect(&m_stubProc, SIGNAL(processError(QString)), SLOT(stubError(QString)));
|
connect(&m_stubProc, SIGNAL(processError(QString)),
|
||||||
connect(&m_stubProc, SIGNAL(processStarted()), SLOT(stubStarted()));
|
this, SLOT(stubError(QString)));
|
||||||
connect(&m_stubProc, SIGNAL(wrapperStopped()), q, SLOT(exitDebugger()));
|
connect(&m_stubProc, SIGNAL(processStarted()),
|
||||||
|
this, SLOT(stubStarted()));
|
||||||
|
connect(&m_stubProc, SIGNAL(wrapperStopped()),
|
||||||
|
q, SLOT(exitDebugger()));
|
||||||
|
|
||||||
|
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
|
||||||
|
this, SLOT(uploadProcError(QProcess::ProcessError)));
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
|
connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
|
||||||
SLOT(readDebugeeOutput(QByteArray)));
|
this, SLOT(readDebugeeOutput(QByteArray)));
|
||||||
|
|
||||||
connect(this, SIGNAL(gdbOutputAvailable(QString,QString)),
|
connect(this, SIGNAL(gdbOutputAvailable(QString,QString)),
|
||||||
q, SLOT(showDebuggerOutput(QString,QString)),
|
q, SLOT(showDebuggerOutput(QString,QString)),
|
||||||
@@ -225,6 +231,43 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
|
|||||||
q->exitDebugger();
|
q->exitDebugger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GdbEngine::uploadProcError(QProcess::ProcessError error)
|
||||||
|
{
|
||||||
|
QString msg;
|
||||||
|
switch (error) {
|
||||||
|
case QProcess::FailedToStart:
|
||||||
|
msg = tr("The upload process failed to start. Either the "
|
||||||
|
"invoked script '%1' is missing, or you may have insufficient "
|
||||||
|
"permissions to invoke the program.")
|
||||||
|
.arg(theDebuggerStringSetting(GdbLocation));
|
||||||
|
break;
|
||||||
|
case QProcess::Crashed:
|
||||||
|
msg = tr("The upload process crashed some time after starting "
|
||||||
|
"successfully.");
|
||||||
|
break;
|
||||||
|
case QProcess::Timedout:
|
||||||
|
msg = tr("The last waitFor...() function timed out. "
|
||||||
|
"The state of QProcess is unchanged, and you can try calling "
|
||||||
|
"waitFor...() again.");
|
||||||
|
break;
|
||||||
|
case QProcess::WriteError:
|
||||||
|
msg = tr("An error occurred when attempting to write "
|
||||||
|
"to the upload process. For example, the process may not be running, "
|
||||||
|
"or it may have closed its input channel.");
|
||||||
|
break;
|
||||||
|
case QProcess::ReadError:
|
||||||
|
msg = tr("An error occurred when attempting to read from "
|
||||||
|
"the upload process. For example, the process may not be running.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg = tr("An unknown error in the upload process occurred. "
|
||||||
|
"This is the default return value of error().");
|
||||||
|
}
|
||||||
|
|
||||||
|
q->showStatusMessage(msg);
|
||||||
|
QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void dump(const char *first, const char *middle, const QString & to)
|
static void dump(const char *first, const char *middle, const QString & to)
|
||||||
{
|
{
|
||||||
@@ -535,7 +578,7 @@ void GdbEngine::interruptInferior()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->startMode() == AttachRemote) {
|
if (q->startMode() == StartRemote) {
|
||||||
execCommand(_("-exec-interrupt"));
|
execCommand(_("-exec-interrupt"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -613,7 +656,7 @@ void GdbEngine::flushCommand(GdbCommand &cmd)
|
|||||||
++currentToken();
|
++currentToken();
|
||||||
m_cookieForToken[currentToken()] = cmd;
|
m_cookieForToken[currentToken()] = cmd;
|
||||||
cmd.command = QString::number(currentToken()) + cmd.command;
|
cmd.command = QString::number(currentToken()) + cmd.command;
|
||||||
if (cmd.command.contains(__("%1")))
|
if (cmd.flags & EmbedToken)
|
||||||
cmd.command = cmd.command.arg(currentToken());
|
cmd.command = cmd.command.arg(currentToken());
|
||||||
|
|
||||||
m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
|
m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
|
||||||
@@ -907,6 +950,7 @@ void GdbEngine::handleAqcuiredInferior()
|
|||||||
#endif
|
#endif
|
||||||
if (theDebuggerBoolSetting(ListSourceFiles))
|
if (theDebuggerBoolSetting(ListSourceFiles))
|
||||||
reloadSourceFiles();
|
reloadSourceFiles();
|
||||||
|
|
||||||
tryLoadDebuggingHelpers();
|
tryLoadDebuggingHelpers();
|
||||||
|
|
||||||
#ifndef Q_OS_MAC
|
#ifndef Q_OS_MAC
|
||||||
@@ -1313,7 +1357,7 @@ void GdbEngine::exitDebugger()
|
|||||||
qDebug() << "STATUS ON EXITDEBUGGER: " << q->status());
|
qDebug() << "STATUS ON EXITDEBUGGER: " << q->status());
|
||||||
interruptInferior();
|
interruptInferior();
|
||||||
}
|
}
|
||||||
if (q->startMode() == AttachExternal || q->startMode() == AttachRemote)
|
if (q->startMode() == AttachExternal || q->startMode() == StartRemote)
|
||||||
execCommand(_("detach"));
|
execCommand(_("detach"));
|
||||||
else
|
else
|
||||||
execCommand(_("kill"));
|
execCommand(_("kill"));
|
||||||
@@ -1357,8 +1401,19 @@ bool GdbEngine::startDebugger()
|
|||||||
|
|
||||||
if (q->startMode() == AttachCore || q->startMode() == AttachExternal) {
|
if (q->startMode() == AttachCore || q->startMode() == AttachExternal) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
} else if (q->startMode() == AttachRemote) {
|
} else if (q->startMode() == StartRemote) {
|
||||||
// nothing to do
|
// Start the remote server
|
||||||
|
if (q->m_serverStartScript.isEmpty()) {
|
||||||
|
q->showStatusMessage(_("No server start script given. "
|
||||||
|
"Assuming server runs already."));
|
||||||
|
} else {
|
||||||
|
if (!q->m_workingDir.isEmpty())
|
||||||
|
m_uploadProc.setWorkingDirectory(q->m_workingDir);
|
||||||
|
if (!q->m_environment.isEmpty())
|
||||||
|
m_uploadProc.setEnvironment(q->m_environment);
|
||||||
|
m_uploadProc.start(_("/bin/sh ") + q->m_serverStartScript);
|
||||||
|
m_uploadProc.waitForStarted();
|
||||||
|
}
|
||||||
} else if (q->m_useTerminal) {
|
} else if (q->m_useTerminal) {
|
||||||
m_stubProc.stop(); // We leave the console open, so recycle it now.
|
m_stubProc.stop(); // We leave the console open, so recycle it now.
|
||||||
|
|
||||||
@@ -1495,7 +1550,7 @@ bool GdbEngine::startDebugger()
|
|||||||
execCommand(_("-file-exec-and-symbols ") + fileName);
|
execCommand(_("-file-exec-and-symbols ") + fileName);
|
||||||
execCommand(_("target core ") + coreName, CB(handleTargetCore));
|
execCommand(_("target core ") + coreName, CB(handleTargetCore));
|
||||||
qq->breakHandler()->removeAllBreakpoints();
|
qq->breakHandler()->removeAllBreakpoints();
|
||||||
} else if (q->startMode() == AttachRemote) {
|
} else if (q->startMode() == StartRemote) {
|
||||||
execCommand(_("set architecture %1").arg(q->m_remoteArchitecture));
|
execCommand(_("set architecture %1").arg(q->m_remoteArchitecture));
|
||||||
qq->breakHandler()->setAllPending();
|
qq->breakHandler()->setAllPending();
|
||||||
//QFileInfo fi(q->m_executable);
|
//QFileInfo fi(q->m_executable);
|
||||||
@@ -2795,7 +2850,7 @@ bool GdbEngine::hasDebuggingHelperForType(const QString &type) const
|
|||||||
if (!theDebuggerBoolSetting(UseDebuggingHelpers))
|
if (!theDebuggerBoolSetting(UseDebuggingHelpers))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (q->startMode() == AttachCore) {
|
if (!startModeAllowsDumpers()) {
|
||||||
// "call" is not possible in gdb when looking at core files
|
// "call" is not possible in gdb when looking at core files
|
||||||
return type == __("QString") || type.endsWith(__("::QString"))
|
return type == __("QString") || type.endsWith(__("::QString"))
|
||||||
|| type == __("QStringList") || type.endsWith(__("::QStringList"));
|
|| type == __("QStringList") || type.endsWith(__("::QStringList"));
|
||||||
@@ -2834,7 +2889,7 @@ void GdbEngine::runDirectDebuggingHelper(const WatchData &data, bool dumpChildre
|
|||||||
|
|
||||||
void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
|
void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
|
||||||
{
|
{
|
||||||
if (q->startMode() == AttachCore) {
|
if (!startModeAllowsDumpers()) {
|
||||||
runDirectDebuggingHelper(data0, dumpChildren);
|
runDirectDebuggingHelper(data0, dumpChildren);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2867,7 +2922,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
|
|||||||
|
|
||||||
QVariant var;
|
QVariant var;
|
||||||
var.setValue(data);
|
var.setValue(data);
|
||||||
execCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue1), var);
|
execCommand(cmd, WatchUpdate | EmbedToken, CB(handleDebuggingHelperValue1), var);
|
||||||
|
|
||||||
q->showStatusMessage(
|
q->showStatusMessage(
|
||||||
tr("Retrieving data for watch view (%1 requests pending)...")
|
tr("Retrieving data for watch view (%1 requests pending)...")
|
||||||
@@ -3832,6 +3887,9 @@ void GdbEngine::tryLoadDebuggingHelpers()
|
|||||||
if (m_debuggingHelperState != DebuggingHelperUninitialized)
|
if (m_debuggingHelperState != DebuggingHelperUninitialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!startModeAllowsDumpers())
|
||||||
|
return;
|
||||||
|
|
||||||
PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS");
|
PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS");
|
||||||
m_debuggingHelperState = DebuggingHelperUnavailable;
|
m_debuggingHelperState = DebuggingHelperUnavailable;
|
||||||
if (!qq->qtDumperLibraryEnabled())
|
if (!qq->qtDumperLibraryEnabled())
|
||||||
@@ -3875,15 +3933,24 @@ void GdbEngine::tryLoadDebuggingHelpers()
|
|||||||
execCommand(_("sharedlibrary ") + dotEscape(lib));
|
execCommand(_("sharedlibrary ") + dotEscape(lib));
|
||||||
#endif
|
#endif
|
||||||
// retreive list of dumpable classes
|
// retreive list of dumpable classes
|
||||||
execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"));
|
execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"), EmbedToken);
|
||||||
execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
|
execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::recheckDebuggingHelperAvailability()
|
void GdbEngine::recheckDebuggingHelperAvailability()
|
||||||
{
|
{
|
||||||
// retreive list of dumpable classes
|
if (startModeAllowsDumpers()) {
|
||||||
execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"));
|
// retreive list of dumpable classes
|
||||||
execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
|
execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"), EmbedToken);
|
||||||
|
execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GdbEngine::startModeAllowsDumpers() const
|
||||||
|
{
|
||||||
|
return q->startMode() == StartInternal
|
||||||
|
|| q->startMode() == StartExternal
|
||||||
|
|| q->startMode() == AttachExternal;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts)
|
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts)
|
||||||
|
|||||||
@@ -147,7 +147,8 @@ public: // otherwise the Qt flag macros are unhappy
|
|||||||
NeedsStop = 1,
|
NeedsStop = 1,
|
||||||
Discardable = 2,
|
Discardable = 2,
|
||||||
RebuildModel = 4,
|
RebuildModel = 4,
|
||||||
WatchUpdate = Discardable|RebuildModel
|
WatchUpdate = Discardable|RebuildModel,
|
||||||
|
EmbedToken = 8
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
|
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
|
||||||
private:
|
private:
|
||||||
@@ -191,6 +192,7 @@ private slots:
|
|||||||
void readDebugeeOutput(const QByteArray &data);
|
void readDebugeeOutput(const QByteArray &data);
|
||||||
void stubStarted();
|
void stubStarted();
|
||||||
void stubError(const QString &msg);
|
void stubError(const QString &msg);
|
||||||
|
void uploadProcError(QProcess::ProcessError error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int terminationIndex(const QByteArray &buffer, int &length);
|
int terminationIndex(const QByteArray &buffer, int &length);
|
||||||
@@ -226,6 +228,7 @@ private:
|
|||||||
QByteArray m_inbuffer;
|
QByteArray m_inbuffer;
|
||||||
|
|
||||||
QProcess m_gdbProc;
|
QProcess m_gdbProc;
|
||||||
|
QProcess m_uploadProc;
|
||||||
|
|
||||||
Core::Utils::ConsoleProcess m_stubProc;
|
Core::Utils::ConsoleProcess m_stubProc;
|
||||||
|
|
||||||
@@ -354,6 +357,8 @@ private:
|
|||||||
const WatchData &parent);
|
const WatchData &parent);
|
||||||
void setWatchDataType(WatchData &data, const GdbMi &mi);
|
void setWatchDataType(WatchData &data, const GdbMi &mi);
|
||||||
void setLocals(const QList<GdbMi> &locals);
|
void setLocals(const QList<GdbMi> &locals);
|
||||||
|
|
||||||
|
bool startModeAllowsDumpers() const;
|
||||||
|
|
||||||
QString m_editedData;
|
QString m_editedData;
|
||||||
int m_pendingRequests;
|
int m_pendingRequests;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>AttachRemoteDialog</class>
|
<class>StartRemoteDialog</class>
|
||||||
<widget class="QDialog" name="AttachRemoteDialog">
|
<widget class="QDialog" name="StartRemoteDialog">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
@@ -49,6 +49,16 @@
|
|||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QComboBox" name="architectureComboBox"/>
|
<widget class="QComboBox" name="architectureComboBox"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="serverStartScriptLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Server start script</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="Core::Utils::PathChooser" name="serverStartScript" native="true"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -56,6 +56,12 @@
|
|||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
#ifdef __GNUC__ // MinGW does not have a complete windows.h
|
||||||
|
|
||||||
|
typedef DWORD (__stdcall *PTHREAD_START_ROUTINE) (LPVOID lpThreadParameter);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
enum { debug = 0 };
|
enum { debug = 0 };
|
||||||
|
|
||||||
static QString msgFuncFailed(const char *f, unsigned long error)
|
static QString msgFuncFailed(const char *f, unsigned long error)
|
||||||
@@ -68,7 +74,7 @@ template <class SymbolType>
|
|||||||
inline bool resolveSymbol(const char *libraryName, HMODULE libraryHandle, const char *symbolName, SymbolType *s, QString *errorMessage)
|
inline bool resolveSymbol(const char *libraryName, HMODULE libraryHandle, const char *symbolName, SymbolType *s, QString *errorMessage)
|
||||||
{
|
{
|
||||||
*s = 0;
|
*s = 0;
|
||||||
void *vs = ::GetProcAddress(libraryHandle, symbolName);
|
FARPROC WINAPI vs = ::GetProcAddress(libraryHandle, symbolName);
|
||||||
if (vs == 0) {
|
if (vs == 0) {
|
||||||
*errorMessage = QString::fromLatin1("Unable to resolve '%2' in '%1'.").arg(QString::fromAscii(symbolName), QString::fromAscii(libraryName));
|
*errorMessage = QString::fromLatin1("Unable to resolve '%2' in '%1'.").arg(QString::fromAscii(symbolName), QString::fromAscii(libraryName));
|
||||||
return false;
|
return false;
|
||||||
@@ -158,29 +164,29 @@ bool SharedLibraryInjector::hasLoaded(const QString &modulePath)
|
|||||||
|
|
||||||
QString SharedLibraryInjector::findModule(const QString &moduleName)
|
QString SharedLibraryInjector::findModule(const QString &moduleName)
|
||||||
{
|
{
|
||||||
const TCHAR *moduleNameC = moduleName.utf16();
|
const TCHAR *moduleNameC = reinterpret_cast<const TCHAR*>(moduleName.utf16());
|
||||||
if (GetFileAttributesW(moduleNameC) != INVALID_FILE_ATTRIBUTES)
|
if (GetFileAttributesW(moduleNameC) != INVALID_FILE_ATTRIBUTES)
|
||||||
return moduleName;
|
return moduleName;
|
||||||
|
|
||||||
TCHAR testpathC[MAX_PATH];
|
TCHAR testpathC[MAX_PATH];
|
||||||
// Check application path first
|
// Check application path first
|
||||||
GetModuleFileNameW(NULL, testpathC, MAX_PATH);
|
GetModuleFileNameW(NULL, testpathC, MAX_PATH);
|
||||||
QString testPath = QString::fromUtf16(testpathC);
|
QString testPath = QString::fromUtf16(reinterpret_cast<unsigned short*>(testpathC));
|
||||||
const int lastSlash = testPath.lastIndexOf(QLatin1Char('\\'));
|
const int lastSlash = testPath.lastIndexOf(QLatin1Char('\\'));
|
||||||
if (lastSlash != -1)
|
if (lastSlash != -1)
|
||||||
testPath.truncate(lastSlash + 1);
|
testPath.truncate(lastSlash + 1);
|
||||||
testPath += moduleName;
|
testPath += moduleName;
|
||||||
if (GetFileAttributesW(testPath.utf16()) != INVALID_FILE_ATTRIBUTES)
|
if (GetFileAttributesW(reinterpret_cast<const TCHAR*>(testPath.utf16())) != INVALID_FILE_ATTRIBUTES)
|
||||||
return testPath;
|
return testPath;
|
||||||
// Path Search
|
// Path Search
|
||||||
if (SearchPathW(NULL, moduleName.utf16(), NULL, sizeof(testpathC)/2, testpathC, NULL))
|
if (SearchPathW(NULL, reinterpret_cast<const TCHAR*>(moduleName.utf16()), NULL, sizeof(testpathC)/2, testpathC, NULL))
|
||||||
return QString::fromUtf16(testpathC);
|
return QString::fromUtf16(reinterpret_cast<unsigned short*>(testpathC));
|
||||||
// Last chance, if the module has already been loaded in this process, then use that path
|
// Last chance, if the module has already been loaded in this process, then use that path
|
||||||
const HMODULE loadedModule = GetModuleHandleW(moduleName.utf16());
|
const HMODULE loadedModule = GetModuleHandleW(reinterpret_cast<const TCHAR*>(moduleName.utf16()));
|
||||||
if (loadedModule) {
|
if (loadedModule) {
|
||||||
GetModuleFileNameW(loadedModule, testpathC, sizeof(testpathC));
|
GetModuleFileNameW(loadedModule, testpathC, sizeof(testpathC));
|
||||||
if (GetFileAttributes(testpathC) != INVALID_FILE_ATTRIBUTES)
|
if (GetFileAttributes(testpathC) != INVALID_FILE_ATTRIBUTES)
|
||||||
return QString::fromUtf16(testpathC);
|
return QString::fromUtf16(reinterpret_cast<unsigned short*>(testpathC));
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
@@ -188,13 +194,13 @@ QString SharedLibraryInjector::findModule(const QString &moduleName)
|
|||||||
unsigned long SharedLibraryInjector::getModuleEntryPoint(const QString &moduleName)
|
unsigned long SharedLibraryInjector::getModuleEntryPoint(const QString &moduleName)
|
||||||
{
|
{
|
||||||
// If file doesn't exist, just treat it like we cannot figure out the entry point
|
// If file doesn't exist, just treat it like we cannot figure out the entry point
|
||||||
if (moduleName.isEmpty() || GetFileAttributesW(moduleName.utf16()) == INVALID_FILE_ATTRIBUTES)
|
if (moduleName.isEmpty() || GetFileAttributesW(reinterpret_cast<const TCHAR*>(moduleName.utf16())) == INVALID_FILE_ATTRIBUTES)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Read the first 1K of data from the file
|
// Read the first 1K of data from the file
|
||||||
unsigned char peData[1024];
|
unsigned char peData[1024];
|
||||||
unsigned long peDataSize = 0;
|
unsigned long peDataSize = 0;
|
||||||
const HANDLE hFile = CreateFileW(moduleName.utf16(), FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
const HANDLE hFile = CreateFileW(reinterpret_cast<const WCHAR*>(moduleName.utf16()), FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
if (hFile == INVALID_HANDLE_VALUE
|
if (hFile == INVALID_HANDLE_VALUE
|
||||||
|| !ReadFile(hFile, peData, sizeof(peData), &peDataSize, NULL))
|
|| !ReadFile(hFile, peData, sizeof(peData), &peDataSize, NULL))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -236,7 +242,7 @@ bool SharedLibraryInjector::escalatePrivileges(QString *errorMessage)
|
|||||||
Debug_Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // set to enable privilege
|
Debug_Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // set to enable privilege
|
||||||
Debug_Privileges.PrivilegeCount = 1; // working with only 1
|
Debug_Privileges.PrivilegeCount = 1; // working with only 1
|
||||||
|
|
||||||
if (!OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
|
||||||
*errorMessage = msgFuncFailed("OpenProcessToken", GetLastError());
|
*errorMessage = msgFuncFailed("OpenProcessToken", GetLastError());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -289,8 +295,8 @@ bool SharedLibraryInjector::doStubInjection(unsigned long pid,
|
|||||||
|
|
||||||
if (!escalatePrivileges(errorMessage))
|
if (!escalatePrivileges(errorMessage))
|
||||||
return false;
|
return false;
|
||||||
|
// MinGW lacks OpenThread() and the advapi.lib as of 6.5.2009
|
||||||
#if (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
|
#if (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) || defined(__GNUC__)
|
||||||
*errorMessage = QLatin1String("Not implemented for this architecture.");
|
*errorMessage = QLatin1String("Not implemented for this architecture.");
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
@@ -462,7 +468,7 @@ HMODULE SharedLibraryInjector::findModuleHandle(const QString &modulePath, QStri
|
|||||||
for (unsigned i = 0; i < count; i++) {
|
for (unsigned i = 0; i < count; i++) {
|
||||||
TCHAR szModName[MAX_PATH];
|
TCHAR szModName[MAX_PATH];
|
||||||
if (m_pfnGetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName))) {
|
if (m_pfnGetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName))) {
|
||||||
if (QString::fromUtf16(szModName) == modulePath) {
|
if (QString::fromUtf16(reinterpret_cast<const unsigned short *>(szModName)) == modulePath) {
|
||||||
::FreeLibrary(m_hModPSAPI);
|
::FreeLibrary(m_hModPSAPI);
|
||||||
::CloseHandle(hProcess);
|
::CloseHandle(hProcess);
|
||||||
return hMods[i];
|
return hMods[i];
|
||||||
|
|||||||
@@ -7,5 +7,8 @@ HEADERS += $$PWD/peutils.h \
|
|||||||
$$PWD/dbgwinutils.h \
|
$$PWD/dbgwinutils.h \
|
||||||
$$PWD/sharedlibraryinjector.h
|
$$PWD/sharedlibraryinjector.h
|
||||||
|
|
||||||
# For the Privilege manipulation functions in sharedlibraryinjector.cpp
|
contains(QMAKE_CXX, cl) {
|
||||||
LIBS += advapi32.lib
|
# For the Privilege manipulation functions in sharedlibraryinjector.cpp.
|
||||||
|
# Not required for MinGW.
|
||||||
|
LIBS += advapi32.lib
|
||||||
|
}
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ void FindToolWindow::writeSettings()
|
|||||||
{
|
{
|
||||||
QSettings *settings = Core::ICore::instance()->settings();
|
QSettings *settings = Core::ICore::instance()->settings();
|
||||||
settings->beginGroup("Find");
|
settings->beginGroup("Find");
|
||||||
settings->setValue("CurrentFilter", m_currentFilter ? 0 : m_currentFilter->id());
|
settings->setValue("CurrentFilter", m_currentFilter ? m_currentFilter->id() : 0);
|
||||||
foreach (IFindFilter *filter, m_filters)
|
foreach (IFindFilter *filter, m_filters)
|
||||||
filter->writeSettings(settings);
|
filter->writeSettings(settings);
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|||||||
@@ -131,8 +131,6 @@ ProjectWindow::~ProjectWindow()
|
|||||||
|
|
||||||
void ProjectWindow::restoreStatus()
|
void ProjectWindow::restoreStatus()
|
||||||
{
|
{
|
||||||
m_panelsTabWidget->setFocus();
|
|
||||||
|
|
||||||
if (!m_treeWidget->currentItem() && m_treeWidget->topLevelItemCount()) {
|
if (!m_treeWidget->currentItem() && m_treeWidget->topLevelItemCount()) {
|
||||||
m_treeWidget->setCurrentItem(m_treeWidget->topLevelItem(0), 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
m_treeWidget->setCurrentItem(m_treeWidget->topLevelItem(0), 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
IDE_BUILD_TREE = $$OUT_PWD/../../..
|
|
||||||
include(../qtcreator.pri)
|
include(../qtcreator.pri)
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
isEmpty(IDE_BUILD_TREE) {
|
|
||||||
IDE_BUILD_TREE = $$OUT_PWD/../../..
|
|
||||||
}
|
|
||||||
include(../qtcreator.pri)
|
include(../qtcreator.pri)
|
||||||
|
|
||||||
isEmpty(PROVIDER) {
|
isEmpty(PROVIDER) {
|
||||||
@@ -17,25 +14,17 @@ isEmpty(TARGET) {
|
|||||||
error("qworkbenchplugin.pri: You must provide a TARGET")
|
error("qworkbenchplugin.pri: You must provide a TARGET")
|
||||||
}
|
}
|
||||||
|
|
||||||
# Copy the pluginspec file to the library directory.
|
PLUGINSPECS = $${_PRO_FILE_PWD_}/$${TARGET}.pluginspec
|
||||||
# Note: On Windows/MinGW with some sh.exe in the path,
|
copy2build.input = PLUGINSPECS
|
||||||
# QMAKE_COPY is some cp command that does not understand
|
copy2build.output = $$DESTDIR/${QMAKE_FUNC_FILE_IN_stripSrcDir}
|
||||||
# "\". Force the standard windows copy.
|
isEmpty(vcproj):copy2build.variable_out = PRE_TARGETDEPS
|
||||||
COPYDEST = $${DESTDIR}
|
copy2build.commands = $$QMAKE_COPY \"${QMAKE_FILE_IN}\" \"${QMAKE_FILE_OUT}\"
|
||||||
COPYSRC = $${_PRO_FILE_PWD_}/$${TARGET}.pluginspec
|
copy2build.name = COPY ${QMAKE_FILE_IN}
|
||||||
|
copy2build.CONFIG += no_link
|
||||||
|
QMAKE_EXTRA_COMPILERS += copy2build
|
||||||
|
|
||||||
TARGET = $$qtLibraryTarget($$TARGET)
|
TARGET = $$qtLibraryTarget($$TARGET)
|
||||||
|
|
||||||
win32 {
|
|
||||||
COPYDEST ~= s|/+|\|
|
|
||||||
COPYSRC ~= s|/+|\|
|
|
||||||
COPY_CMD=xcopy /y
|
|
||||||
} else {
|
|
||||||
COPY_CMD=$${QMAKE_COPY}
|
|
||||||
}
|
|
||||||
|
|
||||||
QMAKE_POST_LINK += $${COPY_CMD} $${COPYSRC} $${COPYDEST}
|
|
||||||
|
|
||||||
macx {
|
macx {
|
||||||
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../PlugIns/$${PROVIDER}/
|
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../PlugIns/$${PROVIDER}/
|
||||||
} else:linux-* {
|
} else:linux-* {
|
||||||
|
|||||||
15
tests/manual/fakevim/runremotely.sh
Executable file
15
tests/manual/fakevim/runremotely.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
account=berlin@hd
|
||||||
|
sourcedir=/data5/dev/creator/tests/manual/fakevim/
|
||||||
|
exename=fakevim
|
||||||
|
targetdir=/tmp/run-${exename}
|
||||||
|
|
||||||
|
executable=${sourcedir}/${exename}
|
||||||
|
qtlibs=`ldd ${executable} | grep libQt | sed -e 's/^.*=> \(.*\) (.*)$/\1/'`
|
||||||
|
|
||||||
|
ssh ${account} "mkdir -p ${targetdir}"
|
||||||
|
scp ${executable} ${qtlibs} ${account}:${targetdir}
|
||||||
|
ssh ${account} "chrpath -r ${targetdir} ${targetdir}/*"
|
||||||
|
ssh ${account} "gdbserver localhost:5555 ${targetdir}/${exename}"
|
||||||
|
ssh ${account} "rm ${targetdir}/* ; rmdir ${targetdir}"
|
||||||
|
|
||||||
Reference in New Issue
Block a user