Merge remote-tracking branch 'origin/3.5'

This commit is contained in:
Eike Ziller
2015-07-10 14:08:29 +02:00
84 changed files with 2748 additions and 4709 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1466,6 +1466,11 @@
\endlist
The locations of search hits, breakpoints, and bookmarks in your document
are highlighted on the editor scroll bar. To turn highlighting off, select
\uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} >
\uicontrol {Highlight search results on the scrollbar}.
\section1 Advanced Search
To search through projects, files on a file system or currently open files:
@@ -2403,9 +2408,10 @@
\endlist
To move directly to a particular line in the document when you open the
document, append a plus sign (+) or a colon (:) to the file name in the
locator. For example, to open main.cpp to line 41, enter: \c {main.cpp:41}.
To move directly to a particular line and column in the document when you
open the document, append them to the file name in the locator, separated by
plus signs (+) or colons (:). For example, to open main.cpp to line 41 and
column 2, enter: \c {main.cpp:41:2}.
If the path to a file is very long, it might not fit into the locator
window. To view the full path, press \key Alt when the filename is selected
@@ -2446,7 +2452,7 @@
\li Locating symbols in the current document (\c {.})
\li Locating a specific line and column in the document displayed in
your editor (\c {l})
your editor (\c {l <line_number>:<column_number>})
\li Opening help topics, including Qt documentation (\c {?})
@@ -2460,6 +2466,8 @@
\li Executing version control system commands (\c {git}). For more
information, see \l{Using Version Control Systems}
\li Running external tools (\c x)
\endlist
To use a specific locator filter, type the assigned prefix followed by

View File

@@ -31,16 +31,16 @@
\title Using Command Line Options
You can start \QC and specify some options from the command line. For
example, you can open a file to any line.
example, you can open a file to any line and column.
To specify command line options, enter the following command in the \QC
installation or build directory:
\c {qtcreator [option] [filename[:line_number]]}
\c {qtcreator [option] [filename[:line_number[:column_number]]]}
\note You can use either a colon (:) or a plus sign (+) as a separator
between the filename and line number. You can also use a space between the
separator and the line number.
between the filename and line number and the line number and the column
number. You can also use a space between the separator and the line number.
For example, on Windows:
@@ -48,9 +48,9 @@
\li \c {C:\qtcreator\bin>qtcreator -help}
\li \c {C:\qtcreator\bin>qtcreator C:\TextFinder\textfinder.cpp:100}
\li \c {C:\qtcreator\bin>qtcreator C:\TextFinder\textfinder.cpp:100:2}
\li \c {C:\qtcreator\bin>qtcreator C:\TextFinder\textfinder.cpp +100}
\li \c {C:\qtcreator\bin>qtcreator C:\TextFinder\textfinder.cpp +100+2}
\endlist

View File

@@ -36,6 +36,9 @@
for use. You can change their default configurations and configure new
tools.
To run the tools, select \uicontrol Tools > \uicontrol External, or use the
\c x filter in the locator.
\section1 Using Qt Linguist
You can use the Qt Linguist release manager tools, lupdate and lrelease,

View File

@@ -64,8 +64,19 @@
\li Select a command from the list.
\li In \uicontrol{Key Sequence} enter the shortcut key you want to associate
with the selected command.
\li In the \uicontrol{Key Sequence} field, you have the following
options:
\list
\li Enter the shortcut key you want to associate with the
selected command.
\li Select \uicontrol Record, press the keys to use as the
keyboard shortcut, and select \uicontrol {Stop Recording}
when you are done.
\endlist
\li To revert to the default shortcut, select \uicontrol Reset.

View File

@@ -114,6 +114,12 @@
Create a Qt Quick application using Qt Quick Controls
\li Qt Canvas 3D Application
Create a Qt Quick application that imports the Qt Canvas 3D
module and, optionally, includes \l{http://threejs.org}
{three.js}.
\li Qt Console Application
Use a single main.cpp file

View File

@@ -46,6 +46,10 @@
\li \uicontrol {Qt Quick Controls Application} is like
\uicontrol {Qt Quick Application}, but using Qt Quick Controls.
\li \uicontrol {Qt Canvas 3D Application} creates a Qt Quick application
that imports the Qt Canvas 3D module and, optionally, includes
\l{http://threejs.org}{three.js}.
\li \uicontrol {Qt Quick UI} (in the \uicontrol {Other Project}
category) creates a Qt Quick UI project with a single QML file that
contains the main view. You can review Qt Quick UI projects in a

View File

@@ -1,9 +1,9 @@
!isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included")
QTCREATOR_PRI_INCLUDED = 1
QTCREATOR_VERSION = 3.4.81
QTCREATOR_COMPAT_VERSION = 3.4.81
BINARY_ARTIFACTS_BRANCH = master
QTCREATOR_VERSION = 3.4.82
QTCREATOR_COMPAT_VERSION = 3.4.82
BINARY_ARTIFACTS_BRANCH = 3.5
# enable c++11
CONFIG += c++11

View File

@@ -6,11 +6,11 @@ Project {
property bool withAutotests: qbs.buildVariant === "debug"
property string ide_version_major: '3'
property string ide_version_minor: '4'
property string ide_version_release: '81'
property string ide_version_release: '82'
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release
property string ide_compat_version_major: '3'
property string ide_compat_version_minor: '4'
property string ide_compat_version_release: '81'
property string ide_compat_version_release: '82'
property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release
property path ide_source_tree: path
property string ide_app_path: qbs.targetOS.contains("osx") ? "" : "bin"

View File

@@ -191,7 +191,9 @@ def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, qt_qml_
target = os.path.join(install_dir, 'bin', 'imports', qtimport)
if (os.path.exists(target)):
shutil.rmtree(target)
shutil.copytree(os.path.join(qt_import_dir, qtimport), target, ignore=copy_ignore_func, symlinks=True)
import_path = os.path.join(qt_import_dir, qtimport)
if os.path.exists(import_path):
shutil.copytree(import_path, target, ignore=copy_ignore_func, symlinks=True)
if (os.path.exists(qt_qml_dir)):
print "Copying qt quick 2 imports"
@@ -230,20 +232,33 @@ def copyPreservingLinks(source, destination):
shutil.copy(source, destination)
def copy_libclang(install_dir, llvm_install_dir):
libsources = []
libtarget = ""
# contains pairs of (source, target directory)
deployinfo = []
if sys.platform.startswith("win"):
libsources = [os.path.join(llvm_install_dir, 'bin', 'libclang.dll')]
libtarget = os.path.join(install_dir, 'bin')
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'libclang.dll'),
os.path.join(install_dir, 'bin')))
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'clang-cl.exe'),
os.path.join(install_dir, 'bin')))
else:
libsources = glob(os.path.join(llvm_install_dir, 'lib', 'libclang.so*'))
libtarget = os.path.join(install_dir, 'lib', 'qtcreator')
for libsource in libsources:
deployinfo.append((libsource, os.path.join(install_dir, 'lib', 'qtcreator')))
clangbinary = os.path.join(llvm_install_dir, 'bin', 'clang')
clangbinary_targetdir = os.path.join(install_dir, 'bin')
deployinfo.append((clangbinary, clangbinary_targetdir))
# copy link target if clang is actually a symlink
if os.path.islink(clangbinary):
linktarget = os.readlink(clangbinary)
deployinfo.append((os.path.join(os.path.dirname(clangbinary), linktarget),
os.path.join(clangbinary_targetdir, linktarget)))
resourcesource = os.path.join(llvm_install_dir, 'lib', 'clang')
resourcetarget = os.path.join(install_dir, 'share', 'qtcreator', 'cplusplus', 'clang')
print "copying libclang..."
for libsource in libsources:
print libsource, '->', libtarget
copyPreservingLinks(libsource, libtarget)
for source, target in deployinfo:
print source, '->', target
copyPreservingLinks(source, target)
print resourcesource, '->', resourcetarget
if (os.path.exists(resourcetarget)):
shutil.rmtree(resourcetarget)

View File

@@ -61,6 +61,12 @@ if [ $LLVM_INSTALL_DIR ]; then
# use recursive copy to make it copy symlinks as symlinks
cp -Rf "$LLVM_INSTALL_DIR"/lib/libclang.*dylib "$1/Contents/Frameworks/" || exit 1
cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$1/Contents/Resources/cplusplus/" || exit 1
clangsource="$LLVM_INSTALL_DIR"/bin/clang
clanglinktarget="$(readlink "$clangsource")"
cp -Rf "$clangsource" "$1/Contents/Resources/" || exit 1
if [ $clanglinktarget ]; then
cp -Rf "$(dirname "$clangsource")/$clanglinktarget" "$1/Contents/Resources/$clanglinktarget" || exit 1
fi
fi
_CLANG_CODEMODEL_LIB="$1/Contents/PlugIns/libClangCodeModel_debug.dylib"
if [ ! -f "$_CLANG_CODEMODEL_LIB" ]; then

View File

