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 \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 \section1 Advanced Search
To search through projects, files on a file system or currently open files: To search through projects, files on a file system or currently open files:
@@ -2403,9 +2408,10 @@
\endlist \endlist
To move directly to a particular line in the document when you open the To move directly to a particular line and column in the document when you
document, append a plus sign (+) or a colon (:) to the file name in the open the document, append them to the file name in the locator, separated by
locator. For example, to open main.cpp to line 41, enter: \c {main.cpp:41}. 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 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 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 symbols in the current document (\c {.})
\li Locating a specific line and column in the document displayed in \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 {?}) \li Opening help topics, including Qt documentation (\c {?})
@@ -2460,6 +2466,8 @@
\li Executing version control system commands (\c {git}). For more \li Executing version control system commands (\c {git}). For more
information, see \l{Using Version Control Systems} information, see \l{Using Version Control Systems}
\li Running external tools (\c x)
\endlist \endlist
To use a specific locator filter, type the assigned prefix followed by To use a specific locator filter, type the assigned prefix followed by

View File

@@ -31,16 +31,16 @@
\title Using Command Line Options \title Using Command Line Options
You can start \QC and specify some options from the command line. For 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 To specify command line options, enter the following command in the \QC
installation or build directory: 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 \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 between the filename and line number and the line number and the column
separator and the line number. number. You can also use a space between the separator and the line number.
For example, on Windows: For example, on Windows:
@@ -48,9 +48,9 @@
\li \c {C:\qtcreator\bin>qtcreator -help} \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 \endlist

View File

@@ -36,6 +36,9 @@
for use. You can change their default configurations and configure new for use. You can change their default configurations and configure new
tools. tools.
To run the tools, select \uicontrol Tools > \uicontrol External, or use the
\c x filter in the locator.
\section1 Using Qt Linguist \section1 Using Qt Linguist
You can use the Qt Linguist release manager tools, lupdate and lrelease, 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 Select a command from the list.
\li In \uicontrol{Key Sequence} enter the shortcut key you want to associate \li In the \uicontrol{Key Sequence} field, you have the following
with the selected command. 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. \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 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 \li Qt Console Application
Use a single main.cpp file Use a single main.cpp file

View File

@@ -46,6 +46,10 @@
\li \uicontrol {Qt Quick Controls Application} is like \li \uicontrol {Qt Quick Controls Application} is like
\uicontrol {Qt Quick Application}, but using Qt Quick Controls. \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} \li \uicontrol {Qt Quick UI} (in the \uicontrol {Other Project}
category) creates a Qt Quick UI project with a single QML file that 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 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") !isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included")
QTCREATOR_PRI_INCLUDED = 1 QTCREATOR_PRI_INCLUDED = 1
QTCREATOR_VERSION = 3.4.81 QTCREATOR_VERSION = 3.4.82
QTCREATOR_COMPAT_VERSION = 3.4.81 QTCREATOR_COMPAT_VERSION = 3.4.82
BINARY_ARTIFACTS_BRANCH = master BINARY_ARTIFACTS_BRANCH = 3.5
# enable c++11 # enable c++11
CONFIG += c++11 CONFIG += c++11

View File

