Merge remote-tracking branch 'origin/3.5'
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -1466,6 +1466,11 @@
|
||||
|
||||
\endlist
|
||||
|
||||
The locations of search hits, breakpoints, and bookmarks in your document
|
||||
are highlighted on the editor scroll bar. To turn highlighting off, select
|
||||
\uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} >
|
||||
\uicontrol {Highlight search results on the scrollbar}.
|
||||
|
||||
\section1 Advanced Search
|
||||
|
||||
To search through projects, files on a file system or currently open files:
|
||||
@@ -2403,9 +2408,10 @@
|
||||
|
||||
\endlist
|
||||
|
||||
To move directly to a particular line in the document when you open the
|
||||
document, append a plus sign (+) or a colon (:) to the file name in the
|
||||
locator. For example, to open main.cpp to line 41, enter: \c {main.cpp:41}.
|
||||
To move directly to a particular line and column in the document when you
|
||||
open the document, append them to the file name in the locator, separated by
|
||||
plus signs (+) or colons (:). For example, to open main.cpp to line 41 and
|
||||
column 2, enter: \c {main.cpp:41:2}.
|
||||
|
||||
If the path to a file is very long, it might not fit into the locator
|
||||
window. To view the full path, press \key Alt when the filename is selected
|
||||
@@ -2446,7 +2452,7 @@
|
||||
\li Locating symbols in the current document (\c {.})
|
||||
|
||||
\li Locating a specific line and column in the document displayed in
|
||||
your editor (\c {l})
|
||||
your editor (\c {l <line_number>:<column_number>})
|
||||
|
||||
\li Opening help topics, including Qt documentation (\c {?})
|
||||
|
||||
@@ -2460,6 +2466,8 @@
|
||||
\li Executing version control system commands (\c {git}). For more
|
||||
information, see \l{Using Version Control Systems}
|
||||
|
||||
\li Running external tools (\c x)
|
||||
|
||||
\endlist
|
||||
|
||||
To use a specific locator filter, type the assigned prefix followed by
|
||||
|
@@ -31,16 +31,16 @@
|
||||
\title Using Command Line Options
|
||||
|
||||
You can start \QC and specify some options from the command line. For
|
||||
example, you can open a file to any line.
|
||||
example, you can open a file to any line and column.
|
||||
|
||||
To specify command line options, enter the following command in the \QC
|
||||
installation or build directory:
|
||||
|
||||
\c {qtcreator [option] [filename[:line_number]]}
|
||||
\c {qtcreator [option] [filename[:line_number[:column_number]]]}
|
||||
|
||||
\note You can use either a colon (:) or a plus sign (+) as a separator
|
||||
between the filename and line number. You can also use a space between the
|
||||
separator and the line number.
|
||||
between the filename and line number and the line number and the column
|
||||
number. You can also use a space between the separator and the line number.
|
||||
|
||||
For example, on Windows:
|
||||
|
||||
@@ -48,9 +48,9 @@
|
||||
|
||||
\li \c {C:\qtcreator\bin>qtcreator -help}
|
||||
|
||||
\li \c {C:\qtcreator\bin>qtcreator C:\TextFinder\textfinder.cpp:100}
|
||||
\li \c {C:\qtcreator\bin>qtcreator C:\TextFinder\textfinder.cpp:100:2}
|
||||
|
||||
\li \c {C:\qtcreator\bin>qtcreator C:\TextFinder\textfinder.cpp +100}
|
||||
\li \c {C:\qtcreator\bin>qtcreator C:\TextFinder\textfinder.cpp +100+2}
|
||||
|
||||
\endlist
|
||||
|
||||
|
@@ -36,6 +36,9 @@
|
||||
for use. You can change their default configurations and configure new
|
||||
tools.
|
||||
|
||||
To run the tools, select \uicontrol Tools > \uicontrol External, or use the
|
||||
\c x filter in the locator.
|
||||
|
||||
\section1 Using Qt Linguist
|
||||
|
||||
You can use the Qt Linguist release manager tools, lupdate and lrelease,
|
||||
|
@@ -64,8 +64,19 @@
|
||||
|
||||
\li Select a command from the list.
|
||||
|
||||
\li In \uicontrol{Key Sequence} enter the shortcut key you want to associate
|
||||
with the selected command.
|
||||
\li In the \uicontrol{Key Sequence} field, you have the following
|
||||
options:
|
||||
|
||||
\list
|
||||
|
||||
\li Enter the shortcut key you want to associate with the
|
||||
selected command.
|
||||
|
||||
\li Select \uicontrol Record, press the keys to use as the
|
||||
keyboard shortcut, and select \uicontrol {Stop Recording}
|
||||
when you are done.
|
||||
|
||||
\endlist
|
||||
|
||||
\li To revert to the default shortcut, select \uicontrol Reset.
|
||||
|
||||
|
@@ -114,6 +114,12 @@
|
||||
|
||||
Create a Qt Quick application using Qt Quick Controls
|
||||
|
||||
\li Qt Canvas 3D Application
|
||||
|
||||
Create a Qt Quick application that imports the Qt Canvas 3D
|
||||
module and, optionally, includes \l{http://threejs.org}
|
||||
{three.js}.
|
||||
|
||||
\li Qt Console Application
|
||||
|
||||
Use a single main.cpp file
|
||||
|
@@ -46,6 +46,10 @@
|
||||
\li \uicontrol {Qt Quick Controls Application} is like
|
||||
\uicontrol {Qt Quick Application}, but using Qt Quick Controls.
|
||||
|
||||
\li \uicontrol {Qt Canvas 3D Application} creates a Qt Quick application
|
||||
that imports the Qt Canvas 3D module and, optionally, includes
|
||||
\l{http://threejs.org}{three.js}.
|
||||
|
||||
\li \uicontrol {Qt Quick UI} (in the \uicontrol {Other Project}
|
||||
category) creates a Qt Quick UI project with a single QML file that
|
||||
contains the main view. You can review Qt Quick UI projects in a
|
||||
|
@@ -1,9 +1,9 @@
|
||||
!isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included")
|
||||
QTCREATOR_PRI_INCLUDED = 1
|
||||
|
||||
QTCREATOR_VERSION = 3.4.81
|
||||
QTCREATOR_COMPAT_VERSION = 3.4.81
|
||||
BINARY_ARTIFACTS_BRANCH = master
|
||||
QTCREATOR_VERSION = 3.4.82
|
||||
QTCREATOR_COMPAT_VERSION = 3.4.82
|
||||
BINARY_ARTIFACTS_BRANCH = 3.5
|
||||
|
||||
# enable c++11
|
||||
CONFIG += c++11
|
||||
|
@@ -6,11 +6,11 @@ Project {
|
||||
property bool withAutotests: qbs.buildVariant === "debug"
|
||||
property string ide_version_major: '3'
|
||||
property string ide_version_minor: '4'
|
||||
property string ide_version_release: '81'
|
||||
property string ide_version_release: '82'
|
||||
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release
|
||||
property string ide_compat_version_major: '3'
|
||||
property string ide_compat_version_minor: '4'
|
||||
property string ide_compat_version_release: '81'
|
||||
property string ide_compat_version_release: '82'
|
||||
property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release
|
||||
property path ide_source_tree: path
|
||||
property string ide_app_path: qbs.targetOS.contains("osx") ? "" : "bin"
|
||||
|
@@ -191,7 +191,9 @@ def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, qt_qml_
|
||||
target = os.path.join(install_dir, 'bin', 'imports', qtimport)
|
||||
if (os.path.exists(target)):
|
||||
shutil.rmtree(target)
|
||||
shutil.copytree(os.path.join(qt_import_dir, qtimport), target, ignore=copy_ignore_func, symlinks=True)
|
||||
import_path = os.path.join(qt_import_dir, qtimport)
|
||||
if os.path.exists(import_path):
|
||||
shutil.copytree(import_path, target, ignore=copy_ignore_func, symlinks=True)
|
||||
|
||||
if (os.path.exists(qt_qml_dir)):
|
||||
print "Copying qt quick 2 imports"
|
||||
@@ -230,20 +232,33 @@ def copyPreservingLinks(source, destination):
|
||||
shutil.copy(source, destination)
|
||||
|
||||
def copy_libclang(install_dir, llvm_install_dir):
|
||||
libsources = []
|
||||
libtarget = ""
|
||||
# contains pairs of (source, target directory)
|
||||
deployinfo = []
|
||||
if sys.platform.startswith("win"):
|
||||
libsources = [os.path.join(llvm_install_dir, 'bin', 'libclang.dll')]
|
||||
libtarget = os.path.join(install_dir, 'bin')
|
||||
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'libclang.dll'),
|
||||
os.path.join(install_dir, 'bin')))
|
||||
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'clang-cl.exe'),
|
||||
os.path.join(install_dir, 'bin')))
|
||||
else:
|
||||
libsources = glob(os.path.join(llvm_install_dir, 'lib', 'libclang.so*'))
|
||||
libtarget = os.path.join(install_dir, 'lib', 'qtcreator')
|
||||
for libsource in libsources:
|
||||
deployinfo.append((libsource, os.path.join(install_dir, 'lib', 'qtcreator')))
|
||||
clangbinary = os.path.join(llvm_install_dir, 'bin', 'clang')
|
||||
clangbinary_targetdir = os.path.join(install_dir, 'bin')
|
||||
deployinfo.append((clangbinary, clangbinary_targetdir))
|
||||
# copy link target if clang is actually a symlink
|
||||
if os.path.islink(clangbinary):
|
||||
linktarget = os.readlink(clangbinary)
|
||||
deployinfo.append((os.path.join(os.path.dirname(clangbinary), linktarget),
|
||||
os.path.join(clangbinary_targetdir, linktarget)))
|
||||
|
||||
resourcesource = os.path.join(llvm_install_dir, 'lib', 'clang')
|
||||
resourcetarget = os.path.join(install_dir, 'share', 'qtcreator', 'cplusplus', 'clang')
|
||||
|
||||
print "copying libclang..."
|
||||
for libsource in libsources:
|
||||
print libsource, '->', libtarget
|
||||
copyPreservingLinks(libsource, libtarget)
|
||||
for source, target in deployinfo:
|
||||
print source, '->', target
|
||||
copyPreservingLinks(source, target)
|
||||
print resourcesource, '->', resourcetarget
|
||||
if (os.path.exists(resourcetarget)):
|
||||
shutil.rmtree(resourcetarget)
|
||||
|
@@ -61,6 +61,12 @@ if [ $LLVM_INSTALL_DIR ]; then
|
||||
# use recursive copy to make it copy symlinks as symlinks
|
||||
cp -Rf "$LLVM_INSTALL_DIR"/lib/libclang.*dylib "$1/Contents/Frameworks/" || exit 1
|
||||
cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$1/Contents/Resources/cplusplus/" || exit 1
|
||||
clangsource="$LLVM_INSTALL_DIR"/bin/clang
|
||||
clanglinktarget="$(readlink "$clangsource")"
|
||||
cp -Rf "$clangsource" "$1/Contents/Resources/" || exit 1
|
||||
if [ $clanglinktarget ]; then
|
||||
cp -Rf "$(dirname "$clangsource")/$clanglinktarget" "$1/Contents/Resources/$clanglinktarget" || exit 1
|
||||
fi
|
||||
fi
|
||||
_CLANG_CODEMODEL_LIB="$1/Contents/PlugIns/libClangCodeModel_debug.dylib"
|
||||
if [ ! -f "$_CLANG_CODEMODEL_LIB" ]; then
|
||||
|
@@ -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
|
||||
|
@@ -387,12 +387,27 @@ class DumperBase:
|
||||
self.isCli = False
|
||||
|
||||
# Later set, or not set:
|
||||
# cachedQtVersion
|
||||
self.stringCutOff = 10000
|
||||
self.displayStringLimit = 100
|
||||
|
||||
self.resetCaches()
|
||||
|
||||
self.childrenPrefix = 'children=['
|
||||
self.childrenSuffix = '],'
|
||||
|
||||
self.dumpermodules = [
|
||||
"qttypes",
|
||||
"stdtypes",
|
||||
"misctypes",
|
||||
"boosttypes",
|
||||
"creatortypes",
|
||||
"personaltypes",
|
||||
]
|
||||
|
||||
|
||||
def resetCaches(self):
|
||||
# This is a cache mapping from 'type name' to 'display alternatives'.
|
||||
self.qqFormats = {}
|
||||
self.qqFormats = { "QVariant (QVariantMap)" : mapForms() }
|
||||
|
||||
# This is a cache of all known dumpers.
|
||||
self.qqDumpers = {}
|
||||
@@ -407,18 +422,6 @@ class DumperBase:
|
||||
# to not be QObject derived, it contains a 0 value.
|
||||
self.knownStaticMetaObjects = {}
|
||||
|
||||
self.childrenPrefix = 'children=['
|
||||
self.childrenSuffix = '],'
|
||||
|
||||
self.dumpermodules = [
|
||||
"qttypes",
|
||||
"stdtypes",
|
||||
"misctypes",
|
||||
"boosttypes",
|
||||
"creatortypes",
|
||||
"personaltypes",
|
||||
]
|
||||
|
||||
|
||||
def putNewline(self):
|
||||
pass
|
||||
@@ -1674,10 +1677,7 @@ class DumperBase:
|
||||
pass
|
||||
|
||||
def setupDumpers(self, _ = {}):
|
||||
self.qqDumpers = {}
|
||||
self.qqFormats = {}
|
||||
self.qqEditable = {}
|
||||
self.typeCache = {}
|
||||
self.resetCaches()
|
||||
|
||||
for mod in self.dumpermodules:
|
||||
m = importlib.import_module(mod)
|
||||
|
@@ -144,6 +144,7 @@ ScanStackCommand()
|
||||
class PlainDumper:
|
||||
def __init__(self, printer):
|
||||
self.printer = printer
|
||||
self.typeCache = {}
|
||||
|
||||
def __call__(self, d, value):
|
||||
printer = self.printer.invoke(value)
|
||||
@@ -223,6 +224,7 @@ class Dumper(DumperBase):
|
||||
# These values will be kept between calls to 'showData'.
|
||||
self.isGdb = True
|
||||
self.childEventAddress = None
|
||||
self.typeCache = {}
|
||||
self.typesReported = {}
|
||||
self.typesToReport = {}
|
||||
self.qtNamespaceToReport = None
|
||||
|
@@ -1031,6 +1031,13 @@ def qdump__QMultiMap(d, value):
|
||||
qdump__QMap(d, value)
|
||||
|
||||
|
||||
def qform__QVariantMap():
|
||||
return mapForms()
|
||||
|
||||
def qdump__QVariantMap(d, value):
|
||||
qdump__QMap(d, value)
|
||||
|
||||
|
||||
def qdump__QMetaObjectPrivate(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
@@ -1899,6 +1906,16 @@ def qdump__QUrl(d, value):
|
||||
d.putGenericItem("fragment", stringType, fragment, Hex4EncodedLittleEndian)
|
||||
d.putFields(value)
|
||||
|
||||
|
||||
def qdump__QUuid(d, value):
|
||||
v = value["data4"]
|
||||
d.putValue("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"
|
||||
% (value["data1"], value["data2"], value["data3"],
|
||||
v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]))
|
||||
d.putNumChild(1)
|
||||
d.putPlainChildren(value)
|
||||
|
||||
|
||||
def qdumpHelper_QVariant_0(d, blob):
|
||||
# QVariant::Invalid
|
||||
d.putBetterType("%sQVariant (invalid)" % d.qtNamespace())
|
||||
|
@@ -72,12 +72,6 @@ for(data_dir, DATA_DIRS) {
|
||||
dumpinfo.input = qml/qmldump/Info.plist.in
|
||||
dumpinfo.output = $$IDE_DATA_PATH/qml/qmldump/Info.plist
|
||||
QMAKE_SUBSTITUTES += dumpinfo
|
||||
puppetinfo.input = qml/qmlpuppet/qmlpuppet/Info.plist.in
|
||||
puppetinfo.output = $$IDE_DATA_PATH/qml/qmlpuppet/qmlpuppet/Info.plist
|
||||
QMAKE_SUBSTITUES += puppetinfo
|
||||
puppet2info.input = qml/qmlpuppet/qml2puppet/Info.plist.in
|
||||
puppet2info.output = $$IDE_DATA_PATH/qml/qmlpuppet/qml2puppet/Info.plist
|
||||
QMAKE_SUBSTITUES += puppet2info
|
||||
}
|
||||
|
||||
SRCRESOURCEDIR = $$IDE_SOURCE_TREE/src/share/qtcreator/
|
||||
|
@@ -7,8 +7,8 @@
|
||||
"trDisplayName": "Qt Quick Application",
|
||||
"trDisplayCategory": "Application",
|
||||
"icon": "qml_wizard.png",
|
||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQt", "QtSupport.Wizards.FeatureQtQuick.2" ],
|
||||
"enabled": "${JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 && [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0}",
|
||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.3" ],
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 }",
|
||||
|
||||
"options":
|
||||
[
|
||||
@@ -38,6 +38,7 @@
|
||||
"type": "ComboBox",
|
||||
"data":
|
||||
{
|
||||
"index": 2,
|
||||
"items":
|
||||
[
|
||||
{
|
||||
@@ -46,8 +47,7 @@
|
||||
"{
|
||||
'qtQuickVersion': '2.5',
|
||||
'qtQuickWindowVersion': '2.2'
|
||||
}",
|
||||
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.5') >= 0}"
|
||||
}"
|
||||
},
|
||||
{
|
||||
"trKey": "Qt 5.4",
|
||||
@@ -55,8 +55,7 @@
|
||||
"{
|
||||
'qtQuickVersion': '2.4',
|
||||
'qtQuickWindowVersion': '2.2'
|
||||
}",
|
||||
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.4') >= 0}"
|
||||
}"
|
||||
},
|
||||
{
|
||||
"trKey": "Qt 5.3",
|
||||
@@ -64,8 +63,7 @@
|
||||
"{
|
||||
'qtQuickVersion': '2.3',
|
||||
'qtQuickWindowVersion': '2.2'
|
||||
}",
|
||||
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0}"
|
||||
}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -7,8 +7,8 @@
|
||||
"trDisplayName": "Qt Quick Controls Application",
|
||||
"trDisplayCategory": "Application",
|
||||
"icon": "../qtquickapplication/qml_wizard.png",
|
||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQt" ],
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 && [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0 }",
|
||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.3" ],
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0}",
|
||||
|
||||
"options":
|
||||
[
|
||||
@@ -40,6 +40,7 @@
|
||||
"type": "ComboBox",
|
||||
"data":
|
||||
{
|
||||
"index": 2,
|
||||
"items":
|
||||
[
|
||||
{
|
||||
@@ -50,8 +51,7 @@
|
||||
'qtQuickControlsVersion': '1.4',
|
||||
'qtQuickDialogsVersion': '1.2',
|
||||
'qtQuickLayoutsVersion': '1.2'
|
||||
}",
|
||||
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.5') >= 0}"
|
||||
}"
|
||||
},
|
||||
{
|
||||
"trKey": "Qt 5.4",
|
||||
@@ -61,8 +61,7 @@
|
||||
'qtQuickControlsVersion': '1.3',
|
||||
'qtQuickDialogsVersion': '1.2',
|
||||
'qtQuickLayoutsVersion': '1.1'
|
||||
}",
|
||||
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.4') >= 0}"
|
||||
}"
|
||||
},
|
||||
{
|
||||
"trKey": "Qt 5.3",
|
||||
@@ -72,8 +71,7 @@
|
||||
'qtQuickControlsVersion': '1.2',
|
||||
'qtQuickDialogsVersion': '1.2',
|
||||
'qtQuickLayoutsVersion': '1.1'
|
||||
}",
|
||||
"condition": "%{JS: [ %{Features} ].indexOf('QtSupport.Wizards.FeatureQt5.3') >= 0}"
|
||||
}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -164,8 +164,8 @@ void AutotoolsProject::loadProjectTree()
|
||||
// The thread is still busy parsing a previus configuration.
|
||||
// Wait until the thread has been finished and delete it.
|
||||
// TODO: Discuss whether blocking is acceptable.
|
||||
disconnect(m_makefileParserThread, SIGNAL(finished()),
|
||||
this, SLOT(makefileParsingFinished()));
|
||||
disconnect(m_makefileParserThread, &QThread::finished,
|
||||
this, &AutotoolsProject::makefileParsingFinished);
|
||||
m_makefileParserThread->wait();
|
||||
delete m_makefileParserThread;
|
||||
m_makefileParserThread = 0;
|
||||
@@ -402,6 +402,24 @@ QList<Node *> AutotoolsProject::nodes(FolderNode *parent) const
|
||||
return list;
|
||||
}
|
||||
|
||||
static QStringList filterIncludes(const QString &absSrc, const QString &absBuild,
|
||||
const QStringList &in)
|
||||
{
|
||||
QStringList result;
|
||||
foreach (const QString i, in) {
|
||||
QString out = i;
|
||||
out.replace(QLatin1String("$(top_srcdir)"), absSrc);
|
||||
out.replace(QLatin1String("$(abs_top_srcdir)"), absSrc);
|
||||
|
||||
out.replace(QLatin1String("$(top_builddir)"), absBuild);
|
||||
out.replace(QLatin1String("$(abs_top_builddir)"), absBuild);
|
||||
|
||||
result << out;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void AutotoolsProject::updateCppCodeModel()
|
||||
{
|
||||
CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
|
||||
@@ -427,7 +445,12 @@ void AutotoolsProject::updateCppCodeModel()
|
||||
ppBuilder.setCFlags(cflags);
|
||||
ppBuilder.setCxxFlags(cxxflags);
|
||||
|
||||
ppBuilder.setIncludePaths(m_makefileParserThread->includePaths());
|
||||
const QString absSrc = projectDirectory().toString();
|
||||
const Target *target = activeTarget();
|
||||
const QString absBuild = (target && target->activeBuildConfiguration())
|
||||
? target->activeBuildConfiguration()->buildDirectory().toString() : QString();
|
||||
|
||||
ppBuilder.setIncludePaths(filterIncludes(absSrc, absBuild, m_makefileParserThread->includePaths()));
|
||||
ppBuilder.setDefines(m_makefileParserThread->defines());
|
||||
|
||||
const QList<Core::Id> languages = ppBuilder.createProjectPartsForFiles(m_files);
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "makefileparser.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
@@ -131,12 +132,12 @@ QByteArray MakefileParser::defines() const
|
||||
|
||||
QStringList MakefileParser::cflags() const
|
||||
{
|
||||
return m_cflags;
|
||||
return m_cppflags + m_cflags;
|
||||
}
|
||||
|
||||
QStringList MakefileParser::cxxflags() const
|
||||
{
|
||||
return m_cxxflags;
|
||||
return m_cppflags + m_cxxflags;
|
||||
}
|
||||
|
||||
void MakefileParser::cancel()
|
||||
@@ -443,9 +444,22 @@ QString MakefileParser::parseIdentifierBeforeAssign(const QString &line)
|
||||
QStringList MakefileParser::parseTermsAfterAssign(const QString &line)
|
||||
{
|
||||
int assignPos = line.indexOf(QLatin1Char('=')) + 1;
|
||||
if (assignPos >= line.size())
|
||||
if (assignPos <= 0 || assignPos >= line.size())
|
||||
return QStringList();
|
||||
return line.mid(assignPos).split(QLatin1Char(' '), QString::SkipEmptyParts);
|
||||
|
||||
const QStringList parts = Utils::QtcProcess::splitArgs(line.mid(assignPos));
|
||||
QStringList result;
|
||||
for (int i = 0; i < parts.count(); ++i) {
|
||||
const QString cur = parts.at(i);
|
||||
const QString next = (i == parts.count() - 1) ? QString() : parts.at(i + 1);
|
||||
if (cur == QLatin1String("-D") || cur == QLatin1String("-U") || cur == QLatin1String("-I")) {
|
||||
result << cur + next;
|
||||
++i;
|
||||
} else {
|
||||
result << cur;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool MakefileParser::maybeParseDefine(const QString &term)
|
||||
@@ -493,6 +507,15 @@ bool MakefileParser::maybeParseCXXFlag(const QString &term)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MakefileParser::maybeParseCPPFlag(const QString &term)
|
||||
{
|
||||
if (term.startsWith(QLatin1Char('-'))) {
|
||||
m_cppflags += term;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MakefileParser::addAllSources()
|
||||
{
|
||||
QStringList extensions;
|
||||
@@ -523,6 +546,12 @@ void MakefileParser::parseIncludePaths()
|
||||
QString line;
|
||||
do {
|
||||
line = textStream.readLine();
|
||||
while (line.endsWith(QLatin1Char('\\'))) {
|
||||
line.chop(1);
|
||||
QString next = textStream.readLine();
|
||||
line.append(next);
|
||||
}
|
||||
|
||||
const QString varName = parseIdentifierBeforeAssign(line);
|
||||
if (varName.isEmpty())
|
||||
continue;
|
||||
@@ -537,11 +566,14 @@ void MakefileParser::parseIncludePaths()
|
||||
foreach (const QString &term, parseTermsAfterAssign(line))
|
||||
maybeParseDefine(term) || maybeParseInclude(term, dirName)
|
||||
|| maybeParseCFlag(term);
|
||||
} else if (varName.endsWith(QLatin1String("CPPFLAGS"))
|
||||
|| varName.endsWith(QLatin1String("CXXFLAGS"))) {
|
||||
} else if (varName.endsWith(QLatin1String("CXXFLAGS"))) {
|
||||
foreach (const QString &term, parseTermsAfterAssign(line))
|
||||
maybeParseDefine(term) || maybeParseInclude(term, dirName)
|
||||
|| maybeParseCXXFlag(term);
|
||||
} else if (varName.endsWith(QLatin1String("CPPFLAGS"))) {
|
||||
foreach (const QString &term, parseTermsAfterAssign(line))
|
||||
maybeParseDefine(term) || maybeParseInclude(term, dirName)
|
||||
|| maybeParseCPPFlag(term);
|
||||
}
|
||||
} while (!line.isNull());
|
||||
|
||||
|
@@ -258,6 +258,11 @@ private:
|
||||
*/
|
||||
bool maybeParseCXXFlag(const QString &term);
|
||||
|
||||
/**
|
||||
* If term is compiler flag -<flag>, adds it to cppflags and returns true.
|
||||
*/
|
||||
bool maybeParseCPPFlag(const QString &term);
|
||||
|
||||
private:
|
||||
bool m_success; ///< Return value for MakefileParser::parse().
|
||||
|
||||
@@ -272,6 +277,7 @@ private:
|
||||
QByteArray m_defines; ///< Return value for MakefileParser::defines()
|
||||
QStringList m_cflags; ///< Return value for MakefileParser::cflags()
|
||||
QStringList m_cxxflags; ///< Return value for MakefileParser::cxxflags()
|
||||
QStringList m_cppflags; ///< The cpp flags, which will be part of both cflags and cxxflags
|
||||
|
||||
QString m_line; ///< Current line of the makefile
|
||||
QTextStream m_textStream; ///< Textstream that represents the makefile
|
||||
|
@@ -28,7 +28,6 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef CLANGEDITORDOCUMENTPARSER_H
|
||||
#define CLANGEDITORDOCUMENTPARSER_H
|
||||
|
||||
@@ -36,7 +35,6 @@
|
||||
|
||||
#include <cpptools/baseeditordocumentparser.h>
|
||||
|
||||
|
||||
namespace CppTools { class WorkingCopy; }
|
||||
|
||||
namespace ClangCodeModel {
|
||||
@@ -45,9 +43,6 @@ class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
typedef QSharedPointer<ClangEditorDocumentParser> Ptr;
|
||||
|
||||
public:
|
||||
ClangEditorDocumentParser(const QString &filePath);
|
||||
|
||||
@@ -59,8 +54,6 @@ public:
|
||||
|
||||
private:
|
||||
SemanticMarker::Ptr m_marker;
|
||||
QStringList m_options;
|
||||
Internal::UnsavedFiles m_unsavedFiles;
|
||||
};
|
||||
|
||||
} // namespace ClangCodeModel
|
||||
|
@@ -69,6 +69,10 @@ ModelManagerSupportClang::ModelManagerSupportClang()
|
||||
this, &ModelManagerSupportClang::onEditorOpened);
|
||||
|
||||
CppTools::CppModelManager *modelManager = cppModelManager();
|
||||
connect(modelManager, &CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
|
||||
this, &ModelManagerSupportClang::onAbstractEditorSupportContentsUpdated);
|
||||
connect(modelManager, &CppTools::CppModelManager::abstractEditorSupportRemoved,
|
||||
this, &ModelManagerSupportClang::onAbstractEditorSupportRemoved);
|
||||
connect(modelManager, &CppTools::CppModelManager::projectPartsUpdated,
|
||||
this, &ModelManagerSupportClang::onProjectPartsUpdated);
|
||||
connect(modelManager, &CppTools::CppModelManager::projectPartsRemoved,
|
||||
@@ -113,9 +117,8 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor)
|
||||
Core::IDocument *document = editor->document();
|
||||
QTC_ASSERT(document, return);
|
||||
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(document);
|
||||
QTC_ASSERT(textDocument, return);
|
||||
|
||||
if (cppModelManager()->isCppEditor(editor)) {
|
||||
if (textDocument && cppModelManager()->isCppEditor(editor)) {
|
||||
// Handle externally changed documents
|
||||
connect(textDocument, &Core::IDocument::reloadFinished,
|
||||
this, &ModelManagerSupportClang::onCppDocumentReloadFinished,
|
||||
|
@@ -615,6 +615,102 @@ bool hasSnippet(ProposalModel model, const QByteArray &text)
|
||||
return false;
|
||||
}
|
||||
|
||||
class MonitorGeneratedUiFile : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MonitorGeneratedUiFile();
|
||||
bool waitUntilGenerated(int timeout = 10000) const;
|
||||
|
||||
private:
|
||||
void onUiFileGenerated() { m_isGenerated = true; }
|
||||
|
||||
bool m_isGenerated = false;
|
||||
};
|
||||
|
||||
MonitorGeneratedUiFile::MonitorGeneratedUiFile()
|
||||
{
|
||||
connect(CppTools::CppModelManager::instance(),
|
||||
&CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
|
||||
this, &MonitorGeneratedUiFile::onUiFileGenerated);
|
||||
}
|
||||
|
||||
bool MonitorGeneratedUiFile::waitUntilGenerated(int timeout) const
|
||||
{
|
||||
if (m_isGenerated)
|
||||
return true;
|
||||
|
||||
QTime time;
|
||||
time.start();
|
||||
|
||||
forever {
|
||||
if (m_isGenerated)
|
||||
return true;
|
||||
|
||||
if (time.elapsed() > timeout)
|
||||
return false;
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
QThread::msleep(20);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class WriteFileAndWaitForReloadedDocument : public QObject
|
||||
{
|
||||
public:
|
||||
WriteFileAndWaitForReloadedDocument(const QString &filePath,
|
||||
const QByteArray &fileContents,
|
||||
Core::IDocument *document)
|
||||
: m_filePath(filePath)
|
||||
, m_fileContents(fileContents)
|
||||
{
|
||||
QTC_CHECK(document);
|
||||
connect(document, &Core::IDocument::reloadFinished,
|
||||
this, &WriteFileAndWaitForReloadedDocument::onReloadFinished);
|
||||
}
|
||||
|
||||
void onReloadFinished()
|
||||
{
|
||||
m_onReloadFinished = true;
|
||||
}
|
||||
|
||||
bool wait() const
|
||||
{
|
||||
QTC_ASSERT(writeFile(m_filePath, m_fileContents), return false);
|
||||
|
||||
QTime totalTime;
|
||||
totalTime.start();
|
||||
|
||||
QTime writeFileAgainTime;
|
||||
writeFileAgainTime.start();
|
||||
|
||||
forever {
|
||||
if (m_onReloadFinished)
|
||||
return true;
|
||||
|
||||
if (totalTime.elapsed() > 10000)
|
||||
return false;
|
||||
|
||||
if (writeFileAgainTime.elapsed() > 1000) {
|
||||
// The timestamp did not change, try again now.
|
||||
QTC_ASSERT(writeFile(m_filePath, m_fileContents), return false);
|
||||
writeFileAgainTime.restart();
|
||||
}
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
QThread::msleep(20);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_onReloadFinished = false;
|
||||
QString m_filePath;
|
||||
QByteArray m_fileContents;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace ClangCodeModel {
|
||||
@@ -866,11 +962,11 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileExt
|
||||
ProposalModel proposal = completionResults(openSource.editor());
|
||||
QVERIFY(hasItem(proposal, "globalFromHeader"));
|
||||
|
||||
// Simulate external modification
|
||||
QThread::sleep(1); // Ensures different time stamp and thus that the difference will be noticed
|
||||
QVERIFY(writeFile(headerDocument.filePath, "int globalFromHeaderReloaded;\n"));
|
||||
QSignalSpy waitForReloadedDocument(openHeader.editor()->document(),
|
||||
SIGNAL(reloadFinished(bool)));
|
||||
// Simulate external modification and wait for reload
|
||||
WriteFileAndWaitForReloadedDocument waitForReloadedDocument(
|
||||
headerDocument.filePath,
|
||||
"int globalFromHeaderReloaded;\n",
|
||||
openHeader.editor()->document());
|
||||
QVERIFY(waitForReloadedDocument.wait());
|
||||
|
||||
// Retrigger completion and check if its updated
|
||||
@@ -883,6 +979,8 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByCompletingUiObject()
|
||||
CppTools::Tests::TemporaryCopiedDir testDir(qrcPath("qt-widgets-app"));
|
||||
QVERIFY(testDir.isValid());
|
||||
|
||||
MonitorGeneratedUiFile monitorGeneratedUiFile;
|
||||
|
||||
// Open project
|
||||
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
|
||||
CppTools::Tests::ProjectOpenerAndCloser projectManager;
|
||||
@@ -897,11 +995,11 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByCompletingUiObject()
|
||||
QVERIFY(openSource.succeeded());
|
||||
|
||||
// ...and check comletions
|
||||
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
|
||||
ProposalModel proposal = completionResults(openSource.editor());
|
||||
QVERIFY(hasItem(proposal, "menuBar"));
|
||||
QVERIFY(hasItem(proposal, "statusBar"));
|
||||
QVERIFY(hasItem(proposal, "centralWidget"));
|
||||
QEXPECT_FAIL("", "Signals are not yet done", Abort);
|
||||
QVERIFY(hasItem(proposal, "setupUi"));
|
||||
}
|
||||
|
||||
@@ -921,6 +1019,7 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
|
||||
// ... and modify it, so we have an unsaved file.
|
||||
insertTextAtTopOfEditor(openHeader.editor(), "int someGlobal;\n");
|
||||
// Open project ...
|
||||
MonitorGeneratedUiFile monitorGeneratedUiFile;
|
||||
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
|
||||
CppTools::Tests::ProjectOpenerAndCloser projectManager;
|
||||
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
|
||||
@@ -931,6 +1030,7 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
|
||||
QVERIFY(testDocument.isCreatedAndHasValidCursorPosition());
|
||||
OpenEditorAtCursorPosition openSource(testDocument);
|
||||
QVERIFY(openSource.succeeded());
|
||||
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
|
||||
|
||||
// Check commands that would have been sent
|
||||
QVERIFY(compare(LogOutput(spy.senderLog),
|
||||
@@ -939,6 +1039,8 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
|
||||
" ProjectPartContainer id: qt-widgets-app.pro\n"
|
||||
"RegisterTranslationUnitForCodeCompletionCommand\n"
|
||||
" Path: myheader.h ProjectPart: \n"
|
||||
"RegisterTranslationUnitForCodeCompletionCommand\n"
|
||||
" Path: ui_mainwindow.h ProjectPart: \n"
|
||||
)));
|
||||
spy.senderLog.clear();
|
||||
|
||||
@@ -966,3 +1068,5 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
|
||||
} // namespace Tests
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
||||
|
||||
#include "clangcodecompletion_test.moc"
|
||||
|
@@ -53,6 +53,11 @@ void AbstractEditorSupport::updateDocument()
|
||||
m_modelmanager->updateSourceFiles(QSet<QString>() << fileName());
|
||||
}
|
||||
|
||||
void AbstractEditorSupport::notifyAboutUpdatedContents() const
|
||||
{
|
||||
m_modelmanager->emitAbstractEditorSupportContentsUpdated(fileName(), contents());
|
||||
}
|
||||
|
||||
QString AbstractEditorSupport::licenseTemplate(const QString &file, const QString &className)
|
||||
{
|
||||
return Internal::CppFileSettings::licenseTemplate(file, className);
|
||||
|
@@ -51,6 +51,7 @@ public:
|
||||
virtual QString fileName() const = 0;
|
||||
|
||||
void updateDocument();
|
||||
void notifyAboutUpdatedContents() const;
|
||||
unsigned revision() const { return m_revision; }
|
||||
|
||||
static QString licenseTemplate(const QString &file = QString(), const QString &className = QString());
|
||||
|
@@ -41,8 +41,6 @@ namespace CppTools {
|
||||
class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(BaseEditorDocumentParser)
|
||||
BaseEditorDocumentParser();
|
||||
|
||||
public:
|
||||
BaseEditorDocumentParser(const QString &filePath);
|
||||
|
@@ -49,8 +49,6 @@ namespace CppTools {
|
||||
class CPPTOOLS_EXPORT BaseEditorDocumentProcessor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(BaseEditorDocumentProcessor)
|
||||
BaseEditorDocumentProcessor();
|
||||
|
||||
public:
|
||||
BaseEditorDocumentProcessor(TextEditor::TextDocument *document);
|
||||
|
@@ -42,7 +42,6 @@ namespace CppTools {
|
||||
class CPPTOOLS_EXPORT BuiltinEditorDocumentProcessor : public BaseEditorDocumentProcessor
|
||||
{
|
||||
Q_OBJECT
|
||||
BuiltinEditorDocumentProcessor();
|
||||
|
||||
public:
|
||||
BuiltinEditorDocumentProcessor(TextEditor::TextDocument *document,
|
||||
|
@@ -51,7 +51,6 @@ namespace CppTools {
|
||||
class CPPTOOLS_EXPORT CppEditorOutline : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(CppEditorOutline)
|
||||
|
||||
public:
|
||||
explicit CppEditorOutline(TextEditor::TextEditorWidget *editorWidget);
|
||||
|
@@ -958,6 +958,17 @@ void CppModelManager::emitDocumentUpdated(Document::Ptr doc)
|
||||
emit documentUpdated(doc);
|
||||
}
|
||||
|
||||
void CppModelManager::emitAbstractEditorSupportContentsUpdated(const QString &filePath,
|
||||
const QByteArray &contents)
|
||||
{
|
||||
emit abstractEditorSupportContentsUpdated(filePath, contents);
|
||||
}
|
||||
|
||||
void CppModelManager::emitAbstractEditorSupportRemoved(const QString &filePath)
|
||||
{
|
||||
emit abstractEditorSupportRemoved(filePath);
|
||||
}
|
||||
|
||||
void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
|
||||
{
|
||||
QMutexLocker locker(&d->m_projectMutex);
|
||||
|
@@ -111,6 +111,9 @@ public:
|
||||
bool replaceDocument(Document::Ptr newDoc);
|
||||
|
||||
void emitDocumentUpdated(CPlusPlus::Document::Ptr doc);
|
||||
void emitAbstractEditorSupportContentsUpdated(const QString &filePath,
|
||||
const QByteArray &contents);
|
||||
void emitAbstractEditorSupportRemoved(const QString &filePath);
|
||||
|
||||
bool isCppEditor(Core::IEditor *editor) const;
|
||||
|
||||
@@ -173,6 +176,9 @@ signals:
|
||||
|
||||
void gcFinished(); // Needed for tests.
|
||||
|
||||
void abstractEditorSupportContentsUpdated(const QString &filePath, const QByteArray &contents);
|
||||
void abstractEditorSupportRemoved(const QString &filePath);
|
||||
|
||||
public slots:
|
||||
void updateModifiedSourceFiles();
|
||||
void GC();
|
||||
|
@@ -43,7 +43,6 @@ class SemanticInfoUpdaterPrivate;
|
||||
class SemanticInfoUpdater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(SemanticInfoUpdater)
|
||||
|
||||
public:
|
||||
explicit SemanticInfoUpdater();
|
||||
|
@@ -49,7 +49,6 @@ namespace CppTools {
|
||||
class CPPTOOLS_EXPORT SemanticHighlighter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(SemanticHighlighter)
|
||||
|
||||
public:
|
||||
enum Kind {
|
||||
|
@@ -145,16 +145,13 @@ QtcPlugin {
|
||||
name: "QML Debugger"
|
||||
prefix: "qml/"
|
||||
files: [
|
||||
"baseqmldebuggerclient.cpp", "baseqmldebuggerclient.h",
|
||||
"interactiveinterpreter.cpp", "interactiveinterpreter.h",
|
||||
"qmladapter.cpp", "qmladapter.h",
|
||||
"qmlcppengine.cpp", "qmlcppengine.h",
|
||||
"qmlengine.cpp", "qmlengine.h",
|
||||
"qmlengineutils.cpp", "qmlengineutils.h",
|
||||
"qmlinspectoradapter.cpp", "qmlinspectoradapter.h",
|
||||
"qmlinspectoragent.cpp", "qmlinspectoragent.h",
|
||||
"qmlv8debuggerclient.cpp", "qmlv8debuggerclient.h",
|
||||
"qmlv8debuggerclientconstants.h",
|
||||
"qscriptdebuggerclient.cpp", "qscriptdebuggerclient.h"
|
||||
"qmlv8debuggerclientconstants.h"
|
||||
]
|
||||
}
|
||||
|
||||
|
@@ -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
|
@@ -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
|
@@ -1,10 +1,7 @@
|
||||
HEADERS += \
|
||||
$$PWD/qmlengine.h \
|
||||
$$PWD/qmladapter.h \
|
||||
$$PWD/baseqmldebuggerclient.h \
|
||||
$$PWD/qmlengineutils.h \
|
||||
$$PWD/qmlcppengine.h \
|
||||
$$PWD/qscriptdebuggerclient.h \
|
||||
$$PWD/qmlv8debuggerclient.h \
|
||||
$$PWD/interactiveinterpreter.h \
|
||||
$$PWD/qmlv8debuggerclientconstants.h \
|
||||
$$PWD/qmlinspectoragent.h \
|
||||
@@ -12,11 +9,8 @@ HEADERS += \
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qmlengine.cpp \
|
||||
$$PWD/qmladapter.cpp \
|
||||
$$PWD/baseqmldebuggerclient.cpp \
|
||||
$$PWD/qmlengineutils.cpp \
|
||||
$$PWD/qmlcppengine.cpp \
|
||||
$$PWD/qscriptdebuggerclient.cpp \
|
||||
$$PWD/qmlv8debuggerclient.cpp \
|
||||
$$PWD/interactiveinterpreter.cpp \
|
||||
$$PWD/qmlinspectoragent.cpp \
|
||||
$$PWD/qmlinspectoradapter.cpp
|
||||
|
@@ -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
|
@@ -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
|
@@ -31,28 +31,21 @@
|
||||
#ifndef QMLENGINE_H
|
||||
#define QMLENGINE_H
|
||||
|
||||
#include "interactiveinterpreter.h"
|
||||
#include "qmladapter.h"
|
||||
#include "qmlinspectoradapter.h"
|
||||
#include <debugger/debuggerengine.h>
|
||||
|
||||
#include <projectexplorer/applicationlauncher.h>
|
||||
#include <qmldebug/qdebugmessageclient.h>
|
||||
#include <qmldebug/qmldebugclient.h>
|
||||
#include <qmldebug/qmloutputparser.h>
|
||||
#include <qmljs/iscriptevaluator.h>
|
||||
#include <qmljs/qmljsdocument.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QTextDocument)
|
||||
|
||||
namespace Core { class IDocument; }
|
||||
|
||||
namespace TextEditor { class BaseTextEditor; }
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class WatchData;
|
||||
class WatchItem;
|
||||
class QmlEnginePrivate;
|
||||
class QmlAdapter;
|
||||
class WatchTreeView;
|
||||
|
||||
class QmlEngine : public DebuggerEngine, QmlJS::IScriptEvaluator
|
||||
{
|
||||
@@ -63,31 +56,11 @@ public:
|
||||
DebuggerEngine *masterEngine = 0);
|
||||
~QmlEngine();
|
||||
|
||||
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
|
||||
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
|
||||
void filterApplicationMessage(const QString &msg, int channel) const;
|
||||
|
||||
bool canDisplayTooltip() const;
|
||||
|
||||
void showMessage(const QString &msg, int channel = LogDebug,
|
||||
int timeout = -1) const;
|
||||
void gotoLocation(const Internal::Location &location);
|
||||
|
||||
void filterApplicationMessage(const QString &msg, int channel);
|
||||
void inferiorSpontaneousStop();
|
||||
|
||||
enum LogDirection {
|
||||
LogSend,
|
||||
LogReceive
|
||||
};
|
||||
|
||||
void logMessage(const QString &service, LogDirection direction,
|
||||
const QString &str);
|
||||
|
||||
void setSourceFiles(const QStringList &fileNames);
|
||||
void updateScriptSource(const QString &fileName, int lineOffset,
|
||||
int columnOffset, const QString &source);
|
||||
|
||||
void insertBreakpoint(Breakpoint bp);
|
||||
void logServiceStateChange(const QString &service, float version,
|
||||
QmlDebug::QmlDebugClient::State newState);
|
||||
void logServiceActivity(const QString &service, const QString &logMessage);
|
||||
|
||||
private slots:
|
||||
void disconnected();
|
||||
@@ -96,23 +69,28 @@ private slots:
|
||||
|
||||
void errorMessageBoxFinished(int result);
|
||||
void updateCurrentContext();
|
||||
void appendDebugOutput(QtMsgType type, const QString &message,
|
||||
const QmlDebug::QDebugContextInfo &info);
|
||||
|
||||
void tryToConnect(quint16 port = 0);
|
||||
void beginConnection(quint16 port = 0);
|
||||
void connectionEstablished();
|
||||
void connectionStartupFailed();
|
||||
void appStartupFailed(const QString &errorMessage);
|
||||
void connectionError(QDebugSupport::Error error);
|
||||
void serviceConnectionError(const QString &service);
|
||||
void appendMessage(const QString &msg, Utils::OutputFormat);
|
||||
|
||||
void synchronizeWatchers();
|
||||
|
||||
private:
|
||||
// DebuggerEngine implementation.
|
||||
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
|
||||
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
|
||||
|
||||
void showMessage(const QString &msg, int channel = LogDebug,
|
||||
int timeout = -1) const;
|
||||
void gotoLocation(const Internal::Location &location);
|
||||
void insertBreakpoint(Breakpoint bp);
|
||||
|
||||
bool isSynchronous() const { return false; }
|
||||
bool canDisplayTooltip() const { return false; }
|
||||
|
||||
void executeStep();
|
||||
void executeStepOut();
|
||||
void executeNext();
|
||||
@@ -153,7 +131,6 @@ private:
|
||||
void reloadSourceFiles();
|
||||
void reloadFullStack() {}
|
||||
|
||||
bool supportsThreads() const { return false; }
|
||||
void updateWatchData(const QByteArray &iname);
|
||||
void selectWatchData(const QByteArray &iname);
|
||||
void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
|
||||
@@ -162,36 +139,21 @@ private:
|
||||
bool hasCapability(unsigned) const;
|
||||
void quitDebugger();
|
||||
|
||||
private:
|
||||
void closeConnection();
|
||||
void startApplicationLauncher();
|
||||
void stopApplicationLauncher();
|
||||
|
||||
bool isShadowBuildProject() const;
|
||||
QString fromShadowBuildFilename(const QString &filename) const;
|
||||
QString mangleFilenamePaths(const QString &filename,
|
||||
const QString &oldBasePath, const QString &newBasePath) const;
|
||||
QString qmlImportPath() const;
|
||||
|
||||
void updateDocument(Core::IDocument *document, const QTextDocument *textDocument);
|
||||
bool canEvaluateScript(const QString &script);
|
||||
bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line,
|
||||
quint32 *column, bool *valid);
|
||||
|
||||
QmlAdapter m_adapter;
|
||||
QmlInspectorAdapter m_inspectorAdapter;
|
||||
ProjectExplorer::ApplicationLauncher m_applicationLauncher;
|
||||
QTimer m_noDebugOutputTimer;
|
||||
QmlDebug::QmlOutputParser m_outputParser;
|
||||
QHash<QString, QTextDocument*> m_sourceDocuments;
|
||||
QHash<QString, QWeakPointer<TextEditor::BaseTextEditor> > m_sourceEditors;
|
||||
InteractiveInterpreter m_interpreter;
|
||||
QHash<QString,Breakpoint> pendingBreakpoints;
|
||||
QList<quint32> queryIds;
|
||||
bool m_retryOnConnectFail;
|
||||
bool m_automaticConnect;
|
||||
void connectionErrorOccurred(QDebugSupport::Error socketError);
|
||||
void clientStateChanged(QmlDebug::QmlDebugClient::State state);
|
||||
void checkConnectionState();
|
||||
void showConnectionStateMessage(const QString &message);
|
||||
void showConnectionErrorMessage(const QString &message);
|
||||
bool isConnected() const;
|
||||
|
||||
private:
|
||||
friend class QmlCppEngine;
|
||||
friend class QmlEnginePrivate;
|
||||
QmlEnginePrivate *d;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
311
src/plugins/debugger/qml/qmlengineutils.cpp
Normal 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
|
@@ -28,30 +28,22 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 1.1
|
||||
#ifndef QMLENGINEUTILS_H
|
||||
#define QMLENGINEUTILS_H
|
||||
|
||||
Rectangle {
|
||||
width: 640
|
||||
height: 480
|
||||
#include <qmldebug/qdebugmessageclient.h>
|
||||
#include <qmldebug/qmloutputparser.h>
|
||||
|
||||
Image {
|
||||
id: image1
|
||||
x: 20
|
||||
y: 18
|
||||
source: "images/qtcreator.png"
|
||||
}
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
Image {
|
||||
id: image2
|
||||
x: 327
|
||||
y: 18
|
||||
source: "images/qtcreator.jpg"
|
||||
}
|
||||
bool adjustBreakpointLineAndColumn(const QString &filePath, quint32 *line, quint32 *column, bool *valid);
|
||||
void appendDebugOutput(QtMsgType type, const QString &message, const QmlDebug::QDebugContextInfo &info);
|
||||
|
||||
Image {
|
||||
id: image3
|
||||
x: 20
|
||||
y: 288
|
||||
source: "images/qtcreator.ico"
|
||||
}
|
||||
}
|
||||
void clearExceptionSelection();
|
||||
QStringList highlightExceptionCode(int lineNumber, const QString &filePath, const QString &errorMessage);
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
#endif // QMLENGINEUTILS_H
|
@@ -30,8 +30,9 @@
|
||||
|
||||
#include "qmlinspectoradapter.h"
|
||||
|
||||
#include "qmladapter.h"
|
||||
#include "qmlengine.h"
|
||||
#include "qmlinspectoragent.h"
|
||||
|
||||
#include <debugger/debuggeractions.h>
|
||||
#include <debugger/debuggercore.h>
|
||||
#include <debugger/debuggerstringutils.h>
|
||||
@@ -60,15 +61,12 @@ namespace Internal {
|
||||
* QmlInspectorAdapter manages the clients for the inspector, and the
|
||||
* integration with the text editor.
|
||||
*/
|
||||
QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter,
|
||||
DebuggerEngine *engine,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_debugAdapter(debugAdapter)
|
||||
, m_engine(engine)
|
||||
QmlInspectorAdapter::QmlInspectorAdapter(QmlEngine *engine, QmlDebugConnection *connection)
|
||||
: m_qmlEngine(engine)
|
||||
, m_masterEngine(engine)
|
||||
, m_engineClient(0)
|
||||
, m_toolsClient(0)
|
||||
, m_agent(new QmlInspectorAgent(engine, this))
|
||||
, m_agent(new QmlInspectorAgent(engine))
|
||||
, m_targetToSync(NoTarget)
|
||||
, m_debugIdToSelect(-1)
|
||||
, m_currentSelectedDebugId(-1)
|
||||
@@ -79,16 +77,15 @@ QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter,
|
||||
, m_showAppOnTopAction(action(ShowAppOnTop))
|
||||
, m_engineClientConnected(false)
|
||||
{
|
||||
if (!m_engine->isMasterEngine())
|
||||
m_engine = m_engine->masterEngine();
|
||||
connect(m_engine, &DebuggerEngine::stateChanged,
|
||||
if (!m_masterEngine->isMasterEngine())
|
||||
m_masterEngine = m_masterEngine->masterEngine();
|
||||
connect(m_masterEngine, &DebuggerEngine::stateChanged,
|
||||
this, &QmlInspectorAdapter::onEngineStateChanged);
|
||||
connect(m_agent, &QmlInspectorAgent::objectFetched,
|
||||
this, &QmlInspectorAdapter::onObjectFetched);
|
||||
connect(m_agent, &QmlInspectorAgent::jumpToObjectDefinition,
|
||||
this, &QmlInspectorAdapter::jumpToObjectDefinitionInEditor);
|
||||
|
||||
QmlDebugConnection *connection = m_debugAdapter->connection();
|
||||
auto engineClient1 = new DeclarativeEngineDebugClient(connection);
|
||||
connect(engineClient1, &BaseEngineDebugClient::newState,
|
||||
this, &QmlInspectorAdapter::clientStateChanged);
|
||||
@@ -186,7 +183,7 @@ void QmlInspectorAdapter::clientStateChanged(QmlDebugClient::State state)
|
||||
version = client->remoteVersion();
|
||||
}
|
||||
|
||||
m_debugAdapter->logServiceStateChange(serviceName, version, state);
|
||||
m_qmlEngine->logServiceStateChange(serviceName, version, state);
|
||||
}
|
||||
|
||||
void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
|
||||
@@ -199,7 +196,7 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
|
||||
connect(client, &BaseToolsClient::currentObjectsChanged,
|
||||
this, &QmlInspectorAdapter::selectObjectsFromToolsClient);
|
||||
connect(client, &BaseToolsClient::logActivity,
|
||||
m_debugAdapter, &QmlAdapter::logServiceActivity);
|
||||
m_qmlEngine, &QmlEngine::logServiceActivity);
|
||||
connect(client, &BaseToolsClient::reloaded, this, &QmlInspectorAdapter::onReloaded);
|
||||
|
||||
// register actions here
|
||||
@@ -217,15 +214,15 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state)
|
||||
Core::ICore::addAdditionalContext(m_inspectorToolsContext);
|
||||
|
||||
m_toolsClientConnected = true;
|
||||
onEngineStateChanged(m_engine->state());
|
||||
onEngineStateChanged(m_masterEngine->state());
|
||||
if (m_showAppOnTopAction->isChecked())
|
||||
m_toolsClient->showAppOnTop(true);
|
||||
|
||||
} else if (m_toolsClientConnected && client == m_toolsClient) {
|
||||
disconnect(client, SIGNAL(currentObjectsChanged(QList<int>)),
|
||||
this, SLOT(selectObjectsFromToolsClient(QList<int>)));
|
||||
disconnect(client, SIGNAL(logActivity(QString,QString)),
|
||||
m_debugAdapter, SLOT(logServiceActivity(QString,QString)));
|
||||
disconnect(client, &BaseToolsClient::currentObjectsChanged,
|
||||
this, &QmlInspectorAdapter::selectObjectsFromToolsClient);
|
||||
disconnect(client, &BaseToolsClient::logActivity,
|
||||
m_qmlEngine, &QmlEngine::logServiceActivity);
|
||||
|
||||
Core::ActionManager::unregisterAction(m_selectAction, Core::Id(Constants::QML_SELECTTOOL));
|
||||
Core::ActionManager::unregisterAction(m_zoomAction, Core::Id(Constants::QML_ZOOMTOOL));
|
||||
@@ -316,13 +313,13 @@ void QmlInspectorAdapter::setActiveEngineClient(BaseEngineDebugClient *client)
|
||||
|
||||
void QmlInspectorAdapter::showConnectionStateMessage(const QString &message)
|
||||
{
|
||||
m_engine->showMessage(_("QML Inspector: ") + message, LogStatus);
|
||||
m_masterEngine->showMessage(_("QML Inspector: ") + message, LogStatus);
|
||||
}
|
||||
|
||||
void QmlInspectorAdapter::jumpToObjectDefinitionInEditor(
|
||||
const FileReference &objSource, int debugId)
|
||||
{
|
||||
const QString fileName = m_engine->toFileInProject(objSource.url());
|
||||
const QString fileName = m_masterEngine->toFileInProject(objSource.url());
|
||||
|
||||
Core::EditorManager::openEditorAt(fileName, objSource.lineNumber());
|
||||
if (debugId != -1 && debugId != m_currentSelectedDebugId) {
|
||||
|
@@ -41,13 +41,14 @@ class BaseEngineDebugClient;
|
||||
class BaseToolsClient;
|
||||
class ObjectReference;
|
||||
class FileReference;
|
||||
class QmlDebugConnection;
|
||||
}
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class DebuggerEngine;
|
||||
class QmlAdapter;
|
||||
class QmlEngine;
|
||||
class QmlInspectorAgent;
|
||||
|
||||
class QmlInspectorAdapter : public QObject
|
||||
@@ -55,8 +56,7 @@ class QmlInspectorAdapter : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QmlInspectorAdapter(QmlAdapter *debugAdapter, DebuggerEngine *engine,
|
||||
QObject *parent = 0);
|
||||
QmlInspectorAdapter(QmlEngine *engine, QmlDebug::QmlDebugConnection *connection);
|
||||
~QmlInspectorAdapter();
|
||||
|
||||
QmlDebug::BaseEngineDebugClient *engineClient() const;
|
||||
@@ -96,8 +96,8 @@ private:
|
||||
|
||||
void enableTools(const bool enable);
|
||||
|
||||
QmlAdapter *m_debugAdapter;
|
||||
DebuggerEngine *m_engine; // Master Engine
|
||||
QmlEngine *m_qmlEngine;
|
||||
DebuggerEngine *m_masterEngine;
|
||||
QmlDebug::BaseEngineDebugClient *m_engineClient;
|
||||
QHash<QString, QmlDebug::BaseEngineDebugClient*> m_engineClients;
|
||||
QmlDebug::BaseToolsClient *m_toolsClient;
|
||||
|
@@ -686,6 +686,7 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object)
|
||||
m_objectToSelect = -1;
|
||||
}
|
||||
m_debuggerEngine->watchHandler()->updateWatchersWindow();
|
||||
m_debuggerEngine->watchHandler()->reexpandItems();
|
||||
}
|
||||
|
||||
void QmlInspectorAgent::buildDebugIdHashRecursive(const ObjectReference &ref)
|
||||
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -1268,6 +1268,11 @@ void WatchHandler::notifyUpdateFinished()
|
||||
emit m_model->updateFinished();
|
||||
}
|
||||
|
||||
void WatchHandler::reexpandItems()
|
||||
{
|
||||
m_model->reexpandItems();
|
||||
}
|
||||
|
||||
void WatchHandler::removeItemByIName(const QByteArray &iname)
|
||||
{
|
||||
WatchItem *item = m_model->findItem(iname);
|
||||
|
@@ -201,6 +201,8 @@ public:
|
||||
void notifyUpdateStarted(const QList<QByteArray> &inames = {});
|
||||
void notifyUpdateFinished();
|
||||
|
||||
void reexpandItems();
|
||||
|
||||
private:
|
||||
WatchModel *m_model; // Owned.
|
||||
};
|
||||
|
@@ -820,13 +820,15 @@ void JsonFieldPage::ComboBoxField::initializeData(MacroExpander *expander)
|
||||
if (!tmpConditions.at(i)) {
|
||||
tmpItems.removeAt(i);
|
||||
tmpData.removeAt(i);
|
||||
if (i <= index)
|
||||
if (i < index && index > 0)
|
||||
--index;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < 0 || index >= tmpData.count())
|
||||
index = 0;
|
||||
w->setItems(tmpItems, tmpData);
|
||||
w->setInsertPolicy(QComboBox::NoInsert);
|
||||
|
||||
w->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
|
@@ -797,8 +797,6 @@ void QbsProject::updateCppCodeModel()
|
||||
}
|
||||
}
|
||||
|
||||
if (pinfo.projectParts().isEmpty())
|
||||
return;
|
||||
pinfo.finish();
|
||||
|
||||
QtSupport::UiCodeModelManager::update(this, uiFiles);
|
||||
|
@@ -473,6 +473,7 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const
|
||||
|
||||
static QDir resourcesDir(QStringLiteral(":/propertyEditorQmlSources"));
|
||||
QDir importDir(info.importDirectoryPath() + QLatin1String(Constants::QML_DESIGNER_SUBFOLDER));
|
||||
QDir importDirVersion(info.importDirectoryPath() + QStringLiteral(".") + QString::number(info.majorVersion()) + QLatin1String(Constants::QML_DESIGNER_SUBFOLDER));
|
||||
|
||||
const QString versionString = QStringLiteral("_") + QString::number(info.majorVersion())
|
||||
+ QStringLiteral("_")
|
||||
@@ -484,6 +485,14 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const
|
||||
|
||||
//Check for qml files with versions first
|
||||
const QString withoutDirWithVersion = relativePathWithVersion.split(QStringLiteral("/")).last();
|
||||
|
||||
const QString withoutDir = relativePath.split(QStringLiteral("/")).last();
|
||||
|
||||
if (importDirVersion.exists(withoutDir))
|
||||
return importDirVersion.absoluteFilePath(withoutDir);
|
||||
|
||||
|
||||
|
||||
if (importDir.exists(relativePathWithVersion))
|
||||
return importDir.absoluteFilePath(relativePathWithVersion);
|
||||
if (importDir.exists(withoutDirWithVersion)) //Since we are in a subfolder of the import we do not require the directory
|
||||
@@ -493,7 +502,7 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const
|
||||
if (resourcesDir.exists(relativePathWithVersion))
|
||||
return resourcesDir.absoluteFilePath(relativePathWithVersion);
|
||||
|
||||
const QString withoutDir = relativePath.split(QStringLiteral("/")).last();
|
||||
|
||||
if (importDir.exists(relativePath))
|
||||
return importDir.absoluteFilePath(relativePath);
|
||||
if (importDir.exists(withoutDir)) //Since we are in a subfolder of the import we do not require the directory
|
||||
|
@@ -209,6 +209,15 @@ void SubComponentManager::parseDirectories()
|
||||
foreach (const QString &path, importPaths()) {
|
||||
QString fullUrl = path + QLatin1Char('/') + url;
|
||||
dirInfo = QFileInfo(fullUrl);
|
||||
|
||||
if (dirInfo.exists() && dirInfo.isDir()) {
|
||||
//### todo full qualified names QString nameSpace = import.uri();
|
||||
parseDirectory(dirInfo.canonicalFilePath(), false);
|
||||
}
|
||||
|
||||
QString fullUrlVersion = path + QLatin1Char('/') + url + QLatin1Char('.') + import.version().split(".").first();
|
||||
dirInfo = QFileInfo(fullUrlVersion);
|
||||
|
||||
if (dirInfo.exists() && dirInfo.isDir()) {
|
||||
//### todo full qualified names QString nameSpace = import.uri();
|
||||
parseDirectory(dirInfo.canonicalFilePath(), false);
|
||||
|
@@ -47,8 +47,7 @@
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
|
||||
enum { debug = 0 };
|
||||
#include <QLoggingCategory>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace CPlusPlus;
|
||||
@@ -79,20 +78,26 @@ UiCodeModelSupport::UiCodeModelSupport(CppTools::CppModelManager *modelmanager,
|
||||
m_headerFileName(uiHeaderFile),
|
||||
m_state(BARE)
|
||||
{
|
||||
if (debug)
|
||||
qDebug()<<"ctor UiCodeModelSupport for"<<m_uiFileName<<uiHeaderFile;
|
||||
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
|
||||
qCDebug(log) << "ctor UiCodeModelSupport for" << m_uiFileName << uiHeaderFile;
|
||||
connect(&m_process, SIGNAL(finished(int)),
|
||||
this, SLOT(finishProcess()));
|
||||
init();
|
||||
}
|
||||
|
||||
UiCodeModelSupport::~UiCodeModelSupport()
|
||||
{
|
||||
if (debug)
|
||||
qDebug()<<"dtor ~UiCodeModelSupport for"<<m_uiFileName;
|
||||
disconnect(&m_process, SIGNAL(finished(int)),
|
||||
this, SLOT(finishProcess()));
|
||||
m_process.kill();
|
||||
CppTools::CppModelManager::instance()->emitAbstractEditorSupportRemoved(m_headerFileName);
|
||||
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
|
||||
qCDebug(log) << "dtor ~UiCodeModelSupport for" << m_uiFileName;
|
||||
}
|
||||
|
||||
void UiCodeModelSupport::init() const
|
||||
{
|
||||
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
|
||||
if (m_state != BARE)
|
||||
return;
|
||||
QDateTime sourceTime = QFileInfo(m_uiFileName).lastModified();
|
||||
@@ -101,53 +106,43 @@ void UiCodeModelSupport::init() const
|
||||
if (uiHeaderTime.isValid() && (uiHeaderTime > sourceTime)) {
|
||||
QFile file(m_headerFileName);
|
||||
if (file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
if (debug)
|
||||
qDebug()<<"ui*h file is more recent then source file, using information from ui*h file"<<m_headerFileName;
|
||||
qCDebug(log) << "init: ui*h file is more recent then source file, using information from ui*h file" << m_headerFileName;
|
||||
QTextStream stream(&file);
|
||||
m_contents = stream.readAll().toUtf8();
|
||||
m_cacheTime = uiHeaderTime;
|
||||
m_state = FINISHED;
|
||||
notifyAboutUpdatedContents();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
qDebug()<<"ui*h file not found, or not recent enough, trying to create it on the fly";
|
||||
qCDebug(log) << "ui*h file not found, or not recent enough, trying to create it on the fly";
|
||||
QFile file(m_uiFileName);
|
||||
if (file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QTextStream stream(&file);
|
||||
const QString contents = stream.readAll();
|
||||
if (runUic(contents)) {
|
||||
if (debug)
|
||||
qDebug()<<"created on the fly";
|
||||
qCDebug(log) << "created on the fly";
|
||||
return;
|
||||
} else {
|
||||
// uic run was unsuccesfull
|
||||
if (debug)
|
||||
qDebug()<<"uic run wasn't succesfull";
|
||||
qCDebug(log) << "uic run wasn't succesfull";
|
||||
m_cacheTime = QDateTime ();
|
||||
m_contents.clear();
|
||||
m_state = FINISHED;
|
||||
notifyAboutUpdatedContents();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (debug)
|
||||
qDebug()<<"Could open "<<m_uiFileName<<"needed for the cpp model";
|
||||
qCDebug(log) << "Could not open " << m_uiFileName << "needed for the cpp model";
|
||||
m_contents.clear();
|
||||
m_state = FINISHED;
|
||||
notifyAboutUpdatedContents();
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray UiCodeModelSupport::contents() const
|
||||
{
|
||||
// Check the common case first
|
||||
if (m_state == FINISHED)
|
||||
return m_contents;
|
||||
if (m_state == BARE)
|
||||
init();
|
||||
if (m_state == RUNNING)
|
||||
finishProcess();
|
||||
|
||||
return m_contents;
|
||||
}
|
||||
|
||||
@@ -166,16 +161,20 @@ void UiCodeModelSupport::setHeaderFileName(const QString &name)
|
||||
if (m_headerFileName == name && m_cacheTime.isValid())
|
||||
return;
|
||||
|
||||
if (m_state == RUNNING)
|
||||
finishProcess();
|
||||
if (m_state == RUNNING) {
|
||||
m_state = ABORTING;
|
||||
m_process.kill();
|
||||
m_process.waitForFinished(3000);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
qDebug() << "UiCodeModelSupport::setFileName"<<name;
|
||||
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
|
||||
qCDebug(log) << "UiCodeModelSupport::setFileName" << name;
|
||||
|
||||
m_headerFileName = name;
|
||||
m_contents.clear();
|
||||
m_cacheTime = QDateTime();
|
||||
m_state = BARE;
|
||||
init();
|
||||
}
|
||||
|
||||
bool UiCodeModelSupport::runUic(const QString &ui) const
|
||||
@@ -183,10 +182,10 @@ bool UiCodeModelSupport::runUic(const QString &ui) const
|
||||
const QString uic = uicCommand();
|
||||
if (uic.isEmpty())
|
||||
return false;
|
||||
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
|
||||
m_process.setEnvironment(environment());
|
||||
|
||||
if (debug)
|
||||
qDebug() << "UiCodeModelSupport::runUic " << uic << " on " << ui.size() << " bytes";
|
||||
qCDebug(log) << " UiCodeModelSupport::runUic " << uic << " on " << ui.size() << " bytes";
|
||||
m_process.start(uic, QStringList(), QIODevice::ReadWrite);
|
||||
if (!m_process.waitForStarted())
|
||||
return false;
|
||||
@@ -198,8 +197,7 @@ bool UiCodeModelSupport::runUic(const QString &ui) const
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (debug)
|
||||
qDebug() << "failed" << m_process.readAllStandardError();
|
||||
qCDebug(log) << "failed" << m_process.readAllStandardError();
|
||||
m_process.kill();
|
||||
m_state = FINISHED;
|
||||
return false;
|
||||
@@ -207,29 +205,26 @@ error:
|
||||
|
||||
void UiCodeModelSupport::updateFromEditor(const QString &formEditorContents)
|
||||
{
|
||||
if (m_state == BARE)
|
||||
init();
|
||||
if (m_state == RUNNING)
|
||||
finishProcess();
|
||||
if (runUic(formEditorContents))
|
||||
if (finishProcess())
|
||||
updateDocument();
|
||||
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
|
||||
qCDebug(log) << "updating from editor" << m_uiFileName;
|
||||
if (m_state == RUNNING) {
|
||||
m_state = ABORTING;
|
||||
m_process.kill();
|
||||
m_process.waitForFinished(3000);
|
||||
}
|
||||
runUic(formEditorContents);
|
||||
}
|
||||
|
||||
void UiCodeModelSupport::updateFromBuild()
|
||||
{
|
||||
if (debug)
|
||||
qDebug()<<"UiCodeModelSupport::updateFromBuild() for file"<<m_uiFileName;
|
||||
if (m_state == BARE)
|
||||
init();
|
||||
if (m_state == RUNNING)
|
||||
finishProcess();
|
||||
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
|
||||
qCDebug(log) << "UiCodeModelSupport::updateFromBuild() for " << m_uiFileName;
|
||||
|
||||
// This is mostly a fall back for the cases when uic couldn't be run
|
||||
// it pays special attention to the case where a ui_*h was newly created
|
||||
QDateTime sourceTime = QFileInfo(m_uiFileName).lastModified();
|
||||
if (m_cacheTime.isValid() && m_cacheTime >= sourceTime) {
|
||||
if (debug)
|
||||
qDebug()<<"Cache is still more recent then source";
|
||||
qCDebug(log) << "Cache is still more recent then source";
|
||||
return;
|
||||
} else {
|
||||
QFileInfo fi(m_headerFileName);
|
||||
@@ -237,20 +232,19 @@ void UiCodeModelSupport::updateFromBuild()
|
||||
if (uiHeaderTime.isValid() && (uiHeaderTime > sourceTime)) {
|
||||
if (m_cacheTime >= uiHeaderTime)
|
||||
return;
|
||||
if (debug)
|
||||
qDebug()<<"found ui*h updating from it";
|
||||
qCDebug(log) << "found ui*h updating from it";
|
||||
|
||||
QFile file(m_headerFileName);
|
||||
if (file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QTextStream stream(&file);
|
||||
m_contents = stream.readAll().toUtf8();
|
||||
m_cacheTime = uiHeaderTime;
|
||||
notifyAboutUpdatedContents();
|
||||
updateDocument();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (debug)
|
||||
qDebug()<<"ui*h not found or not more recent then source not changing anything";
|
||||
qCDebug(log) << "ui*h not found or not more recent then source not changing anything";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,34 +273,30 @@ QStringList UiCodeModelSupport::environment() const
|
||||
}
|
||||
}
|
||||
|
||||
bool UiCodeModelSupport::finishProcess() const
|
||||
bool UiCodeModelSupport::finishProcess()
|
||||
{
|
||||
if (m_state != RUNNING)
|
||||
return false;
|
||||
QLoggingCategory log("qtc.qtsupport.uicodemodelsupport");
|
||||
if (!m_process.waitForFinished(3000)
|
||||
&& m_process.exitStatus() != QProcess::NormalExit
|
||||
&& m_process.exitCode() != 0) {
|
||||
if (m_state != RUNNING) // waitForFinished can recurse into finishProcess
|
||||
return false;
|
||||
|
||||
if (debug)
|
||||
qDebug() << "failed" << m_process.readAllStandardError();
|
||||
qCDebug(log) << "finish process: failed" << m_process.readAllStandardError();
|
||||
m_process.kill();
|
||||
m_state = FINISHED;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_state != RUNNING) // waitForFinished can recurse into finishProcess
|
||||
return true;
|
||||
|
||||
// As far as I can discover in the UIC sources, it writes out local 8-bit encoding. The
|
||||
// conversion below is to normalize both the encoding, and the line terminators.
|
||||
QString normalized = QString::fromLocal8Bit(m_process.readAllStandardOutput());
|
||||
m_contents = normalized.toUtf8();
|
||||
m_cacheTime = QDateTime::currentDateTime();
|
||||
if (debug)
|
||||
qDebug() << "ok" << m_contents.size() << "bytes.";
|
||||
qCDebug(log) << "finish process: ok" << m_contents.size() << "bytes.";
|
||||
m_state = FINISHED;
|
||||
notifyAboutUpdatedContents();
|
||||
updateDocument();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -73,11 +73,11 @@ private:
|
||||
QStringList environment() const;
|
||||
|
||||
private slots:
|
||||
bool finishProcess() const;
|
||||
bool finishProcess();
|
||||
|
||||
private:
|
||||
ProjectExplorer::Project *m_project;
|
||||
enum State { BARE, RUNNING, FINISHED };
|
||||
enum State { BARE, RUNNING, FINISHED, ABORTING };
|
||||
|
||||
void init() const;
|
||||
bool runUic(const QString &ui) const;
|
||||
|
@@ -2962,6 +2962,14 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check4("url1.d.fragment", "\"\"", "@QString");
|
||||
|
||||
|
||||
QTest::newRow("QUuid")
|
||||
<< Data("#include <QUuid>",
|
||||
"QUuid uuid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);\n"
|
||||
"unused(&uuid);\n")
|
||||
+ CoreProfile()
|
||||
+ Check("uuid", "{00000001-0002-0003-0405-060708090a0b}", "@QUuid");
|
||||
|
||||
|
||||
QByteArray expected1 = "\"AAA";
|
||||
expected1.append(char('\t'));
|
||||
expected1.append(char('\r'));
|
||||
|
@@ -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"
|
||||
}
|
@@ -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
|
||||
}
|
@@ -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"
|
||||
}
|
||||
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 12 KiB |
@@ -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"
|
||||
}
|
||||
|
||||
}
|
@@ -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 }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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 }
|
||||
}
|
@@ -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: "."
|
||||
}
|
||||
}
|
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
@@ -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>"
|
||||
}
|
@@ -105,7 +105,7 @@
|
||||
:Hits_QCLuceneResultWidget {aboveWidget=':Hits_QLabel' type='QCLuceneResultWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Hits_QLabel {text~='\\\\d+ - \\\\d+ of \\\\d+ Hits' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:JavaScript.QmlProfilerEventsTable_QmlProfiler::Internal::QV8ProfilerEventsMainView {container=':*Qt Creator.JavaScript_QDockWidget' name='QmlProfilerEventsTable' type='QmlProfiler::Internal::QV8ProfilerEventsMainView' visible='1'}
|
||||
:Kits_QtVersion_QComboBox {container=':qt_tabwidget_stackedwidget_QWidget' occurrence='5' type='QComboBox' unnamed='1' visible='1'}
|
||||
:Kits_QtVersion_QComboBox {container=':qt_tabwidget_stackedwidget_QWidget' leftWidget=':QtVersionLabel_KitPage' type='QComboBox' unnamed='1' visible='1'}
|
||||
:Locals and Expressions_Debugger::Internal::WatchTreeView {container=':DebugModeWidget.Locals and Expressions_QDockWidget' name='WatchWindow' type='Debugger::Internal::WatchTreeView' visible='1' windowTitle='Locals and Expressions'}
|
||||
:Minimal required Qt version:_QLabel {text='Minimal required Qt version:' type='QLabel' unnamed='1' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
|
||||
:New Text File.Add to project:_QLabel {name='projectLabel' text='Add to project:' type='QLabel' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
|
||||
@@ -182,6 +182,7 @@
|
||||
:QtSupport__Internal__QtVersionManager.errorLabel.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='errorLabel' type='QLabel' visible='1'}
|
||||
:QtSupport__Internal__QtVersionManager.qmake_QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qmakePath' type='QLabel' visible='1'}
|
||||
:QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qtdirList' type='QTreeWidget' visible='1'}
|
||||
:QtVersionLabel_KitPage {container=':qt_tabwidget_stackedwidget_QWidget' text='Qt version:' type='QLabel' unnamed='1' visible='1'}
|
||||
:Restart required.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Restart required_QMessageBox'}
|
||||
:Restart required_QMessageBox {text='The language change will take effect after a restart of Qt Creator.' type='QMessageBox' unnamed='1' visible='1'}
|
||||
:Revert to Saved.Proceed_QPushButton {text='Proceed' type='QPushButton' unnamed='1' visible='1' window=':Revert to Saved_QMessageBox'}
|
||||
|
@@ -270,26 +270,39 @@ def createProject_Qt_Console(path, projectName, checks = True):
|
||||
|
||||
def createNewQtQuickApplication(workingDir, projectName = None,
|
||||
targets=Targets.desktopTargetClasses(), minimumQtVersion="5.3",
|
||||
fromWelcome=False):
|
||||
available = __createProjectOrFileSelectType__(" Application", "Qt Quick Application", fromWelcome)
|
||||
withControls = False, fromWelcome=False):
|
||||
if withControls:
|
||||
template = "Qt Quick Controls Application"
|
||||
else:
|
||||
template = "Qt Quick Application"
|
||||
available = __createProjectOrFileSelectType__(" Application", template, fromWelcome)
|
||||
projectName = __createProjectSetNameAndPath__(workingDir, projectName)
|
||||
requiredQt = __createProjectHandleQtQuickSelection__(minimumQtVersion)
|
||||
__modifyAvailableTargets__(available, requiredQt)
|
||||
checkedTargets = __chooseTargets__(targets, available)
|
||||
snooze(1)
|
||||
if len(checkedTargets):
|
||||
clickButton(waitForObject(":Next_QPushButton"))
|
||||
__createProjectHandleLastPage__()
|
||||
|
||||
progressBarWait(10000)
|
||||
else:
|
||||
clickButton(waitForObject("{type='QPushButton' text='Cancel' visible='1'}"))
|
||||
|
||||
return checkedTargets, projectName
|
||||
|
||||
def createNewQtQuickUI(workingDir, qtQuickVersion="1.1"):
|
||||
__createProjectOrFileSelectType__(" Application", "Qt Quick UI")
|
||||
def createNewQtQuickUI(workingDir, qtVersion = "5.3", withControls = False):
|
||||
if withControls:
|
||||
template = 'Qt Quick Controls UI'
|
||||
else:
|
||||
template = 'Qt Quick UI'
|
||||
__createProjectOrFileSelectType__(" Other Project", template)
|
||||
if workingDir == None:
|
||||
workingDir = tempDir()
|
||||
projectName = __createProjectSetNameAndPath__(workingDir)
|
||||
__createProjectHandleQtQuickSelection__(qtQuickVersion)
|
||||
__createProjectHandleQtQuickSelection__(qtVersion)
|
||||
__createProjectHandleLastPage__()
|
||||
progressBarWait(10000)
|
||||
|
||||
return projectName
|
||||
|
||||
def createNewQmlExtension(workingDir, targets=Targets.DESKTOP_474_GCC, qtQuickVersion=1):
|
||||
|
@@ -217,19 +217,15 @@ def __selectTreeItemOnBuildAndRun__(treeViewOrWidget, itemText, isRegex=False):
|
||||
test.compare(manual.data().toString(), "Manual", "Verifying label for section")
|
||||
if isRegex:
|
||||
pattern = re.compile(itemText)
|
||||
found = False
|
||||
for section in [autoDetected, manual]:
|
||||
for dumpedItem in dumpItems(model, section):
|
||||
if (isRegex and pattern.match(dumpedItem)
|
||||
or itemText == dumpedItem):
|
||||
found = True
|
||||
item = ".".join([str(section.data().toString()),
|
||||
dumpedItem.replace(".", "\\.").replace("_", "\\_")])
|
||||
clickItem(treeViewOrWidget, item, 5, 5, 0, Qt.LeftButton)
|
||||
break
|
||||
if found:
|
||||
break
|
||||
return found
|
||||
return True
|
||||
return False
|
||||
|
||||
def __getTargetFromToolTip__(toolTip):
|
||||
if toolTip == None or not isinstance(toolTip, (str, unicode)):
|
||||
|
@@ -123,7 +123,7 @@ def main():
|
||||
return
|
||||
qmlProjFile = os.path.join(qmlProjDir, projName)
|
||||
# start Creator by passing a .qmlproject file
|
||||
startApplication('qtcreator -load QmlProjectManager' + SettingsPath + ' "%s"' % qmlProjFile)
|
||||
startApplication('qtcreator' + SettingsPath + ' "%s"' % qmlProjFile)
|
||||
if not startedWithoutPluginError():
|
||||
return
|
||||
|
||||
@@ -142,10 +142,6 @@ def main():
|
||||
rootIndex = getQModelIndexStr("text='Rectangle'",
|
||||
":Locals and Expressions_Debugger::Internal::WatchTreeView")
|
||||
# make sure the items inside the root item are visible
|
||||
if JIRA.isBugStillOpen(14210):
|
||||
doubleClick(waitForObject(rootIndex))
|
||||
else:
|
||||
test.warning("QTCREATORBUG-14210 is not open anymore. Can the workaround be removed?")
|
||||
doubleClick(waitForObject(rootIndex))
|
||||
if not object.exists(":DebugModeWidget_QmlJSTools::Internal::QmlConsoleView"):
|
||||
invokeMenuItem("Window", "Output Panes", "QML/JS Console")
|
||||
@@ -156,14 +152,14 @@ def main():
|
||||
("color ='silver'", "silver", "color", u"#\u200bc0c0c0"),
|
||||
("width=66", "66", "width"), ("anchors.centerIn", "<unnamed object>"),
|
||||
("opacity", "1"), ("opacity = .2", u"0.\u200b2", "opacity")]
|
||||
# check green inner Rectangle
|
||||
runChecks("text='Rectangle'", rootIndex, checks)
|
||||
# check red inner Rectangle
|
||||
runChecks("text='Rectangle' occurrence='2'", rootIndex, checks)
|
||||
|
||||
checks = [("color", u"#\u200bff0000"), ("width", "100"), ("height", "100"),
|
||||
("radius = Math.min(width, height) / 2", "50", "radius"),
|
||||
("parent.objectName= 'mainRect'", "mainRect")]
|
||||
# check red inner Rectangle
|
||||
runChecks("text='Rectangle' occurrence='2'", rootIndex, checks)
|
||||
# check green inner Rectangle
|
||||
runChecks("text='Rectangle'", rootIndex, checks)
|
||||
|
||||
checks = [("color", u"#\u200b000000"), ("font.pointSize=14", "14", "font.pointSize"),
|
||||
("font.bold", "false"), ("font.weight=Font.Bold", "75", "font.bold", "true"),
|
||||
|
@@ -45,7 +45,7 @@ def main():
|
||||
return
|
||||
qmlProjFile = os.path.join(qmlProjDir, projName)
|
||||
# start Creator by passing a .qmlproject file
|
||||
startApplication('qtcreator -load QmlProjectManager' + SettingsPath + ' "%s"' % qmlProjFile)
|
||||
startApplication('qtcreator' + SettingsPath + ' "%s"' % qmlProjFile)
|
||||
if not startedWithoutPluginError():
|
||||
return
|
||||
waitFor('object.exists(":Qt Creator_Utils::NavigationTreeView")', 10000)
|
||||
@@ -91,8 +91,8 @@ def main():
|
||||
checkForEmptyRows(items)
|
||||
check = [[None, 0, {"Properties":1, "Rectangle":2, "Text":1}, {"width":"360", "height":"360"}],
|
||||
["Text", 1, {"Properties":1}, {"text":"Check"}],
|
||||
["Rectangle", 1, {"Properties":1}, {"width":"50", "height":"50", "color":"#008000"}],
|
||||
["Rectangle", 2, {"Properties":1}, {"width":"100", "height":"100", "color":"#ff0000"}]
|
||||
["Rectangle", 2, {"Properties":1}, {"width":"50", "height":"50", "color":"#008000"}],
|
||||
["Rectangle", 1, {"Properties":1}, {"width":"100", "height":"100", "color":"#ff0000"}]
|
||||
]
|
||||
for current in check:
|
||||
if current[0]:
|
||||
@@ -108,23 +108,19 @@ def main():
|
||||
def __unfoldTree__():
|
||||
rootIndex = getQModelIndexStr("text='Rectangle'",
|
||||
':Locals and Expressions_Debugger::Internal::WatchTreeView')
|
||||
if JIRA.isBugStillOpen(14210):
|
||||
doubleClick(waitForObject(rootIndex))
|
||||
else:
|
||||
test.warning("QTCREATORBUG-14210 is not open anymore. Can the workaround be removed?")
|
||||
unfoldQModelIndexIncludingProperties(rootIndex)
|
||||
if JIRA.isBugStillOpen(14210):
|
||||
for item in ["text='Rectangle' occurrence='2'", "text='Rectangle' occurrence='2'", "text='Text'"]:
|
||||
# both Rectangles will be clicked because they change their order
|
||||
doubleClick(waitForObject(getQModelIndexStr(item, rootIndex)))
|
||||
snooze(1)
|
||||
subItems = ["text='Rectangle' occurrence='2'", "text='Rectangle'", "text='Text'"]
|
||||
subItems = ["text='Rectangle'", "text='Rectangle' occurrence='2'", "text='Text'"]
|
||||
for item in subItems:
|
||||
unfoldQModelIndexIncludingProperties(getQModelIndexStr(item, rootIndex))
|
||||
|
||||
def unfoldQModelIndexIncludingProperties(indexStr):
|
||||
tv = waitForObject(':Locals and Expressions_Debugger::Internal::WatchTreeView')
|
||||
# HACK to avoid failing clicks
|
||||
tv.scrollToBottom()
|
||||
doubleClick(waitForObject(indexStr))
|
||||
propIndex = getQModelIndexStr("text='Properties'", indexStr)
|
||||
# HACK to avoid failing clicks
|
||||
tv.scrollToBottom()
|
||||
doubleClick(waitForObject(propIndex))
|
||||
|
||||
def fetchItems(index, valIndex, treeView):
|
||||
|
@@ -34,16 +34,31 @@ def main():
|
||||
startApplication("qtcreator" + SettingsPath)
|
||||
if not startedWithoutPluginError():
|
||||
return
|
||||
for targ, qVer in [[Targets.DESKTOP_480_DEFAULT, "1.1"], [Targets.DESKTOP_521_DEFAULT, "2.1"],
|
||||
[Targets.DESKTOP_521_DEFAULT, "2.2"], [Targets.DESKTOP_531_DEFAULT, "2.3"],
|
||||
[Targets.DESKTOP_521_DEFAULT, "Controls 1.0"], [Targets.DESKTOP_521_DEFAULT, "Controls 1.1"],
|
||||
[Targets.DESKTOP_531_DEFAULT, "Controls 1.2"]]:
|
||||
|
||||
available = [("5.3", False), ("5.3", True)]
|
||||
if platform.system() != 'Darwin':
|
||||
available.extend([("5.4", False), ("5.4", True)])
|
||||
|
||||
for qtVersion, controls in available:
|
||||
if qtVersion == "5.3":
|
||||
targ = Targets.DESKTOP_531_DEFAULT
|
||||
quick = "2.3"
|
||||
else:
|
||||
targ = Targets.DESKTOP_541_GCC
|
||||
quick = "2.4"
|
||||
# using a temporary directory won't mess up a potentially existing
|
||||
workingDir = tempDir()
|
||||
checkedTargets, projectName = createNewQtQuickApplication(workingDir, targets=targ,
|
||||
qtQuickVersion=qVer)
|
||||
minimumQtVersion=qtVersion,
|
||||
withControls = controls)
|
||||
if len(checkedTargets) == 0:
|
||||
test.fatal("Could not check wanted target")
|
||||
continue
|
||||
additionalText = ''
|
||||
if controls:
|
||||
additionalText = ' Controls '
|
||||
test.log("Building project Qt Quick%sApplication (%s)"
|
||||
% (qVer, Targets.getStringForTarget(targ)))
|
||||
% (additionalText, Targets.getStringForTarget(targ)))
|
||||
result = modifyRunSettingsForHookInto(projectName, len(checkedTargets), 11223)
|
||||
invokeMenuItem("Build", "Build All")
|
||||
waitForCompile()
|
||||
@@ -57,10 +72,8 @@ def main():
|
||||
allowAppThroughWinFW(workingDir, projectName)
|
||||
if result:
|
||||
function = "subprocessFunctionQuick2"
|
||||
if qVer[0] == "1":
|
||||
function = "subprocessFunctionQuick1"
|
||||
result = runAndCloseApp(True, projectName, 11223, function,
|
||||
SubprocessType.QT_QUICK_APPLICATION, quickVersion=qVer)
|
||||
SubprocessType.QT_QUICK_APPLICATION, quickVersion=quick)
|
||||
else:
|
||||
result = runAndCloseApp(sType=SubprocessType.QT_QUICK_APPLICATION)
|
||||
removeExecutableAsAttachableAUT(projectName, 11223)
|
||||
@@ -70,7 +83,9 @@ def main():
|
||||
if result == None:
|
||||
checkCompile()
|
||||
else:
|
||||
logApplicationOutput()
|
||||
appOutput = logApplicationOutput()
|
||||
test.verify(not ("main.qml" in appOutput or "MainForm.ui.qml" in appOutput),
|
||||
"Does the Application Output indicate QML errors?")
|
||||
invokeMenuItem("File", "Close All Projects and Editors")
|
||||
|
||||
invokeMenuItem("File", "Exit")
|
||||
@@ -82,8 +97,5 @@ def subprocessFunctionGenericQuick(quickVersion):
|
||||
test.log("Clicking 'Hello World' Text to close QtQuick%dApplicationViewer" % quickVersion)
|
||||
mouseClick(helloWorldText, 5, 5, 0, Qt.LeftButton)
|
||||
|
||||
def subprocessFunctionQuick1():
|
||||
subprocessFunctionGenericQuick(1)
|
||||
|
||||
def subprocessFunctionQuick2():
|
||||
subprocessFunctionGenericQuick(2)
|
||||
|
@@ -31,30 +31,42 @@
|
||||
source("../../shared/qtcreator.py")
|
||||
|
||||
def main():
|
||||
startApplication("qtcreator -load QmlProjectManager" + SettingsPath)
|
||||
startApplication("qtcreator" + SettingsPath)
|
||||
if not startedWithoutPluginError():
|
||||
return
|
||||
for quickVersion in ["1.1", "2.1", "2.2", "2.3", "Controls 1.0", "Controls 1.1", "Controls 1.2"]:
|
||||
available = [("5.3", False), ("5.3", True)]
|
||||
if platform.system() != 'Darwin':
|
||||
available.extend([("5.4", False), ("5.4", True)])
|
||||
|
||||
for qtVersion, controls in available:
|
||||
# using a temporary directory won't mess up a potentially existing
|
||||
workingDir = tempDir()
|
||||
projectName = createNewQtQuickUI(workingDir, quickVersion)
|
||||
projectName = createNewQtQuickUI(workingDir, qtVersion, controls)
|
||||
switchViewTo(ViewConstants.PROJECTS)
|
||||
clickButton(waitForObject(":*Qt Creator.Add Kit_QPushButton"))
|
||||
if qtVersion == "5.3":
|
||||
menuItem = Targets.getStringForTarget(Targets.DESKTOP_531_DEFAULT)
|
||||
quick = "2.3"
|
||||
else:
|
||||
menuItem = Targets.getStringForTarget(Targets.DESKTOP_541_GCC)
|
||||
quick = "2.4"
|
||||
if platform.system() == 'Darwin':
|
||||
waitFor("macHackActivateContextMenuItem(menuItem)", 5000)
|
||||
else:
|
||||
activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' "
|
||||
"window=':Qt Creator_Core::Internal::MainWindow'}", menuItem))
|
||||
test.log("Running project Qt Quick %s UI" % quickVersion)
|
||||
qmlViewer = modifyRunSettingsForHookIntoQtQuickUI(2, 1, workingDir, projectName, 11223, quickVersion)
|
||||
additionalText = ''
|
||||
if controls:
|
||||
additionalText = ' Controls '
|
||||
test.log("Running project Qt Quick%sUI (%s)" % (additionalText, menuItem))
|
||||
qmlViewer = modifyRunSettingsForHookIntoQtQuickUI(2, 1, workingDir, projectName, 11223, quick)
|
||||
if qmlViewer!=None:
|
||||
qmlViewerPath = os.path.dirname(qmlViewer)
|
||||
qmlViewer = os.path.basename(qmlViewer)
|
||||
result = addExecutableAsAttachableAUT(qmlViewer, 11223)
|
||||
allowAppThroughWinFW(qmlViewerPath, qmlViewer, None)
|
||||
if result:
|
||||
result = runAndCloseApp(True, qmlViewer, 11223, sType=SubprocessType.QT_QUICK_UI, quickVersion=quickVersion)
|
||||
result = runAndCloseApp(True, qmlViewer, 11223, sType=SubprocessType.QT_QUICK_UI, quickVersion=quick)
|
||||
else:
|
||||
result = runAndCloseApp(sType=SubprocessType.QT_QUICK_UI)
|
||||
removeExecutableAsAttachableAUT(qmlViewer, 11223)
|
||||
@@ -64,6 +76,8 @@ def main():
|
||||
if result == None:
|
||||
checkCompile()
|
||||
else:
|
||||
logApplicationOutput()
|
||||
appOutput = logApplicationOutput()
|
||||
test.verify(not ("untitled.qml" in appOutput or "MainForm.ui.qml" in appOutput),
|
||||
"Does the Application Output indicate QML errors?")
|
||||
invokeMenuItem("File", "Close All Projects and Editors")
|
||||
invokeMenuItem("File", "Exit")
|
||||
|