@@ -1,100 +0,0 @@
#!/bin/bash
################################################################################
# Copyright (C) 2015 The Qt Company Ltd
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of The Qt Company Ltd, nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
################################################################################
if [ $# -lt 1 ]; then
echo "Usage: $(basename $1) <creator_install_dir> [qmake_path]"
exit 1
fi
INSTALL_DIR="$1"
QMAKE_BIN="${2:-$(which qmake)}"
if [ ! -e "$QMAKE_BIN" ]; then
echo "Could not detetermine location of 'qmake'!"
exit 1;
fi
CHRPATH=$(which chrpath)
if [ ! -e "$CHRPATH" ]; then
echo "Cannot find required binary 'chrpath'."
exit 1
fi
QT_INSTALL_LIBS="$($QMAKE_BIN -query QT_INSTALL_LIBS)"
QT_INSTALL_PLUGINS="$($QMAKE_BIN -query QT_INSTALL_PLUGINS)"
QT_INSTALL_IMPORTS="$($QMAKE_BIN -query QT_INSTALL_IMPORTS)"
QT_INSTALL_TRANSLATIONS="$($QMAKE_BIN -query QT_INSTALL_TRANSLATIONS)"
plugins="accessible designer iconengines imageformats sqldrivers"
imports="Qt QtWebKit"
tr_catalogs="assistant designer qt qt_help"
tr_languages="$(cd $INSTALL_DIR/share/qtcreator/translations; echo qtcreator_* | sed -e 's,[^_]*_\([^.]*\)\.,\1 ,g')"
function fix_rpaths()
{
pushd $INSTALL_DIR/lib
find qtcreator/ -maxdepth 1 -name "*.so*" -type f -exec $CHRPATH -r \$ORIGIN {} \;
cd $INSTALL_DIR/lib/qtcreator
find plugins/ -maxdepth 2 -name "*.so" -type f -exec $CHRPATH -r \$ORIGIN/../.. {} \;
cd $INSTALL_DIR/bin
# all executable files in bin
find -maxdepth 1 -type f -executable -exec $CHRPATH -r \$ORIGIN/../lib/qtcreator {} \;
# all lib of imports and plugins one level underneath bin
find -mindepth 2 -maxdepth 2 -type f -name "*.so" -exec $CHRPATH -r \$ORIGIN/../../lib/qtcreator {} \;
find -mindepth 3 -maxdepth 3 -type f -name "*.so" -exec $CHRPATH -r \$ORIGIN/../../../lib/qtcreator {} \;
find -mindepth 4 -maxdepth 4 -type f -name "*.so" -exec $CHRPATH -r \$ORIGIN/../../../../lib/qtcreator {} \;
}
function copy_binaries()
{
cp -a $QT_INSTALL_LIBS/*.so* $INSTALL_DIR/lib/qtcreator
for plugin in $plugins; do
cp -a $QT_INSTALL_PLUGINS/$plugin $INSTALL_DIR/bin
done
for import in $imports; do
cp -a $QT_INSTALL_IMPORTS/$import $INSTALL_DIR/bin
done
}
function copy_translations()
{
for language in $tr_languages; do
for catalog in $tr_catalogs; do
cp -a $QT_INSTALL_TRANSLATIONS/${catalog}_${language}.qm $INSTALL_DIR/share/qtcreator/translations
done
done
}
copy_binaries
copy_translations
fix_rpaths

View File

@@ -387,12 +387,27 @@ class DumperBase:
self.isCli = False
# Later set, or not set:
# cachedQtVersion
self.stringCutOff = 10000
self.displayStringLimit = 100
self.resetCaches()
self.childrenPrefix = 'children=['
self.childrenSuffix = '],'
self.dumpermodules = [
"qttypes",
"stdtypes",
"misctypes",
"boosttypes",
"creatortypes",
"personaltypes",
]
def resetCaches(self):
# This is a cache mapping from 'type name' to 'display alternatives'.
self.qqFormats = {}
self.qqFormats = { "QVariant (QVariantMap)" : mapForms() }
# This is a cache of all known dumpers.
self.qqDumpers = {}
@@ -407,18 +422,6 @@ class DumperBase:
# to not be QObject derived, it contains a 0 value.
self.knownStaticMetaObjects = {}
self.childrenPrefix = 'children=['
self.childrenSuffix = '],'
self.dumpermodules = [
"qttypes",
"stdtypes",
"misctypes",
"boosttypes",
"creatortypes",
"personaltypes",
]
def putNewline(self):
pass
@@ -1674,10 +1677,7 @@ class DumperBase:
pass
def setupDumpers(self, _ = {}):
self.qqDumpers = {}
self.qqFormats = {}
self.qqEditable = {}
self.typeCache = {}
self.resetCaches()
for mod in self.dumpermodules:
m = importlib.import_module(mod)

View File

@@ -144,6 +144,7 @@ ScanStackCommand()
class PlainDumper:
def __init__(self, printer):
self.printer = printer
self.typeCache = {}
def __call__(self, d, value):
printer = self.printer.invoke(value)
@@ -223,6 +224,7 @@ class Dumper(DumperBase):
# These values will be kept between calls to 'showData'.
self.isGdb = True
self.childEventAddress = None
self.typeCache = {}
self.typesReported = {}
self.typesToReport = {}
self.qtNamespaceToReport = None

View File

@@ -1031,6 +1031,13 @@ def qdump__QMultiMap(d, value):
qdump__QMap(d, value)
def qform__QVariantMap():
return mapForms()
def qdump__QVariantMap(d, value):
qdump__QMap(d, value)
def qdump__QMetaObjectPrivate(d, value):
d.putEmptyValue()
d.putNumChild(1)
@@ -1899,6 +1906,16 @@ def qdump__QUrl(d, value):
d.putGenericItem("fragment", stringType, fragment, Hex4EncodedLittleEndian)
d.putFields(value)
def qdump__QUuid(d, value):
v = value["data4"]
d.putValue("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"
% (value["data1"], value["data2"], value["data3"],
v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]))
d.putNumChild(1)
d.putPlainChildren(value)
def qdumpHelper_QVariant_0(d, blob):
# QVariant::Invalid
d.putBetterType("%sQVariant (invalid)" % d.qtNamespace())

View File

@@ -72,12 +72,6 @@ for(data_dir, DATA_DIRS) {
dumpinfo.input = qml/qmldump/Info.plist.in
dumpinfo.output = $$IDE_DATA_PATH/qml/qmldump/Info.plist
QMAKE_SUBSTITUTES += dumpinfo
puppetinfo.input = qml/qmlpuppet/qmlpuppet/Info.plist.in
puppetinfo.output = $$IDE_DATA_PATH/qml/qmlpuppet/qmlpuppet/Info.plist
QMAKE_SUBSTITUES += puppetinfo
puppet2info.input = qml/qmlpuppet/qml2puppet/Info.plist.in
puppet2info.output = $$IDE_DATA_PATH/qml/qmlpuppet/qml2puppet/Info.plist
QMAKE_SUBSTITUES += puppet2info
}
SRCRESOURCEDIR = $$IDE_SOURCE_TREE/src/share/qtcreator/

View File

@@ -7,8 +7,8 @@
"trDisplayName": "Qt Quick Application",
"trDisplayCategory": "Application",
"icon": "qml_wizard.png",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt", "QtSupport.Wizards.FeatureQtQuick.2" ],
"enabled": "${JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 && [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0}",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.3" ],
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 }",
"options":
[
@@ -38,6 +38,7 @@
"type": "ComboBox",
"data":
{
"index": 2,
"items":
[
{
@@ -46,8 +47,7 @@
"{
'qtQuickVersion': '2.5',
'qtQuickWindowVersion': '2.2'
}",
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.5') >= 0}"
}"
},
{
"trKey": "Qt 5.4",
@@ -55,8 +55,7 @@
"{
'qtQuickVersion': '2.4',
'qtQuickWindowVersion': '2.2'
}",
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.4') >= 0}"
}"
},
{
"trKey": "Qt 5.3",
@@ -64,8 +63,7 @@
"{
'qtQuickVersion': '2.3',
'qtQuickWindowVersion': '2.2'
}",
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0}"
}"
}
]
}

View File

@@ -7,8 +7,8 @@
"trDisplayName": "Qt Quick Controls Application",
"trDisplayCategory": "Application",
"icon": "../qtquickapplication/qml_wizard.png",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt" ],
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 && [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0 }",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.3" ],
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0}",
"options":
[
@@ -40,6 +40,7 @@
"type": "ComboBox",
"data":
{
"index": 2,
"items":
[
{
@@ -50,8 +51,7 @@
'qtQuickControlsVersion': '1.4',
'qtQuickDialogsVersion': '1.2',
'qtQuickLayoutsVersion': '1.2'
}",
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.5') >= 0}"
}"
},
{
"trKey": "Qt 5.4",
@@ -61,8 +61,7 @@
'qtQuickControlsVersion': '1.3',
'qtQuickDialogsVersion': '1.2',
'qtQuickLayoutsVersion': '1.1'
}",
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.4') >= 0}"
}"
},
{
"trKey": "Qt 5.3",
@@ -72,8 +71,7 @@
'qtQuickControlsVersion': '1.2',
'qtQuickDialogsVersion': '1.2',
'qtQuickLayoutsVersion': '1.1'
}",
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0}"
}"
}
]
}

View File

@@ -164,8 +164,8 @@ void AutotoolsProject::loadProjectTree()
// The thread is still busy parsing a previus configuration.
// Wait until the thread has been finished and delete it.
// TODO: Discuss whether blocking is acceptable.
disconnect(m_makefileParserThread, SIGNAL(finished()),
this, SLOT(makefileParsingFinished()));
disconnect(m_makefileParserThread, &QThread::finished,
this, &AutotoolsProject::makefileParsingFinished);
m_makefileParserThread->wait();
delete m_makefileParserThread;
m_makefileParserThread = 0;
@@ -402,6 +402,24 @@ QList<Node *> AutotoolsProject::nodes(FolderNode *parent) const
return list;
}
static QStringList filterIncludes(const QString &absSrc, const QString &absBuild,
const QStringList &in)
{
QStringList result;
foreach (const QString i, in) {
QString out = i;
out.replace(QLatin1String("$(top_srcdir)"), absSrc);
out.replace(QLatin1String("$(abs_top_srcdir)"), absSrc);
out.replace(QLatin1String("$(top_builddir)"), absBuild);
out.replace(QLatin1String("$(abs_top_builddir)"), absBuild);
result << out;
}
return result;
}
void AutotoolsProject::updateCppCodeModel()
{
CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
@@ -427,7 +445,12 @@ void AutotoolsProject::updateCppCodeModel()
ppBuilder.setCFlags(cflags);
ppBuilder.setCxxFlags(cxxflags);
ppBuilder.setIncludePaths(m_makefileParserThread->includePaths());
const QString absSrc = projectDirectory().toString();
const Target *target = activeTarget();
const QString absBuild = (target && target->activeBuildConfiguration())
? target->activeBuildConfiguration()->buildDirectory().toString() : QString();
ppBuilder.setIncludePaths(filterIncludes(absSrc, absBuild, m_makefileParserThread->includePaths()));
ppBuilder.setDefines(m_makefileParserThread->defines());
const QList<Core::Id> languages = ppBuilder.createProjectPartsForFiles(m_files);

View File

@@ -33,6 +33,7 @@
#include "makefileparser.h"
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QFile>
#include <QDir>
@@ -131,12 +132,12 @@ QByteArray MakefileParser::defines() const
QStringList MakefileParser::cflags() const
{
return m_cflags;
return m_cppflags + m_cflags;
}
QStringList MakefileParser::cxxflags() const
{
return m_cxxflags;
return m_cppflags + m_cxxflags;
}
void MakefileParser::cancel()
@@ -443,9 +444,22 @@ QString MakefileParser::parseIdentifierBeforeAssign(const QString &line)
QStringList MakefileParser::parseTermsAfterAssign(const QString &line)
{
int assignPos = line.indexOf(QLatin1Char('=')) + 1;
if (assignPos >= line.size())
if (assignPos <= 0 || assignPos >= line.size())
return QStringList();
return line.mid(assignPos).split(QLatin1Char(' '), QString::SkipEmptyParts);
const QStringList parts = Utils::QtcProcess::splitArgs(line.mid(assignPos));
QStringList result;
for (int i = 0; i < parts.count(); ++i) {
const QString cur = parts.at(i);
const QString next = (i == parts.count() - 1) ? QString() : parts.at(i + 1);
if (cur == QLatin1String("-D") || cur == QLatin1String("-U") || cur == QLatin1String("-I")) {
result << cur + next;
++i;
} else {
result << cur;
}
}
return result;
}
bool MakefileParser::maybeParseDefine(const QString &term)
@@ -493,6 +507,15 @@ bool MakefileParser::maybeParseCXXFlag(const QString &term)
return false;
}
bool MakefileParser::maybeParseCPPFlag(const QString &term)
{
if (term.startsWith(QLatin1Char('-'))) {
m_cppflags += term;
return true;
}
return false;
}
void MakefileParser::addAllSources()
{
QStringList extensions;
@@ -523,6 +546,12 @@ void MakefileParser::parseIncludePaths()
QString line;
do {
line = textStream.readLine();
while (line.endsWith(QLatin1Char('\\'))) {
line.chop(1);
QString next = textStream.readLine();
line.append(next);
}
const QString varName = parseIdentifierBeforeAssign(line);
if (varName.isEmpty())
continue;
@@ -537,11 +566,14 @@ void MakefileParser::parseIncludePaths()
foreach (const QString &term, parseTermsAfterAssign(line))
maybeParseDefine(term) || maybeParseInclude(term, dirName)
|| maybeParseCFlag(term);
} else if (varName.endsWith(QLatin1String("CPPFLAGS"))
|| varName.endsWith(QLatin1String("CXXFLAGS"))) {
} else if (varName.endsWith(QLatin1String("CXXFLAGS"))) {
foreach (const QString &term, parseTermsAfterAssign(line))
maybeParseDefine(term) || maybeParseInclude(term, dirName)
|| maybeParseCXXFlag(term);
} else if (varName.endsWith(QLatin1String("CPPFLAGS"))) {
foreach (const QString &term, parseTermsAfterAssign(line))
maybeParseDefine(term) || maybeParseInclude(term, dirName)
|| maybeParseCPPFlag(term);
}
} while (!line.isNull());

View File

@@ -258,6 +258,11 @@ private:
*/
bool maybeParseCXXFlag(const QString &term);
/**
* If term is compiler flag -<flag>, adds it to cppflags and returns true.
*/
bool maybeParseCPPFlag(const QString &term);
private:
bool m_success; ///< Return value for MakefileParser::parse().
@@ -271,7 +276,8 @@ private:
QStringList m_includePaths; ///< Return value for MakefileParser::includePaths()
QByteArray m_defines; ///< Return value for MakefileParser::defines()
QStringList m_cflags; ///< Return value for MakefileParser::cflags()
QStringList m_cxxflags; ///< Return value for MakefileParser::cxxflags()
QStringList m_cxxflags; ///< Return value for MakefileParser::cxxflags()
QStringList m_cppflags; ///< The cpp flags, which will be part of both cflags and cxxflags
QString m_line; ///< Current line of the makefile
QTextStream m_textStream; ///< Textstream that represents the makefile

View File

@@ -28,7 +28,6 @@
**
****************************************************************************/
#ifndef CLANGEDITORDOCUMENTPARSER_H
#define CLANGEDITORDOCUMENTPARSER_H
@@ -36,7 +35,6 @@
#include <cpptools/baseeditordocumentparser.h>
namespace CppTools { class WorkingCopy; }
namespace ClangCodeModel {
@@ -45,9 +43,6 @@ class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
{
Q_OBJECT
public:
typedef QSharedPointer<ClangEditorDocumentParser> Ptr;
public:
ClangEditorDocumentParser(const QString &filePath);
@@ -59,8 +54,6 @@ public:
private:
SemanticMarker::Ptr m_marker;
QStringList m_options;
Internal::UnsavedFiles m_unsavedFiles;
};
} // namespace ClangCodeModel

View File

@@ -69,6 +69,10 @@ ModelManagerSupportClang::ModelManagerSupportClang()
this, &ModelManagerSupportClang::onEditorOpened);
CppTools::CppModelManager *modelManager = cppModelManager();
connect(modelManager, &CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
this, &ModelManagerSupportClang::onAbstractEditorSupportContentsUpdated);
connect(modelManager, &CppTools::CppModelManager::abstractEditorSupportRemoved,
this, &ModelManagerSupportClang::onAbstractEditorSupportRemoved);
connect(modelManager, &CppTools::CppModelManager::projectPartsUpdated,
this, &ModelManagerSupportClang::onProjectPartsUpdated);
connect(modelManager, &CppTools::CppModelManager::projectPartsRemoved,
@@ -113,9 +117,8 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor)
Core::IDocument *document = editor->document();
QTC_ASSERT(document, return);
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(document);
QTC_ASSERT(textDocument, return);
if (cppModelManager()->isCppEditor(editor)) {
if (textDocument && cppModelManager()->isCppEditor(editor)) {
// Handle externally changed documents
connect(textDocument, &Core::IDocument::reloadFinished,
this, &ModelManagerSupportClang::onCppDocumentReloadFinished,

View File

@@ -615,6 +615,102 @@ bool hasSnippet(ProposalModel model, const QByteArray &text)
return false;
}
class MonitorGeneratedUiFile : public QObject
{
Q_OBJECT
public:
MonitorGeneratedUiFile();
bool waitUntilGenerated(int timeout = 10000) const;
private:
void onUiFileGenerated() { m_isGenerated = true; }
bool m_isGenerated = false;
};
MonitorGeneratedUiFile::MonitorGeneratedUiFile()
{
connect(CppTools::CppModelManager::instance(),
&CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
this, &MonitorGeneratedUiFile::onUiFileGenerated);
}
bool MonitorGeneratedUiFile::waitUntilGenerated(int timeout) const
{
if (m_isGenerated)
return true;
QTime time;
time.start();
forever {
if (m_isGenerated)
return true;
if (time.elapsed() > timeout)
return false;
QCoreApplication::processEvents();
QThread::msleep(20);
}
return false;
}
class WriteFileAndWaitForReloadedDocument : public QObject
{
public:
WriteFileAndWaitForReloadedDocument(const QString &filePath,
const QByteArray &fileContents,
Core::IDocument *document)
: m_filePath(filePath)
, m_fileContents(fileContents)
{
QTC_CHECK(document);
connect(document, &Core::IDocument::reloadFinished,
this, &WriteFileAndWaitForReloadedDocument::onReloadFinished);
}
void onReloadFinished()
{
m_onReloadFinished = true;
}
bool wait() const
{
QTC_ASSERT(writeFile(m_filePath, m_fileContents), return false);
QTime totalTime;
totalTime.start();
QTime writeFileAgainTime;
writeFileAgainTime.start();
forever {
if (m_onReloadFinished)
return true;
if (totalTime.elapsed() > 10000)
return false;
if (writeFileAgainTime.elapsed() > 1000) {
// The timestamp did not change, try again now.
QTC_ASSERT(writeFile(m_filePath, m_fileContents), return false);
writeFileAgainTime.restart();
}
QCoreApplication::processEvents();
QThread::msleep(20);
}
}
private:
bool m_onReloadFinished = false;
QString m_filePath;
QByteArray m_fileContents;
};
} // anonymous namespace
namespace ClangCodeModel {
@@ -866,11 +962,11 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileExt
ProposalModel proposal = completionResults(openSource.editor());
QVERIFY(hasItem(proposal, "globalFromHeader"));
// Simulate external modification
QThread::sleep(1); // Ensures different time stamp and thus that the difference will be noticed
QVERIFY(writeFile(headerDocument.filePath, "int globalFromHeaderReloaded;\n"));
QSignalSpy waitForReloadedDocument(openHeader.editor()->document(),
SIGNAL(reloadFinished(bool)));
// Simulate external modification and wait for reload
WriteFileAndWaitForReloadedDocument waitForReloadedDocument(
headerDocument.filePath,
"int globalFromHeaderReloaded;\n",
openHeader.editor()->document());
QVERIFY(waitForReloadedDocument.wait());
// Retrigger completion and check if its updated
@@ -883,6 +979,8 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByCompletingUiObject()
CppTools::Tests::TemporaryCopiedDir testDir(qrcPath("qt-widgets-app"));
QVERIFY(testDir.isValid());
MonitorGeneratedUiFile monitorGeneratedUiFile;
// Open project
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
CppTools::Tests::ProjectOpenerAndCloser projectManager;
@@ -897,11 +995,11 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByCompletingUiObject()
QVERIFY(openSource.succeeded());
// ...and check comletions
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
ProposalModel proposal = completionResults(openSource.editor());
QVERIFY(hasItem(proposal, "menuBar"));
QVERIFY(hasItem(proposal, "statusBar"));
QVERIFY(hasItem(proposal, "centralWidget"));
QEXPECT_FAIL("", "Signals are not yet done", Abort);
QVERIFY(hasItem(proposal, "setupUi"));
}
@@ -921,6 +1019,7 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
// ... and modify it, so we have an unsaved file.
insertTextAtTopOfEditor(openHeader.editor(), "int someGlobal;\n");
// Open project ...
MonitorGeneratedUiFile monitorGeneratedUiFile;
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
CppTools::Tests::ProjectOpenerAndCloser projectManager;
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
@@ -931,6 +1030,7 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
QVERIFY(testDocument.isCreatedAndHasValidCursorPosition());
OpenEditorAtCursorPosition openSource(testDocument);
QVERIFY(openSource.succeeded());
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
// Check commands that would have been sent
QVERIFY(compare(LogOutput(spy.senderLog),
@@ -939,6 +1039,8 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
" ProjectPartContainer id: qt-widgets-app.pro\n"
"RegisterTranslationUnitForCodeCompletionCommand\n"
" Path: myheader.h ProjectPart: \n"
"RegisterTranslationUnitForCodeCompletionCommand\n"
" Path: ui_mainwindow.h ProjectPart: \n"
)));
spy.senderLog.clear();
@@ -966,3 +1068,5 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
} // namespace Tests
} // namespace Internal
} // namespace ClangCodeModel
#include "clangcodecompletion_test.moc"