@@ -6,11 +6,11 @@ Project {
property bool withAutotests: qbs.buildVariant === "debug" property bool withAutotests: qbs.buildVariant === "debug"
property string ide_version_major: '3' property string ide_version_major: '3'
property string ide_version_minor: '4' 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 qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release
property string ide_compat_version_major: '3' property string ide_compat_version_major: '3'
property string ide_compat_version_minor: '4' 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 string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release
property path ide_source_tree: path property path ide_source_tree: path
property string ide_app_path: qbs.targetOS.contains("osx") ? "" : "bin" 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) target = os.path.join(install_dir, 'bin', 'imports', qtimport)
if (os.path.exists(target)): if (os.path.exists(target)):
shutil.rmtree(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)): if (os.path.exists(qt_qml_dir)):
print "Copying qt quick 2 imports" print "Copying qt quick 2 imports"
@@ -230,20 +232,33 @@ def copyPreservingLinks(source, destination):
shutil.copy(source, destination) shutil.copy(source, destination)
def copy_libclang(install_dir, llvm_install_dir): def copy_libclang(install_dir, llvm_install_dir):
libsources = [] # contains pairs of (source, target directory)
libtarget = "" deployinfo = []
if sys.platform.startswith("win"): if sys.platform.startswith("win"):
libsources = [os.path.join(llvm_install_dir, 'bin', 'libclang.dll')] deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'libclang.dll'),
libtarget = os.path.join(install_dir, 'bin') 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: else:
libsources = glob(os.path.join(llvm_install_dir, 'lib', 'libclang.so*')) 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') resourcesource = os.path.join(llvm_install_dir, 'lib', 'clang')
resourcetarget = os.path.join(install_dir, 'share', 'qtcreator', 'cplusplus', 'clang') resourcetarget = os.path.join(install_dir, 'share', 'qtcreator', 'cplusplus', 'clang')
print "copying libclang..." print "copying libclang..."
for libsource in libsources: for source, target in deployinfo:
print libsource, '->', libtarget print source, '->', target
copyPreservingLinks(libsource, libtarget) copyPreservingLinks(source, target)
print resourcesource, '->', resourcetarget print resourcesource, '->', resourcetarget
if (os.path.exists(resourcetarget)): if (os.path.exists(resourcetarget)):
shutil.rmtree(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 # 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/libclang.*dylib "$1/Contents/Frameworks/" || exit 1
cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$1/Contents/Resources/cplusplus/" || 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 fi
_CLANG_CODEMODEL_LIB="$1/Contents/PlugIns/libClangCodeModel_debug.dylib" _CLANG_CODEMODEL_LIB="$1/Contents/PlugIns/libClangCodeModel_debug.dylib"
if [ ! -f "$_CLANG_CODEMODEL_LIB" ]; then 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 self.isCli = False
# Later set, or not set: # Later set, or not set:
# cachedQtVersion
self.stringCutOff = 10000 self.stringCutOff = 10000
self.displayStringLimit = 100 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'. # 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. # This is a cache of all known dumpers.
self.qqDumpers = {} self.qqDumpers = {}
@@ -407,18 +422,6 @@ class DumperBase:
# to not be QObject derived, it contains a 0 value. # to not be QObject derived, it contains a 0 value.
self.knownStaticMetaObjects = {} self.knownStaticMetaObjects = {}
self.childrenPrefix = 'children=['
self.childrenSuffix = '],'
self.dumpermodules = [
"qttypes",
"stdtypes",
"misctypes",
"boosttypes",
"creatortypes",
"personaltypes",
]
def putNewline(self): def putNewline(self):
pass pass
@@ -1674,10 +1677,7 @@ class DumperBase:
pass pass
def setupDumpers(self, _ = {}): def setupDumpers(self, _ = {}):
self.qqDumpers = {} self.resetCaches()
self.qqFormats = {}
self.qqEditable = {}
self.typeCache = {}
for mod in self.dumpermodules: for mod in self.dumpermodules:
m = importlib.import_module(mod) m = importlib.import_module(mod)

View File

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

View File

@@ -1031,6 +1031,13 @@ def qdump__QMultiMap(d, value):
qdump__QMap(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): def qdump__QMetaObjectPrivate(d, value):
d.putEmptyValue() d.putEmptyValue()
d.putNumChild(1) d.putNumChild(1)
@@ -1899,6 +1906,16 @@ def qdump__QUrl(d, value):
d.putGenericItem("fragment", stringType, fragment, Hex4EncodedLittleEndian) d.putGenericItem("fragment", stringType, fragment, Hex4EncodedLittleEndian)
d.putFields(value) 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): def qdumpHelper_QVariant_0(d, blob):
# QVariant::Invalid # QVariant::Invalid
d.putBetterType("%sQVariant (invalid)" % d.qtNamespace()) 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.input = qml/qmldump/Info.plist.in
dumpinfo.output = $$IDE_DATA_PATH/qml/qmldump/Info.plist dumpinfo.output = $$IDE_DATA_PATH/qml/qmldump/Info.plist
QMAKE_SUBSTITUTES += dumpinfo 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/ SRCRESOURCEDIR = $$IDE_SOURCE_TREE/src/share/qtcreator/

View File

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

View File

