Merge commit 'origin/1.3'
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 58 KiB |
BIN
doc/images/qtcreator-qt4-s60sdks.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
doc/images/qtcreator-symbian-add-buildconfiguration.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/qtcreator-symbian-add-runconfiguration.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
doc/images/qtcreator-symbian-change-buildconfiguration.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
doc/images/qtcreator-symbian-change-runconfiguration.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
doc/images/qtcreator-symbian-details-runconfiguration.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
@@ -19,30 +19,6 @@
|
||||
{qt-creator-request@trolltech.com}. For more information on Qt mailing
|
||||
lists, visit \l{http://lists.trolltech.com}{http://lists.trolltech.com}.
|
||||
|
||||
Qt Creator includes a wide range of useful features. Among them are:
|
||||
\list 1
|
||||
\o \bold{Smart Code Editor}: The code editor provides syntax
|
||||
highlighting as well as code completion.
|
||||
\o \bold{Qt4 Project Generating Wizard}: This wizard allows the user
|
||||
to generate a project for a console application, a GUI application,
|
||||
or a C++ library.
|
||||
\o \bold{Qt Help Integration}: Qt's entire documentation can be
|
||||
accessed easily by clicking on the \gui{Help} button.
|
||||
\o \bold{Qt Designer Integration}: User interface forms can be designed
|
||||
within Qt Creator. Simply double-click on a \c{.ui} file within the
|
||||
\gui{Project Explorer} to launch the integration.
|
||||
\o \bold{Locator}: A powerful navigation tool that lets the user locate
|
||||
files and classes using minimal keystrokes.
|
||||
\o \bold{Support for qmake's .pro file format}: The project's \c{.pro}
|
||||
file is used as a project description file.
|
||||
\o \bold{Debugging Interface}: Applications can be debugged
|
||||
within Qt Creator using a graphical frontend to the GNU symbolic
|
||||
debugger (GDB) and the Microsoft Console Debugger (CDB).
|
||||
\endlist
|
||||
|
||||
To learn more about the Qt Creator, click on one of the links below:
|
||||
|
||||
|
||||
\raw HTML
|
||||
<img border="0" style="float:right;" src="images/qtcreator-screenshots.png" />
|
||||
\endraw
|
||||
@@ -60,6 +36,7 @@
|
||||
\o \l{Debugging with Qt Creator}
|
||||
\o \l{CMake Support in Qt Creator}
|
||||
\o \l{Support for Generic Projects in Qt Creator}
|
||||
\o \l{Development of Qt for Symbian Based Applications}
|
||||
\o \l{Handling External Libraries}
|
||||
\o \l{Tips and Tricks}
|
||||
\o \l{Keyboard Shortcuts}
|
||||
@@ -462,7 +439,7 @@
|
||||
\i \image qtcreator-qt4-qtversions-win-symbian.png
|
||||
If you are using Qt for Symbian and your S60 SDK is registered
|
||||
with \c devices.exe, Qt Creator will detect the Qt version automatically.
|
||||
If this does not work, point Creator to \c qmake.exe of Qt for Symbian.
|
||||
A known issue is that you cannot just point Creator to \c qmake.exe of Qt for Symbian.
|
||||
You can add the path to the Metrowerks Compiler (\gui {MWC Directory})
|
||||
if you want to use to build for the emulator. This requires Carbide 2.0
|
||||
to be installed. the MWC directory should then point to the directory
|
||||
@@ -1487,7 +1464,7 @@
|
||||
specified in the \c CMake project file.
|
||||
|
||||
Known issues for the current version can be found
|
||||
\l{Known Issues of Version 1.1.0}{here}.
|
||||
\l{Known Issues of Version 1.2.93}{here}.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1495,7 +1472,7 @@
|
||||
\contentspage index.html
|
||||
\previouspage creator-cmake-support.html
|
||||
\page creator-generic-projects.html
|
||||
\nextpage creator-external-library-handling.html
|
||||
\nextpage creator-qt-for-symbian.html
|
||||
|
||||
\title Support for Generic Projects in Qt Creator
|
||||
|
||||
@@ -1554,10 +1531,151 @@
|
||||
\c{$BUILDDIR} which should work fine.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\contentspage index.html
|
||||
\previouspage creator-generic-projects.html
|
||||
\page creator-qt-for-symbian.html
|
||||
\nextpage creator-external-library-handling.html
|
||||
|
||||
\title Development of Qt for Symbian Based Applications
|
||||
|
||||
Qt Creator 1.3 comes with preliminary support for development of
|
||||
applications using Qt for the Symbian Platform.
|
||||
|
||||
\e{Note that this is highly experimental, and not intended for production use.
|
||||
The primary aim is to allow Symbian developers to familiarize themselves with Qt Creator
|
||||
and provide feedback that will help us improve Symbian support in future versions of
|
||||
Qt Creator.}
|
||||
|
||||
Please provide us with feedback, using the mailing list or IRC, as described on the
|
||||
\l{http://qt.gitorious.org/qt-creator/pages/Home}{Qt Creator Development Wiki}.
|
||||
|
||||
\section2 Getting Started
|
||||
|
||||
You need the following software installed on your PC.
|
||||
Only Windows development is supported.
|
||||
|
||||
\list
|
||||
\o \l{http://www.forum.nokia.com/main/resources/tools_and_sdks/S60SDK/}
|
||||
{S60 Platform SDK 3rd Edition FP1 or higher}
|
||||
\o \l{http://www.forum.nokia.com/main/resources/technologies/openc_cpp/}
|
||||
{Open C/C++ v1.6.0 or higher.} Install this to all S60 SDKs you plan to use Qt with.
|
||||
This is included in the Qt for Symbian binary installers.
|
||||
\o Either the GCCE Arm Toolchain that is included in the S60 Platform SDKs, or
|
||||
RVCT 2.2 [build 686] or later (which is not available free of charge).
|
||||
Your environment needs to find the compiler in the PATH.
|
||||
\o Qt for Symbian 4.6.0, installed into the S60 SDKs you want to use.
|
||||
|
||||
\endlist
|
||||
|
||||
And for deploying and running applications on the device
|
||||
\list
|
||||
\o The Nokia USB drivers that come e.g. with PC Suite.
|
||||
\o The \l{http://tools.ext.nokia.com/trk/}{App TRK} application for your device.
|
||||
\endlist
|
||||
|
||||
Running Qt based applications on real devices requires the following packages to be installed on
|
||||
your device. The packages can be found in the S60 SDK where you installed Open C/C++:
|
||||
\list
|
||||
\o nokia_plugin\\openc\\s60opencsis\\pips_s60_\<version\>.sis
|
||||
\o nokia_plugin\\openc\\s60opencsis\\openc_ssl_s60_\<version\>.sis
|
||||
\o nokia_plugin\\opencpp\\s60opencppsis\\stdcpp_s60_\<version\>.sis
|
||||
\endlist
|
||||
|
||||
If you want to run your applications in the Symbian Emulator, you also need to install
|
||||
Carbide.c++ v2.0.0 or higher.
|
||||
|
||||
\section2 Setting up Qt Creator
|
||||
|
||||
When you run Qt Creator after installing the S60 Platform SDK and Qt for Symbian,
|
||||
the installed SDKs and their corresponding Qt versions are automatically detected.
|
||||
For each detected S60 SDK with Qt, a special entry is made in the Qt Version Management settings
|
||||
\gui{Tools -> Options... -> Qt4 -> Qt Versions}.
|
||||
|
||||
\e{Note that you must use one of these special Qt version entries for building projects
|
||||
for the emulator or devices. You can not just point Qt Creator to the qmake executable
|
||||
like you would do for a desktop version of Qt.}
|
||||
|
||||
\image qtcreator-qt4-qtversions-win-symbian.png
|
||||
|
||||
If you want to run your applications in the Symbian Emulator, you need to point Qt Creator
|
||||
to the Metrowerks Compiler that you want to use, by setting the \gui{MWC Directory}
|
||||
of the Qt version to the corresponding Carbide.c++ installation directory.
|
||||
|
||||
You can check what S60 SDKs and corresponding Qt versions are found in the
|
||||
\gui{Tools -> Options... -> Qt4 -> S60 SDKs} preference page.
|
||||
At the moment it is not possible to override the autodetected settings.
|
||||
|
||||
\image qtcreator-qt4-s60sdks.png
|
||||
|
||||
\section2 Setting up Your Project
|
||||
|
||||
After installing all the prerequisites and checking the setup in Qt Creator as described
|
||||
above, you need to make some settings for your project.
|
||||
\e{Note that the only supported build system for Qt for Symbian applications in Qt Creator
|
||||
is qmake.}
|
||||
|
||||
\section3 Building your Project
|
||||
|
||||
Before you can build your project for the Symbian Platform you need to create build
|
||||
configurations for it.
|
||||
Open \gui{Projects mode} and make sure that your project is selected for editing in
|
||||
\gui{Edit Project Settings for Project ...}. Add debug and release build configurations
|
||||
for the Symbian target by selecting the corresponding Qt version from the build configuration
|
||||
\gui{Add} menu.
|
||||
|
||||
\image qtcreator-symbian-add-buildconfiguration.png
|
||||
|
||||
The created build configurations default to using the GCCE tool chain. If you want to build
|
||||
for the device using RVCT, or for the Symbian Emulator using WINSCW, change the tool chain in
|
||||
the \gui{General} section of the build configuration settings (press the \gui{Show Details}
|
||||
button first).
|
||||
|
||||
Now you can switch to building your project for the device by selecting one of the
|
||||
new build configurations as the active configuration at the top of \gui{Projects mode}.
|
||||
|
||||
\image qtcreator-symbian-change-buildconfiguration.png
|
||||
|
||||
\section3 Running your Project on the Device
|
||||
|
||||
Similar to the build configuration setup for your project you need to create a run configuration
|
||||
for running your project on a Symbian device. Add a new run configuration in \gui{Projects mode}
|
||||
via \gui{Run Settings}, \gui{Add -> YourApplication on Symbian Device} button.
|
||||
|
||||
\image qtcreator-symbian-add-runconfiguration.png
|
||||
|
||||
\image qtcreator-symbian-details-runconfiguration.png
|
||||
|
||||
In the details of the run configuration you can specify a certificate to use, and
|
||||
select one of the devices that you have currently attached to your computer.
|
||||
The only connection mode supported at the moment is USB in \e{PC Suite} mode.
|
||||
For actually running your application on the device, you need to set the device run configuration
|
||||
as the active configuration at the top of \gui{Projects mode}.
|
||||
Start the \gui{App TRK} application on your device and press the run button to create
|
||||
a package for your application, deploy, install and run it automatically on your device.
|
||||
|
||||
\image qtcreator-symbian-change-runconfiguration.png
|
||||
|
||||
When something goes wrong check the following things:
|
||||
\list
|
||||
\o Is the device run configuration selected as the active run configuration?
|
||||
\o Did you build your application with one of the special Qt versions created for the
|
||||
S60 SDKs?
|
||||
\o Is the device connected via USB in \e{PC Suite} mode?
|
||||
\o Is App TRK running on the device, using the USB connection, and does it have status
|
||||
\e{connected}?
|
||||
\o Is your device detected and selected in the run configuration details?
|
||||
\endlist
|
||||
|
||||
If neither of this helps to solve your problem, search the qt-creator@trolltech.com
|
||||
mailinglist archives or provide feedback to us via the methods described on the
|
||||
\l{http://qt.gitorious.org/qt-creator/pages/Home}{Qt Creator Development Wiki}.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\contentspage index.html
|
||||
\previouspage creator-qt-for-symbian.html
|
||||
\page creator-external-library-handling.html
|
||||
\nextpage creator-tips.html
|
||||
|
||||
@@ -1840,6 +1958,20 @@
|
||||
|
||||
\section1 Known Issues of Version 1.3.80
|
||||
|
||||
\list
|
||||
\o Debugging Helper do not work while doing On Device Debugging.
|
||||
|
||||
\o QML Preview (Run Project) only works if build against Qt with
|
||||
Declarative UI.
|
||||
|
||||
\o Setting breakpoints in code that is compiled into the binary more
|
||||
than once does not work.
|
||||
|
||||
\endlist
|
||||
|
||||
|
||||
\section1 Known Issues of Version 1.2.0 and 1.2.1
|
||||
|
||||
\list
|
||||
\o Gdb on Windows may not work if the 'Embassy \reg Security Center' software
|
||||
by 'Wave \reg Systems' is installed and active (causing crashes in \c{vxvault.dll)}).
|
||||
|
||||
@@ -3561,8 +3561,7 @@ void *watchPoint(int x, int y)
|
||||
// Helpers to write out common expression values for CDB
|
||||
#ifdef Q_CC_MSVC
|
||||
// Offsets of a map node value which looks like
|
||||
// "(size_t)&(('QMapNode<QString,QString >'*)0)->value")" in gdb syntax
|
||||
|
||||
// "(size_t)&(((QMapNode<int,int> *)0)->value)-0"
|
||||
template <class Key, class Value>
|
||||
inline QDumper & putQMapNodeOffsetExpression(const char *keyType,
|
||||
const char *valueType,
|
||||
@@ -3570,13 +3569,13 @@ template <class Key, class Value>
|
||||
{
|
||||
QMapNode<Key, Value> *mn = 0;
|
||||
const int valueOffset = (char *)&(mn->value) - (char*)mn;
|
||||
d.put("[\"(size_t)&(('"NS"QMapNode<");
|
||||
d.put("[\"(size_t)&((("NS"QMapNode<");
|
||||
d.put(keyType);
|
||||
d.put(',');
|
||||
d.put(valueType);
|
||||
if (valueType[qstrlen(valueType) - 1] == '>')
|
||||
d.put(' ');
|
||||
d.put(">'*)0)->value\",\"");
|
||||
d.put("> *)0)->value)-0\",\"");
|
||||
d.put(valueOffset);
|
||||
d.put("\"]");
|
||||
return d;
|
||||
@@ -3584,7 +3583,7 @@ template <class Key, class Value>
|
||||
|
||||
// Helper to write out common expression values for CDB:
|
||||
// Offsets of a std::pair for dumping std::map node value which look like
|
||||
// "(size_t)&(('std::pair<int const ,unsigned int>'*)0)->second"
|
||||
// "(size_t)&(((std::pair<int const ,int> *)0)->second)-0"
|
||||
|
||||
template <class Key, class Value>
|
||||
inline QDumper & putStdPairValueOffsetExpression(const char *keyType,
|
||||
@@ -3593,13 +3592,13 @@ template <class Key, class Value>
|
||||
{
|
||||
std::pair<Key, Value> *p = 0;
|
||||
const int valueOffset = (char *)&(p->second) - (char*)p;
|
||||
d.put("[\"(size_t)&(('std::pair<");
|
||||
d.put("[\"(size_t)&(((std::pair<");
|
||||
d.put(keyType);
|
||||
d.put(" const ,");
|
||||
d.put(valueType);
|
||||
if (valueType[qstrlen(valueType) - 1] == '>')
|
||||
d.put(' ');
|
||||
d.put(">'*)0)->second\",\"");
|
||||
d.put("> *)0)->second)-0\",\"");
|
||||
d.put(valueOffset);
|
||||
d.put("\"]");
|
||||
return d;
|
||||
|
||||
@@ -303,48 +303,6 @@
|
||||
<shortcut id="FormEditor.FormSettings" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Diff" >
|
||||
<key value="Alt+G, Alt+D" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Status" >
|
||||
<key value="Alt+G, Alt+S" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Log" >
|
||||
<key value="Alt+G, Alt+L" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Blame" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Undo" >
|
||||
<key value="Alt+G, Alt+U" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Add" >
|
||||
<key value="Alt+G, Alt+A" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.DiffProject" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.StatusProject" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.LogProject" >
|
||||
<key value="Alt+G, Alt+K" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.UndoProject" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.ShowCommit" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Commit" >
|
||||
<key value="Alt+G, Alt+C" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Pull" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Git.Push" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Help.Home" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
@@ -390,12 +348,6 @@
|
||||
<shortcut id="QtScriptEditor.Run" >
|
||||
<key value="Ctrl+R" />
|
||||
</shortcut>
|
||||
<shortcut id="CodePaster.Post" >
|
||||
<key value="Alt+C, Alt+P" />
|
||||
</shortcut>
|
||||
<shortcut id="CodePaster.Fetch" >
|
||||
<key value="Alt+C, Alt+F" />
|
||||
</shortcut>
|
||||
<shortcut id="Debugger.StartExternal" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
@@ -459,57 +411,6 @@
|
||||
<shortcut id="QtCreator.Mode.Debug" >
|
||||
<key value="Meta+3" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Edit" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Add" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Delete" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Revert" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.DiffCurrent" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.DiffProject" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.DiffAll" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Opened" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Submit" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.PendingChanges" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Describe" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.AnnotateCurrent" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Annotate" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.FilelogCurrent" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.Filelog" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.SubmitCurrentLog" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Perforce.DiffSelectedFilesInLog" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="Bookmarks.Toggle" >
|
||||
<key value="Ctrl+D" />
|
||||
</shortcut>
|
||||
@@ -531,36 +432,6 @@
|
||||
<shortcut id="Bookmarks.NextDocument" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="TextEditor.SelectEncoding" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="TextEditor.AutoIndentSelection" >
|
||||
<key value="Ctrl+I" />
|
||||
</shortcut>
|
||||
<shortcut id="TextEditor.VisualizeWhitespace" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="TextEditor.TextWrapping" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="TextEditor.UnCommentSelection" >
|
||||
<key value="Ctrl+/" />
|
||||
</shortcut>
|
||||
<shortcut id="TextEditor.DeleteLine" >
|
||||
<key value="Shift+Del" />
|
||||
</shortcut>
|
||||
<shortcut id="TextEditor.UnCollapseAll" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="FindFilter.Files on Disk" >
|
||||
<key value="" />
|
||||
</shortcut>
|
||||
<shortcut id="FindFilter.All Projects" >
|
||||
<key value="Ctrl+Shift+F" />
|
||||
</shortcut>
|
||||
<shortcut id="FindFilter.Current Project" >
|
||||
<key value="Ctrl+Alt+F" />
|
||||
</shortcut>
|
||||
<shortcut id="QtCreator.Pane.Problems" >
|
||||
<key value="Ctrl+1" />
|
||||
</shortcut>
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QLibrary>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
@@ -51,4 +55,60 @@ QTCREATOR_UTILS_EXPORT QString winErrorMessage(unsigned long error)
|
||||
return rc;
|
||||
}
|
||||
|
||||
QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t,
|
||||
const QString &name,
|
||||
QString *errorMessage)
|
||||
{
|
||||
// Resolve required symbols from the version.dll
|
||||
typedef DWORD (APIENTRY *GetFileVersionInfoSizeProtoType)(LPCTSTR, LPDWORD);
|
||||
typedef BOOL (APIENTRY *GetFileVersionInfoWProtoType)(LPCWSTR, DWORD, DWORD, LPVOID);
|
||||
typedef BOOL (APIENTRY *VerQueryValueWProtoType)(const LPVOID, LPWSTR lpSubBlock, LPVOID, PUINT);
|
||||
|
||||
const char *versionDLLC = "version.dll";
|
||||
QLibrary versionLib(QLatin1String(versionDLLC), 0);
|
||||
if (!versionLib.load()) {
|
||||
*errorMessage = QString::fromLatin1("Unable load %1: %2").arg(QLatin1String(versionDLLC), versionLib.errorString());
|
||||
return QString();
|
||||
}
|
||||
// MinGW requires old-style casts
|
||||
GetFileVersionInfoSizeProtoType getFileVersionInfoSizeW = (GetFileVersionInfoSizeProtoType)(versionLib.resolve("GetFileVersionInfoSizeW"));
|
||||
GetFileVersionInfoWProtoType getFileVersionInfoW = (GetFileVersionInfoWProtoType)(versionLib.resolve("GetFileVersionInfoW"));
|
||||
VerQueryValueWProtoType verQueryValueW = (VerQueryValueWProtoType)(versionLib.resolve("VerQueryValueW"));
|
||||
if (!getFileVersionInfoSizeW || !getFileVersionInfoW || !verQueryValueW) {
|
||||
*errorMessage = QString::fromLatin1("Unable to resolve all required symbols in %1").arg(QLatin1String(versionDLLC));
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Now go ahead, read version info resource
|
||||
DWORD dummy = 0;
|
||||
const LPCTSTR fileName = reinterpret_cast<LPCTSTR>(name.utf16()); // MinGWsy
|
||||
const DWORD infoSize = (*getFileVersionInfoSizeW)(fileName, &dummy);
|
||||
if (infoSize == 0) {
|
||||
*errorMessage = QString::fromLatin1("Unable to determine the size of the version information of %1: %2").arg(name, winErrorMessage(GetLastError()));
|
||||
return QString();
|
||||
}
|
||||
QByteArray dataV(infoSize + 1, '\0');
|
||||
char *data = dataV.data();
|
||||
if (!(*getFileVersionInfoW)(fileName, dummy, infoSize, data)) {
|
||||
*errorMessage = QString::fromLatin1("Unable to determine the version information of %1: %2").arg(name, winErrorMessage(GetLastError()));
|
||||
return QString();
|
||||
}
|
||||
VS_FIXEDFILEINFO *versionInfo;
|
||||
UINT len = 0;
|
||||
if (!(*verQueryValueW)(data, TEXT("\\"), &versionInfo, &len)) {
|
||||
*errorMessage = QString::fromLatin1("Unable to determine version string of %1: %2").arg(name, winErrorMessage(GetLastError()));
|
||||
return QString();
|
||||
}
|
||||
QString rc;
|
||||
switch (t) {
|
||||
case WinDLLFileVersion:
|
||||
QTextStream(&rc) << HIWORD(versionInfo->dwFileVersionMS) << '.' << LOWORD(versionInfo->dwFileVersionMS);
|
||||
break;
|
||||
case WinDLLProductVersion:
|
||||
QTextStream(&rc) << HIWORD(versionInfo->dwProductVersionMS) << '.' << LOWORD(versionInfo->dwProductVersionMS);
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
@@ -42,5 +42,10 @@ namespace Utils {
|
||||
// code as returned by the GetLastError()-API.
|
||||
QTCREATOR_UTILS_EXPORT QString winErrorMessage(unsigned long error);
|
||||
|
||||
// Determine a DLL version
|
||||
enum WinDLLVersionType { WinDLLFileVersion, WinDLLProductVersion };
|
||||
QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t,
|
||||
const QString &name,
|
||||
QString *errorMessage);
|
||||
} // namespace Utils
|
||||
#endif // WINUTILS_H
|
||||
|
||||
@@ -325,43 +325,39 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
|
||||
connect(m_d->m_goForwardAction, SIGNAL(triggered()), this, SLOT(goForwardInNavigationHistory()));
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
QString prefix = tr("Meta+E");
|
||||
#else
|
||||
QString prefix = tr("Ctrl+E");
|
||||
#endif
|
||||
|
||||
m_d->m_splitAction = new QAction(tr("Split"), this);
|
||||
cmd = am->registerAction(m_d->m_splitAction, Constants::SPLIT, editManagerContext);
|
||||
#ifndef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,2")));
|
||||
#endif
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,2").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_splitAction, SIGNAL(triggered()), this, SLOT(split()));
|
||||
|
||||
m_d->m_splitSideBySideAction = new QAction(tr("Split Side by Side"), this);
|
||||
cmd = am->registerAction(m_d->m_splitSideBySideAction, Constants::SPLIT_SIDE_BY_SIDE, editManagerContext);
|
||||
#ifndef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,3")));
|
||||
#endif
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,3").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide()));
|
||||
|
||||
m_d->m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this);
|
||||
cmd = am->registerAction(m_d->m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext);
|
||||
#ifndef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,0")));
|
||||
#endif
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,0").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_removeCurrentSplitAction, SIGNAL(triggered()), this, SLOT(removeCurrentSplit()));
|
||||
|
||||
m_d->m_removeAllSplitsAction = new QAction(tr("Remove All Splits"), this);
|
||||
cmd = am->registerAction(m_d->m_removeAllSplitsAction, Constants::REMOVE_ALL_SPLITS, editManagerContext);
|
||||
#ifndef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,1")));
|
||||
#endif
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,1").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits()));
|
||||
|
||||
m_d->m_gotoOtherSplitAction = new QAction(tr("Goto Other Split"), this);
|
||||
cmd = am->registerAction(m_d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext);
|
||||
#ifndef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,o")));
|
||||
#endif
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,o").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit()));
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Core {
|
||||
struct NavigationView
|
||||
{
|
||||
QWidget *widget;
|
||||
QList<QToolButton *> doockToolBarWidgets;
|
||||
QList<QToolButton *> dockToolBarWidgets;
|
||||
};
|
||||
|
||||
class CORE_EXPORT INavigationWidgetFactory : public QObject
|
||||
|
||||
@@ -426,7 +426,7 @@ void NavigationSubWidget::setCurrentIndex(int index)
|
||||
layout()->addWidget(m_navigationWidget);
|
||||
|
||||
// Add Toolbutton
|
||||
m_additionalToolBarWidgets = n.doockToolBarWidgets;
|
||||
m_additionalToolBarWidgets = n.dockToolBarWidgets;
|
||||
QHBoxLayout *layout = qobject_cast<QHBoxLayout *>(m_toolBar->layout());
|
||||
foreach (QToolButton *w, m_additionalToolBarWidgets) {
|
||||
layout->insertWidget(layout->count()-2, w);
|
||||
|
||||
@@ -113,17 +113,13 @@ bool CodepasterPlugin::initialize(const QStringList &arguments, QString *error_m
|
||||
|
||||
m_postAction = new QAction(tr("Paste Snippet..."), this);
|
||||
command = actionManager->registerAction(m_postAction, "CodePaster.Post", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+P")));
|
||||
#endif
|
||||
connect(m_postAction, SIGNAL(triggered()), this, SLOT(post()));
|
||||
cpContainer->addAction(command);
|
||||
|
||||
m_fetchAction = new QAction(tr("Fetch Snippet..."), this);
|
||||
command = actionManager->registerAction(m_fetchAction, "CodePaster.Fetch", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+F")));
|
||||
#endif
|
||||
connect(m_fetchAction, SIGNAL(triggered()), this, SLOT(fetch()));
|
||||
cpContainer->addAction(command);
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
#include <Control.h>
|
||||
#include <CoreTypes.h>
|
||||
#include <Literals.h>
|
||||
#include <PrettyPrinter.h>
|
||||
#include <Semantic.h>
|
||||
#include <ASTVisitor.h>
|
||||
#include <SymbolVisitor.h>
|
||||
#include <TranslationUnit.h>
|
||||
#include <cplusplus/ExpressionUnderCursor.h>
|
||||
@@ -352,6 +352,24 @@ protected:
|
||||
accept(ast->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
|
||||
{
|
||||
accept(ast->declaration);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(FunctionDeclaratorAST *ast)
|
||||
{
|
||||
accept(ast->parameters);
|
||||
|
||||
for (SpecifierAST *spec = ast->cv_qualifier_seq; spec; spec = spec->next)
|
||||
accept(spec);
|
||||
|
||||
accept(ast->exception_specification);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -541,22 +559,7 @@ CPPEditor::CPPEditor(QWidget *parent)
|
||||
setCodeFoldingVisible(true);
|
||||
baseTextDocument()->setSyntaxHighlighter(new CppHighlighter);
|
||||
|
||||
#ifdef WITH_TOKEN_MOVE_POSITION
|
||||
new QShortcut(QKeySequence::MoveToPreviousWord, this, SLOT(moveToPreviousToken()),
|
||||
/*ambiguousMember=*/ 0, Qt::WidgetShortcut);
|
||||
|
||||
new QShortcut(QKeySequence::MoveToNextWord, this, SLOT(moveToNextToken()),
|
||||
/*ambiguousMember=*/ 0, Qt::WidgetShortcut);
|
||||
|
||||
new QShortcut(QKeySequence::DeleteStartOfWord, this, SLOT(deleteStartOfToken()),
|
||||
/*ambiguousMember=*/ 0, Qt::WidgetShortcut);
|
||||
|
||||
new QShortcut(QKeySequence::DeleteEndOfWord, this, SLOT(deleteEndOfToken()),
|
||||
/*ambiguousMember=*/ 0, Qt::WidgetShortcut);
|
||||
#endif
|
||||
|
||||
m_modelManager = ExtensionSystem::PluginManager::instance()
|
||||
->getObject<CppTools::CppModelManagerInterface>();
|
||||
m_modelManager = CppTools::CppModelManagerInterface::instance();
|
||||
|
||||
if (m_modelManager) {
|
||||
connect(m_modelManager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
|
||||
@@ -691,100 +694,6 @@ void CPPEditor::abortRename()
|
||||
setExtraSelections(CodeSemanticsSelection, m_renameSelections);
|
||||
}
|
||||
|
||||
int CPPEditor::previousBlockState(QTextBlock block) const
|
||||
{
|
||||
block = block.previous();
|
||||
if (block.isValid()) {
|
||||
int state = block.userState();
|
||||
|
||||
if (state != -1)
|
||||
return state;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QTextCursor CPPEditor::moveToPreviousToken(QTextCursor::MoveMode mode) const
|
||||
{
|
||||
SimpleLexer tokenize;
|
||||
QTextCursor c(textCursor());
|
||||
QTextBlock block = c.block();
|
||||
int column = c.columnNumber();
|
||||
|
||||
for (; block.isValid(); block = block.previous()) {
|
||||
const QString textBlock = block.text();
|
||||
QList<SimpleToken> tokens = tokenize(textBlock, previousBlockState(block));
|
||||
|
||||
if (! tokens.isEmpty()) {
|
||||
tokens.prepend(SimpleToken());
|
||||
|
||||
for (int index = tokens.size() - 1; index != -1; --index) {
|
||||
const SimpleToken &tk = tokens.at(index);
|
||||
if (tk.position() < column) {
|
||||
c.setPosition(block.position() + tk.position(), mode);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
column = INT_MAX;
|
||||
}
|
||||
|
||||
c.movePosition(QTextCursor::Start, mode);
|
||||
return c;
|
||||
}
|
||||
|
||||
QTextCursor CPPEditor::moveToNextToken(QTextCursor::MoveMode mode) const
|
||||
{
|
||||
SimpleLexer tokenize;
|
||||
QTextCursor c(textCursor());
|
||||
QTextBlock block = c.block();
|
||||
int column = c.columnNumber();
|
||||
|
||||
for (; block.isValid(); block = block.next()) {
|
||||
const QString textBlock = block.text();
|
||||
QList<SimpleToken> tokens = tokenize(textBlock, previousBlockState(block));
|
||||
|
||||
if (! tokens.isEmpty()) {
|
||||
for (int index = 0; index < tokens.size(); ++index) {
|
||||
const SimpleToken &tk = tokens.at(index);
|
||||
if (tk.position() > column) {
|
||||
c.setPosition(block.position() + tk.position(), mode);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
column = -1;
|
||||
}
|
||||
|
||||
c.movePosition(QTextCursor::End, mode);
|
||||
return c;
|
||||
}
|
||||
|
||||
void CPPEditor::moveToPreviousToken()
|
||||
{
|
||||
setTextCursor(moveToPreviousToken(QTextCursor::MoveAnchor));
|
||||
}
|
||||
|
||||
void CPPEditor::moveToNextToken()
|
||||
{
|
||||
setTextCursor(moveToNextToken(QTextCursor::MoveAnchor));
|
||||
}
|
||||
|
||||
void CPPEditor::deleteStartOfToken()
|
||||
{
|
||||
QTextCursor c = moveToPreviousToken(QTextCursor::KeepAnchor);
|
||||
c.removeSelectedText();
|
||||
setTextCursor(c);
|
||||
}
|
||||
|
||||
void CPPEditor::deleteEndOfToken()
|
||||
{
|
||||
QTextCursor c = moveToNextToken(QTextCursor::KeepAnchor);
|
||||
c.removeSelectedText();
|
||||
setTextCursor(c);
|
||||
}
|
||||
|
||||
void CPPEditor::onDocumentUpdated(Document::Ptr doc)
|
||||
{
|
||||
if (doc->fileName() != file()->fileName())
|
||||
@@ -796,38 +705,13 @@ void CPPEditor::onDocumentUpdated(Document::Ptr doc)
|
||||
updateMethodBoxIndexNow();
|
||||
}
|
||||
|
||||
void CPPEditor::reformatDocument()
|
||||
{
|
||||
using namespace CPlusPlus;
|
||||
|
||||
QByteArray source = toPlainText().toUtf8();
|
||||
|
||||
Control control;
|
||||
StringLiteral *fileId = control.findOrInsertStringLiteral("<file>");
|
||||
TranslationUnit unit(&control, fileId);
|
||||
unit.setQtMocRunEnabled(true);
|
||||
unit.setSource(source.constData(), source.length());
|
||||
unit.parse();
|
||||
if (! unit.ast())
|
||||
return;
|
||||
|
||||
std::ostringstream s;
|
||||
|
||||
TranslationUnitAST *ast = unit.ast()->asTranslationUnit();
|
||||
PrettyPrinter pp(&control, s);
|
||||
pp(ast, source);
|
||||
|
||||
const std::string str = s.str();
|
||||
QTextCursor c = textCursor();
|
||||
c.setPosition(0);
|
||||
c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
c.insertText(QString::fromUtf8(str.c_str(), str.length()));
|
||||
}
|
||||
|
||||
CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
|
||||
Document::Ptr doc,
|
||||
const Snapshot &snapshot) const
|
||||
{
|
||||
if (! doc)
|
||||
return 0;
|
||||
|
||||
QTextCursor tc = cursor;
|
||||
int line, col;
|
||||
convertPosition(tc.position(), &line, &col);
|
||||
@@ -860,16 +744,10 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
|
||||
|
||||
void CPPEditor::findUsages()
|
||||
{
|
||||
updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource()));
|
||||
|
||||
SemanticInfo info = m_lastSemanticInfo;
|
||||
|
||||
if (! info.doc)
|
||||
return;
|
||||
|
||||
if (Symbol *canonicalSymbol = findCanonicalSymbol(textCursor(), info.doc, info.snapshot))
|
||||
if (Symbol *canonicalSymbol = markSymbols()) {
|
||||
m_modelManager->findUsages(canonicalSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
void CPPEditor::renameUsages()
|
||||
{
|
||||
@@ -881,7 +759,15 @@ void CPPEditor::renameUsages()
|
||||
|
||||
void CPPEditor::renameUsagesNow()
|
||||
{
|
||||
if (Symbol *canonicalSymbol = markSymbols()) {
|
||||
Core::EditorManager::instance()->hideEditorInfoBar(QLatin1String("CppEditor.Rename"));
|
||||
m_modelManager->renameUsages(canonicalSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
Symbol *CPPEditor::markSymbols()
|
||||
{
|
||||
updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource()));
|
||||
|
||||
m_currentRenameSelection = -1;
|
||||
|
||||
@@ -889,8 +775,8 @@ void CPPEditor::renameUsagesNow()
|
||||
|
||||
SemanticInfo info = m_lastSemanticInfo;
|
||||
|
||||
if (info.doc) {
|
||||
if (Symbol *canonicalSymbol = findCanonicalSymbol(textCursor(), info.doc, info.snapshot)) {
|
||||
Symbol *canonicalSymbol = findCanonicalSymbol(textCursor(), info.doc, info.snapshot);
|
||||
if (canonicalSymbol) {
|
||||
TranslationUnit *unit = info.doc->translationUnit();
|
||||
|
||||
const QList<int> references = m_modelManager->references(canonicalSymbol, info.doc, info.snapshot);
|
||||
@@ -912,12 +798,10 @@ void CPPEditor::renameUsagesNow()
|
||||
sel.cursor = cursor;
|
||||
selections.append(sel);
|
||||
}
|
||||
}
|
||||
|
||||
setExtraSelections(CodeSemanticsSelection, selections);
|
||||
|
||||
m_modelManager->renameUsages(canonicalSymbol);
|
||||
}
|
||||
}
|
||||
return canonicalSymbol;
|
||||
}
|
||||
|
||||
void CPPEditor::renameSymbolUnderCursor()
|
||||
|
||||
@@ -194,12 +194,6 @@ public Q_SLOTS:
|
||||
void findUsages();
|
||||
void renameUsagesNow();
|
||||
|
||||
void moveToPreviousToken();
|
||||
void moveToNextToken();
|
||||
|
||||
void deleteStartOfToken();
|
||||
void deleteEndOfToken();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e);
|
||||
void contextMenuEvent(QContextMenuEvent *);
|
||||
@@ -231,13 +225,13 @@ private Q_SLOTS:
|
||||
void updateUses();
|
||||
void updateUsesNow();
|
||||
void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
|
||||
void reformatDocument();
|
||||
void onContentsChanged(int position, int charsRemoved, int charsAdded);
|
||||
|
||||
void semanticRehighlight();
|
||||
void updateSemanticInfo(const SemanticInfo &semanticInfo);
|
||||
|
||||
private:
|
||||
CPlusPlus::Symbol *markSymbols();
|
||||
bool sortedMethodOverview() const;
|
||||
CPlusPlus::Symbol *findDefinition(CPlusPlus::Symbol *symbol);
|
||||
virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar);
|
||||
@@ -245,10 +239,6 @@ private:
|
||||
TextEditor::ITextEditor *openCppEditorAt(const QString &fileName, int line,
|
||||
int column = 0);
|
||||
|
||||
int previousBlockState(QTextBlock block) const;
|
||||
QTextCursor moveToPreviousToken(QTextCursor::MoveMode mode) const;
|
||||
QTextCursor moveToNextToken(QTextCursor::MoveMode mode) const;
|
||||
|
||||
SemanticHighlighter::Source currentSource();
|
||||
|
||||
void highlightUses(const QList<SemanticInfo::Use> &uses,
|
||||
|
||||
@@ -337,6 +337,14 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
||||
firstType = resolve(firstType, typeOfExpression.lookupContext(),
|
||||
&resolvedSymbol, &resolvedName);
|
||||
|
||||
if (resolvedSymbol && resolvedSymbol->scope()->isClassScope()) {
|
||||
Class *enclosingClass = resolvedSymbol->scope()->owner()->asClass();
|
||||
if (Identifier *id = enclosingClass->identifier()) {
|
||||
if (id->isEqualTo(resolvedSymbol->identifier()))
|
||||
resolvedSymbol = enclosingClass;
|
||||
}
|
||||
}
|
||||
|
||||
m_helpId = buildHelpId(resolvedSymbol, resolvedName);
|
||||
|
||||
if (m_toolTip.isEmpty()) {
|
||||
@@ -349,7 +357,10 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
||||
overview.setShowReturnTypes(true);
|
||||
overview.setShowFullyQualifiedNamed(true);
|
||||
|
||||
if (lookupSymbol && (lookupSymbol->isDeclaration() || lookupSymbol->isArgument())) {
|
||||
if (symbol == resolvedSymbol && symbol->isClass()) {
|
||||
m_toolTip = m_helpId;
|
||||
|
||||
} else if (lookupSymbol && (lookupSymbol->isDeclaration() || lookupSymbol->isArgument())) {
|
||||
m_toolTip = overview.prettyType(firstType, buildHelpId(lookupSymbol, lookupSymbol->name()));
|
||||
|
||||
} else if (firstType->isClassType() || firstType->isEnumType() ||
|
||||
|
||||
@@ -417,6 +417,24 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
|
||||
{
|
||||
accept(ast->declaration);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(FunctionDeclaratorAST *ast)
|
||||
{
|
||||
accept(ast->parameters);
|
||||
|
||||
for (SpecifierAST *spec = ast->cv_qualifier_seq; spec; spec = spec->next)
|
||||
accept(spec);
|
||||
|
||||
accept(ast->exception_specification);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
QFutureInterface<Utils::FileSearchResult> *_future;
|
||||
Identifier *_id; // ### remove me
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
#include <NameVisitor.h>
|
||||
#include <TypeVisitor.h>
|
||||
#include <ASTVisitor.h>
|
||||
#include <PrettyPrinter.h>
|
||||
#include <Lexer.h>
|
||||
#include <Token.h>
|
||||
|
||||
|
||||
@@ -1,314 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "cppsemanticsearch.h"
|
||||
#include "cppmodelmanager.h"
|
||||
|
||||
#include <AST.h>
|
||||
#include <Literals.h>
|
||||
#include <TranslationUnit.h>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QtConcurrentRun>
|
||||
#include <QtCore/QFutureSynchronizer>
|
||||
#include <qtconcurrent/runextensions.h>
|
||||
|
||||
using namespace CppTools::Internal;
|
||||
using namespace CPlusPlus;
|
||||
|
||||
namespace {
|
||||
|
||||
class SearchClass: public SemanticSearch
|
||||
{
|
||||
QString _text;
|
||||
QTextDocument::FindFlags _findFlags;
|
||||
|
||||
public:
|
||||
SearchClass(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
Document::Ptr doc, Snapshot snapshot)
|
||||
: SemanticSearch(future, doc, snapshot)
|
||||
{ }
|
||||
|
||||
void setText(const QString &text)
|
||||
{ _text = text; }
|
||||
|
||||
void setFindFlags(QTextDocument::FindFlags findFlags)
|
||||
{ _findFlags = findFlags; }
|
||||
|
||||
virtual void run(AST *ast)
|
||||
{ accept(ast); }
|
||||
|
||||
protected:
|
||||
using ASTVisitor::visit;
|
||||
|
||||
bool match(NameAST *name)
|
||||
{
|
||||
if (! name)
|
||||
return false;
|
||||
|
||||
else if (SimpleNameAST *simpleName = name->asSimpleName()) {
|
||||
if (Identifier *id = identifier(simpleName->identifier_token)) {
|
||||
Qt::CaseSensitivity cs = Qt::CaseInsensitive;
|
||||
|
||||
if (_findFlags & QTextDocument::FindCaseSensitively)
|
||||
cs = Qt::CaseSensitive;
|
||||
|
||||
QString s = QString::fromUtf8(id->chars(), id->size());
|
||||
int index = s.indexOf(_text, 0, cs);
|
||||
if (index != -1) {
|
||||
reportResult(simpleName->identifier_token, index, _text.length());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (QualifiedNameAST *q = name->asQualifiedName()) {
|
||||
return match(q->unqualified_name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(ElaboratedTypeSpecifierAST *ast)
|
||||
{
|
||||
if (tokenKind(ast->classkey_token) != T_ENUM) {
|
||||
match(ast->name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool visit(ClassSpecifierAST *ast)
|
||||
{
|
||||
match(ast->name);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class SearchFunctionCall: public SemanticSearch
|
||||
{
|
||||
QString _text;
|
||||
QTextDocument::FindFlags _findFlags;
|
||||
|
||||
public:
|
||||
SearchFunctionCall(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
Document::Ptr doc, Snapshot snapshot)
|
||||
: SemanticSearch(future, doc, snapshot)
|
||||
{ }
|
||||
|
||||
void setText(const QString &text)
|
||||
{ _text = text; }
|
||||
|
||||
void setFindFlags(QTextDocument::FindFlags findFlags)
|
||||
{ _findFlags = findFlags; }
|
||||
|
||||
virtual void run(AST *ast)
|
||||
{ accept(ast); }
|
||||
|
||||
protected:
|
||||
using ASTVisitor::visit;
|
||||
|
||||
bool match(NameAST *name)
|
||||
{
|
||||
if (! name)
|
||||
return false;
|
||||
|
||||
else if (SimpleNameAST *simpleName = name->asSimpleName()) {
|
||||
if (Identifier *id = identifier(simpleName->identifier_token)) {
|
||||
Qt::CaseSensitivity cs = Qt::CaseInsensitive;
|
||||
|
||||
if (_findFlags & QTextDocument::FindCaseSensitively)
|
||||
cs = Qt::CaseSensitive;
|
||||
|
||||
QString s = QString::fromUtf8(id->chars(), id->size());
|
||||
int index = s.indexOf(_text, 0, cs);
|
||||
if (index != -1) {
|
||||
reportResult(simpleName->identifier_token, index, _text.length());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (QualifiedNameAST *q = name->asQualifiedName()) {
|
||||
return match(q->unqualified_name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(PostfixExpressionAST *ast)
|
||||
{
|
||||
NameAST *name = 0;
|
||||
|
||||
if (ast->base_expression)
|
||||
name = ast->base_expression->asName();
|
||||
|
||||
for (PostfixAST *fx = ast->postfix_expressions; fx; fx = fx->next) {
|
||||
if (fx->asCall() != 0) {
|
||||
match(name);
|
||||
} else if (MemberAccessAST *mem = fx->asMemberAccess()) {
|
||||
name = mem->member_name;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
SemanticSearch::SemanticSearch(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
Document::Ptr doc,
|
||||
Snapshot snapshot)
|
||||
: ASTVisitor(doc->control()),
|
||||
_future(future),
|
||||
_doc(doc),
|
||||
_snapshot(snapshot)
|
||||
{
|
||||
_thisDocument = _snapshot.value(_doc->fileName());
|
||||
}
|
||||
|
||||
SemanticSearch::~SemanticSearch()
|
||||
{ }
|
||||
|
||||
const QByteArray &SemanticSearch::source() const
|
||||
{ return _source; }
|
||||
|
||||
void SemanticSearch::setSource(const QByteArray &source)
|
||||
{ _source = source; }
|
||||
|
||||
QString SemanticSearch::matchingLine(const Token &tk) const
|
||||
{
|
||||
const char *beg = _source.constData();
|
||||
const char *cp = beg + tk.offset;
|
||||
for (; cp != beg - 1; --cp) {
|
||||
if (*cp == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
++cp;
|
||||
|
||||
const char *lineEnd = cp + 1;
|
||||
for (; *lineEnd; ++lineEnd) {
|
||||
if (*lineEnd == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
const QString matchingLine = QString::fromUtf8(cp, lineEnd - cp);
|
||||
return matchingLine;
|
||||
}
|
||||
|
||||
void SemanticSearch::reportResult(unsigned tokenIndex, int offset, int len)
|
||||
{
|
||||
const Token &tk = tokenAt(tokenIndex);
|
||||
const QString lineText = matchingLine(tk);
|
||||
|
||||
unsigned line, col;
|
||||
getTokenStartPosition(tokenIndex, &line, &col);
|
||||
|
||||
if (col)
|
||||
--col; // adjust the column position.
|
||||
|
||||
_future.reportResult(Utils::FileSearchResult(QDir::toNativeSeparators(_doc->fileName()),
|
||||
line, lineText, col + offset, len));
|
||||
}
|
||||
|
||||
SemanticSearch *SearchClassDeclarationsFactory::create(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
Document::Ptr doc,
|
||||
Snapshot snapshot)
|
||||
{
|
||||
SearchClass *search = new SearchClass(future, doc, snapshot);
|
||||
search->setText(_text);
|
||||
search->setFindFlags(_findFlags);
|
||||
return search;
|
||||
}
|
||||
|
||||
SemanticSearch *SearchFunctionCallFactory::create(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
Document::Ptr doc,
|
||||
Snapshot snapshot)
|
||||
{
|
||||
SearchFunctionCall *search = new SearchFunctionCall(future, doc, snapshot);
|
||||
search->setText(_text);
|
||||
search->setFindFlags(_findFlags);
|
||||
return search;
|
||||
}
|
||||
|
||||
static void semanticSearch_helper(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
QPointer<CppModelManager> modelManager,
|
||||
QMap<QString, QString> wl,
|
||||
SemanticSearchFactory::Ptr factory)
|
||||
{
|
||||
const Snapshot snapshot = modelManager->snapshot();
|
||||
|
||||
future.setProgressRange(0, snapshot.size());
|
||||
future.setProgressValue(0);
|
||||
|
||||
int progress = 0;
|
||||
foreach (Document::Ptr doc, snapshot) {
|
||||
if (future.isPaused())
|
||||
future.waitForResume();
|
||||
|
||||
if (future.isCanceled())
|
||||
break;
|
||||
|
||||
const QString fileName = doc->fileName();
|
||||
|
||||
QByteArray source;
|
||||
|
||||
if (wl.contains(fileName))
|
||||
source = snapshot.preprocessedCode(wl.value(fileName), fileName);
|
||||
else {
|
||||
QFile file(fileName);
|
||||
if (! file.open(QFile::ReadOnly))
|
||||
continue;
|
||||
|
||||
const QString contents = QTextStream(&file).readAll(); // ### FIXME
|
||||
source = snapshot.preprocessedCode(contents, fileName);
|
||||
}
|
||||
|
||||
Document::Ptr newDoc = snapshot.documentFromSource(source, fileName);
|
||||
newDoc->parse();
|
||||
|
||||
if (SemanticSearch *search = factory->create(future, newDoc, snapshot)) {
|
||||
search->setSource(source);
|
||||
search->run(newDoc->translationUnit()->ast());
|
||||
delete search;
|
||||
}
|
||||
|
||||
future.setProgressValue(++progress);
|
||||
}
|
||||
}
|
||||
|
||||
QFuture<Utils::FileSearchResult> CppTools::Internal::semanticSearch(QPointer<CppModelManager> modelManager,
|
||||
SemanticSearchFactory::Ptr factory)
|
||||
{
|
||||
return QtConcurrent::run(&semanticSearch_helper, modelManager,
|
||||
modelManager->buildWorkingCopyList(), factory);
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef CPPSEMANTICSEARCH_H
|
||||
#define CPPSEMANTICSEARCH_H
|
||||
|
||||
#include <ASTVisitor.h>
|
||||
#include <cplusplus/CppDocument.h>
|
||||
|
||||
#include <utils/filesearch.h>
|
||||
|
||||
#include <QtCore/QFutureInterface>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtGui/QTextDocument>
|
||||
|
||||
namespace CppTools {
|
||||
namespace Internal {
|
||||
|
||||
class CppModelManager;
|
||||
class SemanticSearchFactory;
|
||||
|
||||
class SemanticSearch: protected CPlusPlus::ASTVisitor
|
||||
{
|
||||
QFutureInterface<Utils::FileSearchResult> &_future;
|
||||
CPlusPlus::Document::Ptr _doc;
|
||||
CPlusPlus::Snapshot _snapshot;
|
||||
CPlusPlus::Document::Ptr _thisDocument;
|
||||
QByteArray _source;
|
||||
|
||||
public:
|
||||
SemanticSearch(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
CPlusPlus::Document::Ptr doc,
|
||||
CPlusPlus::Snapshot snapshot);
|
||||
|
||||
virtual ~SemanticSearch();
|
||||
|
||||
virtual void run(CPlusPlus::AST *ast) = 0;
|
||||
|
||||
const QByteArray &source() const;
|
||||
void setSource(const QByteArray &source);
|
||||
|
||||
protected:
|
||||
QString matchingLine(const CPlusPlus::Token &tk) const;
|
||||
void reportResult(unsigned tokenIndex, int offset, int len);
|
||||
};
|
||||
|
||||
class SemanticSearchFactory
|
||||
{
|
||||
Q_DISABLE_COPY(SemanticSearchFactory)
|
||||
|
||||
public:
|
||||
typedef QSharedPointer<SemanticSearchFactory> Ptr;
|
||||
|
||||
SemanticSearchFactory() {}
|
||||
virtual ~SemanticSearchFactory() {}
|
||||
|
||||
virtual SemanticSearch *create(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
CPlusPlus::Document::Ptr doc,
|
||||
CPlusPlus::Snapshot snapshot) = 0;
|
||||
};
|
||||
|
||||
class SearchClassDeclarationsFactory: public SemanticSearchFactory
|
||||
{
|
||||
QString _text;
|
||||
QTextDocument::FindFlags _findFlags;
|
||||
|
||||
public:
|
||||
SearchClassDeclarationsFactory(const QString &text, QTextDocument::FindFlags findFlags)
|
||||
: _text(text), _findFlags(findFlags)
|
||||
{ }
|
||||
|
||||
virtual SemanticSearch *create(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
CPlusPlus::Document::Ptr doc,
|
||||
CPlusPlus::Snapshot snapshot);
|
||||
};
|
||||
|
||||
class SearchFunctionCallFactory: public SemanticSearchFactory
|
||||
{
|
||||
QString _text;
|
||||
QTextDocument::FindFlags _findFlags;
|
||||
|
||||
public:
|
||||
SearchFunctionCallFactory(const QString &text, QTextDocument::FindFlags findFlags)
|
||||
: _text(text), _findFlags(findFlags)
|
||||
{ }
|
||||
|
||||
virtual SemanticSearch *create(QFutureInterface<Utils::FileSearchResult> &future,
|
||||
CPlusPlus::Document::Ptr doc,
|
||||
CPlusPlus::Snapshot snapshot);
|
||||
};
|
||||
|
||||
QFuture<Utils::FileSearchResult> semanticSearch(QPointer<CppModelManager> modelManager,
|
||||
SemanticSearchFactory::Ptr factory);
|
||||
|
||||
|
||||
} // end of namespace Internal
|
||||
} // end of namespace CppTools
|
||||
|
||||
#endif // CPPSEMANTICSEARCH_H
|
||||
@@ -23,7 +23,6 @@ HEADERS += completionsettingspage.h \
|
||||
searchsymbols.h \
|
||||
cppdoxygen.h \
|
||||
cppfilesettingspage.h \
|
||||
cppsemanticsearch.h \
|
||||
cppfindreferences.h
|
||||
|
||||
SOURCES += completionsettingspage.cpp \
|
||||
@@ -39,7 +38,6 @@ SOURCES += completionsettingspage.cpp \
|
||||
cppdoxygen.cpp \
|
||||
cppfilesettingspage.cpp \
|
||||
abstracteditorsupport.cpp \
|
||||
cppsemanticsearch.cpp \
|
||||
cppfindreferences.cpp
|
||||
|
||||
FORMS += completionsettingspage.ui \
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cpptoolsconstants.h"
|
||||
#include "cppquickopenfilter.h"
|
||||
#include "cppsemanticsearch.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
@@ -75,113 +74,6 @@ enum { debug = 0 };
|
||||
|
||||
CppToolsPlugin *CppToolsPlugin::m_instance = 0;
|
||||
|
||||
FindClassDeclarations::FindClassDeclarations(CppModelManager *modelManager)
|
||||
: _modelManager(modelManager),
|
||||
_resultWindow(ExtensionSystem::PluginManager::instance()->getObject<Find::SearchResultWindow>())
|
||||
{
|
||||
m_watcher.setPendingResultsLimit(1);
|
||||
connect(&m_watcher, SIGNAL(resultReadyAt(int)), this, SLOT(displayResult(int)));
|
||||
connect(&m_watcher, SIGNAL(finished()), this, SLOT(searchFinished()));
|
||||
}
|
||||
|
||||
void FindClassDeclarations::findAll(const QString &text, QTextDocument::FindFlags findFlags)
|
||||
{
|
||||
Find::SearchResult *search = _resultWindow->startNewSearch();
|
||||
connect(search, SIGNAL(activated(Find::SearchResultItem)),
|
||||
this, SLOT(openEditor(Find::SearchResultItem)));
|
||||
|
||||
_resultWindow->popup(true);
|
||||
|
||||
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
|
||||
|
||||
SemanticSearchFactory::Ptr factory(new SearchClassDeclarationsFactory(text, findFlags));
|
||||
|
||||
QFuture<Utils::FileSearchResult> result = semanticSearch(_modelManager, factory);
|
||||
|
||||
m_watcher.setFuture(result);
|
||||
|
||||
Core::FutureProgress *progress = progressManager->addTask(result, tr("Search class"),
|
||||
CppTools::Constants::TASK_INDEX,
|
||||
Core::ProgressManager::CloseOnSuccess);
|
||||
|
||||
connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup()));
|
||||
}
|
||||
|
||||
void FindClassDeclarations::displayResult(int index)
|
||||
{
|
||||
Utils::FileSearchResult result = m_watcher.future().resultAt(index);
|
||||
_resultWindow->addResult(result.fileName,
|
||||
result.lineNumber,
|
||||
result.matchingLine,
|
||||
result.matchStart,
|
||||
result.matchLength);
|
||||
}
|
||||
|
||||
void FindClassDeclarations::searchFinished()
|
||||
{
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void FindClassDeclarations::openEditor(const Find::SearchResultItem &item)
|
||||
{
|
||||
TextEditor::BaseTextEditor::openEditorAt(item.fileName, item.lineNumber, item.searchTermStart);
|
||||
}
|
||||
|
||||
//////
|
||||
FindFunctionCalls::FindFunctionCalls(CppModelManager *modelManager)
|
||||
: _modelManager(modelManager),
|
||||
_resultWindow(ExtensionSystem::PluginManager::instance()->getObject<Find::SearchResultWindow>())
|
||||
{
|
||||
m_watcher.setPendingResultsLimit(1);
|
||||
connect(&m_watcher, SIGNAL(resultReadyAt(int)), this, SLOT(displayResult(int)));
|
||||
connect(&m_watcher, SIGNAL(finished()), this, SLOT(searchFinished()));
|
||||
}
|
||||
|
||||
void FindFunctionCalls::findAll(const QString &text, QTextDocument::FindFlags findFlags)
|
||||
{
|
||||
Find::SearchResult *search = _resultWindow->startNewSearch();
|
||||
connect(search, SIGNAL(activated(Find::SearchResultItem)),
|
||||
this, SLOT(openEditor(Find::SearchResultItem)));
|
||||
|
||||
_resultWindow->popup(true);
|
||||
|
||||
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
|
||||
|
||||
SemanticSearchFactory::Ptr factory(new SearchFunctionCallFactory(text, findFlags));
|
||||
|
||||
QFuture<Utils::FileSearchResult> result = semanticSearch(_modelManager, factory);
|
||||
|
||||
m_watcher.setFuture(result);
|
||||
|
||||
Core::FutureProgress *progress = progressManager->addTask(result, tr("Search functions"),
|
||||
CppTools::Constants::TASK_INDEX,
|
||||
Core::ProgressManager::CloseOnSuccess);
|
||||
|
||||
connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup()));
|
||||
}
|
||||
|
||||
void FindFunctionCalls::displayResult(int index)
|
||||
{
|
||||
Utils::FileSearchResult result = m_watcher.future().resultAt(index);
|
||||
_resultWindow->addResult(result.fileName,
|
||||
result.lineNumber,
|
||||
result.matchingLine,
|
||||
result.matchStart,
|
||||
result.matchLength);
|
||||
}
|
||||
|
||||
void FindFunctionCalls::searchFinished()
|
||||
{
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void FindFunctionCalls::openEditor(const Find::SearchResultItem &item)
|
||||
{
|
||||
TextEditor::BaseTextEditor::openEditorAt(item.fileName, item.lineNumber, item.searchTermStart);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CppToolsPlugin::CppToolsPlugin() :
|
||||
m_context(-1),
|
||||
m_modelManager(0),
|
||||
@@ -221,9 +113,6 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
|
||||
addAutoReleasedObject(new CompletionSettingsPage(m_completion));
|
||||
addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings));
|
||||
|
||||
addAutoReleasedObject(new FindClassDeclarations(m_modelManager));
|
||||
addAutoReleasedObject(new FindFunctionCalls(m_modelManager));
|
||||
|
||||
// Menus
|
||||
Core::ActionContainer *mtools = am->actionContainer(Core::Constants::M_TOOLS);
|
||||
Core::ActionContainer *mcpptools = am->createMenu(CppTools::Constants::M_TOOLS_CPP);
|
||||
|
||||
@@ -47,15 +47,6 @@ class QFileInfo;
|
||||
class QDir;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace CPlusPlus {
|
||||
class Snapshot;
|
||||
}
|
||||
|
||||
namespace Find {
|
||||
class SearchResultWindow;
|
||||
struct SearchResultItem;
|
||||
}
|
||||
|
||||
namespace CppTools {
|
||||
namespace Internal {
|
||||
|
||||
@@ -63,56 +54,6 @@ class CppCodeCompletion;
|
||||
class CppModelManager;
|
||||
struct CppFileSettings;
|
||||
|
||||
class FindClassDeclarations: public Find::IFindFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FindClassDeclarations(CppModelManager *modelManager);
|
||||
|
||||
// Find::IFindFilter
|
||||
virtual QString id() const { return QLatin1String("CppTools.Find.ClassDeclarations"); }
|
||||
virtual QString name() const { return tr("Class Declarations"); }
|
||||
virtual bool isEnabled() const { return true; }
|
||||
virtual QKeySequence defaultShortcut() const { return QKeySequence(); }
|
||||
virtual void findAll(const QString &txt, QTextDocument::FindFlags findFlags);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void displayResult(int);
|
||||
void searchFinished();
|
||||
void openEditor(const Find::SearchResultItem &item);
|
||||
|
||||
private:
|
||||
QPointer<CppModelManager> _modelManager;
|
||||
Find::SearchResultWindow *_resultWindow;
|
||||
QFutureWatcher<Utils::FileSearchResult> m_watcher;
|
||||
};
|
||||
|
||||
class FindFunctionCalls: public Find::IFindFilter // ### share code with FindClassDeclarations
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FindFunctionCalls(CppModelManager *modelManager);
|
||||
|
||||
// Find::IFindFilter
|
||||
virtual QString id() const { return QLatin1String("CppTools.Find.FunctionCalls"); }
|
||||
virtual QString name() const { return tr("Function calls"); }
|
||||
virtual bool isEnabled() const { return true; }
|
||||
virtual QKeySequence defaultShortcut() const { return QKeySequence(); }
|
||||
virtual void findAll(const QString &txt, QTextDocument::FindFlags findFlags);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void displayResult(int);
|
||||
void searchFinished();
|
||||
void openEditor(const Find::SearchResultItem &item);
|
||||
|
||||
private:
|
||||
QPointer<CppModelManager> _modelManager;
|
||||
Find::SearchResultWindow *_resultWindow;
|
||||
QFutureWatcher<Utils::FileSearchResult> m_watcher;
|
||||
};
|
||||
|
||||
class CppToolsPlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
Q_DISABLE_COPY(CppToolsPlugin)
|
||||
|
||||
@@ -264,9 +264,7 @@ bool CVSPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
command = ami->registerAction(m_addAction, CMD_ID_ADD,
|
||||
globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+A")));
|
||||
#endif
|
||||
connect(m_addAction, SIGNAL(triggered()), this, SLOT(addCurrentFile()));
|
||||
cvsMenu->addAction(command);
|
||||
|
||||
@@ -296,9 +294,7 @@ bool CVSPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
command = ami->registerAction(m_diffCurrentAction,
|
||||
CMD_ID_DIFF_CURRENT, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+D")));
|
||||
#endif
|
||||
connect(m_diffCurrentAction, SIGNAL(triggered()), this, SLOT(diffCurrentFile()));
|
||||
cvsMenu->addAction(command);
|
||||
|
||||
@@ -314,9 +310,7 @@ bool CVSPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
command = ami->registerAction(m_commitCurrentAction,
|
||||
CMD_ID_COMMIT_CURRENT, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+C")));
|
||||
#endif
|
||||
connect(m_commitCurrentAction, SIGNAL(triggered()), this, SLOT(startCommitCurrentFile()));
|
||||
cvsMenu->addAction(command);
|
||||
|
||||
|
||||
@@ -236,7 +236,9 @@ static inline QString libPath(const QString &libName, const QString &path = QStr
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool DebuggerEngineLibrary::init(const QString &path, QString *errorMessage)
|
||||
bool DebuggerEngineLibrary::init(const QString &path,
|
||||
QString *dbgEngDLL,
|
||||
QString *errorMessage)
|
||||
{
|
||||
// Load the dependent help lib first
|
||||
const QString helpLibPath = libPath(QLatin1String(dbgHelpDllC), path);
|
||||
@@ -252,6 +254,7 @@ bool DebuggerEngineLibrary::init(const QString &path, QString *errorMessage)
|
||||
*errorMessage = msgLibLoadFailed(engineLibPath, lib.errorString());
|
||||
return false;
|
||||
}
|
||||
*dbgEngDLL = engineLibPath;
|
||||
// Locate symbols
|
||||
void *createFunc = lib.resolve(debugCreateFuncC);
|
||||
if (!createFunc) {
|
||||
@@ -317,9 +320,8 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
|
||||
enum { bufLen = 10240 };
|
||||
// Load the DLL
|
||||
DebuggerEngineLibrary lib;
|
||||
if (!lib.init(m_options->path, errorMessage))
|
||||
if (!lib.init(m_options->path, &m_dbengDLL, errorMessage))
|
||||
return false;
|
||||
|
||||
// Initialize the COM interfaces
|
||||
HRESULT hr;
|
||||
hr = lib.debugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_cif.debugClient));
|
||||
@@ -587,9 +589,38 @@ void CdbDebugEnginePrivate::clearDisplay()
|
||||
manager()->registerHandler()->removeAll();
|
||||
}
|
||||
|
||||
void CdbDebugEnginePrivate::checkVersion()
|
||||
{
|
||||
static bool versionNotChecked = true;
|
||||
// Check for version 6.11 (extended expression syntax)
|
||||
if (versionNotChecked) {
|
||||
versionNotChecked = false;
|
||||
// Get engine DLL version
|
||||
QString errorMessage;
|
||||
const QString version = Utils::winGetDLLVersion(Utils::WinDLLProductVersion, m_dbengDLL, &errorMessage);
|
||||
if (version.isEmpty()) {
|
||||
qWarning("%s\n", qPrintable(errorMessage));
|
||||
return;
|
||||
}
|
||||
// Compare
|
||||
const double minVersion = 6.11;
|
||||
manager()->showDebuggerOutput(LogMisc, CdbDebugEngine::tr("Version: %1").arg(version));
|
||||
if (version.toDouble() < minVersion) {
|
||||
const QString msg = CdbDebugEngine::tr(
|
||||
"<html>The installed version of the <i>Debugging Tools for Windows</i> (%1) "
|
||||
"is rather old. Upgrading to version %2 is recommended "
|
||||
"for the proper display of Qt's data types.</html>").arg(version).arg(minVersion);
|
||||
Core::ICore::instance()->showWarningWithOptions(CdbDebugEngine::tr("Debugger"), msg, QString(),
|
||||
QLatin1String(Constants::DEBUGGER_SETTINGS_CATEGORY),
|
||||
CdbOptionsPage::settingsId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CdbDebugEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
|
||||
{
|
||||
setState(AdapterStarting, Q_FUNC_INFO, __LINE__);
|
||||
m_d->checkVersion();
|
||||
if (m_d->m_hDebuggeeProcess) {
|
||||
warning(QLatin1String("Internal error: Attempt to start debugger while another process is being debugged."));
|
||||
setState(AdapterStartFailed, Q_FUNC_INFO, __LINE__);
|
||||
|
||||
@@ -57,7 +57,7 @@ class DebuggerEngineLibrary
|
||||
{
|
||||
public:
|
||||
DebuggerEngineLibrary();
|
||||
bool init(const QString &path, QString *errorMessage);
|
||||
bool init(const QString &path, QString *dbgEngDLL, QString *errorMessage);
|
||||
|
||||
inline HRESULT debugCreate(REFIID interfaceId, PVOID *interfaceHandle) const
|
||||
{ return m_debugCreate(interfaceId, interfaceHandle); }
|
||||
@@ -110,6 +110,7 @@ struct CdbDebugEnginePrivate
|
||||
bool init(QString *errorMessage);
|
||||
~CdbDebugEnginePrivate();
|
||||
|
||||
void checkVersion();
|
||||
void processCreatedAttached(ULONG64 processHandle, ULONG64 initialThreadHandle);
|
||||
void setDebuggeeHandles(HANDLE hDebuggeeProcess, HANDLE hDebuggeeThread);
|
||||
|
||||
@@ -177,6 +178,7 @@ struct CdbDebugEnginePrivate
|
||||
|
||||
DebuggerStartMode m_mode;
|
||||
Utils::ConsoleProcess m_consoleStubProc;
|
||||
QString m_dbengDLL;
|
||||
};
|
||||
|
||||
// helper functions
|
||||
|
||||
@@ -457,7 +457,7 @@ bool CdbDumperHelper::initKnownTypes(QString *errorMessage)
|
||||
QString callCmd;
|
||||
QTextStream(&callCmd) << ".call " << m_dumpObjectSymbol << "(1,0,0,0,0,0,0,0)";
|
||||
const char *outData;
|
||||
if (!callDumper(callCmd, QByteArray(), &outData, false, errorMessage)) {
|
||||
if (callDumper(callCmd, QByteArray(), &outData, false, errorMessage) != CallOk) {
|
||||
return false;
|
||||
}
|
||||
if (!m_helper.parseQuery(outData, QtDumperHelper::CdbDebugger)) {
|
||||
@@ -490,7 +490,8 @@ bool CdbDumperHelper::writeToDebuggee(CIDebugDataSpaces *ds, const QByteArray &b
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CdbDumperHelper::callDumper(const QString &callCmd, const QByteArray &inBuffer, const char **outDataPtr,
|
||||
CdbDumperHelper::CallResult
|
||||
CdbDumperHelper::callDumper(const QString &callCmd, const QByteArray &inBuffer, const char **outDataPtr,
|
||||
bool ignoreAccessViolation, QString *errorMessage)
|
||||
{
|
||||
*outDataPtr = 0;
|
||||
@@ -499,10 +500,10 @@ bool CdbDumperHelper::callDumper(const QString &callCmd, const QByteArray &inBuf
|
||||
// write input buffer
|
||||
if (!inBuffer.isEmpty()) {
|
||||
if (!writeToDebuggee(m_cif->debugDataSpaces, inBuffer, m_inBufferAddress, errorMessage))
|
||||
return false;
|
||||
return CallFailed;
|
||||
}
|
||||
if (!CdbDebugEnginePrivate::executeDebuggerCommand(m_cif->debugControl, callCmd, errorMessage))
|
||||
return false;
|
||||
return CallSyntaxError;
|
||||
// Set up call and a temporary breakpoint after it.
|
||||
// Try to skip debuggee crash exceptions and dumper exceptions
|
||||
// by using 'gN' (go not handled -> pass handling to dumper __try/__catch block)
|
||||
@@ -514,11 +515,11 @@ bool CdbDumperHelper::callDumper(const QString &callCmd, const QByteArray &inBuf
|
||||
if (i)
|
||||
goCmd = QLatin1Char('N');
|
||||
if (!CdbDebugEnginePrivate::executeDebuggerCommand(m_cif->debugControl, goCmd, errorMessage))
|
||||
return false;
|
||||
return CallFailed;
|
||||
HRESULT hr = m_cif->debugControl->WaitForEvent(0, waitTimeOutMS);
|
||||
if (FAILED(hr)) {
|
||||
*errorMessage = msgComFailed("WaitForEvent", hr);
|
||||
return false;
|
||||
return CallFailed;
|
||||
}
|
||||
const int newExceptionCount = exLogger.exceptionCount();
|
||||
// no new exceptions? -> break
|
||||
@@ -535,13 +536,13 @@ bool CdbDumperHelper::callDumper(const QString &callCmd, const QByteArray &inBuf
|
||||
if (exLogger.exceptionCount()) {
|
||||
const QString exMsgs = exLogger.exceptionMessages().join(QString(QLatin1Char(',')));
|
||||
*errorMessage = QString::fromLatin1("Exceptions occurred during the dumper call: %1").arg(exMsgs);
|
||||
return false;
|
||||
return CallFailed;
|
||||
}
|
||||
// Read output
|
||||
const HRESULT hr = m_cif->debugDataSpaces->ReadVirtual(m_outBufferAddress, m_buffer, m_outBufferSize, 0);
|
||||
if (FAILED(hr)) {
|
||||
*errorMessage = msgComFailed("ReadVirtual", hr);
|
||||
return false;
|
||||
return CallFailed;
|
||||
}
|
||||
// see QDumper implementation
|
||||
const char result = m_buffer[0];
|
||||
@@ -550,16 +551,16 @@ bool CdbDumperHelper::callDumper(const QString &callCmd, const QByteArray &inBuf
|
||||
break;
|
||||
case '+':
|
||||
*errorMessage = QString::fromLatin1("Dumper call '%1' resulted in output overflow.").arg(callCmd);
|
||||
return false;
|
||||
return CallFailed;
|
||||
case 'f':
|
||||
*errorMessage = QString::fromLatin1("Dumper call '%1' failed.").arg(callCmd);
|
||||
return false;
|
||||
return CallFailed;
|
||||
default:
|
||||
*errorMessage = QString::fromLatin1("Dumper call '%1' failed ('%2').").arg(callCmd).arg(QLatin1Char(result));
|
||||
return false;
|
||||
return CallFailed;
|
||||
}
|
||||
*outDataPtr = m_buffer + 1;
|
||||
return true;
|
||||
return CallOk;
|
||||
}
|
||||
|
||||
static inline QString msgDumpFailed(const WatchData &wd, const QString *why)
|
||||
@@ -640,12 +641,11 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpTypeI(const WatchData &wd, bool
|
||||
const DumpExecuteResult der = executeDump(wd, td, dumpChildren, result, errorMessage);
|
||||
if (der == DumpExecuteOk)
|
||||
return DumpOk;
|
||||
// Cache types that fail due to complicated template size expressions.
|
||||
// Exceptions OTOH might occur when accessing variables that are not
|
||||
// yet initialized in a particular breakpoint. That should be ignored.
|
||||
// Also fail for complex expression that were not cached/replaced by the helper.
|
||||
if (der == DumpExecuteSizeFailed || der == DumpComplexExpressionEncountered)
|
||||
if (der == CallSyntaxError) {
|
||||
m_failedTypes.push_back(wd.type);
|
||||
if (dumpDebug)
|
||||
qDebug() << "Caching failing type/expression evaluation failed for " << wd.type;
|
||||
}
|
||||
// log error
|
||||
*errorMessage = msgDumpFailed(wd, errorMessage);
|
||||
m_manager->showDebuggerOutput(LogWarning, *errorMessage);
|
||||
@@ -661,37 +661,13 @@ CdbDumperHelper::DumpExecuteResult
|
||||
QStringList extraParameters;
|
||||
// Build parameter list.
|
||||
m_helper.evaluationParameters(wd, td, QtDumperHelper::CdbDebugger, &inBuffer, &extraParameters);
|
||||
// If the parameter list contains sizeof-expressions, execute them separately
|
||||
// and replace them by the resulting numbers
|
||||
const QString sizeOfExpr = QLatin1String("sizeof");
|
||||
const QStringList::iterator eend = extraParameters.end();
|
||||
for (QStringList::iterator it = extraParameters.begin() ; it != eend; ++it) {
|
||||
// Strip 'sizeof(X)' to 'X' and query size
|
||||
QString &ep = *it;
|
||||
if (ep.startsWith(sizeOfExpr)) {
|
||||
int size;
|
||||
ep.truncate(ep.lastIndexOf(QLatin1Char(')')));
|
||||
ep.remove(0, ep.indexOf(QLatin1Char('(')) + 1);
|
||||
const bool sizeOk = getTypeSize(ep, &size, errorMessage);
|
||||
if (loadDebug)
|
||||
qDebug() << "Size" << sizeOk << size << ep;
|
||||
if (!sizeOk)
|
||||
return DumpExecuteSizeFailed;
|
||||
ep = QString::number(size);
|
||||
continue;
|
||||
}
|
||||
// We cannot evaluate any other expressions than 'sizeof()' ;-(
|
||||
if (!ep.isEmpty() && !ep.at(0).isDigit()) {
|
||||
*errorMessage = QString::fromLatin1("Unable to evaluate: '%1'").arg(ep);
|
||||
return DumpComplexExpressionEncountered;
|
||||
}
|
||||
}
|
||||
// Execute call
|
||||
QString callCmd;
|
||||
QTextStream(&callCmd) << ".call " << m_dumpObjectSymbol
|
||||
<< "(2,0," << wd.addr << ','
|
||||
<< (dumpChildren ? 1 : 0) << ',' << extraParameters.join(QString(QLatin1Char(','))) << ')';
|
||||
if (loadDebug)
|
||||
QTextStream str(&callCmd);
|
||||
str << ".call " << m_dumpObjectSymbol << "(2,0," << wd.addr << ',' << (dumpChildren ? 1 : 0);
|
||||
foreach(const QString &e, extraParameters)
|
||||
str << ',' << e;
|
||||
str << ')';
|
||||
if (dumpDebug)
|
||||
qDebug() << "Query: " << wd.toString() << "\nwith: " << callCmd << '\n';
|
||||
const char *outputData;
|
||||
// Completely ignore EXCEPTION_ACCESS_VIOLATION crashes in the dumpers.
|
||||
@@ -700,8 +676,14 @@ CdbDumperHelper::DumpExecuteResult
|
||||
*errorMessage = eb.errorString();
|
||||
return DumpExecuteCallFailed;
|
||||
}
|
||||
if (!callDumper(callCmd, inBuffer, &outputData, true, errorMessage))
|
||||
switch (callDumper(callCmd, inBuffer, &outputData, true, errorMessage)) {
|
||||
case CallFailed:
|
||||
return DumpExecuteCallFailed;
|
||||
case CallSyntaxError:
|
||||
return DumpExpressionFailed;
|
||||
case CallOk:
|
||||
break;
|
||||
}
|
||||
if (!QtDumperHelper::parseValue(outputData, result)) {
|
||||
*errorMessage = QLatin1String("Parsing of value query output failed.");
|
||||
return DumpExecuteCallFailed;
|
||||
|
||||
@@ -122,12 +122,11 @@ private:
|
||||
|
||||
bool getTypeSize(const QString &typeName, int *size, QString *errorMessage);
|
||||
bool runTypeSizeQuery(const QString &typeName, int *size, QString *errorMessage);
|
||||
bool callDumper(const QString &call, const QByteArray &inBuffer, const char **outputPtr,
|
||||
enum CallResult { CallOk, CallSyntaxError, CallFailed };
|
||||
CallResult callDumper(const QString &call, const QByteArray &inBuffer, const char **outputPtr,
|
||||
bool ignoreAccessViolation, QString *errorMessage);
|
||||
|
||||
enum DumpExecuteResult { DumpExecuteOk, DumpExecuteSizeFailed,
|
||||
DumpComplexExpressionEncountered,
|
||||
DumpExecuteCallFailed };
|
||||
enum DumpExecuteResult { DumpExecuteOk, DumpExpressionFailed, DumpExecuteCallFailed };
|
||||
DumpExecuteResult executeDump(const WatchData &wd,
|
||||
const QtDumperHelper::TypeData& td, bool dumpChildren,
|
||||
QList<WatchData> *result, QString *errorMessage);
|
||||
|
||||
@@ -447,6 +447,12 @@ void DebuggerManager::init()
|
||||
connect(theDebuggerAction(AssignValue), SIGNAL(triggered()),
|
||||
this, SLOT(assignValueInDebugger()), Qt::QueuedConnection);
|
||||
|
||||
// Log
|
||||
connect(this, SIGNAL(emitShowInput(int, QString)),
|
||||
d->m_outputWindow, SLOT(showInput(int, QString)), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(emitShowOutput(int, QString)),
|
||||
d->m_outputWindow, SLOT(showOutput(int, QString)), Qt::QueuedConnection);
|
||||
|
||||
// Tooltip
|
||||
//QTreeView *tooltipView = qobject_cast<QTreeView *>(d->m_tooltipWindow);
|
||||
//tooltipView->setModel(d->m_watchHandler->model(TooltipsWatch));
|
||||
@@ -1401,7 +1407,7 @@ void DebuggerManager::modulesDockToggled(bool on)
|
||||
void DebuggerManager::showDebuggerOutput(int channel, const QString &msg)
|
||||
{
|
||||
if (d->m_outputWindow)
|
||||
d->m_outputWindow->showOutput(channel, msg);
|
||||
emit emitShowOutput(channel, msg);
|
||||
else
|
||||
qDebug() << "OUTPUT: " << channel << msg;
|
||||
}
|
||||
@@ -1409,7 +1415,7 @@ void DebuggerManager::showDebuggerOutput(int channel, const QString &msg)
|
||||
void DebuggerManager::showDebuggerInput(int channel, const QString &msg)
|
||||
{
|
||||
if (d->m_outputWindow)
|
||||
d->m_outputWindow->showInput(channel, msg);
|
||||
emit emitShowInput(channel, msg);
|
||||
else
|
||||
qDebug() << "INPUT: " << channel << msg;
|
||||
}
|
||||
|
||||
@@ -309,6 +309,8 @@ signals:
|
||||
void configValueRequested(const QString &name, QVariant *value);
|
||||
void setConfigValueRequested(const QString &name, const QVariant &value);
|
||||
void applicationOutputAvailable(const QString &output);
|
||||
void emitShowOutput(int channel, const QString &output);
|
||||
void emitShowInput(int channel, const QString &input);
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
@@ -50,7 +50,7 @@ AbstractGdbAdapter::~AbstractGdbAdapter()
|
||||
// This cannot be in the c'tor, as it would not connect the "virtual" slots
|
||||
void AbstractGdbAdapter::commonInit()
|
||||
{
|
||||
QTC_ASSERT(state() == DebuggerNotReady, qDebug() << state());
|
||||
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
|
||||
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
|
||||
this, SLOT(handleGdbError(QProcess::ProcessError)));
|
||||
connect(&m_gdbProc, SIGNAL(started()),
|
||||
|
||||
@@ -183,16 +183,6 @@ GdbEngine::GdbEngine(DebuggerManager *manager) :
|
||||
m_trkOptions->fromSettings(Core::ICore::instance()->settings());
|
||||
m_gdbAdapter = 0;
|
||||
|
||||
connect(this, SIGNAL(gdbOutputAvailable(int,QString)),
|
||||
m_manager, SLOT(showDebuggerOutput(int,QString)),
|
||||
Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(gdbInputAvailable(int,QString)),
|
||||
m_manager, SLOT(showDebuggerInput(int,QString)),
|
||||
Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(applicationOutputAvailable(QString)),
|
||||
m_manager, SLOT(showApplicationOutput(QString)),
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(theDebuggerAction(AutoDerefPointers), SIGNAL(valueChanged(QVariant)),
|
||||
this, SLOT(setAutoDerefPointers(QVariant)));
|
||||
}
|
||||
@@ -342,13 +332,13 @@ static void dump(const char *first, const char *middle, const QString & to)
|
||||
|
||||
void GdbEngine::readDebugeeOutput(const QByteArray &data)
|
||||
{
|
||||
emit applicationOutputAvailable(m_outputCodec->toUnicode(
|
||||
m_manager->showApplicationOutput(m_outputCodec->toUnicode(
|
||||
data.constData(), data.length(), &m_outputCodecState));
|
||||
}
|
||||
|
||||
void GdbEngine::debugMessage(const QString &msg)
|
||||
{
|
||||
emit gdbOutputAvailable(LogDebug, msg);
|
||||
gdbOutputAvailable(LogDebug, msg);
|
||||
}
|
||||
|
||||
void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
@@ -356,8 +346,8 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
static QTime lastTime;
|
||||
|
||||
if (theDebuggerBoolSetting(LogTimeStamps))
|
||||
emit gdbOutputAvailable(LogTime, currentTime());
|
||||
emit gdbOutputAvailable(LogOutput, QString::fromLocal8Bit(buff, buff.length()));
|
||||
gdbOutputAvailable(LogTime, currentTime());
|
||||
gdbOutputAvailable(LogOutput, QString::fromLocal8Bit(buff, buff.length()));
|
||||
|
||||
#if 0
|
||||
qDebug() // << "#### start response handling #### "
|
||||
@@ -424,7 +414,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
}
|
||||
}
|
||||
if (asyncClass == "stopped") {
|
||||
handleAsyncOutput(result);
|
||||
handleStopResponse(result);
|
||||
} else if (asyncClass == "running") {
|
||||
// Archer has 'thread-id="all"' here
|
||||
} else if (asyncClass == "library-loaded") {
|
||||
@@ -445,6 +435,9 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
// Archer has "{id="28902"}"
|
||||
QByteArray id = result.findChild("id").data();
|
||||
showStatusMessage(tr("Thread group %1 created.").arg(_(id)));
|
||||
int pid = id.toInt();
|
||||
if (pid != inferiorPid())
|
||||
handleInferiorPidChanged(pid);
|
||||
} else if (asyncClass == "thread-created") {
|
||||
//"{id="1",group-id="28902"}"
|
||||
QByteArray id = result.findChild("id").data();
|
||||
@@ -655,7 +648,7 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
|
||||
return;
|
||||
debugMessage(_("FOUND PID %1").arg(pid));
|
||||
|
||||
manager()->notifyInferiorPidChanged(pid);
|
||||
handleInferiorPidChanged(pid);
|
||||
if (m_dumperInjectionLoad)
|
||||
tryLoadDebuggingHelpers();
|
||||
}
|
||||
@@ -739,7 +732,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
|
||||
{
|
||||
GdbCommand cmd = cmd0;
|
||||
if (state() == DebuggerNotReady) {
|
||||
emit gdbInputAvailable(LogInput, cmd.command);
|
||||
gdbInputAvailable(LogInput, cmd.command);
|
||||
debugMessage(_("GDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + cmd.command);
|
||||
return;
|
||||
}
|
||||
@@ -750,7 +743,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
|
||||
cmd.command = QString::number(currentToken()) + cmd.command;
|
||||
if (cmd.flags & EmbedToken)
|
||||
cmd.command = cmd.command.arg(currentToken());
|
||||
emit gdbInputAvailable(LogInput, cmd.command);
|
||||
gdbInputAvailable(LogInput, cmd.command);
|
||||
|
||||
m_gdbAdapter->write(cmd.command.toLatin1() + "\r\n");
|
||||
}
|
||||
@@ -805,7 +798,7 @@ void GdbEngine::handleResultRecord(const GdbResponse &response)
|
||||
|
||||
GdbCommand cmd = m_cookieForToken.take(token);
|
||||
if (theDebuggerBoolSetting(LogTimeStamps)) {
|
||||
emit gdbOutputAvailable(LogTime, _("Response time: %1: %2 s")
|
||||
gdbOutputAvailable(LogTime, _("Response time: %1: %2 s")
|
||||
.arg(cmd.command)
|
||||
.arg(cmd.postTime.msecsTo(QTime::currentTime()) / 1000.));
|
||||
}
|
||||
@@ -843,10 +836,10 @@ void GdbEngine::handleResultRecord(const GdbResponse &response)
|
||||
// event loop is entered, and let individual commands have a flag to suppress
|
||||
// that behavior.
|
||||
if (m_commandsDoneCallback && m_cookieForToken.isEmpty()) {
|
||||
debugMessage(_("ALL COMMANDS DONE; INVOKING CALLBACK"));
|
||||
CommandsDoneCallback cont = m_commandsDoneCallback;
|
||||
m_commandsDoneCallback = 0;
|
||||
(this->*cont)();
|
||||
showStatusMessage(tr("Continuing after temporary stop."), 1000);
|
||||
} else {
|
||||
PENDING_DEBUG("MISSING TOKENS: " << m_cookieForToken.keys());
|
||||
}
|
||||
@@ -1011,7 +1004,7 @@ void GdbEngine::handleAqcuiredInferior()
|
||||
}
|
||||
#endif
|
||||
|
||||
void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
void GdbEngine::handleStopResponse(const GdbMi &data)
|
||||
{
|
||||
const QByteArray reason = data.findChild("reason").data();
|
||||
|
||||
@@ -1037,17 +1030,15 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
|
||||
QTC_ASSERT(state() == InferiorStopping, qDebug() << state())
|
||||
setState(InferiorStopped);
|
||||
showStatusMessage(tr("Stopped."), 5000);
|
||||
// FIXME: racy
|
||||
showStatusMessage(tr("Processing queued commands."), 1000);
|
||||
while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
|
||||
GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
|
||||
debugMessage(_("RUNNING QUEUED COMMAND %1 %2")
|
||||
.arg(cmd.command).arg(_(cmd.callbackName)));
|
||||
flushCommand(cmd);
|
||||
}
|
||||
showStatusMessage(tr("Processing queued commands."), 1000);
|
||||
QTC_ASSERT(m_commandsDoneCallback == 0, /**/);
|
||||
m_commandsDoneCallback = &GdbEngine::continueInferior;
|
||||
m_commandsDoneCallback = &GdbEngine::autoContinueInferior;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1109,22 +1100,19 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
}
|
||||
|
||||
if (isStoppedReason(reason) || reason.isEmpty()) {
|
||||
QVariant var = QVariant::fromValue<GdbMi>(data);
|
||||
|
||||
// Don't load helpers on stops triggered by signals unless it's
|
||||
// an intentional trap.
|
||||
bool initHelpers = m_debuggingHelperState == DebuggingHelperUninitialized;
|
||||
if (reason == "signal-received"
|
||||
if (initHelpers && reason == "signal-received"
|
||||
&& data.findChild("signal-name").data() != "SIGTRAP")
|
||||
initHelpers = false;
|
||||
|
||||
if (initHelpers) {
|
||||
tryLoadDebuggingHelpers();
|
||||
QVariant var = QVariant::fromValue<GdbMi>(data);
|
||||
postCommand(_("p 4"), CB(handleStop1), var); // dummy
|
||||
} else {
|
||||
GdbResponse response;
|
||||
response.cookie = var;
|
||||
handleStop1(response);
|
||||
handleStop1(data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1152,7 +1140,11 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
|
||||
void GdbEngine::handleStop1(const GdbResponse &response)
|
||||
{
|
||||
GdbMi data = response.cookie.value<GdbMi>();
|
||||
handleStop1(response.cookie.value<GdbMi>());
|
||||
}
|
||||
|
||||
void GdbEngine::handleStop1(const GdbMi &data)
|
||||
{
|
||||
QByteArray reason = data.findChild("reason").data();
|
||||
if (m_modulesListOutdated) {
|
||||
reloadModules();
|
||||
@@ -1476,16 +1468,27 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp)
|
||||
m_gdbAdapter->startAdapter();
|
||||
}
|
||||
|
||||
void GdbEngine::continueInferior()
|
||||
void GdbEngine::continueInferiorInternal()
|
||||
{
|
||||
QTC_ASSERT(state() == InferiorStopped, qDebug() << state());
|
||||
m_manager->resetLocation();
|
||||
setTokenBarrier();
|
||||
setState(InferiorRunningRequested);
|
||||
showStatusMessage(tr("Running requested..."), 5000);
|
||||
postCommand(_("-exec-continue"), CB(handleExecContinue));
|
||||
}
|
||||
|
||||
void GdbEngine::autoContinueInferior()
|
||||
{
|
||||
continueInferiorInternal();
|
||||
showStatusMessage(tr("Continuing after temporary stop..."), 1000);
|
||||
}
|
||||
|
||||
void GdbEngine::continueInferior()
|
||||
{
|
||||
continueInferiorInternal();
|
||||
showStatusMessage(tr("Running requested..."), 5000);
|
||||
}
|
||||
|
||||
void GdbEngine::stepExec()
|
||||
{
|
||||
QTC_ASSERT(state() == InferiorStopped, qDebug() << state());
|
||||
@@ -1618,7 +1621,7 @@ void GdbEngine::setTokenBarrier()
|
||||
);
|
||||
}
|
||||
PENDING_DEBUG("\n--- token barrier ---\n");
|
||||
emit gdbInputAvailable(LogMisc, _("--- token barrier ---"));
|
||||
gdbInputAvailable(LogMisc, _("--- token barrier ---"));
|
||||
m_oldestAcceptableToken = currentToken();
|
||||
}
|
||||
|
||||
@@ -1754,7 +1757,7 @@ void GdbEngine::sendInsertBreakpoint(int index)
|
||||
// cmd += _("-c ") + data->condition + ' ';
|
||||
#endif
|
||||
cmd += where;
|
||||
emit gdbOutputAvailable(LogStatus, _("Current state: %1").arg(state()));
|
||||
gdbOutputAvailable(LogStatus, _("Current state: %1").arg(state()));
|
||||
postCommand(cmd, NeedsStop, CB(handleBreakInsert), index);
|
||||
}
|
||||
|
||||
@@ -2715,7 +2718,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
|
||||
// Avoid endless loops created by faulty dumpers.
|
||||
QString processedName = QString(_("%1-%2").arg(dumpChildren).arg(data.iname));
|
||||
if (m_processedNames.contains(processedName)) {
|
||||
emit gdbInputAvailable(LogStatus,
|
||||
gdbInputAvailable(LogStatus,
|
||||
_("<Breaking endless loop for %1>").arg(data.iname));
|
||||
data.setAllUnneeded();
|
||||
data.setValue(_("<unavailable>"));
|
||||
@@ -2972,7 +2975,7 @@ void GdbEngine::rebuildModel()
|
||||
++count;
|
||||
m_processedNames.clear();
|
||||
PENDING_DEBUG("REBUILDING MODEL" << count);
|
||||
emit gdbInputAvailable(LogStatus, _("<Rebuild Watchmodel %1>").arg(count));
|
||||
gdbInputAvailable(LogStatus, _("<Rebuild Watchmodel %1>").arg(count));
|
||||
showStatusMessage(tr("Finished retrieving data."), 400);
|
||||
manager()->watchHandler()->endCycle();
|
||||
showToolTip();
|
||||
@@ -3044,7 +3047,7 @@ void GdbEngine::sendWatchParameters(const QByteArray ¶ms0)
|
||||
const QString inBufferCmd = arrayFillCommand("qDumpInBuffer", params);
|
||||
|
||||
params.replace('\0','!');
|
||||
emit gdbInputAvailable(LogMisc, QString::fromUtf8(params));
|
||||
gdbInputAvailable(LogMisc, QString::fromUtf8(params));
|
||||
|
||||
params.clear();
|
||||
params.append('\0');
|
||||
|
||||
@@ -87,11 +87,6 @@ public:
|
||||
explicit GdbEngine(DebuggerManager *manager);
|
||||
~GdbEngine();
|
||||
|
||||
signals:
|
||||
void gdbInputAvailable(int channel, const QString &msg);
|
||||
void gdbOutputAvailable(int channel, const QString &msg);
|
||||
void applicationOutputAvailable(const QString &output);
|
||||
|
||||
private:
|
||||
friend class AbstractGdbAdapter;
|
||||
friend class AttachGdbAdapter;
|
||||
@@ -115,6 +110,8 @@ private:
|
||||
void exitDebugger();
|
||||
void detachDebugger();
|
||||
|
||||
void continueInferiorInternal();
|
||||
void autoContinueInferior();
|
||||
void continueInferior();
|
||||
void interruptInferior();
|
||||
|
||||
@@ -233,6 +230,11 @@ private:
|
||||
void updateAll();
|
||||
void updateLocals();
|
||||
|
||||
void gdbInputAvailable(int channel, const QString &msg)
|
||||
{ m_manager->showDebuggerInput(channel, msg); }
|
||||
void gdbOutputAvailable(int channel, const QString &msg)
|
||||
{ m_manager->showDebuggerOutput(channel, msg); }
|
||||
|
||||
private slots:
|
||||
void readGdbStandardOutput();
|
||||
void readGdbStandardError();
|
||||
@@ -255,8 +257,9 @@ private:
|
||||
int terminationIndex(const QByteArray &buffer, int &length);
|
||||
void handleResponse(const QByteArray &buff);
|
||||
void handleStart(const GdbResponse &response);
|
||||
void handleAsyncOutput(const GdbMi &data);
|
||||
void handleStopResponse(const GdbMi &data);
|
||||
void handleStop1(const GdbResponse &response);
|
||||
void handleStop1(const GdbMi &data);
|
||||
void handleStop2(const GdbResponse &response);
|
||||
void handleStop2(const GdbMi &data);
|
||||
void handleResultRecord(const GdbResponse &response);
|
||||
@@ -275,6 +278,7 @@ private:
|
||||
QMainWindow *mainWindow() const;
|
||||
DebuggerStartMode startMode() const;
|
||||
qint64 inferiorPid() const { return m_manager->inferiorPid(); }
|
||||
void handleInferiorPidChanged(qint64 pid) { manager()->notifyInferiorPidChanged(pid); }
|
||||
|
||||
void handleChildren(const WatchData &parent, const GdbMi &child,
|
||||
QList<WatchData> *insertions);
|
||||
|
||||
@@ -1710,29 +1710,6 @@ void TrkGdbAdapter::handleFirstContinue(const GdbResponse &record)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
// Prepend environment of the Symbian Gdb by Cygwin '/bin'
|
||||
static void setGdbCygwinEnvironment(const QString &cygwin, QProcess *process)
|
||||
{
|
||||
if (cygwin.isEmpty() || !QFileInfo(cygwin).isDir())
|
||||
return;
|
||||
const QString cygwinBinPath = QDir::toNativeSeparators(cygwin) + QLatin1String("\\bin");
|
||||
QStringList env = process->environment();
|
||||
if (env.isEmpty())
|
||||
env = QProcess::systemEnvironment();
|
||||
const QRegExp pathPattern(QLatin1String("^PATH=.*"), Qt::CaseInsensitive);
|
||||
const int index = env.indexOf(pathPattern);
|
||||
if (index == -1)
|
||||
return;
|
||||
QString pathValue = env.at(index).mid(5);
|
||||
if (pathValue.startsWith(cygwinBinPath))
|
||||
return;
|
||||
env[index] = QLatin1String("PATH=") + cygwinBinPath + QLatin1Char(';');
|
||||
process->setEnvironment(env);
|
||||
}
|
||||
#endif
|
||||
|
||||
void TrkGdbAdapter::startGdb()
|
||||
{
|
||||
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
|
||||
@@ -1762,9 +1739,6 @@ void TrkGdbAdapter::startGdb()
|
||||
gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file
|
||||
gdbArgs.append(QLatin1String("-i"));
|
||||
gdbArgs.append(QLatin1String("mi"));
|
||||
#ifdef Q_OS_WIN
|
||||
setGdbCygwinEnvironment(m_options->cygwin, &m_gdbProc);
|
||||
#endif
|
||||
m_gdbProc.start(m_options->gdb, gdbArgs);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,24 +54,6 @@ static const char *modeKeyC = "Mode";
|
||||
static const char *blueToothDeviceKeyC = "BlueToothDevice";
|
||||
static const char *blueToothDeviceDefaultC = "/dev/rfcomm0";
|
||||
static const char *gdbKeyC = "gdb";
|
||||
static const char *cygwinKeyC = "Cygwin";
|
||||
|
||||
static inline QString cygwinDefault()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
// Some smartness to check for Cygwin
|
||||
static bool firstTime = true;
|
||||
static QString rc = QLatin1String("C:/cygwin");
|
||||
if (firstTime) {
|
||||
if (!QFileInfo(rc).isDir())
|
||||
rc.clear();
|
||||
firstTime = false;
|
||||
}
|
||||
return rc;
|
||||
#else
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
@@ -80,8 +62,7 @@ TrkOptions::TrkOptions() :
|
||||
mode(modeDefault),
|
||||
serialPort(QLatin1String(serialPortDefaultC)),
|
||||
blueToothDevice(QLatin1String(blueToothDeviceDefaultC)),
|
||||
gdb(QLatin1String(gdbDefaultC)),
|
||||
cygwin(cygwinDefault())
|
||||
gdb(QLatin1String(gdbDefaultC))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -91,7 +72,6 @@ void TrkOptions::fromSettings(const QSettings *s)
|
||||
mode = s->value(keyRoot + QLatin1String(modeKeyC), modeDefault).toInt();
|
||||
serialPort = s->value(keyRoot + QLatin1String(serialPortKeyC), QLatin1String(serialPortDefaultC)).toString();
|
||||
gdb = s->value(keyRoot + QLatin1String(gdbKeyC),QLatin1String(gdbDefaultC)).toString();
|
||||
cygwin = s->value(keyRoot + QLatin1String(cygwinKeyC), cygwinDefault()).toString();
|
||||
blueToothDevice = s->value(keyRoot + QLatin1String(blueToothDeviceKeyC), QLatin1String(blueToothDeviceDefaultC)).toString();
|
||||
}
|
||||
|
||||
@@ -102,7 +82,6 @@ void TrkOptions::toSettings(QSettings *s) const
|
||||
s->setValue(QLatin1String(serialPortKeyC), serialPort);
|
||||
s->setValue(QLatin1String(blueToothDeviceKeyC), blueToothDevice);
|
||||
s->setValue(QLatin1String(gdbKeyC), gdb);
|
||||
s->setValue(QLatin1String(cygwinKeyC), cygwin);
|
||||
s->endGroup();
|
||||
}
|
||||
|
||||
@@ -117,10 +96,6 @@ bool TrkOptions::check(QString *errorMessage) const
|
||||
*errorMessage = QCoreApplication::translate("TrkOptions", "The Symbian gdb executable '%1' could not be found in the search path.").arg(gdb);
|
||||
return false;
|
||||
}
|
||||
if (!cygwin.isEmpty() && !QFileInfo(cygwin).isDir()) {
|
||||
*errorMessage = QCoreApplication::translate("TrkOptions", "The Cygwin directory '%1' does not exist.").arg(cygwin);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -129,8 +104,7 @@ bool TrkOptions::equals(const TrkOptions &o) const
|
||||
return mode == o.mode
|
||||
&& serialPort == o.serialPort
|
||||
&& blueToothDevice == o.blueToothDevice
|
||||
&& gdb == o.gdb
|
||||
&& cygwin == o.cygwin;
|
||||
&& gdb == o.gdb;
|
||||
}
|
||||
|
||||
QStringList TrkOptions::serialPorts()
|
||||
|
||||
@@ -40,8 +40,7 @@ namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
/* Parameter to be used for debugging S60 via TRK.
|
||||
* GDB is a Symbian-ARM Gdb. It is Cygwin-built on Windows; the cygwin
|
||||
* location 'x/bin' will prepended to the execution path.
|
||||
* GDB is a Symbian-ARM Gdb.
|
||||
* Communication happens either via BlueTooth (Linux only) or
|
||||
* serial ports. */
|
||||
|
||||
@@ -64,7 +63,6 @@ struct TrkOptions
|
||||
QString serialPort;
|
||||
QString blueToothDevice;
|
||||
QString gdb;
|
||||
QString cygwin; // ignored on Linux
|
||||
};
|
||||
|
||||
inline bool operator==(const TrkOptions &o1, const TrkOptions &o2)
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
const char * const TRK_SETTINGS_ID = QT_TRANSLATE_NOOP("Debugger::Internal::TrkOptionsPage", "S60 / Trk");
|
||||
const char * const TRK_SETTINGS_ID = QT_TRANSLATE_NOOP("Debugger::Internal::TrkOptionsPage", "Symbian Trk");
|
||||
|
||||
TrkOptionsPage::TrkOptionsPage(const TrkOptionsPtr &options) :
|
||||
m_options(options)
|
||||
|
||||
@@ -41,16 +41,12 @@ TrkOptionsWidget::TrkOptionsWidget(QWidget *parent) :
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->gdbChooser->setExpectedKind(Utils::PathChooser::Command);
|
||||
ui->cygwinChooser->setExpectedKind(Utils::PathChooser::Directory);
|
||||
ui->blueToothComboBox->addItems(TrkOptions::blueToothDevices());
|
||||
ui->serialComboBox->addItems(TrkOptions::serialPorts());
|
||||
connect(ui->commComboBox, SIGNAL(currentIndexChanged(int)), ui->commStackedWidget, SLOT(setCurrentIndex(int)));
|
||||
// No bluetooth on Windows yet...
|
||||
#ifdef Q_OS_WIN
|
||||
ui->commComboBox->setEnabled(false);
|
||||
#else
|
||||
ui->cygwinChooser->setVisible(false);
|
||||
ui->cygwinLabel->setVisible(false);
|
||||
ui->commGroupBox->setVisible(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -78,7 +74,6 @@ void TrkOptionsWidget::setTrkOptions(const TrkOptions &o)
|
||||
const int serialPortIndex = qMax(0, ui->serialComboBox->findText(o.serialPort));
|
||||
ui->serialComboBox->setCurrentIndex(serialPortIndex);
|
||||
ui->gdbChooser->setPath(o.gdb);
|
||||
ui->cygwinChooser->setPath(o.cygwin);
|
||||
const int blueToothIndex = qMax(0, ui->blueToothComboBox->findText(o.blueToothDevice));
|
||||
ui->blueToothComboBox->setCurrentIndex(blueToothIndex);
|
||||
}
|
||||
@@ -88,7 +83,6 @@ TrkOptions TrkOptionsWidget::trkOptions() const
|
||||
TrkOptions rc;
|
||||
rc.mode = ui->commComboBox->currentIndex();
|
||||
rc.gdb = ui->gdbChooser->path();
|
||||
rc.cygwin = ui->cygwinChooser->path();
|
||||
rc.blueToothDevice = ui->blueToothComboBox->currentText();
|
||||
rc.serialPort = ui->serialComboBox->currentText();
|
||||
return rc;
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
<string>Gdb</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="gdbLabel">
|
||||
<property name="text">
|
||||
@@ -30,16 +33,6 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="Utils::PathChooser" name="gdbChooser" native="true"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="cygwinLabel">
|
||||
<property name="text">
|
||||
<string>Cygwin location:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Utils::PathChooser" name="cygwinChooser" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -366,11 +366,11 @@ GuessChildrenResult guessChildren(const QString &type)
|
||||
return HasPossiblyChildren;
|
||||
}
|
||||
|
||||
QString sizeofTypeExpression(const QString &type)
|
||||
QString sizeofTypeExpression(const QString &type, QtDumperHelper::Debugger debugger)
|
||||
{
|
||||
if (type.endsWith(QLatin1Char('*')))
|
||||
return QLatin1String("sizeof(void*)");
|
||||
if (type.endsWith(QLatin1Char('>')))
|
||||
if (debugger != QtDumperHelper::GdbDebugger || type.endsWith(QLatin1Char('>')))
|
||||
return QLatin1String("sizeof(") + type + QLatin1Char(')');
|
||||
return QLatin1String("sizeof(") + gdbQuoteTypes(type) + QLatin1Char(')');
|
||||
}
|
||||
@@ -838,7 +838,7 @@ QtDumperHelper::TypeData QtDumperHelper::typeData(const QString &typeName) const
|
||||
// Format an expression to have the debugger query the
|
||||
// size. Use size cache if possible
|
||||
QString QtDumperHelper::evaluationSizeofTypeExpression(const QString &typeName,
|
||||
Debugger /* debugger */) const
|
||||
Debugger debugger) const
|
||||
{
|
||||
// Look up special size types
|
||||
const SpecialSizeType st = specialSizeType(typeName);
|
||||
@@ -851,7 +851,7 @@ QString QtDumperHelper::evaluationSizeofTypeExpression(const QString &typeName,
|
||||
if (sit != m_sizeCache.constEnd())
|
||||
return QString::number(sit.value());
|
||||
// Finally have the debugger evaluate
|
||||
return sizeofTypeExpression(typeName);
|
||||
return sizeofTypeExpression(typeName, debugger);
|
||||
}
|
||||
|
||||
QtDumperHelper::SpecialSizeType QtDumperHelper::specialSizeType(const QString &typeName) const
|
||||
@@ -962,24 +962,17 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
|
||||
//qDebug() << "OUTERTYPE: " << outertype << " NODETYPE: " << nodetype
|
||||
// << "QT VERSION" << m_qtVersion << ((4 << 16) + (5 << 8) + 0);
|
||||
extraArgs[2] = evaluationSizeofTypeExpression(nodetype, debugger);
|
||||
extraArgs[3] = QLatin1String("(size_t)&(('");
|
||||
extraArgs[3] += nodetype;
|
||||
extraArgs[3] += QLatin1String("'*)0)->value");
|
||||
extraArgs[3] = qMapNodeValueOffsetExpression(nodetype, data.addr, debugger);
|
||||
}
|
||||
break;
|
||||
case QMapNodeType:
|
||||
extraArgs[2] = evaluationSizeofTypeExpression(data.type, debugger);
|
||||
extraArgs[3] = QLatin1String("(size_t)&(('");
|
||||
extraArgs[3] += data.type;
|
||||
extraArgs[3] += QLatin1String("'*)0)->value");
|
||||
extraArgs[3] = qMapNodeValueOffsetExpression(data.type, data.addr, debugger);
|
||||
break;
|
||||
case StdVectorType:
|
||||
//qDebug() << "EXTRACT TEMPLATE: " << outertype << inners;
|
||||
if (inners.at(0) == QLatin1String("bool")) {
|
||||
outertype = QLatin1String("std::vector::bool");
|
||||
} else {
|
||||
//extraArgs[extraArgCount++] = evaluationSizeofTypeExpression(data.type, debugger);
|
||||
//extraArgs[extraArgCount++] = "(size_t)&(('" + data.type + "'*)0)->value";
|
||||
}
|
||||
break;
|
||||
case StdDequeType:
|
||||
@@ -995,27 +988,40 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
|
||||
extraArgs[2] = zero;
|
||||
break;
|
||||
case StdMapType: {
|
||||
// We don't want the comparator and the allocator confuse gdb.
|
||||
// But we need the offset of the second item in the value pair.
|
||||
// We need the offset of the second item in the value pair.
|
||||
// We read the type of the pair from the allocator argument because
|
||||
// that gets the constness "right" (in the sense that gdb can
|
||||
// that gets the constness "right" (in the sense that gdb/cdb can
|
||||
// read it back: "std::allocator<std::pair<Key,Value> >"
|
||||
// -> "std::pair<Key,Value>". Different debuggers have varying
|
||||
// amounts of terminating blanks...
|
||||
extraArgs[2].clear();
|
||||
extraArgs[3] = zero;
|
||||
QString pairType = inners.at(3);
|
||||
int bracketPos = pairType.indexOf(QLatin1Char('<'));
|
||||
if (bracketPos != -1)
|
||||
pairType.remove(0, bracketPos + 1);
|
||||
// We don't want the comparator and the allocator confuse gdb.
|
||||
const QChar closingBracket = QLatin1Char('>');
|
||||
bracketPos = pairType.lastIndexOf(closingBracket);
|
||||
if (bracketPos != -1)
|
||||
bracketPos = pairType.lastIndexOf(closingBracket, bracketPos - pairType.size() - 1);
|
||||
if (bracketPos != -1)
|
||||
pairType.truncate(bracketPos + 1);
|
||||
if (debugger == GdbDebugger) {
|
||||
extraArgs[2] = QLatin1String("(size_t)&(('");
|
||||
extraArgs[2] += pairType;
|
||||
extraArgs[2] += QLatin1String("'*)0)->second");
|
||||
extraArgs[3] = zero;
|
||||
} else {
|
||||
// Cdb: The std::pair is usually in scope. Still, this expression
|
||||
// occasionally fails for complex types (std::string).
|
||||
// We need an address as CDB cannot do the 0-trick.
|
||||
// Use data address or try at least cache if missing.
|
||||
const QString address = data.addr.isEmpty() ? QString::fromLatin1("DUMMY_ADDRESS") : data.addr;
|
||||
QString offsetExpr;
|
||||
QTextStream str(&offsetExpr);
|
||||
str << "(size_t)&(((" << pairType << " *)" << address << ")->second)" << '-' << address;
|
||||
extraArgs[2] = lookupCdbDummyAddressExpression(offsetExpr, address);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case StdStringType:
|
||||
@@ -1068,6 +1074,45 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
|
||||
qDebug() << '\n' << Q_FUNC_INFO << '\n' << data.toString() << "\n-->" << outertype << td.type << extraArgs;
|
||||
}
|
||||
|
||||
// Return debugger expression to get the offset of a map node.
|
||||
QString QtDumperHelper::qMapNodeValueOffsetExpression(const QString &type,
|
||||
const QString &addressIn,
|
||||
Debugger debugger) const
|
||||
{
|
||||
switch (debugger) {
|
||||
case GdbDebugger:
|
||||
return QLatin1String("(size_t)&(('") + type + QLatin1String("'*)0)->value");
|
||||
case CdbDebugger: {
|
||||
// Cdb: This will only work if a QMapNode is in scope.
|
||||
// We need an address as CDB cannot do the 0-trick.
|
||||
// Use data address or try at least cache if missing.
|
||||
const QString address = addressIn.isEmpty() ? QString::fromLatin1("DUMMY_ADDRESS") : addressIn;
|
||||
QString offsetExpression;
|
||||
QTextStream(&offsetExpression) << "(size_t)&(((" << type
|
||||
<< " *)" << address << ")->value)-" << address;
|
||||
return lookupCdbDummyAddressExpression(offsetExpression, address);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
/* Cdb cannot do tricks like ( "&(std::pair<int,int>*)(0)->second)",
|
||||
* that is, use a null pointer to determine the offset of a member.
|
||||
* It tries to dereference the address at some point and fails with
|
||||
* "memory access error". As a trick, use the address of the watch item
|
||||
* to do this. However, in the expression cache, 0 is still used, so,
|
||||
* for cache lookups, use '0' as address. */
|
||||
QString QtDumperHelper::lookupCdbDummyAddressExpression(const QString &expr,
|
||||
const QString &address) const
|
||||
{
|
||||
QString nullExpr = expr;
|
||||
nullExpr.replace(address, QString(QLatin1Char('0')));
|
||||
const QString rc = m_expressionCache.value(nullExpr, expr);
|
||||
if (debug)
|
||||
qDebug() << "lookupCdbDummyAddressExpression" << expr << rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// GdbMi parsing helpers for parsing dumper value results
|
||||
|
||||
static bool gdbMiGetIntValue(int *target,
|
||||
|
||||
@@ -79,7 +79,6 @@ bool isSymbianIntType(const QString &type);
|
||||
enum GuessChildrenResult { HasChildren, HasNoChildren, HasPossiblyChildren };
|
||||
GuessChildrenResult guessChildren(const QString &type);
|
||||
|
||||
QString sizeofTypeExpression(const QString &type);
|
||||
QString quoteUnprintableLatin1(const QByteArray &ba);
|
||||
|
||||
// Editor tooltip support
|
||||
@@ -193,6 +192,11 @@ private:
|
||||
static Type specialType(QString s);
|
||||
QString evaluationSizeofTypeExpression(const QString &typeName, Debugger d) const;
|
||||
void parseQueryTypes(const QStringList &l, Debugger debugger);
|
||||
QString qMapNodeValueOffsetExpression(const QString &type,
|
||||
const QString &addressIn,
|
||||
Debugger debugger) const;
|
||||
|
||||
inline QString lookupCdbDummyAddressExpression(const QString &expr, const QString &address) const;
|
||||
|
||||
NameTypeMap m_nameTypeMap;
|
||||
SizeCache m_sizeCache;
|
||||
|
||||
@@ -241,53 +241,41 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
m_diffAction = new Utils::ParameterAction(tr("Diff Current File"), tr("Diff \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_diffAction, "Git.Diff", globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+D")));
|
||||
#endif
|
||||
connect(m_diffAction, SIGNAL(triggered()), this, SLOT(diffCurrentFile()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_statusAction = new Utils::ParameterAction(tr("File Status"), tr("Status Related to \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_statusAction, "Git.Status", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+S")));
|
||||
#endif
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_statusAction, SIGNAL(triggered()), this, SLOT(statusFile()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_logAction = new Utils::ParameterAction(tr("Log File"), tr("Log of \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_logAction, "Git.Log", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+L")));
|
||||
#endif
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_logAction, SIGNAL(triggered()), this, SLOT(logFile()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_blameAction = new Utils::ParameterAction(tr("Blame"), tr("Blame for \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_blameAction, "Git.Blame", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+B")));
|
||||
#endif
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_blameAction, SIGNAL(triggered()), this, SLOT(blameFile()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_undoFileAction = new Utils::ParameterAction(tr("Undo Changes"), tr("Undo Changes for \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_undoFileAction, "Git.Undo", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+U")));
|
||||
#endif
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_undoFileAction, SIGNAL(triggered()), this, SLOT(undoFileChanges()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_stageAction = new Utils::ParameterAction(tr("Stage File for Commit"), tr("Stage \"%1\" for Commit"), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_stageAction, "Git.Stage", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+A")));
|
||||
#endif
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_stageAction, SIGNAL(triggered()), this, SLOT(stageFile()));
|
||||
gitContainer->addAction(command);
|
||||
@@ -302,9 +290,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
|
||||
m_diffProjectAction = new Utils::ParameterAction(tr("Diff Current Project"), tr("Diff Project \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_diffProjectAction, "Git.DiffProject", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence("Alt+G,Alt+Shift+D"));
|
||||
#endif
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_diffProjectAction, SIGNAL(triggered()), this, SLOT(diffCurrentProject()));
|
||||
gitContainer->addAction(command);
|
||||
@@ -317,9 +303,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
|
||||
m_logProjectAction = new Utils::ParameterAction(tr("Log Project"), tr("Log Project \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_logProjectAction, "Git.LogProject", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+K")));
|
||||
#endif
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_logProjectAction, SIGNAL(triggered()), this, SLOT(logProject()));
|
||||
gitContainer->addAction(command);
|
||||
@@ -354,9 +338,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
|
||||
m_commitAction = new QAction(tr("Commit..."), this);
|
||||
command = actionManager->registerAction(m_commitAction, "Git.Commit", globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+C")));
|
||||
#endif
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_commitAction, SIGNAL(triggered()), this, SLOT(startCommit()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
@@ -260,9 +260,7 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
m_editAction = new Utils::ParameterAction(tr("Edit"), tr("Edit \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
|
||||
command = am->registerAction(m_editAction, CMD_ID_EDIT, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+P,Alt+E")));
|
||||
#endif
|
||||
command->setDefaultText(tr("Edit File"));
|
||||
connect(m_editAction, SIGNAL(triggered()), this, SLOT(openCurrentFile()));
|
||||
mperforce->addAction(command);
|
||||
@@ -270,9 +268,7 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
m_addAction = new Utils::ParameterAction(tr("Add"), tr("Add \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
|
||||
command = am->registerAction(m_addAction, CMD_ID_ADD, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+P,Alt+A")));
|
||||
#endif
|
||||
command->setDefaultText(tr("Add File"));
|
||||
connect(m_addAction, SIGNAL(triggered()), this, SLOT(addCurrentFile()));
|
||||
mperforce->addAction(command);
|
||||
@@ -287,9 +283,7 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
m_revertAction = new Utils::ParameterAction(tr("Revert"), tr("Revert \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
|
||||
command = am->registerAction(m_revertAction, CMD_ID_REVERT, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+P,Alt+R")));
|
||||
#endif
|
||||
command->setDefaultText(tr("Revert File"));
|
||||
connect(m_revertAction, SIGNAL(triggered()), this, SLOT(revertCurrentFile()));
|
||||
mperforce->addAction(command);
|
||||
@@ -310,9 +304,7 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
m_diffProjectAction = new Utils::ParameterAction(diffProjectDefaultText, tr("Diff Project \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = am->registerAction(m_diffProjectAction, CMD_ID_DIFF_PROJECT, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+P,Alt+D")));
|
||||
#endif
|
||||
command->setDefaultText(diffProjectDefaultText);
|
||||
connect(m_diffProjectAction, SIGNAL(triggered()), this, SLOT(diffCurrentProject()));
|
||||
mperforce->addAction(command);
|
||||
@@ -329,9 +321,7 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
|
||||
m_openedAction = new QAction(tr("Opened"), this);
|
||||
command = am->registerAction(m_openedAction, CMD_ID_OPENED, globalcontext);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+P,Alt+O")));
|
||||
#endif
|
||||
connect(m_openedAction, SIGNAL(triggered()), this, SLOT(printOpenedFileList()));
|
||||
mperforce->addAction(command);
|
||||
|
||||
@@ -379,9 +369,7 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
m_filelogCurrentAction = new Utils::ParameterAction(tr("Filelog Current File"), tr("Filelog \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
|
||||
command = am->registerAction(m_filelogCurrentAction, CMD_ID_FILELOG_CURRENT, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+P,Alt+F")));
|
||||
#endif
|
||||
command->setDefaultText(tr("Filelog Current File"));
|
||||
connect(m_filelogCurrentAction, SIGNAL(triggered()), this, SLOT(filelogCurrentFile()));
|
||||
mperforce->addAction(command);
|
||||
|
||||
@@ -109,6 +109,7 @@ void BuildSettingsSubWidgets::addWidget(const QString &name, QWidget *widget)
|
||||
layout()->addWidget(label);
|
||||
layout()->addWidget(widget);
|
||||
|
||||
m_spacerItems.append(item);
|
||||
m_labels.append(label);
|
||||
m_widgets.append(widget);
|
||||
}
|
||||
@@ -122,6 +123,7 @@ void BuildSettingsSubWidgets::clear()
|
||||
qDeleteAll(m_labels);
|
||||
m_widgets.clear();
|
||||
m_labels.clear();
|
||||
m_spacerItems.clear();
|
||||
}
|
||||
|
||||
QList<QWidget *> BuildSettingsSubWidgets::widgets() const
|
||||
@@ -306,13 +308,16 @@ void BuildSettingsWidget::cloneConfiguration(const QString &sourceConfiguration)
|
||||
return;
|
||||
|
||||
QString newDisplayName = newBuildConfiguration;
|
||||
// Check that the internal name is not taken and use a different one otherwise
|
||||
if (m_project->buildConfiguration(newBuildConfiguration)) {
|
||||
int i = 2;
|
||||
while (m_project->buildConfiguration(newBuildConfiguration + QString::number(i)))
|
||||
++i;
|
||||
newBuildConfiguration += QString::number(i);
|
||||
}
|
||||
QStringList buildConfigurationDisplayNames;
|
||||
foreach(BuildConfiguration *bc, m_project->buildConfigurations())
|
||||
buildConfigurationDisplayNames << bc->displayName();
|
||||
newDisplayName = Project::makeUnique(newDisplayName, buildConfigurationDisplayNames);
|
||||
|
||||
QStringList buildConfigurationNames;
|
||||
foreach(BuildConfiguration *bc, m_project->buildConfigurations())
|
||||
buildConfigurationNames << bc->name();
|
||||
|
||||
newBuildConfiguration = Project::makeUnique(newBuildConfiguration, buildConfigurationNames);
|
||||
|
||||
m_project->copyBuildConfiguration(sourceConfiguration, newBuildConfiguration);
|
||||
m_project->setDisplayNameFor(m_project->buildConfiguration(newBuildConfiguration), newDisplayName);
|
||||
|
||||
@@ -210,7 +210,7 @@ Core::NavigationView FolderNavigationWidgetFactory::createWidget()
|
||||
toggleSync->setChecked(ptw->autoSynchronization());
|
||||
toggleSync->setToolTip(tr("Synchronize with Editor"));
|
||||
connect(toggleSync, SIGNAL(clicked(bool)), ptw, SLOT(toggleAutoSynchronization()));
|
||||
n.doockToolBarWidgets << toggleSync;
|
||||
n.dockToolBarWidgets << toggleSync;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,15 +150,10 @@ void Project::addBuildConfiguration(BuildConfiguration *configuration)
|
||||
void Project::removeBuildConfiguration(BuildConfiguration *configuration)
|
||||
{
|
||||
//todo: this might be error prone
|
||||
if (!buildConfigurations().contains(configuration))
|
||||
if (!m_buildConfigurationValues.contains(configuration))
|
||||
return;
|
||||
|
||||
for (int i = 0; i != m_buildConfigurationValues.size(); ++i)
|
||||
if (m_buildConfigurationValues.at(i)->name() == configuration->name()) {
|
||||
delete m_buildConfigurationValues.at(i);
|
||||
m_buildConfigurationValues.removeAt(i);
|
||||
break;
|
||||
}
|
||||
m_buildConfigurationValues.removeOne(configuration);
|
||||
|
||||
for (int i = 0; i != m_buildSteps.size(); ++i)
|
||||
m_buildSteps.at(i)->removeBuildConfiguration(configuration->name());
|
||||
@@ -166,6 +161,7 @@ void Project::removeBuildConfiguration(BuildConfiguration *configuration)
|
||||
m_cleanSteps.at(i)->removeBuildConfiguration(configuration->name());
|
||||
|
||||
emit removedBuildConfiguration(this, configuration->name());
|
||||
delete configuration;
|
||||
}
|
||||
|
||||
void Project::copyBuildConfiguration(const QString &source, const QString &dest)
|
||||
|
||||
@@ -141,6 +141,7 @@ public:
|
||||
virtual QStringList includePaths(const QString &fileName) const;
|
||||
virtual QStringList frameworkPaths(const QString &fileName) const;
|
||||
|
||||
static QString makeUnique(const QString &preferedName, const QStringList &usedNames);
|
||||
signals:
|
||||
void fileListChanged();
|
||||
|
||||
@@ -183,7 +184,6 @@ protected:
|
||||
virtual bool restoreSettingsImpl(PersistentSettingsReader &reader);
|
||||
|
||||
private:
|
||||
static QString makeUnique(const QString &preferedName, const QStringList &usedNames);
|
||||
QList<BuildStep *> m_buildSteps;
|
||||
QList<BuildStep *> m_cleanSteps;
|
||||
QMap<QString, QVariant> m_values;
|
||||
|
||||
@@ -383,7 +383,7 @@ Core::NavigationView ProjectTreeWidgetFactory::createWidget()
|
||||
filterMenu->addAction(ptw->m_filterGeneratedFilesAction);
|
||||
filter->setMenu(filterMenu);
|
||||
|
||||
n.doockToolBarWidgets << filter << ptw->toggleSync();
|
||||
n.dockToolBarWidgets << filter << ptw->toggleSync();
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -112,33 +112,6 @@ ProjectLoadWizard::~ProjectLoadWizard()
|
||||
|
||||
}
|
||||
|
||||
void ProjectLoadWizard::addBuildConfiguration(QString buildConfigurationName, QtVersion *qtversion, QtVersion::QmakeBuildConfig qmakeBuildConfiguration, QStringList additionalArguments)
|
||||
{
|
||||
QMakeStep *qmakeStep = m_project->qmakeStep();
|
||||
MakeStep *makeStep = m_project->makeStep();
|
||||
|
||||
bool debug = qmakeBuildConfiguration & QtVersion::DebugBuild;
|
||||
|
||||
// Add the buildconfiguration
|
||||
ProjectExplorer::BuildConfiguration *bc = new ProjectExplorer::BuildConfiguration(buildConfigurationName);
|
||||
m_project->addBuildConfiguration(bc);
|
||||
const QString &finalBuildConfigurationName = bc->name();
|
||||
qmakeStep->setValue(finalBuildConfigurationName, "qmakeArgs", additionalArguments);
|
||||
|
||||
// set some options for qmake and make
|
||||
if (qmakeBuildConfiguration & QtVersion::BuildAll) // debug_and_release => explicit targets
|
||||
makeStep->setValue(finalBuildConfigurationName, "makeargs", QStringList() << (debug ? "debug" : "release"));
|
||||
|
||||
bc->setValue("buildConfiguration", int(qmakeBuildConfiguration));
|
||||
|
||||
// Finally set the qt version
|
||||
bool defaultQtVersion = (qtversion == 0);
|
||||
if (defaultQtVersion)
|
||||
m_project->setQtVersion(bc, 0);
|
||||
else
|
||||
m_project->setQtVersion(bc, qtversion->uniqueId());
|
||||
}
|
||||
|
||||
void ProjectLoadWizard::done(int result)
|
||||
{
|
||||
QtVersionManager *vm = QtVersionManager::instance();
|
||||
@@ -154,7 +127,7 @@ void ProjectLoadWizard::done(int result)
|
||||
// qDebug()<<"Creating m_buildconfiguration entry from imported stuff";
|
||||
// qDebug()<<((m_importBuildConfig& QtVersion::BuildAll)? "debug_and_release" : "")<<((m_importBuildConfig & QtVersion::DebugBuild)? "debug" : "release");
|
||||
bool debug = m_importBuildConfig & QtVersion::DebugBuild;
|
||||
addBuildConfiguration(debug ? "Debug" : "Release", m_importVersion, m_importBuildConfig, m_additionalArguments);
|
||||
m_project->addQt4BuildConfiguration(debug ? "Debug" : "Release", m_importVersion, m_importBuildConfig, m_additionalArguments);
|
||||
|
||||
if (m_importBuildConfig & QtVersion::BuildAll) {
|
||||
// Also create the other configuration
|
||||
@@ -164,7 +137,7 @@ void ProjectLoadWizard::done(int result)
|
||||
else
|
||||
otherBuildConfiguration = QtVersion::QmakeBuildConfig(otherBuildConfiguration | QtVersion::DebugBuild);
|
||||
|
||||
addBuildConfiguration(debug ? "Release" : "Debug", m_importVersion, otherBuildConfiguration, m_additionalArguments);
|
||||
m_project->addQt4BuildConfiguration(debug ? "Release" : "Debug", m_importVersion, otherBuildConfiguration, m_additionalArguments);
|
||||
}
|
||||
} else {
|
||||
// Not importing
|
||||
@@ -176,11 +149,11 @@ void ProjectLoadWizard::done(int result)
|
||||
if (defaultVersion && defaultVersion->isValid() && (defaultVersion->defaultBuildConfig() & QtVersion::BuildAll))
|
||||
buildAll = true;
|
||||
if (buildAll) {
|
||||
addBuildConfiguration("Debug", 0, QtVersion::QmakeBuildConfig(QtVersion::BuildAll | QtVersion::DebugBuild), m_additionalArguments);
|
||||
addBuildConfiguration("Release", 0, QtVersion::BuildAll, m_additionalArguments);
|
||||
m_project->addQt4BuildConfiguration("Debug", 0, QtVersion::QmakeBuildConfig(QtVersion::BuildAll | QtVersion::DebugBuild), m_additionalArguments);
|
||||
m_project->addQt4BuildConfiguration("Release", 0, QtVersion::BuildAll, m_additionalArguments);
|
||||
} else {
|
||||
addBuildConfiguration("Debug", 0, QtVersion::DebugBuild, m_additionalArguments);
|
||||
addBuildConfiguration("Release", 0, QtVersion::QmakeBuildConfig(0), m_additionalArguments);
|
||||
m_project->addQt4BuildConfiguration("Debug", 0, QtVersion::DebugBuild, m_additionalArguments);
|
||||
m_project->addQt4BuildConfiguration("Release", 0, QtVersion::QmakeBuildConfig(0), m_additionalArguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ public:
|
||||
void execDialog();
|
||||
|
||||
private:
|
||||
void addBuildConfiguration(QString name, QtVersion *qtversion, QtVersion::QmakeBuildConfig buildConfiguration, QStringList additionalArguments);
|
||||
void setupImportPage(QtVersion *version, QtVersion::QmakeBuildConfig buildConfig, QStringList addtionalArguments);
|
||||
|
||||
Qt4Project *m_project;
|
||||
|
||||
@@ -74,7 +74,7 @@ S60DeviceRunConfiguration::S60DeviceRunConfiguration(Project *project, const QSt
|
||||
m_signingMode(SignSelf)
|
||||
{
|
||||
if (!m_proFilePath.isEmpty())
|
||||
setName(tr("%1 on S60 Device").arg(QFileInfo(m_proFilePath).completeBaseName()));
|
||||
setName(tr("%1 on Symbian Device").arg(QFileInfo(m_proFilePath).completeBaseName()));
|
||||
else
|
||||
setName(tr("QtS60DeviceRunConfiguration"));
|
||||
|
||||
@@ -470,7 +470,7 @@ QStringList S60DeviceRunConfigurationFactory::availableCreationTypes(Project *pr
|
||||
QStringList applicationProFiles;
|
||||
QList<Qt4ProFileNode *> list = qt4project->applicationProFiles();
|
||||
foreach (Qt4ProFileNode * node, list) {
|
||||
applicationProFiles.append("QtS60DeviceRunConfiguration." + node->path());
|
||||
applicationProFiles.append("QtSymbianDeviceRunConfiguration." + node->path());
|
||||
}
|
||||
return applicationProFiles;
|
||||
} else {
|
||||
@@ -480,16 +480,16 @@ QStringList S60DeviceRunConfigurationFactory::availableCreationTypes(Project *pr
|
||||
|
||||
QString S60DeviceRunConfigurationFactory::displayNameForType(const QString &type) const
|
||||
{
|
||||
QString fileName = type.mid(QString("QtS60DeviceRunConfiguration.").size());
|
||||
return tr("%1 on S60 Device").arg(QFileInfo(fileName).completeBaseName());
|
||||
QString fileName = type.mid(QString("QtSymbianDeviceRunConfiguration.").size());
|
||||
return tr("%1 on Symbian Device").arg(QFileInfo(fileName).completeBaseName());
|
||||
}
|
||||
|
||||
QSharedPointer<RunConfiguration> S60DeviceRunConfigurationFactory::create(Project *project, const QString &type)
|
||||
{
|
||||
Qt4Project *p = qobject_cast<Qt4Project *>(project);
|
||||
Q_ASSERT(p);
|
||||
if (type.startsWith("QtS60DeviceRunConfiguration.")) {
|
||||
QString fileName = type.mid(QString("QtS60DeviceRunConfiguration.").size());
|
||||
if (type.startsWith("QtSymbianDeviceRunConfiguration.")) {
|
||||
QString fileName = type.mid(QString("QtSymbianDeviceRunConfiguration.").size());
|
||||
return QSharedPointer<RunConfiguration>(new S60DeviceRunConfiguration(p, fileName));
|
||||
}
|
||||
Q_ASSERT(type == "Qt4ProjectManager.DeviceRunConfiguration");
|
||||
@@ -564,7 +564,8 @@ void S60DeviceRunControlBase::start()
|
||||
if (!checkConfiguration(&errorMessage, &settingsCategory, &settingsPage)) {
|
||||
error(this, errorMessage);
|
||||
emit finished();
|
||||
Core::ICore::instance()->showWarningWithOptions(tr("S60 Debugger"), errorMessage, QString(),
|
||||
Core::ICore::instance()->showWarningWithOptions(tr("Debugger for Symbian Platform"),
|
||||
errorMessage, QString(),
|
||||
settingsCategory, settingsPage);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,9 +52,9 @@ S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Project *project, const
|
||||
m_cachedTargetInformationValid(false)
|
||||
{
|
||||
if (!m_proFilePath.isEmpty())
|
||||
setName(tr("%1 in S60 Emulator").arg(QFileInfo(m_proFilePath).completeBaseName()));
|
||||
setName(tr("%1 in Symbian Emulator").arg(QFileInfo(m_proFilePath).completeBaseName()));
|
||||
else
|
||||
setName(tr("QtS60EmulatorRunConfiguration"));
|
||||
setName(tr("QtSymbianEmulatorRunConfiguration"));
|
||||
|
||||
connect(project, SIGNAL(activeBuildConfigurationChanged()),
|
||||
this, SLOT(invalidateCachedTargetInformation()));
|
||||
@@ -141,7 +141,7 @@ void S60EmulatorRunConfiguration::updateTarget()
|
||||
|
||||
if (!reader->readProFile(m_proFilePath)) {
|
||||
delete reader;
|
||||
Core::ICore::instance()->messageManager()->printToOutputPane(tr("Could not parse %1. The QtS60 emulator run configuration %2 can not be started.").arg(m_proFilePath).arg(name()));
|
||||
Core::ICore::instance()->messageManager()->printToOutputPane(tr("Could not parse %1. The Qt for Symbian emulator run configuration %2 can not be started.").arg(m_proFilePath).arg(name()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ QStringList S60EmulatorRunConfigurationFactory::availableCreationTypes(Project *
|
||||
QStringList applicationProFiles;
|
||||
QList<Qt4ProFileNode *> list = qt4project->applicationProFiles();
|
||||
foreach (Qt4ProFileNode * node, list) {
|
||||
applicationProFiles.append("QtS60EmulatorRunConfiguration." + node->path());
|
||||
applicationProFiles.append("QtSymbianEmulatorRunConfiguration." + node->path());
|
||||
}
|
||||
return applicationProFiles;
|
||||
} else {
|
||||
@@ -238,16 +238,16 @@ QStringList S60EmulatorRunConfigurationFactory::availableCreationTypes(Project *
|
||||
|
||||
QString S60EmulatorRunConfigurationFactory::displayNameForType(const QString &type) const
|
||||
{
|
||||
QString fileName = type.mid(QString("QtS60EmulatorRunConfiguration.").size());
|
||||
return tr("%1 in S60 Emulator").arg(QFileInfo(fileName).completeBaseName());
|
||||
QString fileName = type.mid(QString("QtSymbianEmulatorRunConfiguration.").size());
|
||||
return tr("%1 in Symbian Emulator").arg(QFileInfo(fileName).completeBaseName());
|
||||
}
|
||||
|
||||
QSharedPointer<RunConfiguration> S60EmulatorRunConfigurationFactory::create(Project *project, const QString &type)
|
||||
{
|
||||
Qt4Project *p = qobject_cast<Qt4Project *>(project);
|
||||
Q_ASSERT(p);
|
||||
if (type.startsWith("QtS60EmulatorRunConfiguration.")) {
|
||||
QString fileName = type.mid(QString("QtS60EmulatorRunConfiguration.").size());
|
||||
if (type.startsWith("QtSymbianEmulatorRunConfiguration.")) {
|
||||
QString fileName = type.mid(QString("QtSymbianEmulatorRunConfiguration.").size());
|
||||
return QSharedPointer<RunConfiguration>(new S60EmulatorRunConfiguration(p, fileName));
|
||||
}
|
||||
Q_ASSERT(type == "Qt4ProjectManager.EmulatorRunConfiguration");
|
||||
|
||||
@@ -168,11 +168,11 @@ void S60Manager::updateQtVersions()
|
||||
}
|
||||
}
|
||||
if (deviceVersion) {
|
||||
deviceVersion->setName(QString("%1 (Qt %2)").arg(device.id, deviceVersion->qtVersionString()));
|
||||
deviceVersion->setQMakeCommand(device.qt+"/bin/qmake.exe");
|
||||
deviceVersion->setName(QString("%1 (Qt %2)").arg(device.id, deviceVersion->qtVersionString()));
|
||||
handledVersions.append(deviceVersion);
|
||||
} else {
|
||||
deviceVersion = new QtVersion(QString("%1 (Qt %2)").arg(device.id), device.qt,
|
||||
deviceVersion = new QtVersion(QString("%1 (Qt %2)").arg(device.id), device.qt+"/bin/qmake.exe",
|
||||
true, QString("%1.%2").arg(S60_AUTODETECTION_SOURCE, device.id));
|
||||
deviceVersion->setName(deviceVersion->name().arg(deviceVersion->qtVersionString()));
|
||||
versionsToAdd.append(deviceVersion);
|
||||
|
||||
@@ -283,9 +283,15 @@ bool Qt4BuildConfigurationFactory::create(const QString &type) const
|
||||
&ok);
|
||||
if (!ok || buildConfigurationName.isEmpty())
|
||||
return false;
|
||||
BuildConfiguration *bc = new BuildConfiguration(buildConfigurationName);
|
||||
bc->setValue(KEY_QT_VERSION_ID, info.versionId);
|
||||
m_project->addBuildConfiguration(bc);
|
||||
|
||||
QtVersion *version = QtVersionManager::instance()->version(info.versionId);
|
||||
|
||||
m_project->addQt4BuildConfiguration(tr("%1 Debug").arg(buildConfigurationName),
|
||||
version,
|
||||
(QtVersion::QmakeBuildConfig)(version->defaultBuildConfig() | QtVersion::DebugBuild));
|
||||
m_project->addQt4BuildConfiguration(tr("%1 Release").arg(buildConfigurationName),
|
||||
version,
|
||||
(QtVersion::QmakeBuildConfig)(version->defaultBuildConfig() & ~QtVersion::DebugBuild));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -431,6 +437,36 @@ ProjectExplorer::IBuildConfigurationFactory *Qt4Project::buildConfigurationFacto
|
||||
return m_buildConfigurationFactory;
|
||||
}
|
||||
|
||||
void Qt4Project::addQt4BuildConfiguration(QString buildConfigurationName, QtVersion *qtversion,
|
||||
QtVersion::QmakeBuildConfig qmakeBuildConfiguration,
|
||||
QStringList additionalArguments)
|
||||
{
|
||||
QMakeStep *qmake = qmakeStep();
|
||||
MakeStep *make = makeStep();
|
||||
|
||||
bool debug = qmakeBuildConfiguration & QtVersion::DebugBuild;
|
||||
|
||||
// Add the buildconfiguration
|
||||
ProjectExplorer::BuildConfiguration *bc = new ProjectExplorer::BuildConfiguration(buildConfigurationName);
|
||||
addBuildConfiguration(bc);
|
||||
const QString &finalBuildConfigurationName = bc->name();
|
||||
if (!additionalArguments.isEmpty())
|
||||
qmake->setValue(finalBuildConfigurationName, "qmakeArgs", additionalArguments);
|
||||
|
||||
// set some options for qmake and make
|
||||
if (qmakeBuildConfiguration & QtVersion::BuildAll) // debug_and_release => explicit targets
|
||||
make->setValue(finalBuildConfigurationName, "makeargs", QStringList() << (debug ? "debug" : "release"));
|
||||
|
||||
bc->setValue("buildConfiguration", int(qmakeBuildConfiguration));
|
||||
|
||||
// Finally set the qt version
|
||||
bool defaultQtVersion = (qtversion == 0);
|
||||
if (defaultQtVersion)
|
||||
setQtVersion(bc, 0);
|
||||
else
|
||||
setQtVersion(bc, qtversion->uniqueId());
|
||||
}
|
||||
|
||||
namespace {
|
||||
class FindQt4ProFiles: protected ProjectExplorer::NodesVisitor {
|
||||
QList<Qt4ProFileNode *> m_proFiles;
|
||||
|
||||
@@ -160,6 +160,11 @@ public:
|
||||
Qt4Manager *qt4ProjectManager() const;
|
||||
ProjectExplorer::IBuildConfigurationFactory *buildConfigurationFactory() const;
|
||||
|
||||
void addQt4BuildConfiguration(QString buildConfigurationName,
|
||||
QtVersion *qtversion,
|
||||
QtVersion::QmakeBuildConfig qmakeBuildConfiguration,
|
||||
QStringList additionalArguments = QStringList());
|
||||
|
||||
QList<Core::IFile *> dependencies(); //NBS remove
|
||||
QList<ProjectExplorer::Project *>dependsOn();
|
||||
|
||||
|
||||
@@ -293,9 +293,7 @@ bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMe
|
||||
command = ami->registerAction(m_addAction, CMD_ID_ADD,
|
||||
globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+S,Alt+A")));
|
||||
#endif
|
||||
connect(m_addAction, SIGNAL(triggered()), this, SLOT(addCurrentFile()));
|
||||
subversionMenu->addAction(command);
|
||||
|
||||
@@ -325,9 +323,7 @@ bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMe
|
||||
command = ami->registerAction(m_diffCurrentAction,
|
||||
CMD_ID_DIFF_CURRENT, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+S,Alt+D")));
|
||||
#endif
|
||||
connect(m_diffCurrentAction, SIGNAL(triggered()), this, SLOT(diffCurrentFile()));
|
||||
subversionMenu->addAction(command);
|
||||
|
||||
@@ -343,9 +339,7 @@ bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMe
|
||||
command = ami->registerAction(m_commitCurrentAction,
|
||||
CMD_ID_COMMIT_CURRENT, globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+S,Alt+C")));
|
||||
#endif
|
||||
connect(m_commitCurrentAction, SIGNAL(triggered()), this, SLOT(startCommitCurrentFile()));
|
||||
subversionMenu->addAction(command);
|
||||
|
||||
|
||||
@@ -141,11 +141,15 @@ void TextEditorActionHandler::createActions()
|
||||
advancedMenu->addAction(command, Core::Constants::G_EDIT_FORMAT);
|
||||
connect(m_formatAction, SIGNAL(triggered(bool)), this, SLOT(formatAction()));
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
QString modifier = tr("Meta");
|
||||
#else
|
||||
QString modifier = tr("Ctrl");
|
||||
#endif
|
||||
|
||||
m_rewrapParagraphAction = new QAction(tr("&Rewrap Paragraph"), this);
|
||||
command = am->registerAction(m_rewrapParagraphAction, TextEditor::Constants::REWRAP_PARAGRAPH, m_contextId);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+E, R")));
|
||||
#endif
|
||||
command->setDefaultKeySequence(QKeySequence(tr("%1+E, R").arg(modifier)));
|
||||
advancedMenu->addAction(command, Core::Constants::G_EDIT_FORMAT);
|
||||
connect(m_rewrapParagraphAction, SIGNAL(triggered(bool)), this, SLOT(rewrapParagraphAction()));
|
||||
|
||||
@@ -154,9 +158,7 @@ void TextEditorActionHandler::createActions()
|
||||
m_visualizeWhitespaceAction->setCheckable(true);
|
||||
command = am->registerAction(m_visualizeWhitespaceAction,
|
||||
TextEditor::Constants::VISUALIZE_WHITESPACE, m_contextId);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+E, Ctrl+V")));
|
||||
#endif
|
||||
command->setDefaultKeySequence(QKeySequence(tr("%1+E, %2+V").arg(modifier, modifier)));
|
||||
advancedMenu->addAction(command, Core::Constants::G_EDIT_FORMAT);
|
||||
connect(m_visualizeWhitespaceAction, SIGNAL(triggered(bool)), this, SLOT(setVisualizeWhitespace(bool)));
|
||||
|
||||
@@ -170,9 +172,7 @@ void TextEditorActionHandler::createActions()
|
||||
m_textWrappingAction = new QAction(tr("Enable Text &Wrapping"), this);
|
||||
m_textWrappingAction->setCheckable(true);
|
||||
command = am->registerAction(m_textWrappingAction, TextEditor::Constants::TEXT_WRAPPING, m_contextId);
|
||||
#ifndef Q_WS_MAC
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+E, Ctrl+W")));
|
||||
#endif
|
||||
command->setDefaultKeySequence(QKeySequence(tr("%1+E, %2+W").arg(modifier, modifier)));
|
||||
advancedMenu->addAction(command, Core::Constants::G_EDIT_FORMAT);
|
||||
connect(m_textWrappingAction, SIGNAL(triggered(bool)), this, SLOT(setTextWrapping(bool)));
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ CommunityWelcomePageWidget::CommunityWelcomePageWidget(QWidget *parent) :
|
||||
ui->sitesTreeWidget->addItem(tr("Qt Labs"), QLatin1String("http://labs.trolltech.com"));
|
||||
ui->sitesTreeWidget->addItem(tr("Qt Git Hosting"), QLatin1String("http://qt.gitorious.org"));
|
||||
ui->sitesTreeWidget->addItem(tr("Qt Centre"), QLatin1String("http://www.qtcentre.org"));
|
||||
ui->sitesTreeWidget->addItem(tr("Qt for S60 at Forum Nokia"), QLatin1String("http://discussion.forum.nokia.com/forum/forumdisplay.php?f=196"));
|
||||
ui->sitesTreeWidget->addItem(tr("Qt for Symbian at Forum Nokia"), QLatin1String("http://discussion.forum.nokia.com/forum/forumdisplay.php?f=196"));
|
||||
}
|
||||
|
||||
CommunityWelcomePageWidget::~CommunityWelcomePageWidget()
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef CPLUSPLUS_PRETTYPRINTER_H
|
||||
#define CPLUSPLUS_PRETTYPRINTER_H
|
||||
|
||||
#include "CPlusPlusForwardDeclarations.h"
|
||||
#include "ASTVisitor.h"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <QByteArray>
|
||||
|
||||
CPLUSPLUS_BEGIN_HEADER
|
||||
CPLUSPLUS_BEGIN_NAMESPACE
|
||||
|
||||
class CPLUSPLUS_EXPORT PrettyPrinter: protected ASTVisitor
|
||||
{
|
||||
public:
|
||||
PrettyPrinter(Control *control, std::ostream &out);
|
||||
|
||||
void operator()(AST *ast, const QByteArray &contents);
|
||||
|
||||
protected:
|
||||
virtual bool visit(AccessDeclarationAST *ast);
|
||||
virtual bool visit(ArrayAccessAST *ast);
|
||||
virtual bool visit(ArrayDeclaratorAST *ast);
|
||||
virtual bool visit(ArrayInitializerAST *ast);
|
||||
virtual bool visit(AsmDefinitionAST *ast);
|
||||
virtual bool visit(AttributeSpecifierAST *ast);
|
||||
virtual bool visit(AttributeAST *ast);
|
||||
virtual bool visit(BaseSpecifierAST *ast);
|
||||
virtual bool visit(BinaryExpressionAST *ast);
|
||||
virtual bool visit(BoolLiteralAST *ast);
|
||||
virtual bool visit(BreakStatementAST *ast);
|
||||
virtual bool visit(CallAST *ast);
|
||||
virtual bool visit(CaseStatementAST *ast);
|
||||
virtual bool visit(CastExpressionAST *ast);
|
||||
virtual bool visit(CatchClauseAST *ast);
|
||||
virtual bool visit(ClassSpecifierAST *ast);
|
||||
virtual bool visit(CompoundLiteralAST *ast);
|
||||
virtual bool visit(CompoundStatementAST *ast);
|
||||
virtual bool visit(ConditionAST *ast);
|
||||
virtual bool visit(ConditionalExpressionAST *ast);
|
||||
virtual bool visit(ContinueStatementAST *ast);
|
||||
virtual bool visit(ConversionFunctionIdAST *ast);
|
||||
virtual bool visit(CppCastExpressionAST *ast);
|
||||
virtual bool visit(CtorInitializerAST *ast);
|
||||
virtual bool visit(DeclaratorAST *ast);
|
||||
virtual bool visit(DeclarationStatementAST *ast);
|
||||
virtual bool visit(DeclaratorIdAST *ast);
|
||||
virtual bool visit(DeclaratorListAST *ast);
|
||||
virtual bool visit(DeleteExpressionAST *ast);
|
||||
virtual bool visit(DestructorNameAST *ast);
|
||||
virtual bool visit(DoStatementAST *ast);
|
||||
virtual bool visit(ElaboratedTypeSpecifierAST *ast);
|
||||
virtual bool visit(EmptyDeclarationAST *ast);
|
||||
virtual bool visit(EnumSpecifierAST *ast);
|
||||
virtual bool visit(EnumeratorAST *ast);
|
||||
virtual bool visit(ExceptionDeclarationAST *ast);
|
||||
virtual bool visit(ExceptionSpecificationAST *ast);
|
||||
virtual bool visit(ExpressionListAST *ast);
|
||||
virtual bool visit(ExpressionOrDeclarationStatementAST *ast);
|
||||
virtual bool visit(ExpressionStatementAST *ast);
|
||||
virtual bool visit(ForStatementAST *ast);
|
||||
virtual bool visit(FunctionDeclaratorAST *ast);
|
||||
virtual bool visit(FunctionDefinitionAST *ast);
|
||||
virtual bool visit(GotoStatementAST *ast);
|
||||
virtual bool visit(IfStatementAST *ast);
|
||||
virtual bool visit(LabeledStatementAST *ast);
|
||||
virtual bool visit(LinkageBodyAST *ast);
|
||||
virtual bool visit(LinkageSpecificationAST *ast);
|
||||
virtual bool visit(MemInitializerAST *ast);
|
||||
virtual bool visit(MemberAccessAST *ast);
|
||||
virtual bool visit(NamedTypeSpecifierAST *ast);
|
||||
virtual bool visit(NamespaceAST *ast);
|
||||
virtual bool visit(NamespaceAliasDefinitionAST *ast);
|
||||
virtual bool visit(NestedDeclaratorAST *ast);
|
||||
virtual bool visit(NestedExpressionAST *ast);
|
||||
virtual bool visit(NestedNameSpecifierAST *ast);
|
||||
virtual bool visit(NewArrayDeclaratorAST *ast);
|
||||
virtual bool visit(NewPlacementAST *ast);
|
||||
virtual bool visit(NewExpressionAST *ast);
|
||||
virtual bool visit(NewInitializerAST *ast);
|
||||
virtual bool visit(NewTypeIdAST *ast);
|
||||
virtual bool visit(NumericLiteralAST *ast);
|
||||
virtual bool visit(OperatorAST *ast);
|
||||
virtual bool visit(OperatorFunctionIdAST *ast);
|
||||
virtual bool visit(ParameterDeclarationAST *ast);
|
||||
virtual bool visit(ParameterDeclarationClauseAST *ast);
|
||||
virtual bool visit(PointerAST *ast);
|
||||
virtual bool visit(PointerToMemberAST *ast);
|
||||
virtual bool visit(PostIncrDecrAST *ast);
|
||||
virtual bool visit(PostfixExpressionAST *ast);
|
||||
virtual bool visit(QualifiedNameAST *ast);
|
||||
virtual bool visit(ReferenceAST *ast);
|
||||
virtual bool visit(ReturnStatementAST *ast);
|
||||
virtual bool visit(SimpleDeclarationAST *ast);
|
||||
virtual bool visit(SimpleNameAST *ast);
|
||||
virtual bool visit(SimpleSpecifierAST *ast);
|
||||
virtual bool visit(SizeofExpressionAST *ast);
|
||||
virtual bool visit(StringLiteralAST *ast);
|
||||
virtual bool visit(SwitchStatementAST *ast);
|
||||
virtual bool visit(TemplateArgumentListAST *ast);
|
||||
virtual bool visit(TemplateDeclarationAST *ast);
|
||||
virtual bool visit(TemplateIdAST *ast);
|
||||
virtual bool visit(TemplateTypeParameterAST *ast);
|
||||
virtual bool visit(ThisExpressionAST *ast);
|
||||
virtual bool visit(ThrowExpressionAST *ast);
|
||||
virtual bool visit(TranslationUnitAST *ast);
|
||||
virtual bool visit(TryBlockStatementAST *ast);
|
||||
virtual bool visit(TypeConstructorCallAST *ast);
|
||||
virtual bool visit(TypeIdAST *ast);
|
||||
virtual bool visit(TypeidExpressionAST *ast);
|
||||
virtual bool visit(TypeofSpecifierAST *ast);
|
||||
virtual bool visit(TypenameCallExpressionAST *ast);
|
||||
virtual bool visit(TypenameTypeParameterAST *ast);
|
||||
virtual bool visit(UnaryExpressionAST *ast);
|
||||
virtual bool visit(UsingAST *ast);
|
||||
virtual bool visit(UsingDirectiveAST *ast);
|
||||
virtual bool visit(WhileStatementAST *ast);
|
||||
virtual bool visit(QtMethodAST *ast);
|
||||
|
||||
void indent();
|
||||
void deindent();
|
||||
void newline();
|
||||
void outToken(unsigned token);
|
||||
|
||||
private:
|
||||
std::ostream &_out;
|
||||
unsigned _depth;
|
||||
|
||||
unsigned _lastToken;
|
||||
QByteArray _contents;
|
||||
};
|
||||
|
||||
CPLUSPLUS_END_NAMESPACE
|
||||
CPLUSPLUS_END_HEADER
|
||||
|
||||
#endif // CPLUSPLUS_PRETTYPRINTER_H
|
||||
@@ -36,7 +36,6 @@ HEADERS += \
|
||||
$$PWD/TranslationUnit.h \
|
||||
$$PWD/Type.h \
|
||||
$$PWD/TypeVisitor.h \
|
||||
$$PWD/PrettyPrinter.h \
|
||||
$$PWD/ObjectiveCTypeQualifiers.h
|
||||
|
||||
SOURCES += \
|
||||
@@ -75,6 +74,6 @@ SOURCES += \
|
||||
$$PWD/Token.cpp \
|
||||
$$PWD/TranslationUnit.cpp \
|
||||
$$PWD/Type.cpp \
|
||||
$$PWD/TypeVisitor.cpp \
|
||||
$$PWD/PrettyPrinter.cpp
|
||||
$$PWD/TypeVisitor.cpp
|
||||
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
void queueTrkInitialPing();
|
||||
|
||||
// Call this from the device read notification with the results.
|
||||
void slotHandleResult(const TrkResult &result);
|
||||
void slotHandleResult(const TrkResult &result, QMutex *mutex = 0);
|
||||
|
||||
// pendingMessage() can be called periodically in a timer to retrieve
|
||||
// the pending messages to be sent.
|
||||
@@ -252,30 +252,37 @@ void TrkWriteQueue::notifyWriteResult(WriteResult wr)
|
||||
}
|
||||
}
|
||||
|
||||
void TrkWriteQueue::slotHandleResult(const TrkResult &result)
|
||||
void TrkWriteQueue::slotHandleResult(const TrkResult &result, QMutex *mutex)
|
||||
{
|
||||
m_trkWriteBusy = false;
|
||||
//if (result.code != TrkNotifyAck && result.code != TrkNotifyNak)
|
||||
// return;
|
||||
// Find which request the message belongs to and invoke callback
|
||||
// if ACK or on NAK if desired.
|
||||
if (mutex)
|
||||
mutex->lock();
|
||||
m_trkWriteBusy = false;
|
||||
const TokenMessageMap::iterator it = m_writtenTrkMessages.find(result.token);
|
||||
if (it == m_writtenTrkMessages.end())
|
||||
if (it == m_writtenTrkMessages.end()) {
|
||||
if (mutex)
|
||||
mutex->unlock();
|
||||
return;
|
||||
const bool invokeCB = it.value().callback;
|
||||
if (invokeCB) {
|
||||
TrkResult result1 = result;
|
||||
result1.cookie = it.value().cookie;
|
||||
it.value().callback(result1);
|
||||
}
|
||||
TrkCallback callback = it.value().callback;
|
||||
const QVariant cookie = it.value().cookie;
|
||||
m_writtenTrkMessages.erase(it);
|
||||
if (mutex)
|
||||
mutex->unlock();
|
||||
// Invoke callback
|
||||
if (callback) {
|
||||
TrkResult result1 = result;
|
||||
result1.cookie = cookie;
|
||||
callback(result1);
|
||||
}
|
||||
}
|
||||
|
||||
void TrkWriteQueue::queueTrkInitialPing()
|
||||
{
|
||||
// Ping, reset sequence count
|
||||
m_trkWriteToken = 0;
|
||||
m_trkWriteQueue.append(TrkMessage(0, 0));
|
||||
m_trkWriteQueue.append(TrkMessage(TrkPing, 0));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
@@ -496,7 +503,7 @@ void WriterThread::queueTrkInitialPing()
|
||||
// Call this from the device read notification with the results.
|
||||
void WriterThread::slotHandleResult(const TrkResult &result)
|
||||
{
|
||||
m_queue.slotHandleResult(result);
|
||||
m_queue.slotHandleResult(result, &m_dataMutex);
|
||||
tryWrite(); // Have messages been enqueued in-between?
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ MACROSDIR = ../../../share/qtcreator/gdbmacros
|
||||
|
||||
SOURCES += \
|
||||
$$DEBUGGERDIR/gdb/gdbmi.cpp \
|
||||
$$DEBUGGERDIR/tcf/json.cpp \
|
||||
$$MACROSDIR/gdbmacros.cpp \
|
||||
tst_dumpers.cpp \
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "gdb/gdbmi.h"
|
||||
#include "tcf/json.h"
|
||||
#include "gdbmacros.h"
|
||||
#include "gdbmacros_p.h"
|
||||
|
||||
@@ -87,10 +86,6 @@ static const char gdbmi12[] =
|
||||
"numchild=\"0\"}]";
|
||||
|
||||
|
||||
static const char jsont1[] =
|
||||
"{\"Size\":100564,\"UID\":0,\"GID\":0,\"Permissions\":33261,"
|
||||
"\"ATime\":1242370878000,\"MTime\":1239154689000}";
|
||||
|
||||
struct Int3 {
|
||||
Int3() { i1 = 42; i2 = 43; i3 = 44; }
|
||||
int i1, i2, i3;
|
||||
@@ -114,12 +109,6 @@ public:
|
||||
'\n' + QString(input));
|
||||
}
|
||||
|
||||
void testJson(const char* input)
|
||||
{
|
||||
QCOMPARE('\n' + QString::fromLatin1(JsonValue(input).toString(false)),
|
||||
'\n' + QString(input));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void mi1() { testMi(gdbmi1); }
|
||||
void mi2() { testMi(gdbmi2); }
|
||||
@@ -132,8 +121,6 @@ private slots:
|
||||
void mi11() { testMi(gdbmi11); }
|
||||
//void mi12() { testMi(gdbmi12); }
|
||||
|
||||
void json1() { testJson(jsont1); }
|
||||
|
||||
void infoBreak();
|
||||
void niceType();
|
||||
void niceType_data();
|
||||
|
||||