View File

@@ -53,6 +53,11 @@ void AbstractEditorSupport::updateDocument()
m_modelmanager->updateSourceFiles(QSet<QString>() << fileName());
}
void AbstractEditorSupport::notifyAboutUpdatedContents() const
{
m_modelmanager->emitAbstractEditorSupportContentsUpdated(fileName(), contents());
}
QString AbstractEditorSupport::licenseTemplate(const QString &file, const QString &className)
{
return Internal::CppFileSettings::licenseTemplate(file, className);

View File

@@ -51,6 +51,7 @@ public:
virtual QString fileName() const = 0;
void updateDocument();
void notifyAboutUpdatedContents() const;
unsigned revision() const { return m_revision; }
static QString licenseTemplate(const QString &file = QString(), const QString &className = QString());

View File

@@ -41,8 +41,6 @@ namespace CppTools {
class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(BaseEditorDocumentParser)
BaseEditorDocumentParser();
public:
BaseEditorDocumentParser(const QString &filePath);

View File

@@ -49,8 +49,6 @@ namespace CppTools {
class CPPTOOLS_EXPORT BaseEditorDocumentProcessor : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(BaseEditorDocumentProcessor)
BaseEditorDocumentProcessor();
public:
BaseEditorDocumentProcessor(TextEditor::TextDocument *document);

View File

@@ -42,7 +42,6 @@ namespace CppTools {
class CPPTOOLS_EXPORT BuiltinEditorDocumentProcessor : public BaseEditorDocumentProcessor
{
Q_OBJECT
BuiltinEditorDocumentProcessor();
public:
BuiltinEditorDocumentProcessor(TextEditor::TextDocument *document,

View File

@@ -51,7 +51,6 @@ namespace CppTools {
class CPPTOOLS_EXPORT CppEditorOutline : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(CppEditorOutline)
public:
explicit CppEditorOutline(TextEditor::TextEditorWidget *editorWidget);

View File

@@ -958,6 +958,17 @@ void CppModelManager::emitDocumentUpdated(Document::Ptr doc)
emit documentUpdated(doc);
}
void CppModelManager::emitAbstractEditorSupportContentsUpdated(const QString &filePath,
const QByteArray &contents)
{
emit abstractEditorSupportContentsUpdated(filePath, contents);
}
void CppModelManager::emitAbstractEditorSupportRemoved(const QString &filePath)
{
emit abstractEditorSupportRemoved(filePath);
}
void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
{
QMutexLocker locker(&d->m_projectMutex);

View File

@@ -111,6 +111,9 @@ public:
bool replaceDocument(Document::Ptr newDoc);
void emitDocumentUpdated(CPlusPlus::Document::Ptr doc);
void emitAbstractEditorSupportContentsUpdated(const QString &filePath,
const QByteArray &contents);
void emitAbstractEditorSupportRemoved(const QString &filePath);
bool isCppEditor(Core::IEditor *editor) const;
@@ -173,6 +176,9 @@ signals:
void gcFinished(); // Needed for tests.
void abstractEditorSupportContentsUpdated(const QString &filePath, const QByteArray &contents);
void abstractEditorSupportRemoved(const QString &filePath);
public slots:
void updateModifiedSourceFiles();
void GC();

View File

@@ -43,7 +43,6 @@ class SemanticInfoUpdaterPrivate;
class SemanticInfoUpdater : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(SemanticInfoUpdater)
public:
explicit SemanticInfoUpdater();

View File

@@ -49,7 +49,6 @@ namespace CppTools {
class CPPTOOLS_EXPORT SemanticHighlighter : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(SemanticHighlighter)
public:
enum Kind {

View File

@@ -145,16 +145,13 @@ QtcPlugin {
name: "QML Debugger"
prefix: "qml/"
files: [
"baseqmldebuggerclient.cpp", "baseqmldebuggerclient.h",
"interactiveinterpreter.cpp", "interactiveinterpreter.h",
"qmladapter.cpp", "qmladapter.h",
"qmlcppengine.cpp", "qmlcppengine.h",
"qmlengine.cpp", "qmlengine.h",
"qmlengineutils.cpp", "qmlengineutils.h",
"qmlinspectoradapter.cpp", "qmlinspectoradapter.h",
"qmlinspectoragent.cpp", "qmlinspectoragent.h",
"qmlv8debuggerclient.cpp", "qmlv8debuggerclient.h",
"qmlv8debuggerclientconstants.h",
"qscriptdebuggerclient.cpp", "qscriptdebuggerclient.h"
"qmlv8debuggerclientconstants.h"
]
}

View File

@@ -1,83 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "baseqmldebuggerclient.h"
#include <debugger/breakhandler.h>
#include <utils/qtcassert.h>
namespace Debugger {
namespace Internal {
class BaseQmlDebuggerClientPrivate
{
public:
QList<QByteArray> sendBuffer;
};
BaseQmlDebuggerClient::BaseQmlDebuggerClient(QmlDebug::QmlDebugConnection* client, QLatin1String clientName)
: QmlDebugClient(clientName, client),
d(new BaseQmlDebuggerClientPrivate())
{
}
BaseQmlDebuggerClient::~BaseQmlDebuggerClient()
{
delete d;
}
bool BaseQmlDebuggerClient::acceptsBreakpoint(Breakpoint /*bp*/)
{
return false;
}
void BaseQmlDebuggerClient::stateChanged(State state)
{
emit newState(state);
}
void BaseQmlDebuggerClient::sendMessage(const QByteArray &msg)
{
if (state() == Enabled)
QmlDebugClient::sendMessage(msg);
else
d->sendBuffer.append(msg);
}
void BaseQmlDebuggerClient::flushSendBuffer()
{
QTC_ASSERT(state() == Enabled, return);
foreach (const QByteArray &msg, d->sendBuffer)
QmlDebugClient::sendMessage(msg);
d->sendBuffer.clear();
}
} // Internal
} // Debugger

View File

@@ -1,111 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef BASEQMLDEBUGGERCLIENT_H
#define BASEQMLDEBUGGERCLIENT_H
#include <debugger/debuggerengine.h>
#include <qmldebug/qmldebugclient.h>
namespace Debugger {
namespace Internal {
class WatchData;
class WatchItem;
class BreakHandler;
class BreakpointModelId;
class QmlEngine;
class BaseQmlDebuggerClientPrivate;
class BaseQmlDebuggerClient : public QmlDebug::QmlDebugClient
{
Q_OBJECT
public:
BaseQmlDebuggerClient(QmlDebug::QmlDebugConnection* client, QLatin1String clientName);
virtual ~BaseQmlDebuggerClient();
virtual void startSession() = 0;
virtual void endSession() = 0;
virtual void resetSession() = 0;
virtual void executeStep() = 0;
virtual void executeStepOut() = 0;
virtual void executeNext() = 0;
virtual void executeStepI() = 0;
virtual void executeRunToLine(const ContextData &data) = 0;
virtual void continueInferior() = 0;
virtual void interruptInferior() = 0;
virtual void activateFrame(int index) = 0;
virtual bool acceptsBreakpoint(Breakpoint bp);
virtual void insertBreakpoint(Breakpoint bp, int adjustedLine,
int adjustedColumn = -1) = 0;
virtual void removeBreakpoint(Breakpoint bp) = 0;
virtual void changeBreakpoint(Breakpoint bp) = 0;
virtual void synchronizeBreakpoints() = 0;
virtual void assignValueInDebugger(const WatchData *data,
const QString &expression,
const QVariant &valueV) = 0;
virtual void updateWatchData(const WatchData &data) = 0;
virtual void executeDebuggerCommand(const QString &command) = 0;
virtual void synchronizeWatchers(const QStringList &watchers) = 0;
virtual void expandObject(const QByteArray &iname, quint64 objectId) = 0;
virtual void setEngine(QmlEngine *engine) = 0;
virtual void getSourceFiles() {}
void flushSendBuffer();
signals:
void newState(QmlDebug::QmlDebugClient::State state);
void stackFrameCompleted();
protected:
virtual void stateChanged(State state);
void sendMessage(const QByteArray &msg);
private:
BaseQmlDebuggerClientPrivate *d;
friend class BaseQmlDebuggerClientPrivate;
};
} // Internal
} // Debugger
#endif // BASEQMLDEBUGGERCLIENT_H

View File

@@ -1,10 +1,7 @@
HEADERS += \
$$PWD/qmlengine.h \
$$PWD/qmladapter.h \
$$PWD/baseqmldebuggerclient.h \
$$PWD/qmlengineutils.h \
$$PWD/qmlcppengine.h \
$$PWD/qscriptdebuggerclient.h \
$$PWD/qmlv8debuggerclient.h \
$$PWD/interactiveinterpreter.h \
$$PWD/qmlv8debuggerclientconstants.h \
$$PWD/qmlinspectoragent.h \
@@ -12,11 +9,8 @@ HEADERS += \
SOURCES += \
$$PWD/qmlengine.cpp \
$$PWD/qmladapter.cpp \
$$PWD/baseqmldebuggerclient.cpp \
$$PWD/qmlengineutils.cpp \
$$PWD/qmlcppengine.cpp \
$$PWD/qscriptdebuggerclient.cpp \
$$PWD/qmlv8debuggerclient.cpp \
$$PWD/interactiveinterpreter.cpp \
$$PWD/qmlinspectoragent.cpp \
$$PWD/qmlinspectoradapter.cpp

View File

@@ -1,242 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "qmladapter.h"
#include <debugger/debuggerstringutils.h>
#include "qmlengine.h"
#include "qmlv8debuggerclient.h"
#include "qscriptdebuggerclient.h"
#include <utils/qtcassert.h>
#include <QDebug>
using namespace QmlDebug;
namespace Debugger {
namespace Internal {
/*!
QmlAdapter manages the connection & clients for QML/JS debugging.
*/
QmlAdapter::QmlAdapter(DebuggerEngine *engine, QObject *parent)
: QObject(parent)
, m_engine(engine)
, m_qmlClient(0)
, m_conn(0)
, m_msgClient(0)
{
m_connectionTimer.setInterval(4000);
m_connectionTimer.setSingleShot(true);
connect(&m_connectionTimer, &QTimer::timeout, this, &QmlAdapter::checkConnectionState);
m_conn = new QmlDebugConnection(this);
connect(m_conn, &QmlDebugConnection::stateMessage,
this, &QmlAdapter::showConnectionStateMessage);
connect(m_conn, &QmlDebugConnection::errorMessage,
this, &QmlAdapter::showConnectionErrorMessage);
connect(m_conn, &QmlDebugConnection::error,
this, &QmlAdapter::connectionErrorOccurred);
connect(m_conn, &QmlDebugConnection::opened,
&m_connectionTimer, &QTimer::stop);
connect(m_conn, &QmlDebugConnection::opened,
this, &QmlAdapter::connected);
connect(m_conn, &QmlDebugConnection::closed,
this, &QmlAdapter::disconnected);
createDebuggerClients();
m_msgClient = new QDebugMessageClient(m_conn);
connect(m_msgClient, &QDebugMessageClient::newState, this, &QmlAdapter::clientStateChanged);
}
QmlAdapter::~QmlAdapter()
{
}
void QmlAdapter::beginConnectionTcp(const QString &address, quint16 port)
{
if (m_engine.isNull() || !m_conn || m_conn->isOpen())
return;
m_conn->connectToHost(address, port);
//A timeout to check the connection state
m_connectionTimer.start();
}
void QmlAdapter::closeConnection()
{
if (m_connectionTimer.isActive()) {
m_connectionTimer.stop();
} else {
if (m_conn)
m_conn->close();
}
}
void QmlAdapter::connectionErrorOccurred(QDebugSupport::Error error)
{
// this is only an error if we are already connected and something goes wrong.
if (isConnected()) {
emit connectionError(error);
} else {
m_connectionTimer.stop();
emit connectionStartupFailed();
}
}
void QmlAdapter::clientStateChanged(QmlDebugClient::State state)
{
QString serviceName;
float version = 0;
if (QmlDebugClient *client = qobject_cast<QmlDebugClient*>(sender())) {
serviceName = client->name();
version = client->remoteVersion();
}
logServiceStateChange(serviceName, version, state);
}
void QmlAdapter::debugClientStateChanged(QmlDebugClient::State state)
{
if (state != QmlDebugClient::Enabled)
return;
QmlDebugClient *client = qobject_cast<QmlDebugClient*>(sender());
QTC_ASSERT(client, return);
m_qmlClient = qobject_cast<BaseQmlDebuggerClient *>(client);
m_qmlClient->startSession();
}
void QmlAdapter::checkConnectionState()
{
if (!isConnected()) {
closeConnection();
emit connectionStartupFailed();
}
}
bool QmlAdapter::isConnected() const
{
return m_conn && m_qmlClient && m_conn->isOpen();
}
void QmlAdapter::createDebuggerClients()
{
QScriptDebuggerClient *debugClient1 = new QScriptDebuggerClient(m_conn);
connect(debugClient1, &QScriptDebuggerClient::newState,
this, &QmlAdapter::clientStateChanged);
connect(debugClient1, &QScriptDebuggerClient::newState,
this, &QmlAdapter::debugClientStateChanged);
QmlV8DebuggerClient *debugClient2 = new QmlV8DebuggerClient(m_conn);
connect(debugClient2, &QmlV8DebuggerClient::newState,
this, &QmlAdapter::clientStateChanged);
connect(debugClient2, &QmlV8DebuggerClient::newState,
this, &QmlAdapter::debugClientStateChanged);
m_debugClients.insert(debugClient1->name(),debugClient1);
m_debugClients.insert(debugClient2->name(),debugClient2);
debugClient1->setEngine((QmlEngine*)(m_engine.data()));
debugClient2->setEngine((QmlEngine*)(m_engine.data()));
}
QmlDebugConnection *QmlAdapter::connection() const
{
return m_conn;
}
DebuggerEngine *QmlAdapter::debuggerEngine() const
{
return m_engine.data();
}
void QmlAdapter::showConnectionStateMessage(const QString &message)
{
if (!m_engine.isNull())
m_engine.data()->showMessage(_("QML Debugger: ") + message, LogStatus);
}
void QmlAdapter::showConnectionErrorMessage(const QString &message)
{
if (!m_engine.isNull())
m_engine.data()->showMessage(_("QML Debugger: ") + message, LogError);
}
BaseQmlDebuggerClient *QmlAdapter::activeDebuggerClient() const
{
return m_qmlClient;
}
QHash<QString, BaseQmlDebuggerClient*> QmlAdapter::debuggerClients() const
{
return m_debugClients;
}
QDebugMessageClient *QmlAdapter::messageClient() const
{
return m_msgClient;
}
void QmlAdapter::logServiceStateChange(const QString &service, float version,
QmlDebugClient::State newState)
{
switch (newState) {
case QmlDebugClient::Unavailable: {
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'unavailable'.").
arg(service).arg(QString::number(version)));
break;
}
case QmlDebugClient::Enabled: {
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'enabled'.").
arg(service).arg(QString::number(version)));
break;
}
case QmlDebugClient::NotConnected: {
showConnectionStateMessage(_("Status of \"%1\" Version: %2 changed to 'not connected'.").
arg(service).arg(QString::number(version)));
break;
}
}
}
void QmlAdapter::logServiceActivity(const QString &service, const QString &logMessage)
{
if (!m_engine.isNull())
m_engine.data()->showMessage(service + QLatin1Char(' ') + logMessage, LogDebug);
}
} // namespace Internal
} // namespace Debugger

View File

@@ -1,107 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef QMLADAPTER_H
#define QMLADAPTER_H
#include <qmldebug/qmldebugclient.h>
#include <QPointer>
#include <QTimer>
namespace QmlDebug {
class BaseEngineDebugClient;
class QmlDebugConnection;
class QDebugMessageClient;
}
namespace Debugger {
namespace Internal {
class BaseQmlDebuggerClient;
class DebuggerEngine;
class QmlAdapterPrivate;
class QmlAdapter : public QObject
{
Q_OBJECT
public:
explicit QmlAdapter(DebuggerEngine *engine, QObject *parent = 0);
virtual ~QmlAdapter();
void beginConnectionTcp(const QString &address, quint16 port);
void closeConnection();
QmlDebug::QmlDebugConnection *connection() const;
DebuggerEngine *debuggerEngine() const;
BaseQmlDebuggerClient *activeDebuggerClient() const;
QHash<QString, BaseQmlDebuggerClient*> debuggerClients() const;
QmlDebug::QDebugMessageClient *messageClient() const;
public slots:
void logServiceStateChange(const QString &service, float version,
QmlDebug::QmlDebugClient::State newState);
void logServiceActivity(const QString &service, const QString &logMessage);
signals:
void connected();
void disconnected();
void connectionStartupFailed();
void connectionError(QDebugSupport::Error error);
void serviceConnectionError(const QString serviceName);
private slots:
void connectionErrorOccurred(QDebugSupport::Error socketError);
void clientStateChanged(QmlDebug::QmlDebugClient::State state);
void debugClientStateChanged(QmlDebug::QmlDebugClient::State state);
void checkConnectionState();
void showConnectionStateMessage(const QString &message);
void showConnectionErrorMessage(const QString &message);
private:
bool isConnected() const;
void createDebuggerClients();
private:
QPointer<DebuggerEngine> m_engine;
BaseQmlDebuggerClient *m_qmlClient;
QTimer m_connectionTimer;
QmlDebug::QmlDebugConnection *m_conn;
QHash<QString, BaseQmlDebuggerClient*> m_debugClients;
QmlDebug::QDebugMessageClient *m_msgClient;
};
} // namespace Internal
} // namespace Debugger
#endif // QMLADAPTER_H

File diff suppressed because it is too large Load Diff

View File

@@ -31,28 +31,21 @@
#ifndef QMLENGINE_H
#define QMLENGINE_H
#include "interactiveinterpreter.h"
#include "qmladapter.h"
#include "qmlinspectoradapter.h"
#include <debugger/debuggerengine.h>
#include <projectexplorer/applicationlauncher.h>
#include <qmldebug/qdebugmessageclient.h>
#include <qmldebug/qmldebugclient.h>
#include <qmldebug/qmloutputparser.h>
#include <qmljs/iscriptevaluator.h>
#include <qmljs/qmljsdocument.h>
QT_FORWARD_DECLARE_CLASS(QTextDocument)
namespace Core { class IDocument; }
namespace TextEditor { class BaseTextEditor; }
namespace Debugger {
namespace Internal {
class WatchData;
class WatchItem;
class QmlEnginePrivate;
class QmlAdapter;
class WatchTreeView;
class QmlEngine : public DebuggerEngine, QmlJS::IScriptEvaluator
{
@@ -63,31 +56,11 @@ public:
DebuggerEngine *masterEngine = 0);
~QmlEngine();
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
void filterApplicationMessage(const QString &msg, int channel) const;
bool canDisplayTooltip() const;
void showMessage(const QString &msg, int channel = LogDebug,
int timeout = -1) const;
void gotoLocation(const Internal::Location &location);
void filterApplicationMessage(const QString &msg, int channel);
void inferiorSpontaneousStop();
enum LogDirection {
LogSend,
LogReceive
};
void logMessage(const QString &service, LogDirection direction,
const QString &str);
void setSourceFiles(const QStringList &fileNames);
void updateScriptSource(const QString &fileName, int lineOffset,
int columnOffset, const QString &source);
void insertBreakpoint(Breakpoint bp);
void logServiceStateChange(const QString &service, float version,
QmlDebug::QmlDebugClient::State newState);
void logServiceActivity(const QString &service, const QString &logMessage);
private slots:
void disconnected();
@@ -96,23 +69,28 @@ private slots:
void errorMessageBoxFinished(int result);
void updateCurrentContext();
void appendDebugOutput(QtMsgType type, const QString &message,
const QmlDebug::QDebugContextInfo &info);
void tryToConnect(quint16 port = 0);
void beginConnection(quint16 port = 0);
void connectionEstablished();
void connectionStartupFailed();
void appStartupFailed(const QString &errorMessage);
void connectionError(QDebugSupport::Error error);
void serviceConnectionError(const QString &service);
void appendMessage(const QString &msg, Utils::OutputFormat);
void synchronizeWatchers();
private:
// DebuggerEngine implementation.
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
void showMessage(const QString &msg, int channel = LogDebug,
int timeout = -1) const;
void gotoLocation(const Internal::Location &location);
void insertBreakpoint(Breakpoint bp);
bool isSynchronous() const { return false; }
bool canDisplayTooltip() const { return false; }
void executeStep();
void executeStepOut();
void executeNext();
@@ -153,7 +131,6 @@ private:
void reloadSourceFiles();
void reloadFullStack() {}
bool supportsThreads() const { return false; }
void updateWatchData(const QByteArray &iname);
void selectWatchData(const QByteArray &iname);
void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
@@ -162,36 +139,21 @@ private:
bool hasCapability(unsigned) const;
void quitDebugger();
private:
void closeConnection();
void startApplicationLauncher();
void stopApplicationLauncher();
bool isShadowBuildProject() const;
QString fromShadowBuildFilename(const QString &filename) const;
QString mangleFilenamePaths(const QString &filename,
const QString &oldBasePath, const QString &newBasePath) const;
QString qmlImportPath() const;
void updateDocument(Core::IDocument *document, const QTextDocument *textDocument);
bool canEvaluateScript(const QString &script);
bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line,
quint32 *column, bool *valid);
QmlAdapter m_adapter;
QmlInspectorAdapter m_inspectorAdapter;
ProjectExplorer::ApplicationLauncher m_applicationLauncher;
QTimer m_noDebugOutputTimer;
QmlDebug::QmlOutputParser m_outputParser;
QHash<QString, QTextDocument*> m_sourceDocuments;
QHash<QString, QWeakPointer<TextEditor::BaseTextEditor> > m_sourceEditors;
InteractiveInterpreter m_interpreter;
QHash<QString,Breakpoint> pendingBreakpoints;
QList<quint32> queryIds;
bool m_retryOnConnectFail;
bool m_automaticConnect;
void connectionErrorOccurred(QDebugSupport::Error socketError);
void clientStateChanged(QmlDebug::QmlDebugClient::State state);
void checkConnectionState();
void showConnectionStateMessage(const QString &message);
void showConnectionErrorMessage(const QString &message);
bool isConnected() const;
private:
friend class QmlCppEngine;
friend class QmlEnginePrivate;
QmlEnginePrivate *d;
};
} // namespace Internal

View File

@@ -0,0 +1,311 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "qmlengine.h"
#include <qmljs/parser/qmljsast_p.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <qmljs/consolemanagerinterface.h>
#include <coreplugin/editormanager/documentmodel.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
#include <QTextBlock>
using namespace Core;
using namespace QmlDebug;
using namespace QmlJS;
using namespace QmlJS::AST;
using namespace TextEditor;
namespace Debugger {
namespace Internal {
class ASTWalker : public Visitor
{
public:
void operator()(Node *ast, quint32 *l, quint32 *c)
{
done = false;
line = l;
column = c;
Node::accept(ast, this);
}
bool preVisit(Node *ast)
{
return !done && ast->lastSourceLocation().startLine >= *line;
}
//Case 1: Breakpoint is between sourceStart(exclusive) and
// sourceEnd(inclusive) --> End tree walk.
//Case 2: Breakpoint is on sourceStart --> Check for the start
// of the first executable code. Set the line number and
// column number. End tree walk.
//Case 3: Breakpoint is on "unbreakable" code --> Find the next "breakable"
// code and check for Case 2. End tree walk.
//Add more types when suitable.
bool visit(UiScriptBinding *ast)
{
if (!ast->statement)
return true;
quint32 sourceStartLine = ast->firstSourceLocation().startLine;
quint32 statementStartLine;
quint32 statementColumn;
if (ast->statement->kind == Node::Kind_ExpressionStatement) {
statementStartLine = ast->statement->firstSourceLocation().startLine;
statementColumn = ast->statement->firstSourceLocation().startColumn;
} else if (ast->statement->kind == Node::Kind_Block) {
Block *block = static_cast<Block *>(ast->statement);
if (!block || !block->statements)
return true;
statementStartLine = block->statements->firstSourceLocation().startLine;
statementColumn = block->statements->firstSourceLocation().startColumn;
} else {
return true;
}
//Case 1
//Check for possible relocation within the binding statement
//Rewritten to (function <token>() { { }})
//The offset 16 is position of inner lbrace without token length.
const int offset = 16;
//Case 2
if (statementStartLine == *line) {
if (sourceStartLine == *line)
*column = offset + ast->qualifiedId->identifierToken.length;
done = true;
}
//Case 3
if (statementStartLine > *line) {
*line = statementStartLine;
if (sourceStartLine == *line)
*column = offset + ast->qualifiedId->identifierToken.length;
else
*column = statementColumn;
done = true;
}
return true;
}
bool visit(FunctionDeclaration *ast) {
quint32 sourceStartLine = ast->firstSourceLocation().startLine;
quint32 sourceStartColumn = ast->firstSourceLocation().startColumn;
quint32 statementStartLine = ast->body->firstSourceLocation().startLine;
quint32 statementColumn = ast->body->firstSourceLocation().startColumn;
//Case 1
//Check for possible relocation within the function declaration
//Case 2
if (statementStartLine == *line) {
if (sourceStartLine == *line)
*column = statementColumn - sourceStartColumn + 1;
done = true;
}
//Case 3
if (statementStartLine > *line) {
*line = statementStartLine;
if (sourceStartLine == *line)
*column = statementColumn - sourceStartColumn + 1;
else
*column = statementColumn;
done = true;
}
return true;
}
bool visit(EmptyStatement *ast)
{
*line = ast->lastSourceLocation().startLine + 1;
return true;
}
bool visit(VariableStatement *ast) { test(ast); return true; }
bool visit(VariableDeclarationList *ast) { test(ast); return true; }
bool visit(VariableDeclaration *ast) { test(ast); return true; }
bool visit(ExpressionStatement *ast) { test(ast); return true; }
bool visit(IfStatement *ast) { test(ast); return true; }
bool visit(DoWhileStatement *ast) { test(ast); return true; }
bool visit(WhileStatement *ast) { test(ast); return true; }
bool visit(ForStatement *ast) { test(ast); return true; }
bool visit(LocalForStatement *ast) { test(ast); return true; }
bool visit(ForEachStatement *ast) { test(ast); return true; }
bool visit(LocalForEachStatement *ast) { test(ast); return true; }
bool visit(ContinueStatement *ast) { test(ast); return true; }
bool visit(BreakStatement *ast) { test(ast); return true; }
bool visit(ReturnStatement *ast) { test(ast); return true; }
bool visit(WithStatement *ast) { test(ast); return true; }
bool visit(SwitchStatement *ast) { test(ast); return true; }
bool visit(CaseBlock *ast) { test(ast); return true; }
bool visit(CaseClauses *ast) { test(ast); return true; }
bool visit(CaseClause *ast) { test(ast); return true; }
bool visit(DefaultClause *ast) { test(ast); return true; }
bool visit(LabelledStatement *ast) { test(ast); return true; }
bool visit(ThrowStatement *ast) { test(ast); return true; }
bool visit(TryStatement *ast) { test(ast); return true; }
bool visit(Catch *ast) { test(ast); return true; }
bool visit(Finally *ast) { test(ast); return true; }
bool visit(FunctionExpression *ast) { test(ast); return true; }
bool visit(DebuggerStatement *ast) { test(ast); return true; }
void test(Node *ast)
{
quint32 statementStartLine = ast->firstSourceLocation().startLine;
//Case 1/2
if (statementStartLine <= *line && *line <= ast->lastSourceLocation().startLine)
done = true;
//Case 3
if (statementStartLine > *line) {
*line = statementStartLine;
*column = ast->firstSourceLocation().startColumn;
done = true;
}
}
bool done;
quint32 *line;
quint32 *column;
};
bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line, quint32 *column, bool *valid)
{
bool success = false;
//check if file is in the latest snapshot
//ignoring documentChangedOnDisk
//TODO:: update breakpoints if document is changed.
ModelManagerInterface *mmIface = ModelManagerInterface::instance();
if (mmIface) {
Document::Ptr doc = mmIface->newestSnapshot().document(filePath);
if (doc.isNull()) {
ModelManagerInterface::instance()->updateSourceFiles(
QStringList() << filePath, false);
} else {
ASTWalker walker;
walker(doc->ast(), line, column);
*valid = walker.done;
success = true;
}
}
return success;
}
void appendDebugOutput(QtMsgType type, const QString &message, const QDebugContextInfo &info)
{
ConsoleItem::ItemType itemType;
switch (type) {
case QtDebugMsg:
itemType = ConsoleItem::DebugType;
break;
case QtWarningMsg:
itemType = ConsoleItem::WarningType;
break;
case QtCriticalMsg:
case QtFatalMsg:
itemType = ConsoleItem::ErrorType;
break;
default:
//This case is not possible
return;
}
if (auto consoleManager = ConsoleManagerInterface::instance()) {
ConsoleItem *item = new ConsoleItem(consoleManager->rootItem(), itemType, message);
item->file = info.file;
item->line = info.line;
consoleManager->printToConsolePane(item);
}
}
void clearExceptionSelection()
{
QList<QTextEdit::ExtraSelection> selections;
foreach (IEditor *editor, DocumentModel::editorsForOpenedDocuments()) {
if (auto ed = qobject_cast<TextEditorWidget *>(editor->widget()))
ed->setExtraSelections(TextEditorWidget::DebuggerExceptionSelection, selections);
}
}
QStringList highlightExceptionCode(int lineNumber, const QString &filePath, const QString &errorMessage)
{
QStringList messages;
QList<IEditor *> editors = DocumentModel::editorsForFilePath(filePath);
// set up the format for the errors
QTextCharFormat errorFormat;
errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
errorFormat.setUnderlineColor(Qt::red);
foreach (IEditor *editor, editors) {
TextEditorWidget *ed = qobject_cast<TextEditorWidget *>(editor->widget());
if (!ed)
continue;
QList<QTextEdit::ExtraSelection> selections;
QTextEdit::ExtraSelection sel;
sel.format = errorFormat;
QTextCursor c(ed->document()->findBlockByNumber(lineNumber - 1));
const QString text = c.block().text();
for (int i = 0; i < text.size(); ++i) {
if (!text.at(i).isSpace()) {
c.setPosition(c.position() + i);
break;
}
}
c.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
sel.cursor = c;
sel.format.setToolTip(errorMessage);
selections.append(sel);
ed->setExtraSelections(TextEditorWidget::DebuggerExceptionSelection, selections);
messages.append(QString::fromLatin1("%1: %2: %3").arg(filePath).arg(lineNumber).arg(errorMessage));
}
return messages;
}
} // Internal
} // Debugger

View File

@@ -28,30 +28,22 @@
**
****************************************************************************/
import QtQuick 1.1
#ifndef QMLENGINEUTILS_H
#define QMLENGINEUTILS_H
Rectangle {
width: 640
height: 480
#include <qmldebug/qdebugmessageclient.h>
#include <qmldebug/qmloutputparser.h>
Image {
id: image1
x: 20
y: 18
source: "images/qtcreator.png"
}
namespace Debugger {
namespace Internal {
Image {
id: image2
x: 327
y: 18
source: "images/qtcreator.jpg"
}
bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line, quint32 *column, bool *valid);
void appendDebugOutput(QtMsgType type, const QString &message, const QmlDebug::QDebugContextInfo &info);
Image {
id: image3
x: 20
y: 288
source: "images/qtcreator.ico"
}
}
void clearExceptionSelection();
QStringList highlightExceptionCode(int lineNumber, const QString &filePath, const QString &errorMessage);
} // namespace Internal
} // namespace Debugger
#endif // QMLENGINEUTILS_H

View File

@@ -30,8 +30,9 @@
#include "qmlinspectoradapter.h"
#include "qmladapter.h"
#include "qmlengine.h"
#include "qmlinspectoragent.h"
#include <debugger/debuggeractions.h>
#include <debugger/debuggercore.h>
#include <debugger/debuggerstringutils.h>
@@ -60,15 +61,12 @@ namespace Internal {
* QmlInspectorAdapter manages the clients for the inspector, and the
* integration with the text editor.
*/
QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter,
DebuggerEngine *engine,
QObject *parent)
: QObject(parent)
, m_debugAdapter(debugAdapter)
, m_engine(engine)
QmlInspectorAdapter::QmlInspectorAdapter(QmlEngine *engine, QmlDebugConnection *connection)
: m_qmlEngine(engine)
, m_masterEngine(engine)
, m_engineClient(0)
, m_toolsClient(0)
, m_agent(new QmlInspectorAgent(engine, this))
, m_agent(new QmlInspectorAgent(engine))
, m_targetToSync(NoTarget)
, m_debugIdToSelect(-1)
, m_currentSelectedDebugId(-1)
@@ -79,16 +77,15 @@ QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter,
, m_showAppOnTopAction(action(ShowAppOnTop))
, m_engineClientConnected(false)
{
if (!m_engine->isMasterEngine())
m_engine = m_engine->masterEngine();
connect(m_engine, &DebuggerEngine::stateChanged,
if (!m_masterEngine->isMasterEngine())
m_masterEngine = m_masterEngine->masterEngine();
connect(m_masterEngine, &DebuggerEngine::stateChanged,
this, &QmlInspectorAdapter::onEngineStateChanged);
connect(m_agent, &QmlInspectorAgent::objectFetched,
this, &QmlInspectorAdapter::onObjectFetched);
connect(m_agent, &QmlInspectorAgent::jumpToObjectDefinition,
this, &QmlInspectorAdapter::jumpToObjectDefinitionInEditor);
QmlDebugConnection *connection = m_debugAdapter->connection();
auto engineClient1 = new DeclarativeEngineDebugClient(connection);
connect(engineClient1, &BaseEngineDebugClient::newState,
this, &QmlInspectorAdapter::clientStateChanged);
@@ -186,7 +183,7 @@ void QmlInspectorAdapter::clientStateChanged(QmlDebugClient::State state)
version = client->remoteVersion();
}
m_debugAdapter->logServiceStateChange(serviceName, version, state);
m_qmlEngine->logServiceStateChange(serviceName, version, state);
}
void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
@@ -199,7 +196,7 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
connect(client, &BaseToolsClient::currentObjectsChanged,
this, &QmlInspectorAdapter::selectObjectsFromToolsClient);
connect(client, &BaseToolsClient::logActivity,
m_debugAdapter, &QmlAdapter::logServiceActivity);
m_qmlEngine, &QmlEngine::logServiceActivity);
connect(client, &BaseToolsClient::reloaded, this, &QmlInspectorAdapter::onReloaded);
// register actions here
@@ -217,15 +214,15 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
Core::ICore::addAdditionalContext(m_inspectorToolsContext);
m_toolsClientConnected = true;
onEngineStateChanged(m_engine->state());
onEngineStateChanged(m_masterEngine->state());
if (m_showAppOnTopAction->isChecked())
m_toolsClient->showAppOnTop(true);
} else if (m_toolsClientConnected && client == m_toolsClient) {
disconnect(client, SIGNAL(currentObjectsChanged(QList<int>)),
this, SLOT(selectObjectsFromToolsClient(QList<int>)));
disconnect(client, SIGNAL(logActivity(QString,QString)),
m_debugAdapter, SLOT(logServiceActivity(QString,QString)));
disconnect(client, &BaseToolsClient::currentObjectsChanged,
this, &QmlInspectorAdapter::selectObjectsFromToolsClient);
disconnect(client, &BaseToolsClient::logActivity,
m_qmlEngine, &QmlEngine::logServiceActivity);
Core::ActionManager::unregisterAction(m_selectAction, Core::Id(Constants::QML_SELECTTOOL));
Core::ActionManager::unregisterAction(m_zoomAction, Core::Id(Constants::QML_ZOOMTOOL));
@@ -316,13 +313,13 @@ void QmlInspectorAdapter::setActiveEngineClient(BaseEngineDebugClient *client)
void QmlInspectorAdapter::showConnectionStateMessage(const QString &message)
{
m_engine->showMessage(_("QML Inspector: ") + message, LogStatus);
m_masterEngine->showMessage(_("QML Inspector: ") + message, LogStatus);
}
void QmlInspectorAdapter::jumpToObjectDefinitionInEditor(
const FileReference &objSource, int debugId)
{
const QString fileName = m_engine->toFileInProject(objSource.url());
const QString fileName = m_masterEngine->toFileInProject(objSource.url());
Core::EditorManager::openEditorAt(fileName, objSource.lineNumber());
if (debugId != -1 && debugId != m_currentSelectedDebugId) {

View File

@@ -41,13 +41,14 @@ class BaseEngineDebugClient;
class BaseToolsClient;
class ObjectReference;
class FileReference;
class QmlDebugConnection;
}
namespace Debugger {
namespace Internal {
class DebuggerEngine;
class QmlAdapter;
class QmlEngine;
class QmlInspectorAgent;
class QmlInspectorAdapter : public QObject
@@ -55,8 +56,7 @@ class QmlInspectorAdapter : public QObject
Q_OBJECT
public:
QmlInspectorAdapter(QmlAdapter *debugAdapter, DebuggerEngine *engine,
QObject *parent = 0);
QmlInspectorAdapter(QmlEngine *engine, QmlDebug::QmlDebugConnection *connection);
~QmlInspectorAdapter();
QmlDebug::BaseEngineDebugClient *engineClient() const;
@@ -96,8 +96,8 @@ private:
void enableTools(const bool enable);
QmlAdapter *m_debugAdapter;
DebuggerEngine *m_engine; // Master Engine
QmlEngine *m_qmlEngine;
DebuggerEngine *m_masterEngine;
QmlDebug::BaseEngineDebugClient *m_engineClient;
QHash<QString, QmlDebug::BaseEngineDebugClient*> m_engineClients;
QmlDebug::BaseToolsClient *m_toolsClient;

View File

@@ -686,6 +686,7 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object)
m_objectToSelect = -1;
}
m_debuggerEngine->watchHandler()->updateWatchersWindow();
m_debuggerEngine->watchHandler()->reexpandItems();
}
void QmlInspectorAgent::buildDebugIdHashRecursive(const ObjectReference &ref)

File diff suppressed because it is too large Load Diff

View File

@@ -1,130 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef QMLV8DEBUGGERCLIENT_H
#define QMLV8DEBUGGERCLIENT_H
#include "baseqmldebuggerclient.h"
namespace Debugger {
namespace Internal {
class QmlV8DebuggerClientPrivate;
class QmlV8DebuggerClient : public BaseQmlDebuggerClient
{
Q_OBJECT
enum Exceptions
{
NoExceptions,
UncaughtExceptions,
AllExceptions
};
enum StepAction
{
Continue,
In,
Out,
Next
};
public:
explicit QmlV8DebuggerClient(QmlDebug::QmlDebugConnection *client);
~QmlV8DebuggerClient();
void startSession();
void endSession();
void resetSession();
void executeStep();
void executeStepOut();
void executeNext();
void executeStepI();
void executeRunToLine(const ContextData &data);
void continueInferior();
void interruptInferior();
void activateFrame(int index);
bool acceptsBreakpoint(Breakpoint bp);
void insertBreakpoint(Breakpoint bp, int adjustedLine,
int adjustedColumn = -1);
void removeBreakpoint(Breakpoint bp);
void changeBreakpoint(Breakpoint bp);
void synchronizeBreakpoints();
void assignValueInDebugger(const WatchData *data,
const QString &expression,
const QVariant &valueV);
void updateWatchData(const WatchData &);
void executeDebuggerCommand(const QString &command);
void synchronizeWatchers(const QStringList &watchers);
void expandObject(const QByteArray &iname, quint64 objectId);
void setEngine(QmlEngine *engine);
void getSourceFiles();
protected:
void messageReceived(const QByteArray &data);
private:
void updateStack(const QVariant &bodyVal, const QVariant &refsVal);
StackFrame extractStackFrame(const QVariant &bodyVal, const QVariant &refsVal);
void setCurrentFrameDetails(const QVariant &bodyVal, const QVariant &refsVal);
void updateScope(const QVariant &bodyVal, const QVariant &refsVal);
void updateEvaluationResult(int sequence, bool success, const QVariant &bodyVal,
const QVariant &refsVal);
void expandLocalsAndWatchers(const QVariant &bodyVal, const QVariant &refsVal);
void createWatchDataList(const WatchItem *parent,
const QVariantList &properties,
const QVariant &refsVal);
void highlightExceptionCode(int lineNumber, const QString &filePath,
const QString &errorMessage);
void clearExceptionSelection();
private:
QmlV8DebuggerClientPrivate *d;
friend class QmlV8DebuggerClientPrivate;
};
} // Internal
} // Debugger
#endif // QMLV8DEBUGGERCLIENT_H

View File

@@ -1,606 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "qscriptdebuggerclient.h"
#include "qmlengine.h"
#include <debugger/watchhandler.h>
#include <debugger/breakhandler.h>
#include <debugger/stackhandler.h>
#include <debugger/debuggercore.h>
#include <debugger/debuggerstringutils.h>
#include <qmldebug/qmldebugclient.h>
#include <coreplugin/messagebox.h>
#include <QFileInfo>
#include <utils/qtcassert.h>
using QmlDebug::QmlDebugStream;
namespace Debugger {
namespace Internal {
struct JSAgentBreakpointData
{
QByteArray functionName;
QByteArray fileUrl;
qint32 lineNumber;
};
struct JSAgentStackData
{
QByteArray functionName;
QByteArray fileUrl;
qint32 lineNumber;
};
uint qHash(const JSAgentBreakpointData &b)
{
return b.lineNumber ^ qHash(b.fileUrl);
}
QDataStream &operator<<(QDataStream &s, const JSAgentBreakpointData &data)
{
return s << data.functionName << data.fileUrl << data.lineNumber;
}
QDataStream &operator<<(QDataStream &s, const JSAgentStackData &data)
{
return s << data.functionName << data.fileUrl << data.lineNumber;
}
QDataStream &operator>>(QDataStream &s, JSAgentBreakpointData &data)
{
return s >> data.functionName >> data.fileUrl >> data.lineNumber;
}
QDataStream &operator>>(QDataStream &s, JSAgentStackData &data)
{
return s >> data.functionName >> data.fileUrl >> data.lineNumber;
}
bool operator==(const JSAgentBreakpointData &b1, const JSAgentBreakpointData &b2)
{
return b1.lineNumber == b2.lineNumber && b1.fileUrl == b2.fileUrl;
}
typedef QSet<JSAgentBreakpointData> JSAgentBreakpoints;
typedef QList<JSAgentStackData> JSAgentStackFrames;
static QDataStream &operator>>(QDataStream &s, WatchData &data)
{
data = WatchData();
QByteArray name;
QByteArray value;
QByteArray type;
bool hasChildren = false;
s >> data.exp >> name >> value >> type >> hasChildren >> data.id;
data.name = QString::fromUtf8(name);
data.setType(type, false);
data.setValue(QString::fromUtf8(value));
data.setHasChildren(hasChildren);
data.setAllUnneeded();
return s;
}
class QScriptDebuggerClientPrivate
{
public:
explicit QScriptDebuggerClientPrivate(QScriptDebuggerClient *) :
ping(0), sessionStarted(false), engine(0)
{
}
int ping;
bool sessionStarted;
QmlEngine *engine;
JSAgentBreakpoints breakpoints;
void logSendMessage(const QString &msg) const;
void logReceiveMessage(const QString &msg) const;
};
QScriptDebuggerClient::QScriptDebuggerClient(QmlDebug::QmlDebugConnection* client)
: BaseQmlDebuggerClient(client, QLatin1String("JSDebugger")),
d(new QScriptDebuggerClientPrivate(this))
{
}
QScriptDebuggerClient::~QScriptDebuggerClient()
{
delete d;
}
void QScriptDebuggerClient::executeStep()
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "STEPINTO";
rs << cmd;
d->logSendMessage(QLatin1String(cmd));
sendMessage(reply);
}
void QScriptDebuggerClient::executeStepOut()
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "STEPOUT";
rs << cmd;
d->logSendMessage(QLatin1String(cmd));
sendMessage(reply);
}
void QScriptDebuggerClient::executeNext()
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "STEPOVER";
rs << cmd;
d->logSendMessage(QLatin1String(cmd));
sendMessage(reply);
}
void QScriptDebuggerClient::executeStepI()
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "STEPINTO";
rs << cmd;
d->logSendMessage(QLatin1String(cmd));
sendMessage(reply);
}
void QScriptDebuggerClient::executeRunToLine(const ContextData &data)
{
JSAgentBreakpointData bp;
bp.fileUrl = QUrl::fromLocalFile(data.fileName).toString().toUtf8();
bp.lineNumber = data.lineNumber;
bp.functionName = "TEMPORARY";
d->breakpoints.insert(bp);
synchronizeBreakpoints();
continueInferior();
}
void QScriptDebuggerClient::continueInferior()
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "CONTINUE";
rs << cmd;
d->logSendMessage(QLatin1String(cmd));
sendMessage(reply);
}
void QScriptDebuggerClient::interruptInferior()
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "INTERRUPT";
rs << cmd;
d->logSendMessage(QLatin1String(cmd));
sendMessage(reply);
}
void QScriptDebuggerClient::startSession()
{
//Flush buffered data
flushSendBuffer();
//Set all breakpoints
BreakHandler *handler = d->engine->breakHandler();
DebuggerEngine * engine = d->engine->isSlaveEngine() ?
d->engine->masterEngine() : d->engine;
foreach (Breakpoint bp, handler->engineBreakpoints(engine)) {
QTC_CHECK(bp.state() == BreakpointInsertProceeding);
bp.notifyBreakpointInsertOk();
}
d->sessionStarted = true;
}
void QScriptDebuggerClient::endSession()
{
}
void QScriptDebuggerClient::resetSession()
{
d->sessionStarted = false;
}
void QScriptDebuggerClient::activateFrame(int index)
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "ACTIVATE_FRAME";
rs << cmd
<< index;
d->logSendMessage(QLatin1String(cmd) + QLatin1Char(' ') + QString::number(index));
sendMessage(reply);
}
void QScriptDebuggerClient::insertBreakpoint(Breakpoint bp,
int adjustedLine,
int /*adjustedColumn*/)
{
JSAgentBreakpointData jsbp;
jsbp.fileUrl = QUrl::fromLocalFile(bp.fileName()).toString().toUtf8();
jsbp.lineNumber = adjustedLine;
jsbp.functionName = bp.functionName().toUtf8();
d->breakpoints.insert(jsbp);
BreakpointResponse br = bp.response();
br.lineNumber = adjustedLine;
bp.setResponse(br);
if (d->sessionStarted && bp.state() == BreakpointInsertProceeding)
bp.notifyBreakpointInsertOk();
}
void QScriptDebuggerClient::removeBreakpoint(Breakpoint bp)
{
JSAgentBreakpointData jsbp;
jsbp.fileUrl = QUrl::fromLocalFile(bp.fileName()).toString().toUtf8();
jsbp.lineNumber = bp.lineNumber();
jsbp.functionName = bp.functionName().toUtf8();
d->breakpoints.remove(jsbp);
}
void QScriptDebuggerClient::changeBreakpoint(Breakpoint bp)
{
if (bp.isEnabled())
insertBreakpoint(bp, bp.response().lineNumber);
else
removeBreakpoint(bp);
BreakpointResponse br = bp.response();
br.enabled = bp.isEnabled();
bp.setResponse(br);
}
void QScriptDebuggerClient::synchronizeBreakpoints()
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "BREAKPOINTS";
rs << cmd
<< d->breakpoints;
QString logBreakpoints;
QTextStream str(&logBreakpoints);
str << cmd << " (";
bool first = true;
foreach (const JSAgentBreakpointData &bp, d->breakpoints) {
if (first)
first = false;
else
str << ", ";
str << '[' << bp.functionName << ", " << bp.fileUrl << ", " << bp.lineNumber << ']';
}
str << ')';
d->logSendMessage(logBreakpoints);
sendMessage(reply);
}
void QScriptDebuggerClient::assignValueInDebugger(const WatchData *data,
const QString &expr,
const QVariant &valueV)
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "EXEC";
rs << cmd;
QString expression = QString(_("%1 = %2;")).arg(expr).arg(valueV.toString());
rs << data->iname << expression;
d->logSendMessage(QString::fromLatin1("%1 %2 %3 %4").
arg(QLatin1String(cmd), QLatin1String(data->iname), expr,
valueV.toString()));
sendMessage(reply);
}
void QScriptDebuggerClient::updateWatchData(const WatchData &data)
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "EXEC";
rs << cmd;
rs << data.iname << data.name;
d->logSendMessage(QLatin1String(cmd) + QLatin1Char(' ') + QLatin1String(data.iname)
+ QLatin1Char(' ') + data.name);
sendMessage(reply);
}
void QScriptDebuggerClient::executeDebuggerCommand(const QString &command)
{
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "EXEC";
QByteArray console = "console";
rs << cmd << console << command;
d->logSendMessage(QLatin1String(cmd) + QLatin1Char(' ') + QLatin1String(console)
+ QLatin1Char(' ') + command);
sendMessage(reply);
}
void QScriptDebuggerClient::synchronizeWatchers(const QStringList &watchers)
{
// send watchers list
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "WATCH_EXPRESSIONS";
rs << cmd;
d->logSendMessage(QString::fromLatin1("%1 (%2)").arg(QLatin1String(cmd),
watchers.join(QLatin1String(", "))));
sendMessage(reply);
}
void QScriptDebuggerClient::expandObject(const QByteArray &iname, quint64 objectId)
{
//Check if id is valid
if (qint64(objectId) == -1)
return;
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "EXPAND";
rs << cmd;
rs << iname << objectId;
d->logSendMessage(QLatin1String(cmd) + QLatin1Char(' ') + QLatin1String(iname)
+ QString::number(objectId));
sendMessage(reply);
}
void QScriptDebuggerClient::sendPing()
{
d->ping++;
QByteArray reply;
QmlDebugStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd = "PING";
rs << cmd;
rs << d->ping;
d->logSendMessage(QLatin1String(cmd));
sendMessage(reply);
}
void QScriptDebuggerClient::messageReceived(const QByteArray &data)
{
QByteArray rwData = data;
QmlDebugStream stream(&rwData, QIODevice::ReadOnly);
QByteArray command;
stream >> command;
WatchHandler *watchHandler = d->engine->watchHandler();
StackHandler *stackHandler = d->engine->stackHandler();
if (command == "STOPPED") {
d->engine->inferiorSpontaneousStop();
QString logString = QString::fromLatin1(command);
JSAgentStackFrames stackFrames;
QList<WatchData> watches;
QList<WatchData> locals;
stream >> stackFrames >> watches >> locals;
logString += QString::fromLatin1(" (%1 stack frames) (%2 watches) (%3 locals)").
arg(stackFrames.size()).arg(watches.size()).arg(locals.size());
StackFrames ideStackFrames;
for (int i = 0; i != stackFrames.size(); ++i) {
StackFrame frame;
frame.line = stackFrames.at(i).lineNumber;
frame.function = QLatin1String(stackFrames.at(i).functionName);
frame.file = d->engine->toFileInProject(QUrl(QLatin1String(stackFrames.at(i).fileUrl)));
frame.usable = QFileInfo(frame.file).isReadable();
frame.level = i + 1;
ideStackFrames << frame;
}
stackHandler->setFrames(ideStackFrames);
bool becauseOfException;
stream >> becauseOfException;
logString += becauseOfException ? QLatin1String(" exception") : QLatin1String(" no_exception");
if (becauseOfException) {
QString error;
stream >> error;
logString += QLatin1Char(' ');
logString += error;
d->logReceiveMessage(logString);
QString msg = stackFrames.isEmpty()
? tr("<p>An uncaught exception occurred:</p><p>%1</p>")
.arg(error.toHtmlEscaped())
: tr("<p>An uncaught exception occurred in \"%1\":</p><p>%2</p>")
.arg(QLatin1String(stackFrames.value(0).fileUrl), error.toHtmlEscaped());
Core::AsynchronousMessageBox::information(tr("Uncaught Exception"), msg);
} else {
QString file;
int line = -1;
if (!ideStackFrames.isEmpty()) {
file = ideStackFrames.at(0).file;
line = ideStackFrames.at(0).line;
}
QList<JSAgentBreakpointData> breakpoints(d->breakpoints.toList());
foreach (const JSAgentBreakpointData &data, breakpoints) {
if (data.fileUrl == QUrl::fromLocalFile(file).toString().toUtf8() &&
data.lineNumber == line &&
data.functionName == "TEMPORARY") {
breakpoints.removeOne(data);
d->breakpoints = JSAgentBreakpoints::fromList(breakpoints);
synchronizeBreakpoints();
break;
}
}
d->logReceiveMessage(logString);
}
if (!ideStackFrames.isEmpty())
d->engine->gotoLocation(ideStackFrames.value(0));
insertLocalsAndWatches(locals, watches, stackHandler->currentIndex());
} else if (command == "RESULT") {
WatchData data;
QByteArray iname;
stream >> iname >> data;
d->logReceiveMessage(QLatin1String(command) + QLatin1Char(' ')
+ QLatin1String(iname) + QLatin1Char(' ') + data.value);
auto item = new WatchItem(data);
item->iname = iname;
if (iname.startsWith("watch.")) {
watchHandler->insertItem(item);
} else if (iname == "console") {
d->engine->showMessage(item->value, ConsoleOutput);
} else if (iname.startsWith("local.")) {
item->name = item->name.left(item->name.indexOf(QLatin1Char(' ')));
watchHandler->insertItem(item);
} else {
qWarning() << "QmlEngine: Unexcpected result: " << iname << item->value;
}
} else if (command == "EXPANDED") {
QList<WatchData> result;
QByteArray iname;
stream >> iname >> result;
d->logReceiveMessage(QString::fromLatin1("%1 %2 (%3 x watchdata)").
arg(QLatin1String(command), QLatin1String(iname),
QString::number(result.size())));
bool needPing = false;
foreach (WatchData data, result) {
data.iname = iname + '.' + data.exp;
watchHandler->insertItem(new WatchItem(data));
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname, data.id);
}
}
if (needPing)
sendPing();
} else if (command == "LOCALS") {
QList<WatchData> locals;
QList<WatchData> watches;
int frameId;
stream >> frameId >> locals;
if (!stream.atEnd()) { // compatibility with jsdebuggeragent from 2.1, 2.2
stream >> watches;
}
d->logReceiveMessage(QString::fromLatin1("%1 %2 (%3 x locals) (%4 x watchdata)").arg(
QLatin1String(command), QString::number(frameId),
QString::number(locals.size()), QString::number(watches.size())));
insertLocalsAndWatches(locals, watches, frameId);
} else if (command == "PONG") {
int ping;
stream >> ping;
d->logReceiveMessage(QLatin1String(command) + QLatin1Char(' ') + QString::number(ping));
} else {
qDebug() << Q_FUNC_INFO << "Unknown command: " << command;
d->logReceiveMessage(QLatin1String(command) + QLatin1String(" UNKNOWN COMMAND!!"));
}
}
void QScriptDebuggerClient::insertLocalsAndWatches(QList<WatchData> &locals,
QList<WatchData> &watches,
int stackFrameIndex)
{
WatchHandler *watchHandler = d->engine->watchHandler();
watchHandler->removeAllData();
if (stackFrameIndex < 0)
return;
const StackFrame frame = d->engine->stackHandler()->frameAt(stackFrameIndex);
if (!frame.isUsable())
return;
bool needPing = false;
foreach (const WatchData &data, watches) {
auto item = new WatchItem(data);
item->iname = watchHandler->watcherName(data.exp);
watchHandler->insertItem(item);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname, data.id);
}
}
foreach (const WatchData &data, locals) {
auto item = new WatchItem(data);
if (item->name == QLatin1String("<no initialized data>"))
item->name = tr("No Local Variables");
item->iname = "local." + item->exp;
watchHandler->insertItem(item);
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
needPing = true;
expandObject(data.iname, data.id);
}
}
if (needPing)
sendPing();
emit stackFrameCompleted();
}
void QScriptDebuggerClient::setEngine(QmlEngine *engine)
{
d->engine = engine;
connect(this, &QScriptDebuggerClient::stackFrameCompleted,
engine, &DebuggerEngine::stackFrameCompleted);
}
void QScriptDebuggerClientPrivate::logSendMessage(const QString &msg) const
{
if (engine)
engine->logMessage(QLatin1String("QScriptDebuggerClient"), QmlEngine::LogSend, msg);
}
void QScriptDebuggerClientPrivate::logReceiveMessage(const QString &msg) const
{
if (engine)
engine->logMessage(QLatin1String("QScriptDebuggerClient"), QmlEngine::LogReceive, msg);
}
} // Internal
} // Debugger