@@ -7,8 +7,8 @@
"trDisplayName": "Qt Quick Controls Application", "trDisplayName": "Qt Quick Controls Application",
"trDisplayCategory": "Application", "trDisplayCategory": "Application",
"icon": "../qtquickapplication/qml_wizard.png", "icon": "../qtquickapplication/qml_wizard.png",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt" ], "featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.3" ],
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 && [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0 }", "enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0}",
"options": "options":
[ [
@@ -40,6 +40,7 @@
"type": "ComboBox", "type": "ComboBox",
"data": "data":
{ {
"index": 2,
"items": "items":
[ [
{ {
@@ -50,8 +51,7 @@
'qtQuickControlsVersion': '1.4', 'qtQuickControlsVersion': '1.4',
'qtQuickDialogsVersion': '1.2', 'qtQuickDialogsVersion': '1.2',
'qtQuickLayoutsVersion': '1.2' 'qtQuickLayoutsVersion': '1.2'
}", }"
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.5') >= 0}"
}, },
{ {
"trKey": "Qt 5.4", "trKey": "Qt 5.4",
@@ -61,8 +61,7 @@
'qtQuickControlsVersion': '1.3', 'qtQuickControlsVersion': '1.3',
'qtQuickDialogsVersion': '1.2', 'qtQuickDialogsVersion': '1.2',
'qtQuickLayoutsVersion': '1.1' 'qtQuickLayoutsVersion': '1.1'
}", }"
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.4') >= 0}"
}, },
{ {
"trKey": "Qt 5.3", "trKey": "Qt 5.3",
@@ -72,8 +71,7 @@
'qtQuickControlsVersion': '1.2', 'qtQuickControlsVersion': '1.2',
'qtQuickDialogsVersion': '1.2', 'qtQuickDialogsVersion': '1.2',
'qtQuickLayoutsVersion': '1.1' '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. // The thread is still busy parsing a previus configuration.
// Wait until the thread has been finished and delete it. // Wait until the thread has been finished and delete it.
// TODO: Discuss whether blocking is acceptable. // TODO: Discuss whether blocking is acceptable.
disconnect(m_makefileParserThread, SIGNAL(finished()), disconnect(m_makefileParserThread, &QThread::finished,
this, SLOT(makefileParsingFinished())); this, &AutotoolsProject::makefileParsingFinished);
m_makefileParserThread->wait(); m_makefileParserThread->wait();
delete m_makefileParserThread; delete m_makefileParserThread;
m_makefileParserThread = 0; m_makefileParserThread = 0;
@@ -402,6 +402,24 @@ QList<Node *> AutotoolsProject::nodes(FolderNode *parent) const
return list; 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() void AutotoolsProject::updateCppCodeModel()
{ {
CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
@@ -427,7 +445,12 @@ void AutotoolsProject::updateCppCodeModel()
ppBuilder.setCFlags(cflags); ppBuilder.setCFlags(cflags);
ppBuilder.setCxxFlags(cxxflags); 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()); ppBuilder.setDefines(m_makefileParserThread->defines());
const QList<Core::Id> languages = ppBuilder.createProjectPartsForFiles(m_files); const QList<Core::Id> languages = ppBuilder.createProjectPartsForFiles(m_files);

View File

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

View File

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

View File

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

View File

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

View File

@@ -615,6 +615,102 @@ bool hasSnippet(ProposalModel model, const QByteArray &text)
return false; 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 } // anonymous namespace
namespace ClangCodeModel { namespace ClangCodeModel {
@@ -866,11 +962,11 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileExt
ProposalModel proposal = completionResults(openSource.editor()); ProposalModel proposal = completionResults(openSource.editor());
QVERIFY(hasItem(proposal, "globalFromHeader")); QVERIFY(hasItem(proposal, "globalFromHeader"));
// Simulate external modification // Simulate external modification and wait for reload
QThread::sleep(1); // Ensures different time stamp and thus that the difference will be noticed WriteFileAndWaitForReloadedDocument waitForReloadedDocument(
QVERIFY(writeFile(headerDocument.filePath, "int globalFromHeaderReloaded;\n")); headerDocument.filePath,
QSignalSpy waitForReloadedDocument(openHeader.editor()->document(), "int globalFromHeaderReloaded;\n",
SIGNAL(reloadFinished(bool))); openHeader.editor()->document());
QVERIFY(waitForReloadedDocument.wait()); QVERIFY(waitForReloadedDocument.wait());
// Retrigger completion and check if its updated // Retrigger completion and check if its updated
@@ -883,6 +979,8 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByCompletingUiObject()
CppTools::Tests::TemporaryCopiedDir testDir(qrcPath("qt-widgets-app")); CppTools::Tests::TemporaryCopiedDir testDir(qrcPath("qt-widgets-app"));
QVERIFY(testDir.isValid()); QVERIFY(testDir.isValid());
MonitorGeneratedUiFile monitorGeneratedUiFile;
// Open project // Open project
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro"); const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
CppTools::Tests::ProjectOpenerAndCloser projectManager; CppTools::Tests::ProjectOpenerAndCloser projectManager;
@@ -897,11 +995,11 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByCompletingUiObject()
QVERIFY(openSource.succeeded()); QVERIFY(openSource.succeeded());
// ...and check comletions // ...and check comletions
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
ProposalModel proposal = completionResults(openSource.editor()); ProposalModel proposal = completionResults(openSource.editor());
QVERIFY(hasItem(proposal, "menuBar")); QVERIFY(hasItem(proposal, "menuBar"));
QVERIFY(hasItem(proposal, "statusBar")); QVERIFY(hasItem(proposal, "statusBar"));
QVERIFY(hasItem(proposal, "centralWidget")); QVERIFY(hasItem(proposal, "centralWidget"));
QEXPECT_FAIL("", "Signals are not yet done", Abort);
QVERIFY(hasItem(proposal, "setupUi")); QVERIFY(hasItem(proposal, "setupUi"));
} }
@@ -921,6 +1019,7 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
// ... and modify it, so we have an unsaved file. // ... and modify it, so we have an unsaved file.
insertTextAtTopOfEditor(openHeader.editor(), "int someGlobal;\n"); insertTextAtTopOfEditor(openHeader.editor(), "int someGlobal;\n");
// Open project ... // Open project ...
MonitorGeneratedUiFile monitorGeneratedUiFile;
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro"); const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
CppTools::Tests::ProjectOpenerAndCloser projectManager; CppTools::Tests::ProjectOpenerAndCloser projectManager;
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true); const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
@@ -931,6 +1030,7 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
QVERIFY(testDocument.isCreatedAndHasValidCursorPosition()); QVERIFY(testDocument.isCreatedAndHasValidCursorPosition());
OpenEditorAtCursorPosition openSource(testDocument); OpenEditorAtCursorPosition openSource(testDocument);
QVERIFY(openSource.succeeded()); QVERIFY(openSource.succeeded());
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
// Check commands that would have been sent // Check commands that would have been sent
QVERIFY(compare(LogOutput(spy.senderLog), QVERIFY(compare(LogOutput(spy.senderLog),
@@ -939,6 +1039,8 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
" ProjectPartContainer id: qt-widgets-app.pro\n" " ProjectPartContainer id: qt-widgets-app.pro\n"
"RegisterTranslationUnitForCodeCompletionCommand\n" "RegisterTranslationUnitForCodeCompletionCommand\n"
" Path: myheader.h ProjectPart: \n" " Path: myheader.h ProjectPart: \n"
"RegisterTranslationUnitForCodeCompletionCommand\n"
" Path: ui_mainwindow.h ProjectPart: \n"
))); )));
spy.senderLog.clear(); spy.senderLog.clear();
@@ -966,3 +1068,5 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
} // namespace Tests } // namespace Tests
} // namespace Internal } // namespace Internal
} // namespace ClangCodeModel } // namespace ClangCodeModel
#include "clangcodecompletion_test.moc"