View File

@@ -1,99 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef QSCRIPTDEBUGGERCLIENT_H
#define QSCRIPTDEBUGGERCLIENT_H
#include "baseqmldebuggerclient.h"
namespace Debugger {
namespace Internal {
class QScriptDebuggerClientPrivate;
class QScriptDebuggerClient : public BaseQmlDebuggerClient
{
Q_OBJECT
public:
QScriptDebuggerClient(QmlDebug::QmlDebugConnection *client);
~QScriptDebuggerClient();
void startSession();
void endSession();
void resetSession();
void executeStep();
void executeStepOut();
void executeNext();
void executeStepI();
void executeRunToLine(const ContextData &data);
void continueInferior();
void interruptInferior();
void activateFrame(int index);
void insertBreakpoint(Breakpoint bp, int adjustedLine,
int adjustedColumn = -1);
void removeBreakpoint(Breakpoint bp);
void changeBreakpoint(Breakpoint bp);
void synchronizeBreakpoints();
void assignValueInDebugger(const WatchData *data, const QString &expression,
const QVariant &valueV);
void updateWatchData(const WatchData &data);
void executeDebuggerCommand(const QString &command);
void synchronizeWatchers(const QStringList &watchers);
void expandObject(const QByteArray &iname, quint64 objectId);
void setEngine(QmlEngine *engine);
protected:
void messageReceived(const QByteArray &data);
private:
void sendPing();
void insertLocalsAndWatches(QList<WatchData> &locals, QList<WatchData> &watches,
int stackFrameIndex);
private:
QScriptDebuggerClientPrivate *d;
friend class QScriptDebuggerClientPrivate;
};
} // Internal
} // Debugger
#endif // QSCRIPTDEBUGGERCLIENT_H

View File

@@ -1268,6 +1268,11 @@ void WatchHandler::notifyUpdateFinished()
emit m_model->updateFinished();
}
void WatchHandler::reexpandItems()
{
m_model->reexpandItems();
}
void WatchHandler::removeItemByIName(const QByteArray &iname)
{
WatchItem *item = m_model->findItem(iname);

View File

@@ -201,6 +201,8 @@ public:
void notifyUpdateStarted(const QList<QByteArray> &inames = {});
void notifyUpdateFinished();
void reexpandItems();
private:
WatchModel *m_model; // Owned.
};

View File

@@ -820,13 +820,15 @@ void JsonFieldPage::ComboBoxField::initializeData(MacroExpander *expander)
if (!tmpConditions.at(i)) {
tmpItems.removeAt(i);
tmpData.removeAt(i);
if (i <= index)
if (i < index && index > 0)
--index;
}
}
if (index < 0 || index >= tmpData.count())
index = 0;
w->setItems(tmpItems, tmpData);
w->setInsertPolicy(QComboBox::NoInsert);
w->setCurrentIndex(index);
}

View File

@@ -797,8 +797,6 @@ void QbsProject::updateCppCodeModel()
}
}
if (pinfo.projectParts().isEmpty())
return;
pinfo.finish();
QtSupport::UiCodeModelManager::update(this, uiFiles);