View File

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

View File

@@ -51,6 +51,7 @@ public:
virtual QString fileName() const = 0; virtual QString fileName() const = 0;
void updateDocument(); void updateDocument();
void notifyAboutUpdatedContents() const;
unsigned revision() const { return m_revision; } unsigned revision() const { return m_revision; }
static QString licenseTemplate(const QString &file = QString(), const QString &className = QString()); 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 class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(BaseEditorDocumentParser)
BaseEditorDocumentParser();
public: public:
BaseEditorDocumentParser(const QString &filePath); BaseEditorDocumentParser(const QString &filePath);

View File

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

View File

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

View File

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

View File

@@ -958,6 +958,17 @@ void CppModelManager::emitDocumentUpdated(Document::Ptr doc)
emit documentUpdated(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 *) void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
{ {
QMutexLocker locker(&d->m_projectMutex); QMutexLocker locker(&d->m_projectMutex);

View File

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

View File

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

View File

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

View File

@@ -145,16 +145,13 @@ QtcPlugin {
name: "QML Debugger" name: "QML Debugger"
prefix: "qml/" prefix: "qml/"
files: [ files: [
"baseqmldebuggerclient.cpp", "baseqmldebuggerclient.h",
"interactiveinterpreter.cpp", "interactiveinterpreter.h", "interactiveinterpreter.cpp", "interactiveinterpreter.h",
"qmladapter.cpp", "qmladapter.h",
"qmlcppengine.cpp", "qmlcppengine.h", "qmlcppengine.cpp", "qmlcppengine.h",
"qmlengine.cpp", "qmlengine.h", "qmlengine.cpp", "qmlengine.h",
"qmlengineutils.cpp", "qmlengineutils.h",
"qmlinspectoradapter.cpp", "qmlinspectoradapter.h", "qmlinspectoradapter.cpp", "qmlinspectoradapter.h",
"qmlinspectoragent.cpp", "qmlinspectoragent.h", "qmlinspectoragent.cpp", "qmlinspectoragent.h",
"qmlv8debuggerclient.cpp", "qmlv8debuggerclient.h", "qmlv8debuggerclientconstants.h"
"qmlv8debuggerclientconstants.h",
"qscriptdebuggerclient.cpp", "qscriptdebuggerclient.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 += \ HEADERS += \
$$PWD/qmlengine.h \ $$PWD/qmlengine.h \
$$PWD/qmladapter.h \ $$PWD/qmlengineutils.h \
$$PWD/baseqmldebuggerclient.h \
$$PWD/qmlcppengine.h \ $$PWD/qmlcppengine.h \
$$PWD/qscriptdebuggerclient.h \
$$PWD/qmlv8debuggerclient.h \
$$PWD/interactiveinterpreter.h \ $$PWD/interactiveinterpreter.h \
$$PWD/qmlv8debuggerclientconstants.h \ $$PWD/qmlv8debuggerclientconstants.h \
$$PWD/qmlinspectoragent.h \ $$PWD/qmlinspectoragent.h \
@@ -12,11 +9,8 @@ HEADERS += \
SOURCES += \ SOURCES += \
$$PWD/qmlengine.cpp \ $$PWD/qmlengine.cpp \
$$PWD/qmladapter.cpp \ $$PWD/qmlengineutils.cpp \
$$PWD/baseqmldebuggerclient.cpp \
$$PWD/qmlcppengine.cpp \ $$PWD/qmlcppengine.cpp \
$$PWD/qscriptdebuggerclient.cpp \
$$PWD/qmlv8debuggerclient.cpp \
$$PWD/interactiveinterpreter.cpp \ $$PWD/interactiveinterpreter.cpp \
$$PWD/qmlinspectoragent.cpp \ $$PWD/qmlinspectoragent.cpp \
$$PWD/qmlinspectoradapter.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 #ifndef QMLENGINE_H
#define QMLENGINE_H #define QMLENGINE_H
#include "interactiveinterpreter.h"
#include "qmladapter.h"
#include "qmlinspectoradapter.h"
#include <debugger/debuggerengine.h> #include <debugger/debuggerengine.h>
#include <projectexplorer/applicationlauncher.h>
#include <qmldebug/qdebugmessageclient.h> #include <qmldebug/qdebugmessageclient.h>
#include <qmldebug/qmldebugclient.h>
#include <qmldebug/qmloutputparser.h> #include <qmldebug/qmloutputparser.h>
#include <qmljs/iscriptevaluator.h> #include <qmljs/iscriptevaluator.h>
#include <qmljs/qmljsdocument.h> #include <qmljs/qmljsdocument.h>
QT_FORWARD_DECLARE_CLASS(QTextDocument)
namespace Core { class IDocument; }
namespace TextEditor { class BaseTextEditor; }
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
class WatchData;
class WatchItem;
class QmlEnginePrivate;
class QmlAdapter; class QmlAdapter;
class WatchTreeView;
class QmlEngine : public DebuggerEngine, QmlJS::IScriptEvaluator class QmlEngine : public DebuggerEngine, QmlJS::IScriptEvaluator
{ {
@@ -63,31 +56,11 @@ public:
DebuggerEngine *masterEngine = 0); DebuggerEngine *masterEngine = 0);
~QmlEngine(); ~QmlEngine();
void notifyEngineRemoteServerRunning(const QByteArray &, int pid); void filterApplicationMessage(const QString &msg, int channel) const;
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
bool canDisplayTooltip() const; void logServiceStateChange(const QString &service, float version,
QmlDebug::QmlDebugClient::State newState);
void showMessage(const QString &msg, int channel = LogDebug, void logServiceActivity(const QString &service, const QString &logMessage);
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);
private slots: private slots:
void disconnected(); void disconnected();
@@ -96,23 +69,28 @@ private slots:
void errorMessageBoxFinished(int result); void errorMessageBoxFinished(int result);
void updateCurrentContext(); void updateCurrentContext();
void appendDebugOutput(QtMsgType type, const QString &message,
const QmlDebug::QDebugContextInfo &info);
void tryToConnect(quint16 port = 0); void tryToConnect(quint16 port = 0);
void beginConnection(quint16 port = 0); void beginConnection(quint16 port = 0);
void connectionEstablished(); void connectionEstablished();
void connectionStartupFailed(); void connectionStartupFailed();
void appStartupFailed(const QString &errorMessage); void appStartupFailed(const QString &errorMessage);
void connectionError(QDebugSupport::Error error);
void serviceConnectionError(const QString &service);
void appendMessage(const QString &msg, Utils::OutputFormat); void appendMessage(const QString &msg, Utils::OutputFormat);
void synchronizeWatchers(); void synchronizeWatchers();
private: 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 isSynchronous() const { return false; }
bool canDisplayTooltip() const { return false; }
void executeStep(); void executeStep();
void executeStepOut(); void executeStepOut();
void executeNext(); void executeNext();
@@ -153,7 +131,6 @@ private:
void reloadSourceFiles(); void reloadSourceFiles();
void reloadFullStack() {} void reloadFullStack() {}
bool supportsThreads() const { return false; }
void updateWatchData(const QByteArray &iname); void updateWatchData(const QByteArray &iname);
void selectWatchData(const QByteArray &iname); void selectWatchData(const QByteArray &iname);
void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
@@ -162,36 +139,21 @@ private:
bool hasCapability(unsigned) const; bool hasCapability(unsigned) const;
void quitDebugger(); void quitDebugger();
private:
void closeConnection(); void closeConnection();
void startApplicationLauncher(); void startApplicationLauncher();
void stopApplicationLauncher(); void stopApplicationLauncher();
bool isShadowBuildProject() const; void connectionErrorOccurred(QDebugSupport::Error socketError);
QString fromShadowBuildFilename(const QString &filename) const; void clientStateChanged(QmlDebug::QmlDebugClient::State state);
QString mangleFilenamePaths(const QString &filename, void checkConnectionState();
const QString &oldBasePath, const QString &newBasePath) const; void showConnectionStateMessage(const QString &message);
QString qmlImportPath() const; void showConnectionErrorMessage(const QString &message);
bool isConnected() 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;
private:
friend class QmlCppEngine; friend class QmlCppEngine;
friend class QmlEnginePrivate;
QmlEnginePrivate *d;
}; };
} // namespace Internal } // 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 { #include <qmldebug/qdebugmessageclient.h>
width: 640 #include <qmldebug/qmloutputparser.h>
height: 480
Image { namespace Debugger {
id: image1 namespace Internal {
x: 20
y: 18
source: "images/qtcreator.png"
}
Image { bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line, quint32 *column, bool *valid);
id: image2 void appendDebugOutput(QtMsgType type, const QString &message, const QmlDebug::QDebugContextInfo &info);
x: 327
y: 18
source: "images/qtcreator.jpg"
}
Image { void clearExceptionSelection();
id: image3 QStringList highlightExceptionCode(int lineNumber, const QString &filePath, const QString &errorMessage);
x: 20
y: 288 } // namespace Internal
source: "images/qtcreator.ico" } // namespace Debugger
}
} #endif // QMLENGINEUTILS_H