View File

@@ -473,6 +473,7 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const
static QDir resourcesDir(QStringLiteral(":/propertyEditorQmlSources"));
QDir importDir(info.importDirectoryPath() + QLatin1String(Constants::QML_DESIGNER_SUBFOLDER));
QDir importDirVersion(info.importDirectoryPath() + QStringLiteral(".") + QString::number(info.majorVersion()) + QLatin1String(Constants::QML_DESIGNER_SUBFOLDER));
const QString versionString = QStringLiteral("_") + QString::number(info.majorVersion())
+ QStringLiteral("_")
@@ -484,6 +485,14 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const
//Check for qml files with versions first
const QString withoutDirWithVersion = relativePathWithVersion.split(QStringLiteral("/")).last();
const QString withoutDir = relativePath.split(QStringLiteral("/")).last();
if (importDirVersion.exists(withoutDir))
return importDirVersion.absoluteFilePath(withoutDir);
if (importDir.exists(relativePathWithVersion))
return importDir.absoluteFilePath(relativePathWithVersion);
if (importDir.exists(withoutDirWithVersion)) //Since we are in a subfolder of the import we do not require the directory
@@ -493,7 +502,7 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const
if (resourcesDir.exists(relativePathWithVersion))
return resourcesDir.absoluteFilePath(relativePathWithVersion);
const QString withoutDir = relativePath.split(QStringLiteral("/")).last();
if (importDir.exists(relativePath))
return importDir.absoluteFilePath(relativePath);
if (importDir.exists(withoutDir)) //Since we are in a subfolder of the import we do not require the directory