View File

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

View File

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

View File

@@ -686,6 +686,7 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object)
m_objectToSelect = -1; m_objectToSelect = -1;
} }
m_debuggerEngine->watchHandler()->updateWatchersWindow(); m_debuggerEngine->watchHandler()->updateWatchersWindow();
m_debuggerEngine->watchHandler()->reexpandItems();
} }
void QmlInspectorAgent::buildDebugIdHashRecursive(const ObjectReference &ref) 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(); emit m_model->updateFinished();
} }
void WatchHandler::reexpandItems()
{
m_model->reexpandItems();
}
void WatchHandler::removeItemByIName(const QByteArray &iname) void WatchHandler::removeItemByIName(const QByteArray &iname)
{ {
WatchItem *item = m_model->findItem(iname); WatchItem *item = m_model->findItem(iname);

View File

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

View File

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

View File

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

View File

@@ -473,6 +473,7 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const
static QDir resourcesDir(QStringLiteral(":/propertyEditorQmlSources")); static QDir resourcesDir(QStringLiteral(":/propertyEditorQmlSources"));
QDir importDir(info.importDirectoryPath() + QLatin1String(Constants::QML_DESIGNER_SUBFOLDER)); 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()) const QString versionString = QStringLiteral("_") + QString::number(info.majorVersion())
+ QStringLiteral("_") + QStringLiteral("_")
@@ -484,6 +485,14 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const
//Check for qml files with versions first //Check for qml files with versions first
const QString withoutDirWithVersion = relativePathWithVersion.split(QStringLiteral("/")).last(); 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)) if (importDir.exists(relativePathWithVersion))
return importDir.absoluteFilePath(relativePathWithVersion); return importDir.absoluteFilePath(relativePathWithVersion);
if (importDir.exists(withoutDirWithVersion)) //Since we are in a subfolder of the import we do not require the directory 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)) if (resourcesDir.exists(relativePathWithVersion))
return resourcesDir.absoluteFilePath(relativePathWithVersion); return resourcesDir.absoluteFilePath(relativePathWithVersion);
const QString withoutDir = relativePath.split(QStringLiteral("/")).last();
if (importDir.exists(relativePath)) if (importDir.exists(relativePath))
return importDir.absoluteFilePath(relativePath); return importDir.absoluteFilePath(relativePath);
if (importDir.exists(withoutDir)) //Since we are in a subfolder of the import we do not require the directory 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()) { foreach (const QString &path, importPaths()) {
QString fullUrl = path + QLatin1Char('/') + url; QString fullUrl = path + QLatin1Char('/') + url;
dirInfo = QFileInfo(fullUrl); 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()) { if (dirInfo.exists() && dirInfo.isDir()) {
//### todo full qualified names QString nameSpace = import.uri(); //### todo full qualified names QString nameSpace = import.uri();
parseDirectory(dirInfo.canonicalFilePath(), false); parseDirectory(dirInfo.canonicalFilePath(), false);

View File

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

View File

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

View File

@@ -2962,6 +2962,14 @@ void tst_Dumpers::dumper_data()
+ Check4("url1.d.fragment", "\"\"", "@QString"); + 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"; QByteArray expected1 = "\"AAA";
expected1.append(char('\t')); expected1.append(char('\t'));
expected1.append(char('\r')); 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_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'} :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'} :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'} :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'} :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'} :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.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.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'} :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.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'} :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'} :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, def createNewQtQuickApplication(workingDir, projectName = None,
targets=Targets.desktopTargetClasses(), minimumQtVersion="5.3", targets=Targets.desktopTargetClasses(), minimumQtVersion="5.3",
fromWelcome=False): withControls = False, fromWelcome=False):
available = __createProjectOrFileSelectType__(" Application", "Qt Quick Application", fromWelcome) if withControls:
template = "Qt Quick Controls Application"
else:
template = "Qt Quick Application"
available = __createProjectOrFileSelectType__(" Application", template, fromWelcome)
projectName = __createProjectSetNameAndPath__(workingDir, projectName) projectName = __createProjectSetNameAndPath__(workingDir, projectName)
requiredQt = __createProjectHandleQtQuickSelection__(minimumQtVersion) requiredQt = __createProjectHandleQtQuickSelection__(minimumQtVersion)
__modifyAvailableTargets__(available, requiredQt) __modifyAvailableTargets__(available, requiredQt)
checkedTargets = __chooseTargets__(targets, available) checkedTargets = __chooseTargets__(targets, available)
snooze(1) snooze(1)
clickButton(waitForObject(":Next_QPushButton")) if len(checkedTargets):
__createProjectHandleLastPage__() clickButton(waitForObject(":Next_QPushButton"))
__createProjectHandleLastPage__()
progressBarWait(10000)
else:
clickButton(waitForObject("{type='QPushButton' text='Cancel' visible='1'}"))
progressBarWait(10000)
return checkedTargets, projectName return checkedTargets, projectName
def createNewQtQuickUI(workingDir, qtQuickVersion="1.1"): def createNewQtQuickUI(workingDir, qtVersion = "5.3", withControls = False):
__createProjectOrFileSelectType__(" Application", "Qt Quick UI") if withControls:
template = 'Qt Quick Controls UI'
else:
template = 'Qt Quick UI'
__createProjectOrFileSelectType__(" Other Project", template)
if workingDir == None: if workingDir == None:
workingDir = tempDir() workingDir = tempDir()
projectName = __createProjectSetNameAndPath__(workingDir) projectName = __createProjectSetNameAndPath__(workingDir)
__createProjectHandleQtQuickSelection__(qtQuickVersion) __createProjectHandleQtQuickSelection__(qtVersion)
__createProjectHandleLastPage__() __createProjectHandleLastPage__()
progressBarWait(10000)
return projectName return projectName
def createNewQmlExtension(workingDir, targets=Targets.DESKTOP_474_GCC, qtQuickVersion=1): 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") test.compare(manual.data().toString(), "Manual", "Verifying label for section")
if isRegex: if isRegex:
pattern = re.compile(itemText) pattern = re.compile(itemText)
found = False
for section in [autoDetected, manual]: for section in [autoDetected, manual]:
for dumpedItem in dumpItems(model, section): for dumpedItem in dumpItems(model, section):
if (isRegex and pattern.match(dumpedItem) if (isRegex and pattern.match(dumpedItem)
or itemText == dumpedItem): or itemText == dumpedItem):
found = True
item = ".".join([str(section.data().toString()), item = ".".join([str(section.data().toString()),
dumpedItem.replace(".", "\\.").replace("_", "\\_")]) dumpedItem.replace(".", "\\.").replace("_", "\\_")])
clickItem(treeViewOrWidget, item, 5, 5, 0, Qt.LeftButton) clickItem(treeViewOrWidget, item, 5, 5, 0, Qt.LeftButton)
break return True
if found: return False
break
return found
def __getTargetFromToolTip__(toolTip): def __getTargetFromToolTip__(toolTip):
if toolTip == None or not isinstance(toolTip, (str, unicode)): if toolTip == None or not isinstance(toolTip, (str, unicode)):