View File

@@ -209,6 +209,15 @@ void SubComponentManager::parseDirectories()
foreach (const QString &path, importPaths()) {
QString fullUrl = path + QLatin1Char('/') + url;
dirInfo = QFileInfo(fullUrl);
if (dirInfo.exists() && dirInfo.isDir()) {
//### todo full qualified names QString nameSpace = import.uri();
parseDirectory(dirInfo.canonicalFilePath(), false);
}
QString fullUrlVersion = path + QLatin1Char('/') + url + QLatin1Char('.') + import.version().split(".").first();
dirInfo = QFileInfo(fullUrlVersion);
if (dirInfo.exists() && dirInfo.isDir()) {
//### todo full qualified names QString nameSpace = import.uri();
parseDirectory(dirInfo.canonicalFilePath(), false);

View File

@@ -47,8 +47,7 @@
#include <QFile>
#include <QFileInfo>
enum { debug = 0 };
#include <QLoggingCategory>
using namespace ProjectExplorer;
using namespace CPlusPlus;
@@ -79,20 +78,26 @@ UiCodeModelSupport::UiCodeModelSupport(CppTools::CppModelManager *modelmanager,
m_headerFileName(uiHeaderFile),
m_state(BARE)
{
if (debug)
qDebug()<<"ctor UiCodeModelSupport for"<<m_uiFileName<<uiHeaderFile;
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
qCDebug(log) << "ctor UiCodeModelSupport for" << m_uiFileName << uiHeaderFile;
connect(&m_process, SIGNAL(finished(int)),
this, SLOT(finishProcess()));
init();
}
UiCodeModelSupport::~UiCodeModelSupport()
{
if (debug)
qDebug()<<"dtor ~UiCodeModelSupport for"<<m_uiFileName;
disconnect(&m_process, SIGNAL(finished(int)),
this, SLOT(finishProcess()));
m_process.kill();
CppTools::CppModelManager::instance()->emitAbstractEditorSupportRemoved(m_headerFileName);
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
qCDebug(log) << "dtor ~UiCodeModelSupport for" << m_uiFileName;
}
void UiCodeModelSupport::init() const
{
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
if (m_state != BARE)
return;
QDateTime sourceTime = QFileInfo(m_uiFileName).lastModified();
@@ -101,53 +106,43 @@ void UiCodeModelSupport::init() const
if (uiHeaderTime.isValid() && (uiHeaderTime > sourceTime)) {
QFile file(m_headerFileName);
if (file.open(QFile::ReadOnly | QFile::Text)) {
if (debug)
qDebug()<<"ui*h file is more recent then source file, using information from ui*h file"<<m_headerFileName;
qCDebug(log) << "init: ui*h file is more recent then source file, using information from ui*h file" << m_headerFileName;
QTextStream stream(&file);
m_contents = stream.readAll().toUtf8();
m_cacheTime = uiHeaderTime;
m_state = FINISHED;
notifyAboutUpdatedContents();
return;
}
}
if (debug)
qDebug()<<"ui*h file not found, or not recent enough, trying to create it on the fly";
qCDebug(log) << "ui*h file not found, or not recent enough, trying to create it on the fly";
QFile file(m_uiFileName);
if (file.open(QFile::ReadOnly | QFile::Text)) {
QTextStream stream(&file);
const QString contents = stream.readAll();
if (runUic(contents)) {
if (debug)
qDebug()<<"created on the fly";
qCDebug(log) << "created on the fly";
return;
} else {
// uic run was unsuccesfull
if (debug)
qDebug()<<"uic run wasn't succesfull";
qCDebug(log) << "uic run wasn't succesfull";
m_cacheTime = QDateTime ();
m_contents.clear();
m_state = FINISHED;
notifyAboutUpdatedContents();
return;
}
} else {
if (debug)
qDebug()<<"Could open "<<m_uiFileName<<"needed for the cpp model";
qCDebug(log) << "Could not open " << m_uiFileName << "needed for the cpp model";
m_contents.clear();
m_state = FINISHED;
notifyAboutUpdatedContents();
}
}
QByteArray UiCodeModelSupport::contents() const
{
// Check the common case first
if (m_state == FINISHED)
return m_contents;
if (m_state == BARE)
init();
if (m_state == RUNNING)
finishProcess();
return m_contents;
}
@@ -166,16 +161,20 @@ void UiCodeModelSupport::setHeaderFileName(const QString &name)
if (m_headerFileName == name && m_cacheTime.isValid())
return;
if (m_state == RUNNING)
finishProcess();
if (m_state == RUNNING) {
m_state = ABORTING;
m_process.kill();
m_process.waitForFinished(3000);
}
if (debug)
qDebug() << "UiCodeModelSupport::setFileName"<<name;
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
qCDebug(log) << "UiCodeModelSupport::setFileName" << name;
m_headerFileName = name;
m_contents.clear();
m_cacheTime = QDateTime();
m_state = BARE;
init();
}
bool UiCodeModelSupport::runUic(const QString &ui) const
@@ -183,10 +182,10 @@ bool UiCodeModelSupport::runUic(const QString &ui) const
const QString uic = uicCommand();
if (uic.isEmpty())
return false;
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
m_process.setEnvironment(environment());
if (debug)
qDebug() << "UiCodeModelSupport::runUic " << uic << " on " << ui.size() << " bytes";
qCDebug(log) << " UiCodeModelSupport::runUic " << uic << " on " << ui.size() << " bytes";
m_process.start(uic, QStringList(), QIODevice::ReadWrite);
if (!m_process.waitForStarted())
return false;
@@ -198,8 +197,7 @@ bool UiCodeModelSupport::runUic(const QString &ui) const
return true;
error:
if (debug)
qDebug() << "failed" << m_process.readAllStandardError();
qCDebug(log) << "failed" << m_process.readAllStandardError();
m_process.kill();
m_state = FINISHED;
return false;
@@ -207,29 +205,26 @@ error:
void UiCodeModelSupport::updateFromEditor(const QString &formEditorContents)
{
if (m_state == BARE)
init();
if (m_state == RUNNING)
finishProcess();
if (runUic(formEditorContents))
if (finishProcess())
updateDocument();
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
qCDebug(log) << "updating from editor" << m_uiFileName;
if (m_state == RUNNING) {
m_state = ABORTING;
m_process.kill();
m_process.waitForFinished(3000);
}
runUic(formEditorContents);
}
void UiCodeModelSupport::updateFromBuild()
{
if (debug)
qDebug()<<"UiCodeModelSupport::updateFromBuild() for file"<<m_uiFileName;
if (m_state == BARE)
init();
if (m_state == RUNNING)
finishProcess();
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
qCDebug(log) << "UiCodeModelSupport::updateFromBuild() for " << m_uiFileName;
// This is mostly a fall back for the cases when uic couldn't be run
// it pays special attention to the case where a ui_*h was newly created
QDateTime sourceTime = QFileInfo(m_uiFileName).lastModified();
if (m_cacheTime.isValid() && m_cacheTime >= sourceTime) {
if (debug)
qDebug()<<"Cache is still more recent then source";
qCDebug(log) << "Cache is still more recent then source";
return;
} else {
QFileInfo fi(m_headerFileName);
@@ -237,20 +232,19 @@ void UiCodeModelSupport::updateFromBuild()
if (uiHeaderTime.isValid() && (uiHeaderTime > sourceTime)) {
if (m_cacheTime >= uiHeaderTime)
return;
if (debug)
qDebug()<<"found ui*h updating from it";
qCDebug(log) << "found ui*h updating from it";
QFile file(m_headerFileName);
if (file.open(QFile::ReadOnly | QFile::Text)) {
QTextStream stream(&file);
m_contents = stream.readAll().toUtf8();
m_cacheTime = uiHeaderTime;
notifyAboutUpdatedContents();
updateDocument();
return;
}
}
if (debug)
qDebug()<<"ui*h not found or not more recent then source not changing anything";
qCDebug(log) << "ui*h not found or not more recent then source not changing anything";
}
}
@@ -279,34 +273,30 @@ QStringList UiCodeModelSupport::environment() const
}
}
bool UiCodeModelSupport::finishProcess() const
bool UiCodeModelSupport::finishProcess()
{
if (m_state != RUNNING)
return false;
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
if (!m_process.waitForFinished(3000)
&& m_process.exitStatus() != QProcess::NormalExit
&& m_process.exitCode() != 0) {
if (m_state != RUNNING) // waitForFinished can recurse into finishProcess
return false;
if (debug)
qDebug() << "failed" << m_process.readAllStandardError();
qCDebug(log) << "finish process: failed" << m_process.readAllStandardError();
m_process.kill();
m_state = FINISHED;
return false;
}
if (m_state != RUNNING) // waitForFinished can recurse into finishProcess
return true;
// As far as I can discover in the UIC sources, it writes out local 8-bit encoding. The
// conversion below is to normalize both the encoding, and the line terminators.
QString normalized = QString::fromLocal8Bit(m_process.readAllStandardOutput());
m_contents = normalized.toUtf8();
m_cacheTime = QDateTime::currentDateTime();
if (debug)
qDebug() << "ok" << m_contents.size() << "bytes.";
qCDebug(log) << "finish process: ok" << m_contents.size() << "bytes.";
m_state = FINISHED;
notifyAboutUpdatedContents();
updateDocument();
return true;
}

View File

@@ -73,11 +73,11 @@ private:
QStringList environment() const;
private slots:
bool finishProcess() const;
bool finishProcess();
private:
ProjectExplorer::Project *m_project;
enum State { BARE, RUNNING, FINISHED };
enum State { BARE, RUNNING, FINISHED, ABORTING };
void init() const;
bool runUic(const QString &ui) const;

View File

@@ -2962,6 +2962,14 @@ void tst_Dumpers::dumper_data()
+ Check4("url1.d.fragment", "\"\"", "@QString");
QTest::newRow("QUuid")
<< Data("#include <QUuid>",
"QUuid uuid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);\n"
"unused(&uuid);\n")
+ CoreProfile()
+ Check("uuid", "{00000001-0002-0003-0405-060708090a0b}", "@QUuid");
QByteArray expected1 = "\"AAA";
expected1.append(char('\t'));
expected1.append(char('\r'));

View File

@@ -1,37 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
Rectangle {
width: 64
height: 48
color: "Red"
}

View File

@@ -1,36 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
Rectangle {
width: 640
height: 480
}

View File

@@ -1,43 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
Flipable {
width: 640
height: 480
front: Text {
text: "front"
}
back: Text {
text: "back"
}
}

View File

@@ -1,41 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
Rectangle {
width: 200
height: 200
Text {
x: 66
y: 93
text: "Hello World"
}
}

View File

@@ -1,43 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
Rectangle {
width: 200
height: 200
color: "black"
Text {
x: 66
y: 93
text: "Hello World"
color: "white"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,40 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
ListModel {
id: myModel
ListElement {
content: "foo"
text: "bar"
}
}

View File

@@ -1,74 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
Item {
width: 200
height: 100
ListView {
anchors.fill: parent;
model: ListModel {
ListElement {
name: "BMW"
speed: 200
}
ListElement {
name: "Mercedes"
speed: 180
}
ListElement {
name: "Audi"
speed: 190
}
ListElement {
name: "VW"
speed: 180
}
}
delegate: Item {
height: 40
Row {
spacing: 10
Text {
text: name;
font.bold: true
}
Text { text: "speed: " + speed }
}
}
}
}

View File

@@ -1,74 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
Rectangle {
id: rect
width: 200
height: 200
Text {
id: text
x: 66
y: 93
text: "Base State"
}
states: [
State {
name: "State1"
PropertyChanges {
target: rect
color: "blue"
}
PropertyChanges {
target: text
text: "State1"
}
},
State {
name: "State2"
PropertyChanges {
target: rect
color: "gray"
}
PropertyChanges {
target: text
text: "State2"
}
}
]
Image {
id: image1
x: 41
y: 46
source: "images/qtcreator.png"
}
}

View File

@@ -1,47 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
Rectangle {
width: 640
height: 480
Component {
id: redSquare
Rectangle {
color: "red"
width: 100
height: 100
}
}
Loader { sourceComponent: redSquare;}
Loader { sourceComponent: redSquare; x: 20 }
}

View File

@@ -1,16 +0,0 @@
// File generated by QtCreator
import QmlProject 1.0
Project {
// Scan current directory for .qml, .js, and image files
QmlFiles {
directory: "."
}
JavaScriptFiles {
directory: "."
}
ImageFiles {
directory: "."
}
}

View File

@@ -1,41 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
import "components" as X
Rectangle {
width: 640
height: 480
X.MyButton {
}
}

View File

@@ -1,43 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
import QtQuick 1.1
import QtWebKit 1.0
// Test loading of import libraries
WebView {
width: 640
height: 480
html:"\
<body bgcolor=white>\
Hello World\
</body>"
}

View File

@@ -105,7 +105,7 @@
:Hits_QCLuceneResultWidget {aboveWidget=':Hits_QLabel' type='QCLuceneResultWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Hits_QLabel {text~='\\\\d+ - \\\\d+ of \\\\d+ Hits' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:JavaScript.QmlProfilerEventsTable_QmlProfiler::Internal::QV8ProfilerEventsMainView {container=':*Qt Creator.JavaScript_QDockWidget' name='QmlProfilerEventsTable' type='QmlProfiler::Internal::QV8ProfilerEventsMainView' visible='1'}
:Kits_QtVersion_QComboBox {container=':qt_tabwidget_stackedwidget_QWidget' occurrence='5' type='QComboBox' unnamed='1' visible='1'}
:Kits_QtVersion_QComboBox {container=':qt_tabwidget_stackedwidget_QWidget' leftWidget=':QtVersionLabel_KitPage' type='QComboBox' unnamed='1' visible='1'}
:Locals and Expressions_Debugger::Internal::WatchTreeView {container=':DebugModeWidget.Locals and Expressions_QDockWidget' name='WatchWindow' type='Debugger::Internal::WatchTreeView' visible='1' windowTitle='Locals and Expressions'}
:Minimal required Qt version:_QLabel {text='Minimal required Qt version:' type='QLabel' unnamed='1' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
:New Text File.Add to project:_QLabel {name='projectLabel' text='Add to project:' type='QLabel' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
@@ -182,6 +182,7 @@
:QtSupport__Internal__QtVersionManager.errorLabel.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='errorLabel' type='QLabel' visible='1'}
:QtSupport__Internal__QtVersionManager.qmake_QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qmakePath' type='QLabel' visible='1'}
:QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qtdirList' type='QTreeWidget' visible='1'}
:QtVersionLabel_KitPage {container=':qt_tabwidget_stackedwidget_QWidget' text='Qt version:' type='QLabel' unnamed='1' visible='1'}
:Restart required.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Restart required_QMessageBox'}
:Restart required_QMessageBox {text='The language change will take effect after a restart of Qt Creator.' type='QMessageBox' unnamed='1' visible='1'}
:Revert to Saved.Proceed_QPushButton {text='Proceed' type='QPushButton' unnamed='1' visible='1' window=':Revert to Saved_QMessageBox'}

View File

@@ -270,26 +270,39 @@ def createProject_Qt_Console(path, projectName, checks = True):
def createNewQtQuickApplication(workingDir, projectName = None,
targets=Targets.desktopTargetClasses(), minimumQtVersion="5.3",
fromWelcome=False):
available = __createProjectOrFileSelectType__(" Application", "Qt Quick Application", fromWelcome)
withControls = False, fromWelcome=False):
if withControls:
template = "Qt Quick Controls Application"
else:
template = "Qt Quick Application"
available = __createProjectOrFileSelectType__(" Application", template, fromWelcome)
projectName = __createProjectSetNameAndPath__(workingDir, projectName)
requiredQt = __createProjectHandleQtQuickSelection__(minimumQtVersion)
__modifyAvailableTargets__(available, requiredQt)
checkedTargets = __chooseTargets__(targets, available)
snooze(1)
clickButton(waitForObject(":Next_QPushButton"))
__createProjectHandleLastPage__()
if len(checkedTargets):
clickButton(waitForObject(":Next_QPushButton"))
__createProjectHandleLastPage__()
progressBarWait(10000)
else:
clickButton(waitForObject("{type='QPushButton' text='Cancel' visible='1'}"))
progressBarWait(10000)
return checkedTargets, projectName
def createNewQtQuickUI(workingDir, qtQuickVersion="1.1"):
__createProjectOrFileSelectType__(" Application", "Qt Quick UI")
def createNewQtQuickUI(workingDir, qtVersion = "5.3", withControls = False):
if withControls:
template = 'Qt Quick Controls UI'
else:
template = 'Qt Quick UI'
__createProjectOrFileSelectType__(" Other Project", template)
if workingDir == None:
workingDir = tempDir()
projectName = __createProjectSetNameAndPath__(workingDir)
__createProjectHandleQtQuickSelection__(qtQuickVersion)
__createProjectHandleQtQuickSelection__(qtVersion)
__createProjectHandleLastPage__()
progressBarWait(10000)
return projectName
def createNewQmlExtension(workingDir, targets=Targets.DESKTOP_474_GCC, qtQuickVersion=1):

View File

@@ -217,19 +217,15 @@ def __selectTreeItemOnBuildAndRun__(treeViewOrWidget, itemText, isRegex=False):
test.compare(manual.data().toString(), "Manual", "Verifying label for section")
if isRegex:
pattern = re.compile(itemText)
found = False
for section in [autoDetected, manual]:
for dumpedItem in dumpItems(model, section):
if (isRegex and pattern.match(dumpedItem)
or itemText == dumpedItem):
found = True
item = ".".join([str(section.data().toString()),
dumpedItem.replace(".", "\\.").replace("_", "\\_")])
clickItem(treeViewOrWidget, item, 5, 5, 0, Qt.LeftButton)
break
if found:
break
return found
return True
return False
def __getTargetFromToolTip__(toolTip):
if toolTip == None or not isinstance(toolTip, (str, unicode)):

View File

@@ -123,7 +123,7 @@ def main():
return
qmlProjFile = os.path.join(qmlProjDir, projName)
# start Creator by passing a .qmlproject file
startApplication('qtcreator -load QmlProjectManager' + SettingsPath + ' "%s"' % qmlProjFile)
startApplication('qtcreator' + SettingsPath + ' "%s"' % qmlProjFile)
if not startedWithoutPluginError():
return
@@ -142,10 +142,6 @@ def main():
rootIndex = getQModelIndexStr("text='Rectangle'",
":Locals and Expressions_Debugger::Internal::WatchTreeView")
# make sure the items inside the root item are visible
if JIRA.isBugStillOpen(14210):
doubleClick(waitForObject(rootIndex))
else:
test.warning("QTCREATORBUG-14210 is not open anymore. Can the workaround be removed?")
doubleClick(waitForObject(rootIndex))
if not object.exists(":DebugModeWidget_QmlJSTools::Internal::QmlConsoleView"):
invokeMenuItem("Window", "Output Panes", "QML/JS Console")
@@ -156,14 +152,14 @@ def main():
("color ='silver'", "silver", "color", u"#\u200bc0c0c0"),
("width=66", "66", "width"), ("anchors.centerIn", "<unnamed object>"),
("opacity", "1"), ("opacity = .2", u"0.\u200b2", "opacity")]
# check green inner Rectangle
runChecks("text='Rectangle'", rootIndex, checks)
# check red inner Rectangle
runChecks("text='Rectangle' occurrence='2'", rootIndex, checks)
checks = [("color", u"#\u200bff0000"), ("width", "100"), ("height", "100"),
("radius = Math.min(width, height) / 2", "50", "radius"),
("parent.objectName= 'mainRect'", "mainRect")]
# check red inner Rectangle
runChecks("text='Rectangle' occurrence='2'", rootIndex, checks)
# check green inner Rectangle
runChecks("text='Rectangle'", rootIndex, checks)
checks = [("color", u"#\u200b000000"), ("font.pointSize=14", "14", "font.pointSize"),
("font.bold", "false"), ("font.weight=Font.Bold", "75", "font.bold", "true"),

View File

@@ -45,7 +45,7 @@ def main():
return
qmlProjFile = os.path.join(qmlProjDir, projName)
# start Creator by passing a .qmlproject file
startApplication('qtcreator -load QmlProjectManager' + SettingsPath + ' "%s"' % qmlProjFile)
startApplication('qtcreator' + SettingsPath + ' "%s"' % qmlProjFile)
if not startedWithoutPluginError():
return
waitFor('object.exists(":Qt Creator_Utils::NavigationTreeView")', 10000)
@@ -91,8 +91,8 @@ def main():
checkForEmptyRows(items)
check = [[None, 0, {"Properties":1, "Rectangle":2, "Text":1}, {"width":"360", "height":"360"}],
["Text", 1, {"Properties":1}, {"text":"Check"}],
["Rectangle", 1, {"Properties":1}, {"width":"50", "height":"50", "color":"#008000"}],
["Rectangle", 2, {"Properties":1}, {"width":"100", "height":"100", "color":"#ff0000"}]
["Rectangle", 2, {"Properties":1}, {"width":"50", "height":"50", "color":"#008000"}],
["Rectangle", 1, {"Properties":1}, {"width":"100", "height":"100", "color":"#ff0000"}]
]
for current in check:
if current[0]:
@@ -108,23 +108,19 @@ def main():
def __unfoldTree__():
rootIndex = getQModelIndexStr("text='Rectangle'",
':Locals and Expressions_Debugger::Internal::WatchTreeView')
if JIRA.isBugStillOpen(14210):
doubleClick(waitForObject(rootIndex))
else:
test.warning("QTCREATORBUG-14210 is not open anymore. Can the workaround be removed?")
unfoldQModelIndexIncludingProperties(rootIndex)
if JIRA.isBugStillOpen(14210):
for item in ["text='Rectangle' occurrence='2'", "text='Rectangle' occurrence='2'", "text='Text'"]:
# both Rectangles will be clicked because they change their order
doubleClick(waitForObject(getQModelIndexStr(item, rootIndex)))
snooze(1)
subItems = ["text='Rectangle' occurrence='2'", "text='Rectangle'", "text='Text'"]
subItems = ["text='Rectangle'", "text='Rectangle' occurrence='2'", "text='Text'"]
for item in subItems:
unfoldQModelIndexIncludingProperties(getQModelIndexStr(item, rootIndex))
def unfoldQModelIndexIncludingProperties(indexStr):
tv = waitForObject(':Locals and Expressions_Debugger::Internal::WatchTreeView')
# HACK to avoid failing clicks
tv.scrollToBottom()
doubleClick(waitForObject(indexStr))
propIndex = getQModelIndexStr("text='Properties'", indexStr)
# HACK to avoid failing clicks
tv.scrollToBottom()
doubleClick(waitForObject(propIndex))
def fetchItems(index, valIndex, treeView):

View File

@@ -34,16 +34,31 @@ def main():
startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError():
return
for targ, qVer in [[Targets.DESKTOP_480_DEFAULT, "1.1"], [Targets.DESKTOP_521_DEFAULT, "2.1"],
[Targets.DESKTOP_521_DEFAULT, "2.2"], [Targets.DESKTOP_531_DEFAULT, "2.3"],
[Targets.DESKTOP_521_DEFAULT, "Controls 1.0"], [Targets.DESKTOP_521_DEFAULT, "Controls 1.1"],
[Targets.DESKTOP_531_DEFAULT, "Controls 1.2"]]:
available = [("5.3", False), ("5.3", True)]
if platform.system() != 'Darwin':
available.extend([("5.4", False), ("5.4", True)])
for qtVersion, controls in available:
if qtVersion == "5.3":
targ = Targets.DESKTOP_531_DEFAULT
quick = "2.3"
else:
targ = Targets.DESKTOP_541_GCC
quick = "2.4"
# using a temporary directory won't mess up a potentially existing
workingDir = tempDir()
checkedTargets, projectName = createNewQtQuickApplication(workingDir, targets=targ,
qtQuickVersion=qVer)
test.log("Building project Qt Quick %s Application (%s)"
% (qVer, Targets.getStringForTarget(targ)))
minimumQtVersion=qtVersion,
withControls = controls)
if len(checkedTargets) == 0:
test.fatal("Could not check wanted target")
continue
additionalText = ''
if controls:
additionalText = ' Controls '
test.log("Building project Qt Quick%sApplication (%s)"
% (additionalText, Targets.getStringForTarget(targ)))
result = modifyRunSettingsForHookInto(projectName, len(checkedTargets), 11223)
invokeMenuItem("Build", "Build All")
waitForCompile()
@@ -57,10 +72,8 @@ def main():
allowAppThroughWinFW(workingDir, projectName)
if result:
function = "subprocessFunctionQuick2"
if qVer[0] == "1":
function = "subprocessFunctionQuick1"
result = runAndCloseApp(True, projectName, 11223, function,
SubprocessType.QT_QUICK_APPLICATION, quickVersion=qVer)
SubprocessType.QT_QUICK_APPLICATION, quickVersion=quick)
else:
result = runAndCloseApp(sType=SubprocessType.QT_QUICK_APPLICATION)
removeExecutableAsAttachableAUT(projectName, 11223)
@@ -70,7 +83,9 @@ def main():
if result == None:
checkCompile()
else:
logApplicationOutput()
appOutput = logApplicationOutput()
test.verify(not ("main.qml" in appOutput or "MainForm.ui.qml" in appOutput),
"Does the Application Output indicate QML errors?")
invokeMenuItem("File", "Close All Projects and Editors")
invokeMenuItem("File", "Exit")
@@ -82,8 +97,5 @@ def subprocessFunctionGenericQuick(quickVersion):
test.log("Clicking 'Hello World' Text to close QtQuick%dApplicationViewer" % quickVersion)
mouseClick(helloWorldText, 5, 5, 0, Qt.LeftButton)
def subprocessFunctionQuick1():
subprocessFunctionGenericQuick(1)
def subprocessFunctionQuick2():
subprocessFunctionGenericQuick(2)

View File

@@ -31,30 +31,42 @@
source("../../shared/qtcreator.py")
def main():
startApplication("qtcreator -load QmlProjectManager" + SettingsPath)
startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError():
return
for quickVersion in ["1.1", "2.1", "2.2", "2.3", "Controls 1.0", "Controls 1.1", "Controls 1.2"]:
available = [("5.3", False), ("5.3", True)]
if platform.system() != 'Darwin':
available.extend([("5.4", False), ("5.4", True)])
for qtVersion, controls in available:
# using a temporary directory won't mess up a potentially existing
workingDir = tempDir()
projectName = createNewQtQuickUI(workingDir, quickVersion)
projectName = createNewQtQuickUI(workingDir, qtVersion, controls)
switchViewTo(ViewConstants.PROJECTS)
clickButton(waitForObject(":*Qt Creator.Add Kit_QPushButton"))
menuItem = Targets.getStringForTarget(Targets.DESKTOP_531_DEFAULT)
if qtVersion == "5.3":
menuItem = Targets.getStringForTarget(Targets.DESKTOP_531_DEFAULT)
quick = "2.3"
else:
menuItem = Targets.getStringForTarget(Targets.DESKTOP_541_GCC)
quick = "2.4"
if platform.system() == 'Darwin':
waitFor("macHackActivateContextMenuItem(menuItem)", 5000)
else:
activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", menuItem))
test.log("Running project Qt Quick %s UI" % quickVersion)
qmlViewer = modifyRunSettingsForHookIntoQtQuickUI(2, 1, workingDir, projectName, 11223, quickVersion)
additionalText = ''
if controls:
additionalText = ' Controls '
test.log("Running project Qt Quick%sUI (%s)" % (additionalText, menuItem))
qmlViewer = modifyRunSettingsForHookIntoQtQuickUI(2, 1, workingDir, projectName, 11223, quick)
if qmlViewer!=None:
qmlViewerPath = os.path.dirname(qmlViewer)
qmlViewer = os.path.basename(qmlViewer)
result = addExecutableAsAttachableAUT(qmlViewer, 11223)
allowAppThroughWinFW(qmlViewerPath, qmlViewer, None)
if result:
result = runAndCloseApp(True, qmlViewer, 11223, sType=SubprocessType.QT_QUICK_UI, quickVersion=quickVersion)
result = runAndCloseApp(True, qmlViewer, 11223, sType=SubprocessType.QT_QUICK_UI, quickVersion=quick)
else:
result = runAndCloseApp(sType=SubprocessType.QT_QUICK_UI)
removeExecutableAsAttachableAUT(qmlViewer, 11223)
@@ -64,6 +76,8 @@ def main():
if result == None:
checkCompile()
else:
logApplicationOutput()
appOutput = logApplicationOutput()
test.verify(not ("untitled.qml" in appOutput or "MainForm.ui.qml" in appOutput),
"Does the Application Output indicate QML errors?")
invokeMenuItem("File", "Close All Projects and Editors")
invokeMenuItem("File", "Exit")