View File

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

View File

@@ -45,7 +45,7 @@ def main():
return return
qmlProjFile = os.path.join(qmlProjDir, projName) qmlProjFile = os.path.join(qmlProjDir, projName)
# start Creator by passing a .qmlproject file # start Creator by passing a .qmlproject file
startApplication('qtcreator -load QmlProjectManager' + SettingsPath + ' "%s"' % qmlProjFile) startApplication('qtcreator' + SettingsPath + ' "%s"' % qmlProjFile)
if not startedWithoutPluginError(): if not startedWithoutPluginError():
return return
waitFor('object.exists(":Qt Creator_Utils::NavigationTreeView")', 10000) waitFor('object.exists(":Qt Creator_Utils::NavigationTreeView")', 10000)
@@ -91,8 +91,8 @@ def main():
checkForEmptyRows(items) checkForEmptyRows(items)
check = [[None, 0, {"Properties":1, "Rectangle":2, "Text":1}, {"width":"360", "height":"360"}], check = [[None, 0, {"Properties":1, "Rectangle":2, "Text":1}, {"width":"360", "height":"360"}],
["Text", 1, {"Properties":1}, {"text":"Check"}], ["Text", 1, {"Properties":1}, {"text":"Check"}],
["Rectangle", 1, {"Properties":1}, {"width":"50", "height":"50", "color":"#008000"}], ["Rectangle", 2, {"Properties":1}, {"width":"50", "height":"50", "color":"#008000"}],
["Rectangle", 2, {"Properties":1}, {"width":"100", "height":"100", "color":"#ff0000"}] ["Rectangle", 1, {"Properties":1}, {"width":"100", "height":"100", "color":"#ff0000"}]
] ]
for current in check: for current in check:
if current[0]: if current[0]:
@@ -108,23 +108,19 @@ def main():
def __unfoldTree__(): def __unfoldTree__():
rootIndex = getQModelIndexStr("text='Rectangle'", rootIndex = getQModelIndexStr("text='Rectangle'",
':Locals and Expressions_Debugger::Internal::WatchTreeView') ':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) unfoldQModelIndexIncludingProperties(rootIndex)
if JIRA.isBugStillOpen(14210): subItems = ["text='Rectangle'", "text='Rectangle' occurrence='2'", "text='Text'"]
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'"]
for item in subItems: for item in subItems:
unfoldQModelIndexIncludingProperties(getQModelIndexStr(item, rootIndex)) unfoldQModelIndexIncludingProperties(getQModelIndexStr(item, rootIndex))
def unfoldQModelIndexIncludingProperties(indexStr): def unfoldQModelIndexIncludingProperties(indexStr):
tv = waitForObject(':Locals and Expressions_Debugger::Internal::WatchTreeView')
# HACK to avoid failing clicks
tv.scrollToBottom()
doubleClick(waitForObject(indexStr)) doubleClick(waitForObject(indexStr))
propIndex = getQModelIndexStr("text='Properties'", indexStr) propIndex = getQModelIndexStr("text='Properties'", indexStr)
# HACK to avoid failing clicks
tv.scrollToBottom()
doubleClick(waitForObject(propIndex)) doubleClick(waitForObject(propIndex))
def fetchItems(index, valIndex, treeView): def fetchItems(index, valIndex, treeView):

View File

@@ -34,16 +34,31 @@ def main():
startApplication("qtcreator" + SettingsPath) startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError(): if not startedWithoutPluginError():
return 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"], available = [("5.3", False), ("5.3", True)]
[Targets.DESKTOP_521_DEFAULT, "Controls 1.0"], [Targets.DESKTOP_521_DEFAULT, "Controls 1.1"], if platform.system() != 'Darwin':
[Targets.DESKTOP_531_DEFAULT, "Controls 1.2"]]: 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 # using a temporary directory won't mess up a potentially existing
workingDir = tempDir() workingDir = tempDir()
checkedTargets, projectName = createNewQtQuickApplication(workingDir, targets=targ, checkedTargets, projectName = createNewQtQuickApplication(workingDir, targets=targ,
qtQuickVersion=qVer) minimumQtVersion=qtVersion,
test.log("Building project Qt Quick %s Application (%s)" withControls = controls)
% (qVer, Targets.getStringForTarget(targ))) 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) result = modifyRunSettingsForHookInto(projectName, len(checkedTargets), 11223)
invokeMenuItem("Build", "Build All") invokeMenuItem("Build", "Build All")
waitForCompile() waitForCompile()
@@ -57,10 +72,8 @@ def main():
allowAppThroughWinFW(workingDir, projectName) allowAppThroughWinFW(workingDir, projectName)
if result: if result:
function = "subprocessFunctionQuick2" function = "subprocessFunctionQuick2"
if qVer[0] == "1":
function = "subprocessFunctionQuick1"
result = runAndCloseApp(True, projectName, 11223, function, result = runAndCloseApp(True, projectName, 11223, function,
SubprocessType.QT_QUICK_APPLICATION, quickVersion=qVer) SubprocessType.QT_QUICK_APPLICATION, quickVersion=quick)
else: else:
result = runAndCloseApp(sType=SubprocessType.QT_QUICK_APPLICATION) result = runAndCloseApp(sType=SubprocessType.QT_QUICK_APPLICATION)
removeExecutableAsAttachableAUT(projectName, 11223) removeExecutableAsAttachableAUT(projectName, 11223)
@@ -70,7 +83,9 @@ def main():
if result == None: if result == None:
checkCompile() checkCompile()
else: 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", "Close All Projects and Editors")
invokeMenuItem("File", "Exit") invokeMenuItem("File", "Exit")
@@ -82,8 +97,5 @@ def subprocessFunctionGenericQuick(quickVersion):
test.log("Clicking 'Hello World' Text to close QtQuick%dApplicationViewer" % quickVersion) test.log("Clicking 'Hello World' Text to close QtQuick%dApplicationViewer" % quickVersion)
mouseClick(helloWorldText, 5, 5, 0, Qt.LeftButton) mouseClick(helloWorldText, 5, 5, 0, Qt.LeftButton)
def subprocessFunctionQuick1():
subprocessFunctionGenericQuick(1)
def subprocessFunctionQuick2(): def subprocessFunctionQuick2():
subprocessFunctionGenericQuick(2) subprocessFunctionGenericQuick(2)

View File

@@ -31,30 +31,42 @@
source("../../shared/qtcreator.py") source("../../shared/qtcreator.py")
def main(): def main():
startApplication("qtcreator -load QmlProjectManager" + SettingsPath) startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError(): if not startedWithoutPluginError():
return 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 # using a temporary directory won't mess up a potentially existing
workingDir = tempDir() workingDir = tempDir()
projectName = createNewQtQuickUI(workingDir, quickVersion) projectName = createNewQtQuickUI(workingDir, qtVersion, controls)
switchViewTo(ViewConstants.PROJECTS) switchViewTo(ViewConstants.PROJECTS)
clickButton(waitForObject(":*Qt Creator.Add Kit_QPushButton")) 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': if platform.system() == 'Darwin':
waitFor("macHackActivateContextMenuItem(menuItem)", 5000) waitFor("macHackActivateContextMenuItem(menuItem)", 5000)
else: else:
activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' " activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", menuItem)) "window=':Qt Creator_Core::Internal::MainWindow'}", menuItem))
test.log("Running project Qt Quick %s UI" % quickVersion) additionalText = ''
qmlViewer = modifyRunSettingsForHookIntoQtQuickUI(2, 1, workingDir, projectName, 11223, quickVersion) 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: if qmlViewer!=None:
qmlViewerPath = os.path.dirname(qmlViewer) qmlViewerPath = os.path.dirname(qmlViewer)
qmlViewer = os.path.basename(qmlViewer) qmlViewer = os.path.basename(qmlViewer)
result = addExecutableAsAttachableAUT(qmlViewer, 11223) result = addExecutableAsAttachableAUT(qmlViewer, 11223)
allowAppThroughWinFW(qmlViewerPath, qmlViewer, None) allowAppThroughWinFW(qmlViewerPath, qmlViewer, None)
if result: 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: else:
result = runAndCloseApp(sType=SubprocessType.QT_QUICK_UI) result = runAndCloseApp(sType=SubprocessType.QT_QUICK_UI)
removeExecutableAsAttachableAUT(qmlViewer, 11223) removeExecutableAsAttachableAUT(qmlViewer, 11223)
@@ -64,6 +76,8 @@ def main():
if result == None: if result == None:
checkCompile() checkCompile()
else: 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", "Close All Projects and Editors")
invokeMenuItem("File", "Exit") invokeMenuItem("File", "Exit")